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.

  • 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

Reply
  • 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

Children
Related