System hangs when using dual UARTs (UART20 & UART30) on nRF54L15

Hello, 

I am developing a project on the nRF54L15 and encountered a system hang when using two UART instances simultaneously: UART20 (for logging and printk) and UART30 (for external device communication).

Symptoms:

  • When compiled with Default settings, the system hangs as soon as there is concurrent output from both the logs and UART30.

  • When compiled with the -g (Debug) flag, the program runs normally without any issues.

  • If I set CONFIG_LOG=n in the Default build (printk can output), the program also runs normally.

Configuration:

  • UART30 is configured with CONFIG_UART_INTERRUPT_DRIVEN=y and CONFIG_UART_30_INTERRUPT_DRIVEN=y.

I am unsure why the logging system is causing the crash in the release/default build while the debug build works fine. Are there known conflicts between the logging backend and interrupt-driven UART on this series? How can I resolve this?

Parents
  • Hi,

    On the nRF54L15 this behavior is expected if TF-M is enabled and the same UART instance is used by both the secure and non-secure domains. As the system is split into a secure image (TF-M) and a non-secure application. The application you build and run is the non-secure one, while TF-M runs separately in the secure world and is built automatically when enabled. By default on nRF54L, the non-secure application typically uses UART20, while TF-M uses UART30 for logging.

    If the non-secure application also configures UART30 (for example, for external device communication with CONFIG_UART_INTERRUPT_DRIVEN), this can lead to undefined behavior or hangs when logging is active, as both domains end up interacting with the same UART. This also explains why the issue disappears when logging is disabled, and why it may not reproduce in a debug (-g) build due to timing and layout differences.

    To resolve this, we recommend one of the following:

    1. Disable TF-M logging if it is not needed which will free up UART30 by adding this to your prj.conf:
      CONFIG_TFM_LOG_LEVEL_SILENCE=y
    2. Avoid using UART30 in the non-secure application and move the external device to another UART instance (e.g. UART21 or another available UART)
    3. Switch application logging to a non-UART backend, such as RTT, to avoid UART resource conflicts during development.

    After applying one of the above, using multiple UARTs concurrently in the non-secure application should work as expected. Best Regards,

    Syed Maysum

  • Hi Syed,

    I previously tested my project using the cpuapp/ns (Non-Secure) target and confirmed that setting CONFIG_TFM_LOG_LEVEL_SILENCE=y allowed both the application logs and UART_CONSOLE to function correctly.

    Currently, I am building for the cpuapp target. I have the following technical questions regarding the behavior I've observed:

    TF-M Activation in cpuapp Builds: When building for the cpuapp target, is TF-M still enabled by default? Specifically, if MCUBoot is included in the project, does it automatically trigger the activation of TF-M (Trusted Firmware-M)?

    Current Workaround: I have confirmed that adding CONFIG_TFM_LOG_LEVEL_SILENCE=y to my current cpuapp build resolves the system hang. Without this setting, the program freezes as soon as UART30 begins transmission.

    Resource Contention: Why does silencing TF-M logs prevent the application from hanging? It appears that the Secure Domain's logging mechanism conflicts with the application's interrupt-driven UART (UART30), even when the application is not explicitly built as "Non-Secure."

    Can the UART output instance of TF-M be switched?

Reply
  • Hi Syed,

    I previously tested my project using the cpuapp/ns (Non-Secure) target and confirmed that setting CONFIG_TFM_LOG_LEVEL_SILENCE=y allowed both the application logs and UART_CONSOLE to function correctly.

    Currently, I am building for the cpuapp target. I have the following technical questions regarding the behavior I've observed:

    TF-M Activation in cpuapp Builds: When building for the cpuapp target, is TF-M still enabled by default? Specifically, if MCUBoot is included in the project, does it automatically trigger the activation of TF-M (Trusted Firmware-M)?

    Current Workaround: I have confirmed that adding CONFIG_TFM_LOG_LEVEL_SILENCE=y to my current cpuapp build resolves the system hang. Without this setting, the program freezes as soon as UART30 begins transmission.

    Resource Contention: Why does silencing TF-M logs prevent the application from hanging? It appears that the Secure Domain's logging mechanism conflicts with the application's interrupt-driven UART (UART30), even when the application is not explicitly built as "Non-Secure."

    Can the UART output instance of TF-M be switched?

Children
No Data
Related