ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.67k stars 2.98k forks source link

Output to USBSerial freezes execution on Arduino Nano 33 BLE #12091

Closed asprenger closed 2 years ago

asprenger commented 4 years ago

Description of defect

I trying to create a working setup for an Arduino Nano 33 BLE board with Mbed for an upcoming project. I'm having problems with simple printf() output to the serial terminal.

The following code freezes after 520 seconds.

#include "mbed.h"
#include "USBSerial.h"

#define SLEEP_TIME 100

USBSerial serial(false);
FileHandle *mbed::mbed_override_console(int) {
  return &serial;
}

static mbed::Timer t;
int i = 0;
int main() {
  t.start();
  serial.connect();
  while (true) {
    printf("%d\n\r", t.read_ms());
    printf("Hello-%d\n\r", i++);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

I don't know what happens after 520 seconds but its reproducible and it does not depend on the amount of data written to the console or frequency. I had no success so far analysing this with an Ozon debugger. When I launch the script from the debugger the problem does not show up. When I attach the debugger after the freeze I only see activity from the idle thread but do not know if the main thread is blocked somewhere or has terminated.

I'll try with a debugger that is aware of threads.

The other question is if the USBSerial is the proper way to write to the console for this board. But this is the only way I could get working.

Target(s) affected by this defect ?

ARDUINO_NANO33BLE

Toolchain(s) (name and version) displaying this defect ?

GCC_ARM gcc version 8.3.1 20190703 (release) [gcc-8-branch revision 273027] (GNU Tools for Arm Embedded Processors 8-2019-q3-update)

What version of Mbed-os are you using (tag or sha) ?

https://github.com/ARMmbed/mbed-os/#cf4f12a123c05fcae83fc56d76442015cb8a39e9

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli version 1.10.1

How is this defect reproduced ?

See scripts included above.

trowbridgec commented 4 years ago

@asprenger When I've used the USBSerial class starting in disconnected mode, I've usually added a call to the wait_ready() function after calling connect().

Can you try something like this?

#include "mbed.h"
#include "USBSerial.h"

#define SLEEP_TIME 100

USBSerial serial(false);
FileHandle *mbed::mbed_override_console(int) {
  return &serial;
}

static mbed::Timer t;
int i = 0;
int main() {
  t.start();
  serial.connect();
  serial.wait_ready();
  while (true) {
    printf("%d\n\r", t.read_ms());
    printf("Hello-%d\n\r", i++);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

You can see that that's essentially what they do in the constructor for a USBSerial object when you set connect_blocking to true:

USBSerial::USBSerial(bool connect_blocking, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
    USBCDC(get_usb_phy(), vendor_id, product_id, product_release)
{
    _settings_changed_callback = 0;

    if (connect_blocking) {
        connect();
        wait_ready();
    } else {
        init();
    }
}
asprenger commented 4 years ago

@trowbridgec Thanks for picking this up. The wait_ready() is not the issue. If you use it the application blocks at this point until a serial terminal connects. I you leave it out it works as well, you might just loose the output written to the USBSerial until a serial terminal connects.

I looked more into this. My initial assessment has been wrong, the problem is not related to USBSerial. The issue is an overflow in some low level code that triggers an interrupt that is not properly handled. The Arduino core implementation for the board has a fix for this: https://github.com/arduino/ArduinoCore-nRF528x-mbedos/blob/a5bce2f964d2ff877a6a59ec366e071ca116598e/variants/ARDUINO_NANO33BLE/variant.cpp#L74

I still need to look more into to get a better understanding.

asprenger commented 4 years ago

There are some other issues and for me the Arduino Nano 33 BLE is broken for Mbed development. But the main users of the board are probably people developing with the Arduino stack anyway.

kjbracey commented 4 years ago

Just going to add a note that if the USB is the primary debug output port here on this board, then the target itself should be providing mbed::mbed_target_override_console so that printf on its own automatically goes there without the application needing to handle it.

If the board has a couple of options, then it could be providing a target.console-type option to select between UART and USB.

Applications should only need to do their own overrides in non-typical scenarios for a board - eg redirecting a console off to a plugged-in Arduino shield.

asprenger commented 4 years ago

@kjbracey-arm I fully agree, default console configuration should be handled in the target code. It took us some time to figure out how this works. We found another issue with the error/fault reporting in the board (https://github.com/ARMmbed/mbed-os/issues/12053). It might just be that there is not enough interest to make Mbed fully working on this board. It's not an official Mbed board, does not support DAP link (at least not out of the box) and most buyers will probably use the Arduino toolchain.

ciarmcom commented 4 years ago

Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers. Internal Jira reference: https://jira.arm.com/browse/IOTOSM-2295

ghost commented 4 years ago

Is this really specific to the nano33 or to all nrf5 boards with USB?

ciarmcom commented 2 years ago

We closed this issue because it has been inactive for quite some time and we believe it to be low priority. If you think that the priority should be higher, then please reopen with your justification for increasing the priority.