Configuring logging on the nRF54H20
To read logs on the nRF54H20 DK, you can use the following methods:
A direct UART connection to a specific core.
Local domain logging with System Trace Macrocell (STM). STM has two modes:
Standalone logging
Assisted multicore logging
For general information on how logging works in the nRF Connect SDK, consult the Logging in nRF Connect SDK and Logging documentation pages.
nRF54H20 logging using a direct UART connection
Similarly to other SoCs from Nordic Semiconductor, to use a UART connection for reading logs, follow the UART logging guide in the application development section.
nRF54H20 logging using System Trace Macrocell (STM)
nRF54H20 domains include ARM Coresight System Trace Macrocell (STM) hardware, which collects trace data from multiple domains using standalone or assisted multicore logging. The STM writes trace data generated by the domains using memory-mapped registers. The STM multiplexes trace protocol data, formatted according to the MIPI System Trace Protocol (STP) v2, and sends it to a single output, like a UART. This approach has a minimal cost on performance and code size, allowing for a non-intrusive collection of system debug-and-trace information.
The STM implements a frontend of the Zephyr logging subsystem, allowing you to use the standard Zephyr logging API. For more information on STM, see Multi-domain logging using ARM Coresight STM.
Note
The STM logging feature for the nRF54H20 SoC underwent testing with the J-Trace PRO V2 Cortex-M, using firmware compiled on Mar 28 2024 15:14:04.
Using this feature also requires nrfutil-trace version 2.10.0 or later.
Embedded Trace Router (ETR)
The Embedded Trace Router (ETR) is a hardware feature that provides a circular buffer in RAM for trace data. For more information on ETR, see Multi-domain logging using ARM Coresight STM.
When using ETR on the nRF54H20 SoC, one of the cores acts as a proxy to manage the trace data.
Note
Currently, only the Application core can act as a proxy.
The proxy core is responsible for handling the data from the ETR and outputting it through the desired transport mechanism (like UART or USB). The proxy core approach allows for on-chip data processing, offering more flexibility than the Trace Port Interface Unit (TPIU). However, the limited size of the ETR buffer poses a risk of data loss if not handled appropriately.
Standalone logging
The standalone logging mode with STM on the nRF54H20 SoC works as follows:
All domains write the raw encoded log data to their own STM peripheral called the STM Extended Stimulus Port (STMESP).
The STMESP generates a data stream based on the register writes.
The STM multiplexes the data stream with streams from other domains, and it places them in the single memory buffer provided by the ETR.
The application core, acting as the ETR-designated proxy, reads the buffer and decodes the raw encoded log data.
The IronSide Secure Enclave (IronSide SE) outputs the logging data in a human-readable format over UART.
Standalone logging leverages the frontend API of the Zephyr logging subsystem to select the stimulus ports and writes log messages directly to memory-mapped registers. This method bypasses the need for string formatting functions and peripheral drivers, as the core writes directly to the STM port.
Configuring logging
To show the logs for a given domain in the UART output, you must enable the STM for both the application core (as the ETR buffer processing proxy) and that domain’s CPU. To do so, use the Nordic Standalone STM logging snippet (nordic-log-stm) snippet when building the application for the related cores: For example, the following command uses the snippet when building for the application core:
west build -b nrf54h20dk/nrf54h20/cpuapp -S nordic-log-stm
All cores must use the same logging configuration.
Reading the logs
To read the STM log output on the UART, consult the following documentation pages:
If you want to use the nRF Serial Terminal from nRF Connect for VS Code, see the nRF Terminal documentation on the nRF Connect for Visual Studio Code documentation site.
If you want to use PuTTY, see Testing and optimization.
Note
To use UART in your application, define the UART node in the devicetree. For more details, see Introduction to devicetree.
The following is an example log output:
[00:00:00.154,790] <inf> app/spsc_pbuf: alloc in 0x2f0df800
[00:00:00.163,319] <inf> app/spsc_pbuf: alloc 0x2f0df800 wr_idx:20
[00:00:00.181,112] <inf> app/spsc_pbuf: commit in 0x2f0df800
[00:00:00.189,090] <inf> app/spsc_pbuf: commit 0x2f0df800, len:20 wr_idx: 44
[00:00:00.202,577] <inf> rad/icmsg: mbox_callback
[00:00:00.214,750] <inf> rad/spsc_pbuf: claim 0x2f0df800 rd_idx:20
[00:00:00.235,823] <inf> rad/spsc_pbuf: free 0x2f0df800 len:20 rd_idx: 44
[00:00:00.244,507] <inf> rad/spsc_pbuf: read done 0x2f0df800 len:20
[00:00:00.272,444] <inf> rad/host: ep recv 0x330021f0, len:20
[00:00:00.283,939] <inf> rad/host: rx:00 exp:00
[00:00:00.292,200] <inf> rad/icmsg: read 0
[00:00:05.077,026] <inf> rad/spsc_pbuf: alloc in 0x2f0df000
[00:00:05.077,068] <inf> rad/spsc_pbuf: alloc 0x2f0df000 wr_idx:44
[00:00:05.077,098] <inf> rad/spsc_pbuf: commit in 0x2f0df000
[00:00:05.077,134] <inf> rad/spsc_pbuf: commit 0x2f0df000, len:20 wr_idx
Each log line contains a domain-related or core-related prefix between the log level and the module name, indicating the core that generated the log entry. The following are the prefixes used to indicate the cores:
Core |
Prefix |
|---|---|
Secure Domain |
|
Application core |
|
Radio core |
|
System Controller (SysCtrl) |
|
Fast Lightweight Processor (FLPR) |
|
Peripheral Processor (PPR) |
|
Assisted multicore logging
Assisted multicore logging uses dictionary-based logging to send messages without redundant strings to STM. It is based on the Dictionary-based Logging feature of the Zephyr logging API. For more information on assisted multicore logging, see Multi-domain logging using ARM Coresight STM.
Configuring logging
To show the logs for a given domain in the UART output, you must enable the STM for both the application core (as the ETR buffer processing proxy) and that domain’s CPU. To do so, use the Nordic Dictionary-based STM logging snippet (nordic-log-stm-dict) snippet when building the application for the related cores. For example, the following command uses the snippet when building for the application core:
west build -b nrf54h20dk/nrf54h20/cpuapp -S nordic-log-stm-dict
All cores must use the same logging configuration.
After building your application, the build directories for each core (build/<app_name>/zephyr/, where <app_name> is the application name for each core) will contain a dictionary database file named log_database.json.
This file is crucial for decoding the logs and updates with every build.
Reading the logs
To read the dictionary-based STM log output, do the following:
Start capturing the log with the
nrfutil trace stmcommand. Use the following command pattern, with<domain_id>being the ID of the domain which the application is running on,<port>being the serial port used for output, and<app_name>being the application name:nrfutil trace stm --database-config <domain_id>:build/<app_name>/zephyr/log_dictionary.json --input-serialport <port> --baudrate 115200 --stdout ascii
The output can be either the console (
--stdout ascii) or a file (theout.txtfile if--output-ascii out.txt).When done, stop tracing by pressing CTRL-C.
Read the terminal or open the output file to review the decoded log messages.
The output contains timestamps and the log messages in a human-readable format.
If the log capture fails to find a sync, rerun the capture process.
Note
Decoding artifacts or incorrect timestamps might occur when rerunning the process.
Each log line contains a domain-related or core-related prefix between the log level and the module name, indicating the core that generated the log entry. The following are the prefixes used to indicate the cores:
Core |
Prefix |
ID |
|---|---|---|
Secure Domain |
|
0x21 |
Application core |
|
0x22 |
Radio core |
|
0x23 |
System Controller (SysCtrl) |
|
0x2c |
Fast Lightweight Processor (FLPR) |
|
0x2d |
Peripheral Processor (PPR) |
|
0x2e |
For more information, see Capturing STM trace data in the nRF Util documentation.
Additional considerations
When using assisted multicore logging, consider the following:
Use optimized log macros (having up to 2 word size numeric arguments, like
LOG_INF("%d %c", (int)x, (char)y)) to improve the size and speed of logging.For memory constrained applications (for example, when running on the PPR or FLPR cores), disable the
printk()function by setting both theCONFIG_PRINTKandCONFIG_BOOT_BANNERKconfig options tonin your project configuration.When working with multiple domains, such as the Secure Domain and Application core, ensure that each database has the correct domain ID prefix.
The limited size of the RAM buffer storing STM logs may cause some log messages to drop.