Automation and CI

The command line arnodiqa uses the same engine and the same project files as the desktop app. It is intended for test benches without a screen, nightly runs and CI pipelines. Every command returns a documented exit code and, with --json, a report for further processing.

EULA and licence on build agents

On first use, Arnodiqa asks you to accept the EULA. On a non-interactive build agent, use --accept-eula or the environment variable ARNODIQA_ACCEPT_EULA=yes; the acceptance is recorded locally once. For a silent installation, pass ARNODIQA_ACCEPT_EULA=yes to msiexec /qn or setup.exe /S; the acceptance then applies to the whole machine. arnodiqa license eula shows the text offline.

Place a licence file in the machine licence folder or pass it with ARNODIQA_LICENSE_FILE, for example as a read-only mount in a container.

CI agent
export ARNODIQA_ACCEPT_EULA=yes
export ARNODIQA_LICENSE_FILE=/licences/site.arnlic
arnodiqa license show --json

Run a project

The desktop app comes as a Windows installer that installs and runs without an internet connection. The examples need no hardware. Without a licence file, Arnodiqa works for 30 days with all features.

1. Validate a project

arnodiqa validate
$ arnodiqa validate examples/demo/demo.yaml
ok

2. Run a measurement

The demo project has two virtual CAN networks (PowerTrain on CAN FD, Comfort on CAN). The interaction layer simulates all nodes from the two DBC files. The measurement runs on the simulated bus, so it runs as fast as the CPU allows.

arnodiqa run
$ arnodiqa run examples/demo/demo.yaml --duration 2s
measurement #3: 2.000000 s, 990 events, stop: Duration

channel  frames      rx      tx  err  fps(last s)  load%   peak%  state
CAN1        920       0     920    0          460   14.2    14.2  ErrorActive
CAN2         70       0      70    0           35    0.8     0.8  ErrorActive

channel  id            count  cycle avg/min/max [ms]
CAN1    400             400  4.998/4.002/5.998
CAN1    100             200  9.999/9.496/10.504
CAN1    210             200  10.000/9.500/10.500
CAN1    1A0             100  19.989/18.865/20.252
CAN2    320              40  50.000/49.536/50.464
CAN1    300              20  99.987/99.750/100.000
CAN2    321              20  99.987/99.708/100.292
CAN2    18FF1E01x        10  199.953/199.580/200.000

logging:
  Logging: 990 events, 0 lost
    examples\demo\logs\Demo_3.blf
  HighRpmLog: 94 events, 0 lost
    examples\demo\logs\high_rpm_003.asc

The measurement index (#3) is kept outside the project in demo.state.yaml. The project file therefore does not change on every run, and git stays clean.

3. In CI: JSON report

With --json, the complete report is printed on stdout as one JSON object (shown formatted here). Times are in nanoseconds.

arnodiqa run --json
$ arnodiqa run examples/demo/demo.yaml --duration 2s --json | jq .
{
  "exitCode": 0,
  "report": {
    "duration": 2000000000,
    "events": 990,
    "lateEvents": 0,
    "logging": [
      {
        "error": null,
        "eventsWritten": 990,
        "files": [
          "examples\\demo\\logs\\Demo_4.blf"
        ],
        "id": "Logging",
        "lost": 0,
        "preTriggerOverflow": 0,
        "sysvarsWritten": 0
      },
      {
        "error": null,
        "eventsWritten": 94,
        "files": [
          "examples\\demo\\logs\\high_rpm_004.asc"
        ],
        "id": "HighRpmLog",
        "lost": 0,
        "preTriggerOverflow": 0,
        "sysvarsWritten": 0
      }
    ],
    "mainQueueDropped": 0,
    "measurementIndex": 4,
    "messages": [],
    "statistics": {
      "channels": [
        {
          "busloadMeasured": true,
          "busloadPeakPercent": 14.1834,
          "busloadPercent": 14.1832,
          "channel": 1,
          "chipState": "errorActive",
          "errorFrames": 0,
          "errorFramesPerSec": 0.0,
          "extData": 0,
          "extRemote": 0,
          "fdFrames": 400,
          "frames": 920,
          "framesPerSec": 460.0,
          "rec": 0,
          "recPeak": 0,
          "rx": 0,
          "rxOverruns": 0,
          "stdData": 920,
          "stdRemote": 0,
          "tec": 0,
          "tecPeak": 0,
          "tx": 920,
          "txQueueOverflows": 0,
          "txRequests": 0
        },
        {
          "busloadMeasured": true,
          "busloadPeakPercent": 0.814,
          "busloadPercent": 0.814,
          "channel": 2,
          "chipState": "errorActive",
          "errorFrames": 0,
          "errorFramesPerSec": 0.0,
          "extData": 10,
          "extRemote": 0,
          "fdFrames": 0,
          "frames": 70,
          "framesPerSec": 35.0,
          "rec": 0,
          "recPeak": 0,
          "rx": 0,
          "rxOverruns": 0,
          "stdData": 60,
          "stdRemote": 0,
          "tec": 0,
          "tecPeak": 0,
          "tx": 70,
          "txQueueOverflows": 0,
          "txRequests": 0
        }
      ],
      "eventsTotal": 990,
      "ids": [
        {
          "channel": 1,
          "count": 200,
          "cycleAvg": 9998723.618090453,
          "cycleLast": 9748000,
          "cycleMax": 10504000,
          "cycleMin": 9496000,
          "dlc": 8,
          "id": "0x100",
          "lastTime": 1990488000,
          "minSendDistance": 9258000
        },
        {
          "channel": 1,
          "count": 100,
          "cycleAvg": 19988535.353535354,
          "cycleLast": 20000000,
          "cycleMax": 20252000,
          "cycleMin": 18865000,
          "dlc": 8,
          "id": "0x1A0",
          "lastTime": 1980242000,
          "minSendDistance": 18623000
        },
        {
          "channel": 1,
          "count": 200,
          "cycleAvg": 10000000.0,
          "cycleLast": 9752000,
          "cycleMax": 10500000,
          "cycleMin": 9500000,
          "dlc": 8,
          "id": "0x210",
          "lastTime": 1990244000,
          "minSendDistance": 9256000
        },
        {
          "channel": 1,
          "count": 20,
          "cycleAvg": 99986842.10526316,
          "cycleLast": 100000000,
          "cycleMax": 100000000,
          "cycleMin": 99750000,
          "dlc": 8,
          "id": "0x300",
          "lastTime": 1900246000,
          "minSendDistance": 99504000
        },
        {
          "channel": 1,
          "count": 400,
          "cycleAvg": 4998125.313283208,
          "cycleLast": 4506000,
          "cycleMax": 5998000,
          "cycleMin": 4002000,
          "dlc": 15,
          "id": "0x400",
          "lastTime": 1995381000,
          "minSendDistance": 3621000
        },
        {
          "channel": 2,
          "count": 40,
          "cycleAvg": 50000000.0,
          "cycleLast": 49828000,
          "cycleMax": 50464000,
          "cycleMin": 49536000,
          "dlc": 8,
          "id": "0x320",
          "lastTime": 1950242000,
          "minSendDistance": 49294000
        },
        {
          "channel": 2,
          "count": 20,
          "cycleAvg": 99986947.36842105,
          "cycleLast": 99708000,
          "cycleMax": 100292000,
          "cycleMin": 99708000,
          "dlc": 4,
          "id": "0x321",
          "lastTime": 1900166000,
          "minSendDistance": 99542000
        },
        {
          "channel": 2,
          "count": 10,
          "cycleAvg": 199953333.33333334,
          "cycleLast": 200000000,
          "cycleMax": 200000000,
          "cycleMin": 199580000,
          "dlc": 8,
          "id": "0x18FF1E01x",
          "lastTime": 1800286000,
          "minSendDistance": 199294000
        }
      ],
      "time": 2000000000
    },
    "stopReason": "duration",
    "txFailed": 0
  }
}

4. Offline: re-analyse a log file

shell
arnodiqa run examples/demo/demo.yaml --offline examples/demo/logs/Demo_1.blf

The log files replace the project's sources. Filters, triggers and logging blocks behave exactly as they do online.

Commands

arnodiqa --help
arnodiqa headless measurement runner

Usage: arnodiqa.exe <COMMAND>

Commands:
  run       Run a measurement and print statistics
  validate  Check a project for errors
  schema    Print the JSON Schema of project files
  capl      CAPL tools
  convert   Convert a log file between ASC, BLF, MF4 and PCAPNG (formats from the extensions)
  export    Decode a log file with databases and export the signals as CSV, MATLAB (.mat) or Parquet
  stats     Print the contents of a log file: duration, counts per channel and identifier
  hw        Hardware interfaces
  db        Database tools for DBC, LDF and ARXML: lint, diff, convert, info
  test      Run the test units (`*.vtestunit.yaml`) or CAPL test modules of a project in the simulated bus and write reports. Exit code by verdict
  flash     Flash an ECU with its flash program (`diagnostics.ecus[].flash`): Intel HEX, S-record, binary or ODX-F/PDX. Exit code and JSON report for CI and the production line
  support   Support: bundle with logs and system information, system info, log folder
  license   Licence: status, install a licence file, machine fingerprint, EULA
  help      Print this message or the help of the given subcommand(s)

Options:
      --accept-eula  Accept the EULA on behalf of your company (recorded once; for CI also ARNODIQA_ACCEPT_EULA=yes). Read it with `arnodiqa license eula`
  -h, --help         Print help
  -V, --version      Print version
CommandPurpose
runRun a measurement (online, offline or simulated), statistics and log files
validate, schemaCheck a project; JSON Schema of project files
testRun test units and CAPL test modules, write reports
capl check, capl lspCompile a CAPL program and show diagnostics; language server for editors
hw list, hw selftestDriver backends, status and connected channels; self-test of an interface
flashFlash an ECU via UDS, with JSON report
licenseLicence status, install a licence file, fingerprint, EULA
supportSupport bundle, system information and log folder
stats, convertSummarise a log file; convert between ASC, BLF, MF4 and PCAPNG
exportExport signals to CSV, MATLAB or Parquet
dbCheck, compare, convert and summarise databases (DBC, LDF, ARXML)

arnodiqa run <PROJECT>

OptionMeaning
--duration <SPAN>Stop after this measurement time (e.g. 10s, 500ms, 2min). Without this option, an online measurement runs until Ctrl+C.
--offline <FILE>Offline with these log files (repeatable); replaces the project's sources.
--simulatedSimulated bus (no hardware).
--real-busReal bus (hardware or virtual networks on the wall clock).
--without-loggingStart with all logging blocks disabled.
--timeout <SPAN>Wall-clock safety limit for the whole run; reaching it returns exit code 6.
--start-time <ISO8601>Fixed start time for log file headers and {MeasurementStart}, for reproducible files.
--top-ids <N>Number of IDs listed in the statistics (default 20).
-q, --quietOnly errors and the summary line.
--jsonReport as JSON on stdout: {"exitCode": n, "report": {…}} or {"exitCode": n, "error": "…"}.

A project with CAPL nodes runs the same way. Messages from the nodes appear with their measurement time before the report.

arnodiqa run
$ arnodiqa run examples/demo/capl_demo.yaml --duration 2s
[    0.000000] info: CaplGateway: gateway PowerTrain -> Comfort active
[    0.000000] info: ParkAssist: park assist started
[    1.000000] info: CaplGateway: 100 frames routed, last speed 800 rpm
[    2.000000] info: CaplGateway: id 0x100 seen 200 times
[    2.000000] info: CaplGateway: id 0x210 seen 200 times
measurement #3: 2.000000 s, 1209 events, stop: Duration

channel  frames      rx      tx  err  fps(last s)  load%   peak%  state
CAN1        939       0     939    0          470   14.4    14.4  ErrorActive
CAN2        270       0     270    0          135    2.5     2.5  ErrorActive
…

arnodiqa validate <PROJECT> · arnodiqa schema

validate checks the YAML model, then loads the databases and block references through the engine and prints ok or the issues found. schema prints the JSON Schema of project files.

Exit codes of run

CodeMeaning
0Measurement ran and stopped normally
1Measurement ran, but a logging block reported an error
2Invalid command line
3Project could not be loaded or is inconsistent
4Measurement could not be started or failed while running
5Measurement ran, but events were lost (overload or full logging queue)
6--timeout reached; report and log files are complete up to that point
130Stopped with Ctrl+C (after a clean stop with report and closed logs); a second Ctrl+C exits immediately

arnodiqa test <PROJECT>

Runs the test units (*.vtestunit.yaml) or CAPL test modules of a project on the simulated bus. Each unit runs in its own measurement with the simulation nodes, the rest bus and a test node. Simulated time runs as fast as the PC allows, so a 1 s wait takes less than a real second, and two runs produce identical reports.

arnodiqa test
$ arnodiqa test examples/demo/capl_demo.yaml --html report.html --junit junit.xml --report report.json
running Demo ...
Demo [test unit] PASS
  PASS         T-1 EngineData cycle time
  PASS         T-2 Cycle time 256 in [9, 11] ms
  PASS         T-2 Cycle time 416 in [18, 22] ms
  PASS         T-2 Cycle time 528 in [9, 11] ms
  PASS         T-3 Park assist / Mode request 1
  PASS         T-3 Park assist / Mode request 2
  PASS         T-4 Park assist / Mode Off stops the status frame
  PASS         T-5 Speed limit ramp (stimulus)
verdict PASS: 1 test unit(s), 8 test case(s): 8 passed, 0 failed, 0 inconclusive, 0 error, 0 skipped
$ echo $?
0
OptionMeaning
--unit <UNIT>Unit by name, .vtestunit.yaml file or CAPL test module (.can); repeatable. Default: all units of the project.
--variant <NAME=VALUE>Value of a variant property (repeatable).
--report, --junit, --html <FILE>Report as JSON, JUnit XML or HTML. The HTML report is a single self-contained page without scripts.
--max-time <SPAN>Maximum measurement time per unit (default 1 hour of simulated time).
--real-busUse the project's working mode instead of the simulated bus.
--json, -qJSON report on stdout; summary only.
Exit codeMeaning
0All executed test cases passed
1At least one test case failed
2Invalid command line
3Project, test unit or test tree could not be loaded, or no unit found
4Error in the test system (compile error, runtime error, unit not completed)
5Worst verdict: inconclusive
8No test case executed

arnodiqa capl check <FILE>

Compiles a CAPL program and prints diagnostics as file:line:col: severity code: message. With --project, the compiler uses the project's databases and system variables; without a project, messages and system variables are unknown. --json returns the diagnostics as JSON for editors. The exit code is 0 without errors, 1 with errors and 3 if the project cannot be loaded.

arnodiqa capl check
$ arnodiqa capl check examples/demo/capl/gateway.can --project examples/demo/capl_demo.yaml
examples/demo/capl/gateway.can: 0 error(s), 0 warning(s)
$ arnodiqa capl check examples/demo/capl/gateway.can
examples/demo/capl/gateway.can:21:12: error E1012: unknown message 'EngineData'
examples/demo/capl/gateway.can:31:12: error E1012: unknown message 'WheelSpeeds'
examples/demo/capl/gateway.can:36:1: error E1013: unknown system variable 'Demo::Mode'
examples/demo/capl/gateway.can: 3 error(s), 0 warning(s)
$ echo $?
1

Further options: --db (additional DBC files), -I (include paths), --node (value of %NODE_NAME%), --allow-undeclared-sysvars.

arnodiqa hw list

For each driver backend, shows whether the manufacturer's library was found and which devices and channels are connected. A missing library is not an error; the backend is then reported as "not found". Use --json for scripts.

arnodiqa hw list
$ arnodiqa hw list
virtual    Virtual CAN bus (in-process) found, 8 channels
             Virtual CAN Bus (serial VIRTUAL, 8 channels)
pcan       not found: PCANBasic.dll is missing (LoadLibraryExW failed)
vector-xl  not found: vxlapi64.dll is missing (LoadLibraryExW failed)
kvaser     not found: canlib32.dll is missing (LoadLibraryExW failed)
socketcan  not available on this operating system
slcan      SLCAN (serial) found, 2 channels
             COM4 (serial COM4, 1 channel)
             COM5 (serial COM5, 1 channel)
gs_usb     gs_usb / candleLight found, 0 channels

Output on a Windows PC without PEAK, Vector and Kvaser drivers installed. Channel mapping in the project: hardware: {pcan: {channel: PCAN_USBBUS1}}, {vector: {app: arnodiqa, channel: 1}}, {kvaser: {serial: …, channel: 0}}, {socketcan: {interface: can0}}, {slcan: {port: COM5}}, {gs_usb: {channel: 0}}.

arnodiqa hw selftest tests a new interface with two channels on one bus (--pair), one channel with internal loopback (--channel) or two LIN channels (--lin-pair), and writes a report as JSON or HTML.

arnodiqa flash <PROJECT> --ecu <ECU>

Flashes an ECU with the flash program from the project (diagnostics.ecus[].flash). Firmware can be Intel HEX, Motorola S-record, a binary file (with --base) or ODX-F/PDX (--odx-session). Without custom steps, the default sequence applies: extended session, DTC setting and communication off, programming session, security access, fingerprint, then erase, download and verify per segment, and finally an ECU reset. After an error or a cancellation, an ECU reset follows.

arnodiqa flash
arnodiqa flash project.yaml --ecu DoorECU --file door_v2.hex --report flash.json
arnodiqa flash project.yaml --ecu DoorECU --file door.bin --base 0x80000 --var fingerprint=261015000000000001
arnodiqa flash project.yaml --ecu DoorECU --file door.pdx --odx-session APP --simulated --json

Further options: --format ihex|srec|bin|odx, --timeout (exit code 6 when exceeded), --real-bus, -q. With --simulated, the project's ECU simulation responds, so a flash program can be checked without hardware.

arnodiqa support bundle | info | logs

Creates a support bundle (zip) with system information, version and settings, the hardware list, recent logs and crash reports. User names, host name and serial numbers are anonymised. Keys, bus data and CAPL sources are never included. Nothing is uploaded. --dry-run shows in advance what the bundle will contain.

arnodiqa support
arnodiqa support bundle --since 7d --out support.zip
arnodiqa support bundle --include-project project.yaml --dry-run
arnodiqa support info
arnodiqa support logs

On Windows, logs are stored in %LOCALAPPDATA%\Arnodiqa\logs; on Linux, in ~/.local/state/arnodiqa/logs. Set the log level with ARNODIQA_LOG or in diagnostics.json, or in the app via Help.

arnodiqa export --db <[CH:]FILE> <INPUT> <OUTPUT>

Decodes a log file (ASC, BLF, MF4 or PCAPNG) with DBC or LDF databases and exports the signals as CSV, MATLAB (.mat) or Parquet. With a CHANNEL: prefix, a database applies to that channel only. The wide layout (default) gives one table per message; long gives one table with a row per signal value (time, channel, message, signal, value, unit, text).

arnodiqa export
$ arnodiqa export --db 1:powertrain.dbc --db 2:comfort.dbc --format csv Demo_1.blf signals
1485 frames decoded (0 without database entry) of 1485 events, 12638 signal values in 8 table(s), 0.041 s
  EngineData                              300 rows  signals\EngineData.csv
  BCM_Lights                               60 rows  signals\BCM_Lights.csv
  DCM_DoorState                            30 rows  signals\DCM_DoorState.csv
  TransmissionData                        150 rows  signals\TransmissionData.csv
  Seat_Climate                             15 rows  signals\Seat_Climate.csv
  WheelSpeeds                             300 rows  signals\WheelSpeeds.csv
  BCM_MuxInfo                              30 rows  signals\BCM_MuxInfo.csv
  PT_FD_Status                            600 rows  signals\PT_FD_Status.csv
$ head -3 signals/EngineData.csv
time,channel,EngineSpeed,CoolantTemp,OilTemp,ThrottlePos,EngineState,EngineTorque,AliveCounter,Checksum
0.000242,1,768,20,0,0,0,0,0,0
0.01024,1,768.25,20,0,0,0,0,0,0
$ arnodiqa export --db 1:powertrain.dbc --db 2:comfort.dbc --format parquet --layout long Demo_1.blf signals.parquet
1485 frames decoded (0 without database entry) of 1485 events, 12638 signal values in 1 table(s), 0.066 s
  signals                               12638 rows  signals.parquet
FormatwidelongNotes
csvfolder with <Message>.csvsignals.csvComma separator, dot as decimal mark
matstruct per messagecolumns and signal namesMATLAB Level 5
parquetfolder with <Message>.parquetsignals.parquetSnappy compression, units as metadata; for pandas, Polars, Spark and DuckDB

time is in seconds since measurement start; the absolute start time is stored in the metadata. CSV and Parquet are written while reading and therefore suit very large logs. Exit codes: 0 success, 2 usage error, 3 database cannot be loaded, 4 read or write error.

arnodiqa db lint | diff | convert | info

Database tools for DBC, LDF and ARXML. For an ARXML file with several clusters, select one with --cluster; without it, lint and info handle each cluster separately.

arnodiqa db info
$ arnodiqa db info system.arxml
system.arxml#PT_CAN (CAN (AUTOSAR))
  frames:        5
  signals:       24
  nodes:         3 (ECM, GW, TCM)
  value tables:  0
  bus load:      3.6 % .. 4.3 % at 500 / 2000 kbit/s (cycle times; 3 frames, 160 frames/s; bit rate from database)

system.arxml#Body_CANFD (CAN FD (AUTOSAR))
  frames:        4
  signals:       15
  nodes:         2 (BCM, GW)
  value tables:  0
  bus load:      4.2 % .. 7.5 % at 500 / 2000 kbit/s (cycle times; 3 frames, 152 frames/s; bit rate from database)

system.arxml#Door_LIN (LIN)
  frames:        6
  signals:       9
  nodes:         3 (BCM, DDM, PDM)
  value tables:  2
  schedules:     Normal, Collision_Resolve, Config
  bus load:      33.3 % .. 46.7 % at 19.2 kbit/s (schedule table Normal; 4 frames, 100 frames/s; bit rate from database)
$ arnodiqa db convert system.arxml pt_can.dbc --cluster PT_CAN
pt_can.dbc written (dbc: 5 frames, 24 signals)
$ arnodiqa db diff system.arxml pt_can.dbc --cluster-a PT_CAN
--- system.arxml#PT_CAN
+++ pt_can.dbc
no differences
arnodiqa db lint
$ arnodiqa db lint body.ldf
body.ldf:20: warning[parse-warning] frame 'F2' reuses id 0x10
body.ldf:19: warning[parse-warning] frame 'F1': signal 'B' overlaps another signal
body.ldf: error[duplicate-id] F1: identifier 0x10 used by F1, F2
body.ldf: warning[unused-signal] Orphan: signal Orphan is in no frame
body.ldf: warning[unused-value-table] encoding type Unused is not used by any signal
body.ldf: error[zero-factor] encoding TooBig: scale 0
body.ldf: warning[value-description-out-of-range] Small: encoding TooBig uses raw 9..9, signal has 2 bits
body.ldf: warning[value-description-out-of-range] Small: encoding TooBig uses raw 0..10, signal has 2 bits
body.ldf: warning[suspicious-cycle-time] schedule table Main: delay 7 ms is no multiple of the time base 5 ms
2 error(s), 7 warning(s), 2 info(s)
$ arnodiqa db lint --format github body.ldf
::warning file=body.ldf,line=20,title=parse-warning::frame 'F2' reuses id 0x10
::warning file=body.ldf,line=19,title=parse-warning::frame 'F1': signal 'B' overlaps another signal
::error file=body.ldf,title=duplicate-id::F1: identifier 0x10 used by F1, F2
…
CommandPurpose and optionsExit code
db lint <FILES>…Errors and warnings (overlapping signals, duplicate IDs, ranges, cycle times, unused value tables and more). Several files count as one network and are also checked for ID conflicts. --level, --strict, --format text|json|github.0 without errors, 1 with errors (with --strict also with warnings), 4 file cannot be loaded
db diff <A> <B>Semantic differences in frames, signals and nodes, also across formats (ARXML against DBC).0 equal, 1 differences, 4 file cannot be loaded
db convert <IN> <OUT>ARXML to DBC (CAN cluster) or LDF (LIN cluster), or normalise a DBC/LDF. --check writes nothing and checks in CI whether a file is normalised; --cp1252 for DBC in Windows-1252.with --check: 1 if the file would change
db info <FILE>Number of frames, signals, nodes and value tables, with a bus load estimate. --frames, --bitrate.0

arnodiqa license show | install | fingerprint | eula | accept

Licences are signed files (*.arnlic) that are checked locally, without a network connection.

CommandPurpose
license showStatus: type, customer, end of maintenance, evaluation (--json)
license install <FILE>Install a licence file after checking its signature; --system for all users of the computer
license fingerprintFingerprint of this computer, for a node-locked licence
license eulaShow the EULA (--lang nl|en)
license acceptAccept the EULA on behalf of the company; --system for all users

arnodiqa capl lsp and VS Code

The CAPL language server speaks the Language Server Protocol over stdin/stdout and uses the same compiler as capl check and measurement start. It provides diagnostics while typing, completion (including messages, signals and system variables from the project), hover, go to definition, outline, signature help and semantic tokens. The server finds the project through the arnodiqa.project setting or takes the nearest project above the file.

The VS Code extension contains syntax highlighting, snippets, the LSP client and the command Arnodiqa: run test. It is delivered as a .vsix file and installs without an internet connection:

shell
$ code --install-extension arnodiqa-capl.vsix

Other editors use arnodiqa capl lsp (or arnodiqa-capl-lsp) as language server; a TextMate grammar is available for syntax highlighting.

Example: CI step

.gitlab-ci.yml / GitHub Actions (sketch)
export ARNODIQA_ACCEPT_EULA=yes
arnodiqa db lint --format github db/*.dbc db/*.ldf
arnodiqa validate project.yaml
arnodiqa test project.yaml --junit junit.xml --html report.html
code=$?      # 0 = pass, 1 = fail, 4 = error in test system, 8 = no test case ...
arnodiqa run project.yaml --simulated --duration 30s --json > run.json
exit $code

File formats, stats and convert

FormatReadWriteDetails
BLFYesYesObjects CAN_MESSAGE(2), CAN_FD_MESSAGE(_64), error frames, driver error and chip state, LIN objects; zlib containers; streaming with bounded memory; resync on corrupt objects; salvages complete objects from a truncated file.
ASCYesYesVariants from CANoe 7 to 13, EN/DE date, absolute or relative time, CAN FD lines with length and bit count, LIN lines, system variables (SV:), 6 or 9 decimals.
DBCYesYesUTF-8 and Windows-1252; mux and extended mux, VAL_, SIG_VALTYPE_, attributes, J1939.
LDFYesYesLIN 1.3, 2.0, 2.1, 2.2A, ISO 17987-3, SAE J2602-3.
ODX / PDXYesNoDiagnostic descriptions (ASAM MCD-2D) for symbolic diagnostics and ECU simulation.
MF4YesYesASAM MDF 4.1, bus logging for CAN, CAN FD and LIN; deflate compression.
PCAPNGYesYesCAN and CAN FD (SocketCAN link type), opens in Wireshark. LIN is skipped and counted.
ARXMLYesto DBC/LDFAUTOSAR Classic 4.x and 3.x: CAN, CAN FD, container PDUs, LIN clusters; E2E and SecOC properties are read. Several files are merged.
CSV, MATLAB, ParquetNoYesSignal export, see arnodiqa export.

arnodiqa stats <FILE>

arnodiqa stats
$ arnodiqa stats examples/demo/logs/Demo_1.blf
file:        examples/demo/logs/Demo_1.blf
format:      BLF
start:       2026-10-14 17:51:22.976
stop:        2026-10-14 17:51:25.971
objects (header): 1485
events:      1485
time span:   0.000242 .. 2.995380 s (duration 2.995138 s)
skipped:     0

channel  classic   remote       fd   errors
      1      780        0      600        0
      2      105        0        0        0

channel  id            count
      1  100             300
      1  1A0             150
      1  210             300
      1  300              30
      1  400             600
      2  320              60
      2  321              30
      2  18FF1E01x        15

read in 0.004 s (395715 events/s)

For a small file, start-up time dominates throughput; see Performance for large files.

arnodiqa convert <INPUT> <OUTPUT>

arnodiqa convert
$ arnodiqa convert Demo_1.blf Demo_1.mf4
1485 events written to Demo_1.mf4 in 0.018 s (81291 events/s); 0 skipped, 0 unparsable, 0 not representable
$ arnodiqa convert Demo_1.mf4 Demo_1.pcapng
1485 events written to Demo_1.pcapng in 0.013 s (112468 events/s); 0 skipped, 0 unparsable, 0 not representable

Converts between ASC, BLF, MF4 and PCAPNG; the format follows from the extensions. Start time and channel names are kept. Events the target format cannot store (for example LIN in PCAPNG) are skipped and counted. With --db, the output may also be a signal file (.csv, .parquet, .mat). --level 0-9 sets the compression for BLF and MF4 (default 6, the smallest file; measurements log with level 1). --json prints the result as JSON. bf-logtool is an alias with the same functions.