Problem of using mbed_override_console

I try the code as stated below. The listing 1 works correctly but listing 2 only prints he and doesn’t show anything else. It shows that whether the code works or not is depending on where I place the declaration. It makes me very concerned. Anyone know what is going on?
I have a C background only. I remember I encountered something similar a year ago and I decided not trying anymore cpp on mcu :frowning:

// /Listing 1
#include <stdio.h>
#include "mbed.h"

using namespace mbed;
int main() { //
    while(1){
        osDelay(1000);
        printf("hello\r\n");
    }
}

UARTSerial console(USBTX, USBRX);
FileHandle *mbed::mbed_override_console(int) {
    // static UARTSerial console(USBTX, USBRX);
    // UARTSerial* console = new UARTSerial(USBTX, USBRX);
    return &console;
}
/// Listing 2
#include <stdio.h>
#include "mbed.h"

using namespace mbed;
int main() { //
    while(1){
        osDelay(1000);
        printf("hello\r\n");
    }
}

// UARTSerial console(USBTX, USBRX);
FileHandle *mbed::mbed_override_console(int) {
    static UARTSerial console(USBTX, USBRX);
    // UARTSerial* console = new UARTSerial(USBTX, USBRX);
    return &console;
}

Tools:

  • mbed-cli==1.8.3
  • mbed-os, fork from 5.10. I made some modifications by deleting unused features library and add my own board target.
  • armcc compiler 5

I believe the problem should be very basic. When i continue to debug, I observer the followings:

  • the mcu is busy to serve serial_device.c/uart_irq
  • the method UARTSerial.tx_irq is never being called again

I think i have to go through some codes to understand the class relationship but it may take some time. If any expert can help, it is much appreciated.

I think something is wrong with my own target. It explains why I see this problem again. I did try to create new target in mbed-os last time.

Anyway, my target board is similar to NUCLEO_F303RE. The differences are

  • NUCLEO_F303RE uses uart2 for usb serial. My target makes use of uart1
  • my target doesnt have DAP interface. i use stlink to load program.

The reason I conclude like that because after trying to compile the project with the target NUCLEO_F303RE, listing 2 works fine. Here is how I created my own target,

  • i duplicate the dir .\mbed-os\targets\TARGET_STM\TARGET_STM32F3\TARGET_STM32F303xE\TARGET_NUCLEO_F303RE and rename it to TARGET_MY_BOARD
  • in the dir above/PinNames.h, i map USBTX to pa9 and USBRX to pa10
  • in the .\mbed-os\targets\target.json, i add my board entry like below (which is exactly the same config of NUCLEO_F303RE)
# PinNames.h
    // STDIO for console print
#ifdef MBED_CONF_TARGET_STDIO_UART_TX
    STDIO_UART_TX = MBED_CONF_TARGET_STDIO_UART_TX,
#else
    STDIO_UART_TX = PA_9,
#endif
#ifdef MBED_CONF_TARGET_STDIO_UART_RX
    STDIO_UART_RX = MBED_CONF_TARGET_STDIO_UART_RX,
#else
    STDIO_UART_RX = PA_10,
#endif
    // Generic signals namings
    LED1        = PB_0,
    USER_BUTTON = PA_8,
    "MY_BOARD": {
        "inherits": ["FAMILY_STM32"],
        "supported_form_factors": ["ARDUINO", "MORPHO"],
        "core": "Cortex-M4F",
        "extra_labels_add": ["STM32F3", "STM32F303xE", "STM32F303RE"],
        "config": {
            "clock_source": {
                "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI",
                "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI",
                "macro_name": "CLOCK_SOURCE"
            }
        },
        "detect_code": ["9999"],
        "device_has_add": ["ANALOGOUT", "CAN", "CRC", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"],
        "release_versions": ["2", "5"],
        "bootloader_supported": false,
        "device_name": "STM32F303RE"
    },   
    "NUCLEO_F303RE": {
        "inherits": ["FAMILY_STM32"],
        "supported_form_factors": ["ARDUINO", "MORPHO"],
        "core": "Cortex-M4F",
        "extra_labels_add": ["STM32F3", "STM32F303xE", "STM32F303RE"],
        "config": {
            "clock_source": {
                "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI",
                "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI",
                "macro_name": "CLOCK_SOURCE"
            }
        },
        "detect_code": ["0745"],
        "device_has_add": ["ANALOGOUT", "CAN", "CRC", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"],
        "release_versions": ["2", "5"],
        "bootloader_supported": true,
        "device_name": "STM32F303RE"
    },

These should be all, right?

I figured out where the problem is. I have another source file for testing. It contains an instance of serial port. As the result of that, the port is configured twice. It leads the issue as stated above. Although, I didnt plan to use the testing source file, mbed-cli compiles all the source files in the project folder anyway and my program initialized the port unintentionally.

Lesson learnt is avoid global declaration when writing code or add the file into mbedignore.

Hello Khiem,

Thank you for bringing the answer back to this post. It really makes searching for answers here so much better.

Best wishes,
Earl, Team mbed

it is my pleasure to learn from mbed softwrae