RAM and flash tips
Fit the recorder to the question you need to answer. Choose the capture workflow, keep the event categories you use, and size the buffers and registries for your firmware. Measure the resulting ELF to check the saving.
These are firmware build settings. Changing a viewer filter, hiding a panel, or editing a host connection file (.vacf) does not remove recorder code or target RAM allocations. Rebuild and flash the firmware after changing recorder options. On Zephyr, use your application's Kconfig settings; on FreeRTOS or bare metal, use your recorder configuration header or consistent build definitions. See Recorder configuration.
Start from reset without RAM metadata
RAM metadata keeps the current task names, channel definitions and configuration in probe-visible RAM. It supports attaching to firmware that is already running, with the matching ELF, and recovering definitions after trace loss. It defaults on for direct RAM-buffer capture in DROP mode without a snapshot tee.
If every recording starts from reset and you can capture the initial setup packets, you can disable that table. For Zephyr RAM-buffer builds, use:
CONFIG_VIEWALYZER_METADATA=n
CONFIG_VIEWALYZER_AUTO_SETUP_INTERVAL_MS=0
CONFIG_VIEWALYZER_RAMBUF_SETUP_ON_ATTACH=n
For a FreeRTOS or bare-metal RAM-buffer build, the equivalent definitions are:
#define VA_METADATA 0
#define VA_AUTO_SETUP_INTERVAL_MS 0
#define VA_RAMBUF_SETUP_ON_ATTACH 0
The three settings control different costs:
| SETTING | WHAT TURNING IT OFF DOES |
|---|---|
| RAM metadata | Removes the metadata table, its 64-byte descriptor and associated service state. The table defaults to 2,048 bytes; a build configured for 4,096 bytes removes that larger allocation. Existing task and object registries remain. |
| Periodic setup interval | Zero stops automatic full setup retransmissions. This reduces recurring trace traffic and CPU work; it does not disable the RAM metadata table by itself. The interval is ignored when RAM metadata is enabled. |
| Setup on attach | Stops the separate resend triggered when a host starts draining the RAM ring. This is normally enabled when metadata is off, even if the periodic interval is zero. |
Initial setup still transmits at initialization, and new tasks, objects and channels still announce their definitions as they are registered. With all three settings off, the automatic bundle service is compiled out. An explicit application call to VA_EmitSetupBundle() can still resend definitions; remove any periodic calls if you want this reset-only workflow.
Check: Keep Reset on Connect enabled and verify that the initial setup and names arrive without loss. A missed definition will not be repaired by a later automatic bundle. Keep calling VA_TickOverflowCheck() often enough to cover the timestamp source's wrap period, including quiet periods. Disabling retransmission does not remove that requirement.
If you need to attach without resetting, retain RAM metadata or the appropriate setup-bundle mechanism. Lower the table capacity only after checking that all your definitions fit; an undersized table can prevent metadata attachment.
Compile only the events you need
Disabling a trace category removes its event generation and associated code. Registry storage is removed when no enabled category needs it. The exact flash and RAM saving depends on the other categories and compiler settings.
For a small FreeRTOS or bare-metal configuration focused on execution timing, start with an explicit selection:
#define VA_TRACE_DEFAULT 0
#define VA_TRACE_TASKS 1
#define VA_TRACE_ISRS 1
#define VA_TRACE_TASK_STATES 0
#define VA_TRACE_STACK_USAGE 0
This retains task execution and enabled ISR instrumentation, while omitting task-state detail and stack measurements. Task states default to the task-tracing setting, so explicitly turn them off when you need execution slices only. Timer callback spans similarly follow timer tracing unless explicitly disabled.
On Zephyr, disable the corresponding categories individually. Useful options to review include:
| INFORMATION YOU CAN OMIT | ZEPHYR SETTING | RECORDER MACRO |
|---|---|---|
| Ready, blocked, sleeping and suspended task detail | CONFIG_VIEWALYZER_TRACE_TASK_STATES=n | VA_TRACE_TASK_STATES=0 |
| Stack high-water measurements | CONFIG_VIEWALYZER_STACK_USAGE=n | VA_TRACE_STACK_USAGE=0 |
| Text log markers | CONFIG_VIEWALYZER_TRACE_STRINGS=n | VA_TRACE_STRINGS=0 |
| Timer callback spans | CONFIG_VIEWALYZER_TRACE_TIMER_CALLBACKS=n | VA_TRACE_TIMER_CALLBACKS=0 |
Keep queue and event-flag detail enabled only when you need their extra snapshots. These details are separate from the base queue and event-flag categories. Keep task-state tracing when you need wait reasons or off-CPU states; disabling it leaves the viewer without that evidence.
Size registries for the actual application
The recorder reserves fixed-capacity arrays for enabled task, object and channel registries. Reduce oversized capacities after counting the entities your application needs, including kernel and system threads.
| CAPACITY | RECORDER DEFAULT | ZEPHYR SETTING |
|---|---|---|
| Tasks and threads | VA_MAX_TASKS=16 | CONFIG_VIEWALYZER_MAX_TASKS |
| Synchronization objects | VA_MAX_SYNC_OBJECTS=64 | CONFIG_VIEWALYZER_MAX_SYNC_OBJECTS |
| User event spans | VA_MAX_USER_EVENTS=16 | CONFIG_VIEWALYZER_MAX_USER_EVENTS |
| User traces and ISR names | VA_MAX_USER_TRACES=16 | CONFIG_VIEWALYZER_MAX_USER_TRACES |
| Stored name length | VA_MAX_TASK_NAME_LEN=16 | CONFIG_VIEWALYZER_MAX_TASK_NAME_LEN |
The default name length includes the terminating NUL, leaving 15 visible characters. Shorter names can reduce per-slot RAM and packet sizes, but keep enough characters to distinguish entities. A registry that is too small can leave tasks or objects unnamed or unregistered; exercise peak concurrency and look for registry-full reports before accepting a smaller limit. User events and user traces have separate capacities.
Reserve only the buffers you use
These allocations serve different purposes. A buffer-size setting consumes RAM only when its corresponding feature is compiled in.
| ALLOCATION | DEFAULT SIZE | WHEN IT EXISTS |
|---|---|---|
| Live RAM ring | VA_RAMBUF_SIZE=8192 | RAM-buffer transport |
| Recorder-owned RTT up-buffer | VA_RTT_BUFFER_SIZE=4096 | RTT with recorder-managed buffer configuration |
| Output staging ring | VA_BUFFER_SIZE=4096 | Buffered output, disabled by default |
| Additional snapshot ring | VA_SNAPSHOT_SIZE=4096 | Snapshot tee, disabled by default |
| Snapshot setup storage | VA_SNAPSHOT_SETUP_SIZE=1024 | Snapshot or WRAP capture |
Sizes above are buffer bytes, excluding descriptors and other bookkeeping. Zephyr exposes the same size names with the CONFIG_VIEWALYZER_ prefix. Buffered output is enabled by CONFIG_VIEWALYZER_BUFFERED; the C macro is VA_TRANSPORT_BUFFERED.
Disable the snapshot tee if you do not need a post-mortem window. If you do need snapshots, preserve enough setup storage to retain names; setting its size to zero can save RAM at the cost of unnamed history. Disabling output staging removes that extra ring, but also removes its protection against slow transport writes. See Transports and snapshots.
Reduce the live ring in steps while testing your busiest workload. It must absorb bursts, initial setup and the time between host reads. A smaller ring can increase packet loss; switching to BLOCK mode can instead stall firmware until the host drains it. Verify both trace integrity and application timing.
On a target with ITM and a connected SWO pin, direct ITM output avoids the recorder's RAM transport ring. That is a transport change: the target and probe must support it, and the host must be configured for SWO. It is not an option on Cortex-M0, M0+ or M23.
Reduce recurring work without confusing it with memory savings
Increase the stack-usage heartbeat interval if you need occasional high-water measurements rather than frequent updates. Its default is 500 ms per task. Zero means sample on every switch-out, which increases overhead; it does not disable stack sampling. Disable the stack-usage category to remove the feature.
Emit application values at the rate the investigation needs, and prefer numeric traces to repeated long text messages where practical. These choices mainly reduce CPU work, bandwidth and pressure on the buffers. They do not automatically reduce a statically allocated ring or registry.
Measure the result
- Save a baseline ELF and linker map, then change one group of settings at a time. Keep the toolchain, optimization settings and workload consistent.
- Open each ELF in ViewAlyzer's Memory view. Add the linker map to see memory regions and discarded sections. Compare flash, RAM and the largest sections; initialized data consumes both flash and RAM.
- Exercise startup and peak load. Check task and channel names, registry-full reports, dropped packets and timestamp continuity. If you retain hot attachment or snapshots, test those workflows too.
- Check stack and heap headroom at run time. Linked section sizes alone do not establish that your application has enough working memory.
Flash savings from disabled features depend on inlining, optimization and unused-section removal. Compare the resulting images instead of assuming a fixed number of bytes per switch. The recorder impact report provides measured examples for one workload and configuration.