BKPT LabsDOCS/VIEWALYZER CLI/THE .VADB FILE VIEWALYZER · HEADLESS CLI
VIEWALYZER · CLI & AUTOMATION

The .vadb file

One SQLite file per recording, the same schema the app, the CLI queries and the Python SDK read. When a query does not shape the data the way you need, open the file: query sql runs one read-only statement, the SDK's Recording.connect() hands you a read-only connection, and any SQLite client works.

Tables

TABLE COLUMNS HOLDS
metakey, valueformat, version, capture_source, capture_utc, va_cpu_hz, va_os, recorder_version, and the hardware-trace keys below
va_objectsid, ns, va_id, name, extraEverything that has a name: tasks and ISRs, sync objects, user channels and events, DWT comparators, ITM ports. ns is the namespace (task, isr, user_trace, dwt, itm, ...), va_id the firmware's id inside it
va_eventsid, t_cycles, t_atoms, frame_pos, kind, start_end, obj, obj2, value_i, value_f, text, pre_syncEvery event. t_cycles is CPU cycles; seconds = t_cycles / va_cpu_hz. kind is the event kind (task_switch, isr, user_trace, user_event, string, mutex, queue, dwt_pc, ...), start_end 1 for a start, 0 for an end, obj the object id
healthstage, countersstage = 'recorder': corrupt_bytes, corrupt_runs, lost_events, seq_gaps, main_trace_bytes
raw_logsection, dataThe byte-log (section = 'va_file'), so a recording can be re-parsed by a newer engine
va_summary, va_task_stats, va_trace_stats, va_timer_stats, va_work_stats, va_comm_paths, va_comm_resourcesDerived statistics the app shows on open, recomputed by load
va_signal_blocksFull-rate waveforms from an external instrument, present only when a file has any

Queries by hand

-- what is in the file
select kind, count(*) as n from va_events group by kind order by n desc;

-- a user channel's samples in seconds (integer channels fill value_i, float channels value_f)
select e.t_cycles * 1.0 / (select value from meta where key = 'va_cpu_hz') as t_s, coalesce(e.value_f, e.value_i) as value
from va_events e join va_objects o on o.id = e.obj
where o.ns = 'user_trace' and o.name = 'Sine Wave' order by e.t_cycles;

-- ISR run times in microseconds (start/end pairs on the same object)
with s as (
  select obj, t_cycles as t0, lead(t_cycles) over (partition by obj order by t_cycles) as t1, start_end
  from va_events where kind = 'isr')
select o.name, count(*) as runs, avg(t1 - t0) * 1e6 / 170e6 as mean_us, max(t1 - t0) * 1e6 / 170e6 as max_us
from s join va_objects o on o.id = s.obj where s.start_end = 1 group by o.name;
$ viewalyzer-cli query sql --recording run.vadb --sql "select kind, count(*) as n from va_events group by kind order by n desc limit 5"
{"schema_version":2,"query":"sql","columns":["kind","n"],"rows":[["user_event",19136],["isr",10222],["user_trace",7176],["user_toggle",75],["string",5]],"row_count":5,"truncated":false}
from viewalyzer_sdk import ViewAlyzer
rec = ViewAlyzer().open("run.vadb")
with rec.connect() as db:                       # read-only sqlite3 connection
    rows = db.execute("select name from va_objects where ns = 'task'").fetchall()

Hardware trace in the file

Hardware trace rides va_events with no schema change (meta.version stays 1):

KIND NS / VA_ID FIELDS
dwt_pcdwt / 0x2000value_i = the sampled PC, or NULL when the core was asleep
dwt_excdwt / 0x1000 + exception numbervalue_i = 1 enter, 2 exit, 3 return
dwt_datadwt / comparator 0 to 3, named after the watchvalue_i = the value, obj2 = size, text = w or r plus pc=0x... when traced
dwt_data_pcdwt / comparatorPC-only comparators: value_i = PC
dwt_countersdwt / 0x2010 + index (cpi, exc, sleep, lsu, fold, cyc)value_i = cycles per wrap
itm_textitm / porttext

Meta keys: hardware_trace (the applied register image, the registers found, and the capture's swo_load), pc_sample_source (dwt-swo or pcsr-poll), pc_sample_interval_cycles, va_itmhw_bytes, va_itmhw_overflows.

Byte-logs and raw dumps

load accepts a .vadb, a .va byte-log (the recorder's bytes with a small container header, written while a capture runs) and a raw wire dump with no header at all; all decode to the same recording, and load x.va --output x.vadb converts. A .vadb also keeps its byte-log in raw_log, so a recording can always be re-parsed by a newer engine.