Zephyr Interactive Shell#
Sound Open Firmware (SOF) incorporates the native Zephyr RTOS Shell subsystem, providing an interactive, bidirectional command-line terminal directly on the running audio DSP. While production audio firmware operates headlessly without interactive consoles, developer and validation builds can leverage the interactive shell to:
Inspect running thread priorities, states, and entry points.
Audit stack high-water marks across all RTOS threads to detect impending stack overflows.
Check dynamic heap pool allocations and detect memory fragmentation.
Dynamically adjust logging verbosity on a per-module basis without recompiling firmware.
Monitor audio pipeline scheduling states and component parameters in real time.
—
Enabling Shell Support in Firmware#
Firmware builds have the shell disabled by default to minimize memory footprint and power consumption. Enable shell support using build overlays:
# Build Tiger Lake firmware with Zephyr shell enabled
./sof/scripts/xtensa-build-zephyr.py tgl -o app/shell_overlay.conf
# Build Panther Lake (PTL) firmware with shell enabled
./sof/scripts/xtensa-build-zephyr.py ptl -o app/shell_overlay.conf
The shell_overlay.conf configuration enables the following Kconfig options:
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_ADSP_MEMORY_WINDOW=y
CONFIG_SHELL_STACK_SIZE=2048
CONFIG_SHELL_CMD_BUFF_SIZE=256
CONFIG_THREAD_NAME=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_INIT_STACKS=y
—
Connecting with cavstool.py#
The cavstool.py host utility communicates with the DSP memory window over the PCIe bus and spawns a virtual pseudo-terminal (PTY):
Step 1: Launch cavstool Bridge#
Run cavstool.py on the target machine (or DUT) with -l (listen) and -p (pseudo-terminal):
sudo ./cavstool.py -l -p
Output:
INFO:cavs-fw:Existing driver "snd_sof_pci_intel_tgl" found
INFO:cavs-fw:Mapped PCI bar 0 of length 16384 bytes.
INFO:cavs-fw:Selected output stream 15 (GCAP = 0xffffffff)
INFO:cavs-fw:Mapped PCI bar 4 of length 1048576 bytes.
INFO:cavs-fw:Detected cAVS 2.5 hardware
INFO:cavs-fw:Waiting for firmware handoff, ROM_STATUS = 0x5
INFO:cavs-fw:FW alive, ROM_STATUS = 0x5
INFO:cavs-fw:shell PTY at: /dev/pts/4
Step 2: Attach Terminal Emulator#
In another terminal, attach to the allocated pseudo-terminal (e.g. /dev/pts/4) using minicom, picocom, or screen:
# Connect using minicom
sudo minicom -p /dev/pts/4
# Or connect using picocom
sudo picocom /dev/pts/4
Press Enter to reveal the interactive Zephyr shell prompt:
~$
—
Command Reference & Diagnostics Runbook#
Kernel & System Information#
~$ kernel uptime
Uptime: 45210 ms
~$ kernel version
Zephyr version 3.7.0
Thread State & Scheduling Analysis#
Inspect all active RTOS threads, priorities, and execution states:
~$ kernel threads
Scheduler: 1 since last call
Threads:
*0x9e0a4e78 ll_thread0
options: 0x0, priority: -16 timeout: 0
state: running, entry: 0xbe02e060
stack size 8192, unused 6752, usage 1440 / 8192 (17 %)
0x9e0a37d0 edf_workq
options: 0x0, priority: -14 timeout: 0
state: pending, entry: 0xbe0189a0
stack size 8192, unused 6304, usage 1888 / 8192 (23 %)
0x9e0a3c48 sysworkq
options: 0x0, priority: -1 timeout: 0
state: pending, entry: 0xbe019200
stack size 1024, unused 728, usage 296 / 1024 (28 %)
0x9e0a3180 shell_adsp_memory_window
options: 0x0, priority: 14 timeout: 0
state: running, entry: 0xbe01969c
stack size 2048, unused 760, usage 1288 / 2048 (62 %)
Stack High-Water Mark & Overflow Auditing#
Execute kernel stacks to audit stack headroom across all audio processing threads:
~$ kernel stacks
0x9e0a4e78 ll_thread0 (real size 8192): unused 6752 usage 1440 / 8192 (17 %)
0x9e0a37d0 edf_workq (real size 8192): unused 6304 usage 1888 / 8192 (23 %)
0x9e0a3c48 sysworkq (real size 1024): unused 728 usage 296 / 1024 (28 %)
0x9e0a3180 shell_adsp_memory_window (real size 2048): unused 760 usage 1288 / 2048 (62 %)
0x9e0a3080 logging (real size 4096): unused 3488 usage 608 / 4096 (14 %)
0x9e0a38b0 idle 00 (real size 1024): unused 824 usage 200 / 1024 (19 %)
0xbe09df80 IRQ 00 (real size 2048): unused 1712 usage 336 / 2048 (16 %)
Note
If any thread exhibits usage exceeding 85–90%, increase its stack allocation in Kconfig or the component configuration to avoid intermittent stack corruption exceptions.
SOF Pipeline & Component Diagnostics#
Inspect active audio pipelines, components, and buffer queues:
~$ sof pipeline list
Pipeline 1: Core 0, Priority 0, State: RUNNING, Period: 1000 us
[0] host-copier (ID: 1, Active)
[1] volume (ID: 2, Active)
[2] eq_iir (ID: 3, Active)
[3] dai-copier (ID: 4, Active)
~$ sof mem status
Heap System Pool:
Total: 524288 bytes
Allocated: 184320 bytes (35 %)
Free: 339968 bytes (65 %)
Largest Free Block: 294912 bytes
Dynamic Logging Configuration#
Adjust logging levels on a live DSP without stopping the audio stream:
# Check active log levels
~$ log status
eq_fir: 3 (INF)
volume: 3 (INF)
ipc: 3 (INF)
# Enable verbose debug logging on eq_fir module
~$ log enable 4 eq_fir
# Suppress logging on volume module
~$ log enable 1 volume
—
Handling DSP Low-Power States (D0ix / D3)#
When audio playback or capture stops, the Linux kernel driver allows the audio DSP to transition into low-power states (D0ix clock gating or D3 power gating) to conserve energy:
Terminal Pausing: When the DSP enters D0ix or D3, the hardware memory window becomes inaccessible. In your terminal, keystrokes will not echo and command output will pause.
Transparent Auto-Resume: As soon as an application initiates an audio stream (or a test script starts
aplay/arecord), the DSP powers back up to active D0.cavstool.pydetects the valid ROM status, re-establishes the memory window pointers, and the terminal resumes immediately without dropping the shell session.Zero Restart Needed: Developers do not need to kill
cavstool.pyor restartminicomacross multiple playback sessions.