Porting MBed OS 6 to Adafruit nrf52840 Feather...redirect default printf() to USBSerial

Hi,
I have managed to port Mbed OS 6 to the Adafruit Feather nrf52840 and have been testing to make sure all functionality is working. The simple blink LED works and the BLE Gatt Server also works, so I know many things are working. The best part is the USBSerial also works so I can use serial.printf() for debugging through the virtual USB com port.

I have one thing I really do want working is the default printf() to also go to the USBSeral com port, so I do not need to define the USBSerial in code.

My boards section of the PinNames.h is shown below:

RX_PIN_NUMBER  = p24,
TX_PIN_NUMBER  = p25,
CTS_PIN_NUMBER = NC,
RTS_PIN_NUMBER = NC,

// mBed interface Pins
USBTX = TX_PIN_NUMBER,
USBRX = RX_PIN_NUMBER,
STDIO_UART_TX = TX_PIN_NUMBER,
STDIO_UART_RX = RX_PIN_NUMBER,
STDIO_UART_CTS = CTS_PIN_NUMBER,
STDIO_UART_RTS = RTS_PIN_NUMBER,

My Simple example code is shown below:

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

DigitalOut led1(LED_RED);
USBSerial serial;

// main() runs in its own thread in the OS
int main()
{
    while (true) {
      serial.printf("hello\r\n");
      printf("hello2\r\n");
      // Blink LED
      led1 = !led1;
      wait_us(1000 * 1000);
    }
}

The console shows “hello” every second, but “hello2” does not.
Any ideas on how to setup the board definition are appreciated.

Thanks

Hello Mark,

You can try to define a custom console as advised here. For example:

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

DigitalOut  led1(LED_RED);

FileHandle* mbed::mbed_override_console(int)
{
    static USBSerial  usbSerialConsole;
    return &usbSerialConsole;
}

int main()
{
    while (true) {
        printf("hello\r\n");
        led1 = !led1;
        wait_us(1000 * 1000);
    }
}

If it works you can try to move:

#include "USBSerial.h"

FileHandle* mbed::mbed_override_console(int)
{
    static USBSerial  usbSerialConsole;
    return &usbSerialConsole;
}

to the PinNames.h (or other proper file) of your Adafruit Feather nrf52840 custom board.

Best regards, Zoltan

2 Likes

Hi Zoltan,
That did work great when I placed it in the main.cpp. :+1:
Trying to move it to a spot such as PinNames.h or Devices.h proves much harder. Lots of type conflicts with other header files that I tried to fix but might be a little beyond me. I looked through GitHub for examples of implementations that are not in main.cpp and they do not seem to exist.

Is implementing the mbed_override_console() method the suggested way to handle redirection of the default printf() when porting to a new board?
Seems there would be some boards that write to a UART and others to USB.

If it is the way to do it then I guess I need to continue to figure out the conflicts when I add that routine to the header files.

Thanks for the information.
Mark

Hello Mark,

For testing I did the following:

  • Created a new Adafruit_Feather_NRF52840 library.
  • In the Adafruit_Feather_NRF52840 library I have created a new custom_targets.json file with the following content:
{
    "Adafruit_Feather_NRF52840": {
        "inherits": ["MCU_NRF52840"],
        "device_name": "Adafruit_Feather_NRF52840"
    }
}
  • In the Adafruit_Feather_NRF52840 library I have created a new TARGET_Adafruit_Feather_NRF52840 folder.
  • Because I don’t have your custom files, I copy&pasted the device.h and PinNames.h files from the mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/TARGET_NRF52840_DK folder into the TARGET_Adafruit_Feather_NRF52840 folder.
  • In the TARGET_Adafruit_Feather_NRF52840 folder I have created a new UsbConsole.h file.
  • Copy and pasted the following code into the UsbConsole.h file:
#include "USBSerial.h"

FileHandle* mbed::mbed_override_console(int)
{
    static USBSerial  usbSerialConsole;
    return &usbSerialConsole;
}
  • Created a new project with main.cpp as below:
#include "mbed.h"
#include "UsbConsole.h"

DigitalOut  led1(LED_RED);

int main()
{
    while (true) {
        printf("hello\r\n");
        led1 = !led1;
        wait_us(1000 * 1000);
    }
}
  • Added the Adafruit_Feather_NRF52840 library to the project.
  • When I was building the project for the Adafruit_Feather_NRF52840 custom target it compiled smoothly.

The above could help you get started. Then adapt/configure the custom_targets.json to the real Adafruit Feather NRF52840 board.

Best regards, Zoltan

Hi Zoltan,
I think the only step I was missing from above was creating my own UsbConsole.h file. I was trying to add the mbed_override_console() method to the existing pinNames.h or Devices.h…and that did not go down well.
Your explanation of how to create a custom board configuration was exceptional. Thanks to taking the time to do that. It was very much appreciated.

Thanks
Mark