Zeppelin configuration¶
The library can be configured at build-time as well as at runtime.
Configuring the library¶
To enable Zeppelin tracing support, enable the symbol CONFIG_ZPL_TRACE
in Kconfig.
Build-time configuration¶
The build-time configuration can only be selected during build-time. The configuration can either be appended to the conf files:
CONFIG_ZPL_MEMORY_USAGE_TRACE=y
Or appended to the build command:
west build -b stm32f429i_disc1/stm32f429xx samples/trace/memory_profiling -- -DCONFIG_ZPL_MEMORY_USAGE_TRACE=y
Runtime configuration¶
By default, the runtime configuration is turned off with a Kconfig option CONFIG_ZPL_RUNTIME_CONFIG_NONE
.
To turn it on, select one of the following runtime configuration types:
CONFIG_ZPL_RUNTIME_CONFIG_UART
- UART shell commandsCONFIG_ZPL_RUNTIME_CONFIG_DEBUG
- In-memory debug configuration
UART commands¶
UART commands runtime configuration can be enabled by selecting CONFIG_ZPL_RUNTIME_CONFIG_UART
Kconfig option.
This option enables runtime configuration via shell module with custom configuration commands.
To display the available configs type help
:
uart:~$ help
Available commands:
help
mem_usage_trace
Each config can then be either enabled or disabled using the following syntax:
<command> enable
<command> disable
For example, the memory usage configuration:
mem_usage_trace enable
mem_usage_trace disable
Debug interface¶
Debug runtime configuration can be enabled by selecting CONFIG_ZPL_RUNTIME_CONFIG_DEBUG
Kconfig option.
You can use the debug configuration either directly from GDB, or using the zpl-debug-config
west command.
To use it directly in GDB, make sure to load the ELF file with debug symbols.
Then set the desired config to 0
(disable) or 1
(enable):
set var debug_configs.<config> = <value>
For example, to enable the memory usage tracing:
set var debug_configs.mem_usage_trace = 1
You can also use the zpl-debug-config
west command:
usage: west zpl-debug-config [-h] elf_path config value
Enable/Disable configs in runtime using debug interface. This command can list available configs and enable/disable them.
positional arguments:
elf_path Zephyr ELF path
config Config to set
value Value of the config (enable/disable)
options:
-h, --help show this help message and exit
For example, to enable the memory usage tracing:
west zpl-debug-config build/zephyr/zephyr.elf mem_usage_trace enable
Trace formats¶
The user can then select the following formats:
Plaintext format, by y-selecting
CONFIG_ZPL_TRACE_FORMAT_PLAINTEXT
Common Trace Format (CTF), by y-selecting
CONFIG_ZPL_TRACE_FORMAT_CTF
Trace backends¶
You can choose how the traces will be delivered to the host PC by selecting one of the available tracing backends:
UART, by y-selecting
CONFIG_ZPL_TRACE_BACKEND_UART
USB, by y-selecting
CONFIG_ZPL_TRACE_BACKEND_USB
Debugger, by y-selecting
CONFIG_ZPL_TRACE_BACKEND_DEBUGGER
Renode’s simulated trivial UART, by y-selecting
CONFIG_ZPL_TRACE_BACKEND_TRIVIAL_UART
Depending on the tracing backend used, the following commands can be used for trace capture.
Profiling tiers¶
The library supports three distinct profiling tiers, each offering a different balance of performance impact and tracing detail:
ZPL_TRACE_MINIMAL_MODE
- This mode provides extremely lightweight profiling with minimal overhead.It is designed for environments where performance is critical, and persistent trace data is not required.
When enabled, it activates basic inference profiling (
ZPL_INFERENCE_PROFILING
) and memory usage tracing (ZPL_MEMORY_USAGE_TRACE
) to give a high-level view of system behavior without introducing measurable latency.
ZPL_TRACE_LAYER_PROFILING_MODE
- This mode enables layer-level timing.It offers more granularity by tracking timing at individual model layers.
ZPL_TRACE_FULL_MODE
- This comprehensive profiling mode enables complete tracing.This mode is suitable for in-depth debugging and performance analysis but incurs a higher runtime cost due to its extensive trace capture.
It includes all basic and layer-level profiling features, and additionally implies a wide array of kernel and runtime tracing subsystems, which include:
syscall tracing,
thread scheduling,
interrupt service routines (ISRs),
synchronization primitives (semaphores, mutexes, condition variables),
IPC mechanisms (queues, FIFOs, LIFOs, stacks, message queues, mailboxes, pipes),
memory allocators (heap, memory slabs),
timers,
event handling,
polling,
power management,
networking (core, sockets),
various hardware interfaces (GPIO, idle state tracking).
Adding new configurations¶
Depending on the selected Zeppelin integration, the source files in projects need to be adjusted, as described in the following subsections.
Build-time configuration¶
The build-time configurations can be added to the zpl/Kconfig
file.
The config should follow the Kconfig standard.
For example:
config ZPL_RUNTIME_CONFIG_NONE
bool "No runtime configuration"
Runtime configuration¶
New runtime configurations can be defined in the configuration source files.
To add a new config, first, using macros, declare two functions in include/zpl/configuration.h
:
ZPL_WAIT_FOR_CONF_DEC(config_name)
ZPL_CHECK_IF_CONF_DEC(config_name)
Then, in each configuration type’s source file, define those functions, using the same name, and its corresponding Kconfig option.
For example in the configuration_uart.c
file:
ZPL_CONF_UART_DEF(config_name, kconfig_option)
In the code, there are two ways to use the runtime configuration as guards for the functionalities.
Wait-for function¶
The “wait-for” function stops the thread, and waits for a signal.
Once the signal arrives, the thread is woken up, and continues execution.
This is useful when the functionality which this configuration guards is in a separate thread.
This wait-for functionality can be called using the macro ZPL_WAIT_FOR_CONF
.
Example:
while (true) {
ZPL_WAIT_FOR_CONF(mem_usage_trace);
// ... Guarded code
}
Check-if function¶
The “check-if” functionality doesn’t stop the thread, and only checks if the configuration is turned on.
The function returns a boolean value, which can be checked in a standard “if”, to create a guard for the functionality.
The check-if function can be called using the macro ZPL_CHECK_IF_CONF
.
Example:
if (ZPL_CHECK_IF_CONF(mem_usage_trace)) {
// ... Guarded code
}