Debugging issues whe using Mbed Studio on Linux

Let me first thank you for supporting Linux!

Below are a few issues I came across while trying to use Mbed Studio IDE on Ubuntu 18.04.


I have tried to build and debug a mbed-os-example-blinky-baremetal program.

After selecting NUCLEO-F446RE as my target I tried to debug.
But when stepping over

thread_sleep_for(WAIT_TIME);

the following error message was reported:

...
TransferFaultError: SWD/JTAG Transfer Fault @ 0xe000edf0-0xe000edf7
"0028950:ERROR:gdbserver:Unhandled exception in handle_message: SWD/JTAG Transfer Fault @ 0xe000edf0-0xe000edf7"
Remote failure reply: E01

Unfortunately, to get read of the following message and continue in debugging I had to reboot the linux machine:

error: [Errno 98] Address already in use
"GDB server stopped unexpectedly with exit code 1"

If someone knows about a more friendly and faster way please let me know.

Strangely, after rebooting and replacing

thread_sleep_for(WAIT_TIME);

with a deprecated

wait_ms(WAIT_TIME);

I was able to continue in debugging.


When I selected mbed LPC1768 as my target and tried to debug I have received the following error message:

...
TransferError: No ACK received
"0005428:ERROR:gdbserver:Unhandled exception in handle_message: No ACK received"
Remote failure reply: E01

Any idea how to get rid of it?

Thank you in advance.

NOTE: Everybody is welcome to use this thread for reporting his/her experience/feedback on using Mbed Studio on Linux.

Hi Zoltan,

I have the Nucleo-F446RE but I work on Windows. However I get same error like you, so that issue probably has nothing to do with the Linux.

But it is probably about the board because is still not supported. Here is the list of supported/confirmed boards for debugging in the Mbedstudio.

BR, Jan

Ahoj Jan,

Thank you for the useful info!

  • That explains the mbed LPC1768. Anyway, I’m a bit surprised that debugging on the former mbed flagship (first mbed board) is not supported by pyOCD :frowning:
  • The good news is that the NUCLEO-F446RE (with the wait_ms(WAIT_TIME) workaround) works despite of not being listed yet :slight_smile:

I know! What a shame - I’ve done previous work on that board and now it’ll have to go on a shelf and I’ll need to buy something else.

I know you can’t live in the past, but removing support for so many earlier boards undermines the whole concept of what ‘mbed board’ means. Now boards aren’t ‘mbed’, they are only ‘mbed-for-the-time-being’.

Just in case someone else faced this same issue recently, I have the following workaround.
I’m using a Nucleo-L476RG and the Mbed OS 6.17.0

I’ve started from the simple blinky example. On the first debug session everything worked fine till the debugger reached the sleep_for line. Here is the blinky standard code (simplified):

#include "mbed.h"

int main()
{
    DigitalOut led(LED1);

    while (true) {
        led = !led;
        ThisThread::sleep_for(500ms); // here the debugging session crashes
    }
}

You actually don’t need to reboot your machine. As far as I could understand, once this crash happens the pyOCD server (the debugging tool server) does not finish as it should. Killing the process associated with the pyOCD allows you to start a new debugging session properly. However, this is not a robust troubleshooting; the new debugging session will fail again on the sleep_for line.

Using the Debug build profile, on build the ‘flag’ MBED_DEBUG is defined. Beyond that, the wait_us function do not crash the debug session, then I suggest the following:

#include "mbed.h"

int main()
{
    DigitalOut led(LED1);
    while (true) {
        led = !led;
#ifdef MBED_DEBUG
        wait_us(1000000);
#else
        ThisTread::sleep_for(1s);
#endif
    }
}

It’s advisable to use sleep_for on non-debug builds, as noted by the mbed_wait_api.h:

/** Waits a number of microseconds.
 *
 *  @param us the whole number of microseconds to wait
 *
 *  @note
 *    This function always spins to get the exact number of microseconds.
 *    This will affect power and multithread performance. Therefore, spinning for
 *    millisecond wait is not recommended, and ThisThread::sleep_for should
 *    be used instead.
 *
 *  @note You may call this function from ISR context, but large delays may
 *    impact system stability - interrupt handlers should take less than
 *    50us.
 */
void wait_us(int us);

Plus: as suggested by bthebaudeau’s comment, another workaround (maybe clever than mine’s) is:

#include "mbed.h"

int main()
{
#ifdef MBED_DEBUG
    HAL_DBGMCU_EnableDBGSleepMode();
#endif

    DigitalOut led(LED1);
    while (true) {
        led = !led;
        ThisThread::sleep_for(500ms);
    }
}