Compilation of nRF9151 project with TF-M log routed to UART0 results in error "undefined reference to stdio_init"

I'm developing a project, where I use nRF9151 as a GPS sensor, and nRF52833 as a BLE gateway. I want to send data from 9151 to 52833 over one of UARTs. The problems I'm facing now are either runtime or compile time, depending on the set of configurations. I was able to reproduce this issue on the nRF9151DK.

This demo consists of 3 files.
main.c:

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/uart.h>

#include <nrf_modem_gnss.h>
#include <modem/nrf_modem_lib.h>

#include <modem/lte_lc.h>


LOG_MODULE_REGISTER(main_app, LOG_LEVEL_DBG);

int main(void)
{
LOG_DBG("Starting main app thread on hw %s", CONFIG_BOARD);
return 0;
}


const struct device * uart_1 = DEVICE_DT_GET(DT_NODELABEL(uart1));


void uart1_thread(void* p1, void* p2, void* p3)
{
LOG_DBG("Starting UART1 thread");

if (!device_is_ready(uart_1))
{
LOG_ERR("UART1 init failed");
}

const struct uart_config uart_cfg = {
.baudrate = 115200,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
.data_bits = UART_CFG_DATA_BITS_8,
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};

int err = uart_configure(uart_1, &uart_cfg);
if (err != 0) {
LOG_ERR("UART1 init failed %d", err);
}

uint8_t tx_buff[32] = {0};
snprintf(tx_buff, 20, "%s\n", "hello world\n");

while(1)
{
k_msleep(1000);
uart_tx(uart_1, tx_buff, 20, SYS_FOREVER_MS);
LOG_DBG("UART 1 msg sent");
}
}

K_THREAD_DEFINE(uart1_thr_id, 1024, uart1_thread, NULL, NULL, NULL, 6, 0, 10);

static int modem_configure(void)
{
int err;

LOG_INF("Initializing modem library");

err = nrf_modem_lib_init();
if (err) {
LOG_ERR("Failed to initialize the modem library, error: %d", err);
return err;
}

return 0;
}


void gps_thread(void* p1, void* p2, void* p3)
{
LOG_DBG("Starting GPS thread");

modem_configure();

LOG_DBG("func mode set");
// if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_ACTIVATE_GNSS) != 0) {
if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL) != 0) {
LOG_ERR("Failed to activate GNSS functional mode");
return;
}

while(1)
{
k_msleep(5000);
LOG_DBG("GPS cycle");
}
}

K_THREAD_DEFINE(gps_thr_id, 1024, gps_thread, NULL, NULL, NULL, 6, 0, 10);


prj.conf (it's taken from another project, so it's not a minimal subset of configs)


CONFIG_GPIO=y

CONFIG_SHELL=y
CONFIG_KERNEL_SHELL=y

CONFIG_SERIAL=y

CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_SHELL_VT100_COMMANDS=y
CONFIG_SHELL_VT100_COLORS=y
CONFIG_SHELL_STACK_SIZE=4096
CONFIG_SHELL_CMD_BUFF_SIZE=128

CONFIG_SHELL_WILDCARD=n
CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT=n
CONFIG_SHELL_STATS=n
CONFIG_SHELL_CMDS=n
CONFIG_SHELL_HISTORY=y

CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_DEBUG_THREAD_INFO=y

# Enable CPP support
CONFIG_CPP=y

CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3

CONFIG_REBOOT=y

CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

CONFIG_NRF_MODEM_LIB=y
CONFIG_NRF_MODEM_LIB_LOG_FW_VERSION_UUID=y

CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M_GPS=y

CONFIG_NRF_MODEM_LIB_FAULT_STRERROR=n

CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1536

# CONFIG_AT_HOST_LIBRARY=y
CONFIG_NRF_MODEM_LIB_SHMEM_RX_SIZE=8192
CONFIG_NRF_MODEM_LIB_SHMEM_TX_SIZE=8192


CONFIG_UART_ASYNC_API=y
CONFIG_UART_0_ASYNC=n
#CONFIG_UART_1_ASYNC=y
#CONFIG_UART_1_INTERRUPT_DRIVEN=n
CONFIG_UART_USE_RUNTIME_CONFIGURE=y

CONFIG_TFM_SECURE_UART0=y
#CONFIG_TFM_LOG_LEVEL_SILENCE=y

nrf9151dk_nrf9151.overlay

&pinctrl {
uart0_default: uart0_default {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 18)>,
<NRF_PSEL(UART_RX, 0, 17)>;
};
};

uart0_sleep: uart0_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 18)>,
<NRF_PSEL(UART_RX, 0, 17)>;
low-power-enable;
};
};

uart1_default: uart1_default {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 22)>,
<NRF_PSEL(UART_RX, 0, 21)>;
};
};
uart1_sleep: uart1_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 22)>,
<NRF_PSEL(UART_RX, 0, 21)>;
low-power-enable;
};
};

};

&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <115200>;
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};

&uart1 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <115200>;
pinctrl-0 = <&uart1_default>;
pinctrl-1 = <&uart1_sleep>;
pinctrl-names = "default", "sleep";
};

I use nRF Connect SDK 3.0.2.

I'm trying to follow this manual: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/security/tfm/tfm_logging.html.
When I use config CONFIG_TFM_SECURE_UART0 , compilation fails with the following error:
nrf-sdk/v3.0.2/modules/tee/tf-m/trusted-firmware-m/platform/ext/target/nordic_nrf/common/core/tfm_hal_platform_common.c:36: undefined reference to `stdio_init'

When at the same time I use config
CONFIG_TFM_LOG_LEVEL_SILENCE=y, compilation works, but when I flash the DK - the board stays silent on both UARTs.

I've also attempted changing TF-M logging properties inside the Kconfig, but it was always resulting either in various compilation errors or a silent board.

Primary question of this post: what config would allow me to compile and link file `uart_stdout.c` (the definition of stdio_init is there)? I have an impression that I'm missing a simple configuration flag.
More global (and more important to me) question: is there a comprehensive guide on how to reliably use UART1 in nRF9151 for inter-MCU communication on a system with TF-M (which is required to run modem firmware)? All my attempts so far ended either in: compilation error, silent board or runtime errors, throwing a secure fault on the first call to the `uart_tx` method of Zephyr UART API
Parents
  • Sorry for the formatting in the end. Here is the normal formatting of the last 5 paragraphs

    nrf-sdk/v3.0.2/modules/tee/tf-m/trusted-firmware-m/platform/ext/target/nordic_nrf/common/core/tfm_hal_platform_common.c:36: undefined reference to `stdio_init'
    When at the same time I use config CONFIG_TFM_LOG_LEVEL_SILENCE=y, compilation works, but when I flash the DK - the board stays silent on both UARTs.

    I've also attempted changing TF-M logging properties inside the Kconfig, but it was always resulting either in various compilation errors or a silent board.

    Primary question of this post: what config would allow me to compile and link file `uart_stdout.c` (the definition of stdio_init is there)? I have an impression that I'm missing a simple configuration flag.

    More global (and more important to me) question: is there a comprehensive guide on how to reliably use UART1 in nRF9151 for inter-MCU communication on a system with TF-M (which is required to run modem firmware)? All my attempts so far ended either in: compilation error, silent board or runtime errors, throwing a secure fault on the first call to the `uart_tx` method of Zephyr UART API

  • Hi,

    roman.turkin said:
    Primary question of this post: what config would allow me to compile and link file `uart_stdout.c` (the definition of stdio_init is there)? I have an impression that I'm missing a simple configuration flag.

    This looks like the same issue as mentioned here.

    roman.turkin said:
    When at the same time I use config CONFIG_TFM_LOG_LEVEL_SILENCE=y, compilation works, but when I flash the DK - the board stays silent on both UARTs.

    I've seen some variations of this as well, though I am bit uncertain about what the case is with this particular NCS version. So CONFIG_TFM_LOG_LEVEL_SILENCE disables all UART drivers after the custom secure partition code has configured its things. This can be mended by adding back the nrfx uarte driver, or alternatively I think enabling CONFIG_TFM_SECURE_UART1 could work. Could you give either of these a try?

    Regards,

    Elfving

  • The problem seems to be that if SILENCE config is enabled, TF-M fails to start completely. Debugger fails to attach to the core, both UARTs are silent.

    If I enable CONFIG_TFM_SECURE_UART0=y or CONFIG_TFM_SECURE_UART1=y, or none are specified, I get the same compilation error:
    modules/tee/tf-m/trusted-firmware-m/platform/ext/target/nordic_nrf/common/core/tfm_hal_platform_common.c:36: undefined reference to `stdio_init'

    When both are not specified and config CONFIG_TFM_LOG_LEVEL_SILENCE=y is specified - the board is silent, and I can't attach with a debugger (I use VS Code + J-Link). Every other flashing debugger fails at the start with "protection enabled" error. Error disappears after running "nrfjprog --recover".

    On another board I was able to compile a similar setup, and there I was getting a secure fault upon the first attempt to call `uart_tx()` on any UARTs (except for UART0). I wasn't yet able to reproduce a similar issue on the devkit, so far only compilation errors and/or TF-M failing to boot.

Reply
  • The problem seems to be that if SILENCE config is enabled, TF-M fails to start completely. Debugger fails to attach to the core, both UARTs are silent.

    If I enable CONFIG_TFM_SECURE_UART0=y or CONFIG_TFM_SECURE_UART1=y, or none are specified, I get the same compilation error:
    modules/tee/tf-m/trusted-firmware-m/platform/ext/target/nordic_nrf/common/core/tfm_hal_platform_common.c:36: undefined reference to `stdio_init'

    When both are not specified and config CONFIG_TFM_LOG_LEVEL_SILENCE=y is specified - the board is silent, and I can't attach with a debugger (I use VS Code + J-Link). Every other flashing debugger fails at the start with "protection enabled" error. Error disappears after running "nrfjprog --recover".

    On another board I was able to compile a similar setup, and there I was getting a secure fault upon the first attempt to call `uart_tx()` on any UARTs (except for UART0). I wasn't yet able to reproduce a similar issue on the devkit, so far only compilation errors and/or TF-M failing to boot.

Children
  • roman.turkin said:
    On another board I was able to compile a similar setup, and there I was getting a secure fault upon the first attempt to call `uart_tx()` on any UARTs (except for UART0). I wasn't yet able to reproduce a similar issue on the devkit, so far only compilation errors and/or TF-M failing to boot.

    I see. Though on your custom board you are seeing this with a basic sample as well? I am not immediately seeing how this can be related to HW, but that it's not something you can reproduce on a DK begs the question that it is related to HW. Have you had a HW review from us on this custom board? We do offer those for free (though preferably on a private case, this one is public).

    Regards,

    Elfving 

  • Hi Elfving

    The problem described in this thread is the one that I have been able to reproduce on the devkit.
    The problem I experience on the devkit is slightly different. There I launch 2 threads, one to collect GPS data, another one to obtain a communication channel towards a BLE chip. On the custom board I experience the following exception:

    *** Booting nRF Connect SDK v3.0.2-89ba1294ac9b ***
    *** Using Zephyr OS v4.0.99-f791c49f492c ***
    [00:00:00.387,878] <dbg> main_app: main: Starting main app thread on hw ZeonyxFlyN91
    [00:00:00.387,908] <dbg> gnss: gnss_thread: Starting GNSS thread
    [00:00:00.387,908] <inf> gnss: Initializing modem library
    [00:00:00.487,915] <dbg> m2m: inter_mcu_thread: Starting M2M thread
    [00:00:00.487,945] <dbg> m2m: send_keepalive_message_to_n52: message length: 12
    [00:00:00.487,976] <err> m2m: UART send failed (0)
    [00:00:00.491,271] <err> os: ***** SECURE FAULT *****
    [00:00:00.491,271] <err> os:   Address: 0x10
    [00:00:00.491,302] <err> os:   Attribution unit violation
    [00:00:00.491,302] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000003  r2/a3:  0x00000000
    [00:00:00.491,333] <err> os: r3/a4:  0x0001e6c9 r12/ip:  0x2000cb7c r14/lr:  0x0001e797
    [00:00:00.491,333] <err> os:  xpsr:  0x41000000
    [00:00:00.491,363] <err> os: Faulting instruction address (r15/pc): 0x00011288
    [00:00:00.491,394] <err> os: >>> ZEPHYR FATAL ERROR 41: Unknown error on CPU 0
    [00:00:00.491,455] <err> os: Current thread: 0x2000c870 (m2m_thr_id)
    [00:00:00.608,398] <err> os: Halting system
    uart:~$


    Unfortunately, I cannot attach the whole project. This exception happens upon the call to the function `uart_tx` in the thread that attempts to use UART1 to communicate to BLE chip. This happens, if I delay the launch of the communication thread by 100 ms, otherwise the system stays silent.

  • roman.turkin said:
    The problem described in this thread is the one that I have been able to reproduce on the devkit.
    The problem I experience on the devkit is slightly different.

    Not sure if I understand. It is the same problem, but slightly different due to what you run on it? Could you try running the same sw on both and see if there is a difference?

    Regards,

    Elfving

  • Alright, I've executed identical code on the DK and ended up in the same issue.
    I'm able to reproduce it in the runtime, and it's not identical to the issue described in the topic.
    I'll create another ticket, and I will use my next reply as an answer (I found solution to the compile time errors)

  • Hi  
    I found the rootcause of my underlying issue. It has been a missing return in a function that is supposed to return something.

Related