Skip to content

Releases: mikroverk/cooja-ng

Cooja-NG v0.4.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 12:50
eb23217

This release makes Cooja-NG usable without building it from source. cngsim takes you from the download to a running simulation in three commands, with commented examples, layouts that place many nodes at once, and a web UI that edits the running network and saves it as YAML. Cooja-NG now also runs in the browser: the same C code, compiled to WebAssembly, runs the original firmware and gives byte-for-byte the same output as the native build. That build is what runs the site's live demos.

New features include two TI SimpleLink LaunchPads join (CC1352R1 and CC1312R7, checked against hardware), Contiki-NG talks to Zephyr and to RIOT in two interop demos, and four boards without a radio model leave. Configs are checked harder: an image whose board cannot be told, a duplicate id, too many mote types or a plugin that is not there is an error now rather than a quiet surprise, so read Changed before upgrading. The plugin API (version 3) and the files Contiki-NG's CI uses are unchanged; plugins that read radio_medium_t fields directly must be rebuilt (Changed).

Contributors to this release: @nfi (warnings as errors, and reviews of the CC13x2 boards, cngsim, the browser build, the engine timing fixes and the board removal), and @nvt (reviews of cngsim and the browser build).

Changed — check these before upgrading

  • An unknown or missing firmware extension is an error, in cngsim and test_runner alike: exit 2 before anything starts, naming the file. It used to boot as a Tmote Sky, so an ARM image named .elf ran silently as an MSP430 and did nothing. Name the board with board: on the mote type instead (below). A node added at run time (shell add, JS addMote, a timed config action) is refused the same way, and a removed board's extension says that its board was removed.
  • test_runner with no arguments, or an unknown mode, exits 2 with its usage on stderr. An unknown mode used to run nothing and exit 0. --help prints the usage, now listing every mode and option.
  • More than 16 mote types, or more nodes than the limit (128), is a load error. Mote types beyond 8 used to be dropped without a word. A v1 config is held to it too, counting each distinct firmware image as a type: one with 17 images loaded, and the file Save wrote from it did not. On the command line -n over 128, or more than 128 firmware images, is refused the same way; it used to run 128 nodes under a banner naming more.
  • Durations outside 1 ms to 24.8 days are refused (exit 2): -t, --duration, a config's timeout_ms and a test step's. -t took atoi's word, so abc was 0 and 3000000000 wrapped to a negative run that ended at once, and cngsim run --duration 720h reported DONE at 0 s; a config's timeout_ms of 3000000000 was cut to 24.8 days and 1.5 to 1 without a word. -t takes whole milliseconds only.
  • A plugin that cannot be loaded, or a medium no plugin provides, is an error (exit 2, before the run starts), from --plugin, a config's plugins list or its medium. A misspelt built-in name (energist) used to print one line and run without it, and an unknown medium ran on the default UDGM. cngsim check reports an unknown built-in name and an unreadable plugin path too.
  • With --ui, a test verdict no longer ends the run. It is printed when it is decided and the run continues until the UI ends it (or --wall-timeout); the full report still comes at the end. A script that relied on --ui exiting at the verdict now runs until it is stopped. Headless and --ui-record runs are unchanged (Fixed has the details).
  • Firmware paths are looked up next to the config first (Added): a name that exists both there and in the current directory now gives the file next to the config.
  • libcsim: changed signatures and layouts. sim_board_for_path returns NULL for an unknown extension instead of the Sky board; sim_config_write_yaml takes the directory to write paths relative to, the sim_control ops' save_config a for_page flag and add the mote type's name (sim_control_add_typed names it apart from the images); msp430_config_find, msp430f149_config and cc430f5137_config are gone with their boards. sim_normalized_config_t (16 mote types, node name, meta and relative paths), arm_cpu_t (96 IO windows, io_width) and radio_medium_t (the frame tracker's tail) changed layout, so code built against them, including a medium plugin that reads radio_medium_t fields rather than calling its accessors, must be rebuilt. The plugin headers (csim_plugin.h, sim_service.h, sim_observer.h) are unchanged and CSIM_PLUGIN_API_VERSION stays 3.
  • Two nodes with the same id is a load error, including an explicit id equal to the one an unnumbered node is given. They used to share an address and a console label.
  • Warnings are errors. The build is warning-free on gcc 13–15 and clang, and -Werror is on by default; make WERROR=0 drops it for a compiler that reports something new. The vendored QuickJS header is a system include (-isystem), so its function-pointer cast no longer warns in every file that includes js_node.h.
  • A PR that moves a simulation on purpose says which workloads. A baseline-moves: shell54 line in its description lets the byte-identity vs main job pass when exactly those workloads differ; any other difference, or a named workload that does not move, still fails it. tools/check-baseline.sh takes the list as MOVED.
  • Simulation output moves relative to 0.3.0 where a model was fixed (Fixed below), so a baseline recorded with 0.3.0 differs in these places; of the nine check-baseline workloads only shell54 moves:
    • a timed config action applies at its time: shell54's send lands at 2000 ms instead of 2007 ms;
    • console input to an idle ARM node runs at the time it arrives, and wakes the node;
    • nRF52840 UARTE input keeps the first byte of a line, which arrives one byte time after the ENDRX acknowledgement;
    • an ARM core in WFI with no event queued sleeps to the slice horizon;
    • radio-bus frames too long for the old 160-byte queue entry (a CC1200 frame over about 150 bytes) reach a busy receiver whole, and a frame whose length cannot be read no longer holds up the queue;
    • the 802.15.4g frame tracker takes each frame's own channel and counts the CC1200's trailing CRC bytes with it.

Added

  • cngsim, the command for people (docs/quick-start.md). cngsim run sim.yaml runs a simulation and prints the node consoles, the checks and a one-line verdict, without the radio traces and chip counters (--trace or -v bring them back); --ui opens the browser, paused at real time. cngsim new writes a commented setup from a template, check validates one, examples and boards list what there is, and convert takes a Cooja .csc. It runs the same simulation as test_runner test (CI compares their console lines and exit codes), which stays the developer and CI binary. Its durations take a unit (--duration 60s, 500ms), and Ctrl-C ends a run with INTERRUPTED, how far it got, and exit 130. new places every node within radio reach of node 1 and gives an RPL network time for its depth; the bundled udp-server answers 15 clients (Contiki-NG's 16-route table), so new rpl-udp takes up to 16 nodes.
  • Edit a running simulation in the web UI: add nodes of the setup's mote types, remove and reboot nodes, send a line to a node's console, and save the setup as YAML. On by default on a loopback UI; a UI bound to another address with --ui-bind needs --ui-edit for these (anyone who reaches it can still pause, play, change the speed, restart and move nodes). The browser never names a file.
  • Layouts: a node entry with count and layout (grid, line, circle, random) places many nodes, as Cooja's Add-motes dialog does.
  • board: on a mote type names the board, so Contiki-NG's .nrf, .simplelink and .zoul images, or any .elf, run without renaming; on a .nrf52840 image it picks the board variant (nrf52840-dongle). --board NAME does the same for images given on the command line.
  • Firmware paths are relative to the config file (falling back to the current directory, as before), so a setup and its firmware can live anywhere. --save-config writes those paths relative to the file it saves, and the browser's Save relative to the config; other paths are written as the config gave them. cngsim looks a path up last among its bundled examples, so a copied example still finds its firmware.
  • The web UI page is built into the binary: --ui works from any directory and from an installed binary. A ui/index.html in the current directory still wins, and CSIM_UI_PAGE names another.
  • Twelve commented example simulations (examples/), runnable by name.
  • The quick start is a test (tools/check-quick-start.sh): every command in docs/quick-start.md runs as written, from an empty directory against a package laid out as the release tarball, and the output it shows must be what the package prints. It runs on every PR and on each release's unpacked tarball, beside a check that the README's platform table matches cngsim boards. test-format.md lists the run options, --pcap, --plugin and -d among them.
  • A sanitizer job in CI (ASan + UBSan, interpreter build) runs the malformed-firmware images, failed reboots (tools/check-lifecycle.sh), live saves (tools/check-save.sh) and the config loader's refusals on every PR; the two new checks also run in the normal jobs.
  • make install (PREFIX, DESTDIR), and release tarballs that carry cngsim, the examples, their firmware, the guides and the setups the guides run, beside the build/test_runner and tools/ the Contiki-NG suite uses.
  • Cooja-NG in the browser (wasm/): the whole runner compiled to WebAssembly with Emscripten, running in a Web Worker behind the existing we...
Read more

Cooja-NG v0.3.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 20:09
381e233

Cooja-NG becomes something you can drive, embed and watch: a command shell
and script engine for testing firmware through its own console, the simulator
as a library, Renode as a co-simulation clock master, and recorded runs that
replay in the browser. The nRF54L15's TrustZone-M is enforced the way a Seeed
XIAO nRF54L15 enforces it; three CPU architectures share one RPL network; and
the kernel's wakeup path no longer scales with the node count (in networks
without native motes). Release binaries for linux-x86_64, macos-x64 and
macos-arm64 produce byte-identical simulation output: builds no longer fuse
multiply-adds on arm64 (#72), and the release workflow checks the identity on
real firmware with every JIT on and off.

Contributors to this release: @nfi (the shell, the nRF54L15 console, radio and
TrustZone-M enforcement), and @nvt (hardening, native-mote CCA, the firmware
cache, FreeBSD, the JIT divide-trap fix, and reviews of the kernel,
performance, library, UI-replay, Firefly and release work).

Changed — check these before upgrading

  • The web UI listens on loopback only. --ui PORT binds 127.0.0.1;
    --ui-bind ADDR exposes it deliberately. Cross-origin WebSocket handshakes
    and DNS-rebinding Host headers are refused, and a slow or hostile client
    can no longer hold up the run (#53).
  • The MSP430 PC-trace counters are opt-in. The end-of-run
    FW cc2420_transmit=… eb_process=… queue_add=… line appears only with
    CSIM_PC_TRACE=1; the per-instruction hook it needed is gone from every
    other run (#61).
  • Off-SoC chip drivers moved to src/chips/ and include/chips/ (CC2420,
    CC1200, MX25R6435F, ENC28J60): they are not architecture-specific.
    Out-of-tree code that includes their headers needs -I include/chips (#33).
  • Simulation output moves relative to 0.2.3 where a model was fixed, so a
    regression baseline recorded with 0.2.3 differs in these places:
    • nRF54L15 node_id is the configured mote id (it was a hash, 8251 / 16758
      for motes 1 / 2), so link-layer addresses change (#30);
    • nRF54L15 radio DISABLE→DISABLED latency is 3 µs instead of 8 µs
      (NRF54L_DISABLED_DEFER_NS overrides; the working window is 2.5–4 µs),
      and the DK firmware images were rebuilt for the hardware-ACK path (#34);
    • native-mote CCA follows on-air time: a duty-cycled sixteen-node rpl-udp
      network went from 33–89 % of round trips delivered to 99.9–100 % (#56);
    • CC1200 (Zolertia Firefly sub-GHz) frame timing (#67);
    • ARM output with the JIT on, wherever firmware calls the 64-bit divide
      helpers (nRF52840 TSCH among them) — it now equals JIT-off output (#69).
  • Refusals that used to pass silently: an ELF whose segments place no
    bytes fails at init instead of running a zero-filled image to exit 0 (#50);
    a GDB client must answer within 5 s and an external-node peer must advance
    its clock within 10000 exchanges, or it is dropped (#52); a web-UI client
    that stops reading for 200 ms is dropped (#53).
  • Firmware cache names include the source directory (relative to the
    Contiki-NG root), so existing local builds are rebuilt once; --clean
    removes only untracked builds, never shipped firmware (#57).

Added — interactive shell and command scripts (#43, #45, #47, #54)

  • --shell gives a live simulation a command line (line editing,
    history, completion; plain lines from a pipe). --script FILE runs the
    same commands with blocking expect / sleep / wait-until, at / every
    / on queues and a pass/fail verdict, so one Contiki-NG shell firmware can
    serve many tests: the shell types into a node's console and asserts on what
    it prints. The exit code says what failed: 0 pass, 1 assertion, 2 invalid
    request, 6 wall timeout, 7 cancelled.
  • Node commands (cmd: send a line, wait for the prompt, check the output),
    per-node console masks and log files, environment control, breakpoints and
    watchpoints, register and MSP430 memory access, GPIO, and fault injection —
    a SecureFault injected with reg pc = and caught with expect-fault.
  • --wall-timeout DUR bounds a run in wall-clock time without touching
    the simulation. See docs/shell.md.

Added — web UI recording and replay, and a project site (#65, #66)

  • --ui-record FILE.json writes the stream the web UI would receive as a
    replay file. Without --ui the run stays headless and unpaced, and stdout
    is byte-identical with and without the flag (tools/check-ui-record.sh, in
    CI). ui/index.html?replay=FILE.json plays it from a static file: pause,
    speed, a scrubber. See docs/ui-replay.md.
  • https://mikroverk.github.io/cooja-ng/: recorded runs to watch in the
    browser, recorded by CI from the commit the site is built from, each
    published only if it shows what its card says.

Added — the simulator as a library (#63)

  • make lib builds build/libcsim.a without test/; make lib-link-check
    (in CI) links it with a main of its own, so a kernel, chip or service
    object that needs a symbol only the runner defines fails the build. Three
    such dependencies on runner-only symbols were removed to get there.

Added — Renode co-simulation: csim as a clock slave (#36, #39, #41)

  • Renode can drive csim's simulation clock. New
    src/services/renode_cosim_service.c speaks Renode's CoSimulationPlugin
    protocol — the 24-byte binary message over two TCP sockets, the handshake,
    the fixed-quantum tickClock, bus reads and writes, and the asynchronous
    interrupt and logMessage channel. Every tickClock becomes the runner's
    next horizon, so Renode's virtual time and csim's advance together. From
    Renode's side this needs no Renode-side code: one
    CoSimulated.CoSimulatedPeripheral line in a .repl
    (examples/renode/csim.repl). Everywhere else in csim, csim owns the clock;
    this is the one inversion. See
    docs/design/renode-cosim-plan.md.
  • csim's whole 802.15.4 network as a memory-mapped device. New
    src/native/renode_dev.c is the register window behind that peripheral:
    transmit a frame into csim's medium, read received frames back with their
    sender, channel, per-receiver RSSI and on-air start time, bridge one
    csim node's console, and take a level interrupt when something arrives. The
    guest-side mirror of the map is examples/renode/csim_dev.h.
  • New mote kind renode-cosim, selected by a .renode firmware
    extension the way .py selects an external node (the path is never opened).
    It has no CPU and no clock of its own: it is the device's place in csim's
    medium. Without a master attached it is inert, so a config containing one
    still runs as a plain regression.
  • New runner flags --renode ADDR:MAIN:ASYNC and --renode-freq HZ
    (--renode-freq must match the peripheral's frequency; the tickClock
    message carries only a tick count). Also reachable as plugins: ["renode"]
    with the connection in CSIM_RENODE. tools/csim-renode-launch.sh maps
    Renode's positional spawn arguments onto the flag.
  • Tests: ./build/test_runner renode-cosim covers the wire codec against
    a hand-written byte vector, the register window and its FIFOs, and the real
    protocol loop driven by a scripted mock master over a socketpair.
    tools/renode-mock-master.py plus tools/check-renode-cosim.sh gate it end
    to end: exact clock coupling, frames crossing in both directions, console
    lines forwarded, determinism across identical runs, and a clean exit when
    the master dies mid-run.
  • The runner's loop is touched in exactly two gated places, so with no
    --renode the default path stays byte-identical.

Added — Renode as the RPL root, and three emulators on one network (#37)

  • Renode's own CC2538 as the RPL root of a csim network
    (configs/test-renode-root-rpl.yaml): csim's Sky and nRF52840 clients join
    its DAG and complete UDP round trips through it, with
    examples/renode/bridge/CsimBridge.cs joining Renode's medium to csim's.
    With esp32sim as well, three emulators and three ISAs share one network
    (configs/test-threeway-cosim.yaml). Examples, not CI gates: they need
    Renode (and esp32sim).

Added — nRF54L15 (#30, #31, #32, #34, #38, #42, #44, #46, #51, #58, #59)

  • TrustZone-M under the simulation kernel, on a new board,
    nrf54l15-xiao (Seeed Studio XIAO nRF54L15). A node can carry a
    Secure-world ELF (secure_firmware) beside its Non-secure one; boot starts
    in the Secure world, and the end-of-run report adds SG / BXNS /
    secure-exception counters.
  • Attribution and peripheral permissions enforced as on silicon. The
    per-SoC attribution hook is new: before it, every address answered
    Non-secure, so nothing was refused. The SPU's
    per-peripheral permissions refuse Non-secure accesses with a precise
    BusFault taken by the Secure world, and SecureFault AUVIOL is precise too
    (the frame names the access, and a refused load or store changes nothing).
    The security unit's behaviour was measured on a Seeed XIAO nRF54L15
    (devices/nrf54l15-xiao/HARDWARE-COMPARISON.md).
    New configs: TrustZone boot, a watchdog the Secure world owns (verified line
    for line against a XIAO), a peripheral-permission violation, and two-node
    RPL-UDP over TrustZone with the radio driven through SG veneers.
  • Two-node RPL-UDP on the nRF54L15: timer deadlines, interconnect channel
    groups, and the Nordic 802.15.4 driver's own hardware ACK path, which
    Contiki-NG's port now relies on (#34).
  • Console receive through UARTE20 EasyDMA, paced at the baud rate (#31);
    SPIM with the DK's MX25R6435F flash and an ENC28J60 (#32); FICR.DEVICEID
    seeded so node_id equals the configured mote id (#30).

Added — platforms, tests and tools

  • FreeBSD (tested by hand on 15.1, amd64; not in CI): build with gmake;
    the scripts under `tools/...
Read more

Cooja-NG v0.3.0-rc1

Cooja-NG v0.3.0-rc1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 11 Oct 19:34
381e233

Cooja-NG becomes something you can drive, embed and watch: a command shell
and script engine for testing firmware through its own console, the simulator
as a library, Renode as a co-simulation clock master, and recorded runs that
replay in the browser. The nRF54L15's TrustZone-M is enforced the way a Seeed
XIAO nRF54L15 enforces it; three CPU architectures share one RPL network; and
the kernel's wakeup path no longer scales with the node count (in networks
without native motes). Release binaries for linux-x86_64, macos-x64 and
macos-arm64 produce byte-identical simulation output: builds no longer fuse
multiply-adds on arm64 (#72), and the release workflow checks the identity on
real firmware with every JIT on and off.

Contributors to this release: @nfi (the shell, the nRF54L15 console, radio and
TrustZone-M enforcement), and @nvt (hardening, native-mote CCA, the firmware
cache, FreeBSD, the JIT divide-trap fix, and reviews of the kernel,
performance, library, UI-replay, Firefly and release work).

Changed — check these before upgrading

  • The web UI listens on loopback only. --ui PORT binds 127.0.0.1;
    --ui-bind ADDR exposes it deliberately. Cross-origin WebSocket handshakes
    and DNS-rebinding Host headers are refused, and a slow or hostile client
    can no longer hold up the run (#53).
  • The MSP430 PC-trace counters are opt-in. The end-of-run
    FW cc2420_transmit=… eb_process=… queue_add=… line appears only with
    CSIM_PC_TRACE=1; the per-instruction hook it needed is gone from every
    other run (#61).
  • Off-SoC chip drivers moved to src/chips/ and include/chips/ (CC2420,
    CC1200, MX25R6435F, ENC28J60): they are not architecture-specific.
    Out-of-tree code that includes their headers needs -I include/chips (#33).
  • Simulation output moves relative to 0.2.3 where a model was fixed, so a
    regression baseline recorded with 0.2.3 differs in these places:
    • nRF54L15 node_id is the configured mote id (it was a hash, 8251 / 16758
      for motes 1 / 2), so link-layer addresses change (#30);
    • nRF54L15 radio DISABLE→DISABLED latency is 3 µs instead of 8 µs
      (NRF54L_DISABLED_DEFER_NS overrides; the working window is 2.5–4 µs),
      and the DK firmware images were rebuilt for the hardware-ACK path (#34);
    • native-mote CCA follows on-air time: a duty-cycled sixteen-node rpl-udp
      network went from 33–89 % of round trips delivered to 99.9–100 % (#56);
    • CC1200 (Zolertia Firefly sub-GHz) frame timing (#67);
    • ARM output with the JIT on, wherever firmware calls the 64-bit divide
      helpers (nRF52840 TSCH among them) — it now equals JIT-off output (#69).
  • Refusals that used to pass silently: an ELF whose segments place no
    bytes fails at init instead of running a zero-filled image to exit 0 (#50);
    a GDB client must answer within 5 s and an external-node peer must advance
    its clock within 10000 exchanges, or it is dropped (#52); a web-UI client
    that stops reading for 200 ms is dropped (#53).
  • Firmware cache names include the source directory (relative to the
    Contiki-NG root), so existing local builds are rebuilt once; --clean
    removes only untracked builds, never shipped firmware (#57).

Added — interactive shell and command scripts (#43, #45, #47, #54)

  • --shell gives a live simulation a command line (line editing,
    history, completion; plain lines from a pipe). --script FILE runs the
    same commands with blocking expect / sleep / wait-until, at / every
    / on queues and a pass/fail verdict, so one Contiki-NG shell firmware can
    serve many tests: the shell types into a node's console and asserts on what
    it prints. The exit code says what failed: 0 pass, 1 assertion, 2 invalid
    request, 6 wall timeout, 7 cancelled.
  • Node commands (cmd: send a line, wait for the prompt, check the output),
    per-node console masks and log files, environment control, breakpoints and
    watchpoints, register and MSP430 memory access, GPIO, and fault injection —
    a SecureFault injected with reg pc = and caught with expect-fault.
  • --wall-timeout DUR bounds a run in wall-clock time without touching
    the simulation. See docs/shell.md.

Added — web UI recording and replay, and a project site (#65, #66)

  • --ui-record FILE.json writes the stream the web UI would receive as a
    replay file. Without --ui the run stays headless and unpaced, and stdout
    is byte-identical with and without the flag (tools/check-ui-record.sh, in
    CI). ui/index.html?replay=FILE.json plays it from a static file: pause,
    speed, a scrubber. See docs/ui-replay.md.
  • https://mikroverk.github.io/cooja-ng/: recorded runs to watch in the
    browser, recorded by CI from the commit the site is built from, each
    published only if it shows what its card says.

Added — the simulator as a library (#63)

  • make lib builds build/libcsim.a without test/; make lib-link-check
    (in CI) links it with a main of its own, so a kernel, chip or service
    object that needs a symbol only the runner defines fails the build. Three
    such dependencies on runner-only symbols were removed to get there.

Added — Renode co-simulation: csim as a clock slave (#36, #39, #41)

  • Renode can drive csim's simulation clock. New
    src/services/renode_cosim_service.c speaks Renode's CoSimulationPlugin
    protocol — the 24-byte binary message over two TCP sockets, the handshake,
    the fixed-quantum tickClock, bus reads and writes, and the asynchronous
    interrupt and logMessage channel. Every tickClock becomes the runner's
    next horizon, so Renode's virtual time and csim's advance together. From
    Renode's side this needs no Renode-side code: one
    CoSimulated.CoSimulatedPeripheral line in a .repl
    (examples/renode/csim.repl). Everywhere else in csim, csim owns the clock;
    this is the one inversion. See
    docs/design/renode-cosim-plan.md.
  • csim's whole 802.15.4 network as a memory-mapped device. New
    src/native/renode_dev.c is the register window behind that peripheral:
    transmit a frame into csim's medium, read received frames back with their
    sender, channel, per-receiver RSSI and on-air start time, bridge one
    csim node's console, and take a level interrupt when something arrives. The
    guest-side mirror of the map is examples/renode/csim_dev.h.
  • New mote kind renode-cosim, selected by a .renode firmware
    extension the way .py selects an external node (the path is never opened).
    It has no CPU and no clock of its own: it is the device's place in csim's
    medium. Without a master attached it is inert, so a config containing one
    still runs as a plain regression.
  • New runner flags --renode ADDR:MAIN:ASYNC and --renode-freq HZ
    (--renode-freq must match the peripheral's frequency; the tickClock
    message carries only a tick count). Also reachable as plugins: ["renode"]
    with the connection in CSIM_RENODE. tools/csim-renode-launch.sh maps
    Renode's positional spawn arguments onto the flag.
  • Tests: ./build/test_runner renode-cosim covers the wire codec against
    a hand-written byte vector, the register window and its FIFOs, and the real
    protocol loop driven by a scripted mock master over a socketpair.
    tools/renode-mock-master.py plus tools/check-renode-cosim.sh gate it end
    to end: exact clock coupling, frames crossing in both directions, console
    lines forwarded, determinism across identical runs, and a clean exit when
    the master dies mid-run.
  • The runner's loop is touched in exactly two gated places, so with no
    --renode the default path stays byte-identical.

Added — Renode as the RPL root, and three emulators on one network (#37)

  • Renode's own CC2538 as the RPL root of a csim network
    (configs/test-renode-root-rpl.yaml): csim's Sky and nRF52840 clients join
    its DAG and complete UDP round trips through it, with
    examples/renode/bridge/CsimBridge.cs joining Renode's medium to csim's.
    With esp32sim as well, three emulators and three ISAs share one network
    (configs/test-threeway-cosim.yaml). Examples, not CI gates: they need
    Renode (and esp32sim).

Added — nRF54L15 (#30, #31, #32, #34, #38, #42, #44, #46, #51, #58, #59)

  • TrustZone-M under the simulation kernel, on a new board,
    nrf54l15-xiao (Seeed Studio XIAO nRF54L15). A node can carry a
    Secure-world ELF (secure_firmware) beside its Non-secure one; boot starts
    in the Secure world, and the end-of-run report adds SG / BXNS /
    secure-exception counters.
  • Attribution and peripheral permissions enforced as on silicon. The
    per-SoC attribution hook is new: before it, every address answered
    Non-secure, so nothing was refused. The SPU's
    per-peripheral permissions refuse Non-secure accesses with a precise
    BusFault taken by the Secure world, and SecureFault AUVIOL is precise too
    (the frame names the access, and a refused load or store changes nothing).
    The security unit's behaviour was measured on a Seeed XIAO nRF54L15
    (devices/nrf54l15-xiao/HARDWARE-COMPARISON.md).
    New configs: TrustZone boot, a watchdog the Secure world owns (verified line
    for line against a XIAO), a peripheral-permission violation, and two-node
    RPL-UDP over TrustZone with the radio driven through SG veneers.
  • Two-node RPL-UDP on the nRF54L15: timer deadlines, interconnect channel
    groups, and the Nordic 802.15.4 driver's own hardware ACK path, which
    Contiki-NG's port now relies on (#34).
  • Console receive through UARTE20 EasyDMA, paced at the baud rate (#31);
    SPIM with the DK's MX25R6435F flash and an ENC28J60 (#32); FICR.DEVICEID
    seeded so node_id equals the configured mote id (#30).

Added — platforms, tests and tools

  • FreeBSD (tested by hand on 15.1, amd64; not in CI): build with gmake;
    the scripts under `tools/...
Read more

Cooja-NG v0.2.3

Choose a tag to compare

@github-actions github-actions released this 05 Sep 19:38
ed1cb45

What's Changed

  • docs: plan for external data-driven nodes (+ a worked disturber example) by @joakimeriksson in #22
  • ext_node: emulator peers lag the kernel; run the ESP32-C6 (esp32sim) as an external mote by @joakimeriksson in #24
  • ext motes: put a peer's tx on the air at its stamp, and measure the ACK gap by @joakimeriksson in #25
  • docs: correct the E6 stage-2 findings — the ACK is not late, and the slice model is not the cause by @joakimeriksson in #26
  • config: YAML as the primary format, one strict schema, and --save-config by @joakimeriksson in #27
  • native motes: wake serially-injected motes at the kernel clock; kernel refuses wakeups in the past by @joakimeriksson in #29
  • version: 0.2.3 — YAML configs, ESP32-C6 external motes, ext ACK timing by @joakimeriksson in #28

Full Changelog: v0.2.2...v0.2.3

Cooja-NG v0.2.2

Choose a tag to compare

@github-actions github-actions released this 03 Sep 19:18
743ebbc

What's Changed

  • ci: verified, mirrored GNU Lightning fetch (curl | tar failed silently) by @joakimeriksson in #13
  • release: ship tools/test-border-router.sh in the tarball by @joakimeriksson in #14
  • test: fail loudly — unknown .csc features and missing verdicts are failures, never green by @joakimeriksson in #15
  • version: 0.2.1 — fail-loudly suite + complete tarball by @joakimeriksson in #16
  • MSP430: enforce slice cycle budget, apply RPT to single-op instructions, fix CC2420 footer RSSI by @joakimeriksson in #17
  • run-cooja-tests: default the suite firmware target to cooja (no silent cc2538dk fallback on fresh checkouts) by @joakimeriksson in #18
  • native motes: boot at the scheduled start and receive frames the way COOJA's ContikiRadio does by @joakimeriksson in #19
  • suite: --seed and --logdir, so Contiki-NG's BASESEED/RUNCOUNT loop is faithful by @joakimeriksson in #20
  • version: 0.2.2 — suite --seed/--logdir, fail-loudly, Contiki-NG guide by @joakimeriksson in #21

Full Changelog: v0.2.0...v0.2.2

Cooja-NG v0.2.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 16:04
da456f2

Cooja-NG 0.2.0

First release shipped as prebuilt binaries: cooja-ng-v0.2.0-{linux-x86_64,macos-x64,macos-arm64}.tar.gz + SHA256SUMS. Each tarball holds build/test_runner and the Contiki-NG suite runner scripts (tools/run-cooja-tests.sh, csc2json.py, build-test-firmware.sh) — no JVM, no build step. GNU Lightning is statically linked; the JIT is cycle-exact, so results are byte-identical with or without it.

tar xzf cooja-ng-v0.2.0-linux-x86_64.tar.gz && cd cooja-ng-v0.2.0-linux-x86_64
CONTIKI_DIR=/path/to/contiki-ng tools/run-cooja-tests.sh            # 85 Cooja tests
CONTIKI_DIR=/path/to/contiki-ng tools/run-cooja-tests.sh --with-tun # all 93 (needs sudo/TUN)

Passes the complete Contiki-NG 5.2 Cooja simulation suite: 93/93, 0 skipped, on Linux/x86-64 and macOS/arm64.

ARM performance: interpreter + JIT (#9)

  • Interpreter: 34% faster on the ARM runner workload (inlined condition evaluation, gated debug facilities, flash-window / GDB / ROM-trap hoists, page-indexed MMIO lookup — 1.07x on TSCH, 1.16x on Contiki-NG/nRF52840 from the trap hoist alone).
  • GNU Lightning JIT for Cortex-M (src/arm/arm_decode.c, src/arm/arm_jit.c): hot Thumb-16 blocks — ALU, shifts, branches, guarded SRAM loads/stores, native self-loops. On by default when Lightning is present. zephyr-synchronization 60 s sim: 2.05 s → 0.58 s (3.5x) on Apple Silicon, 5.9x MIPS on x86-64. Contiki-NG protocol firmware is ~1.0–1.2x — the plan document explains why, with measurements.
  • Cycle-exact by gate: CSIM_ARM_JIT=0 and =1 produce byte-identical simulation output on every multinode config.
  • New test suites, both in CI on both hosts: arm-decode (307,800 differential comparisons of the decoder + reference model vs the interpreter) and arm-jit (410,400 comparisons of the generated machine code vs the interpreter). The latter exists because jit_andi(dst, src, 0x80000000) returns 0 on x86-64 Lightning 2.2.3 — every N-reading condition silently took the wrong branch there while all other tests stayed green. Fixed and regression-gated.
  • make pgo repaired and trained on ARM workloads (1.55x clang / 1.18x gcc); arm-bench benchmark mode added.
  • Everything tried and rejected is recorded in docs/design/arm-performance-plan.md, including the negative results.

ARMv8-M TrustZone-M on the nRF54L15 (#8)

  • Security attribution engine (src/arm/arm_trustzone.c): SAU + SPU-as-IDAU, memory-mapped SAU registers, hot-path access enforcement feeding SecureFault/SFSR.
  • Banked SP/CONTROL, SG/BXNS/BLXNS/FNC_RETURN, TT*, secure exception entry/return with integrity signature, NVIC_ITNS banking.
  • Per-node SG / BXNS / secure-exception counters — TEE transition cost is measurable network-wide.
  • test_runner tz-boot <secure.elf> <normal.elf> boots the real Contiki-NG split image. 71 new tests; arm-correctness is now 230.
  • The JIT never runs Non-secure code (interpreter-only there), verified byte-identical on the TZ split image.

CC2538 and nRF radio fixes (#7, by @highlunder)

  • cc2538 SYS_CTRL: CLOCK_STA.OSC mirrors CLOCK_CTRL.OSC; SYNC_32K clear-then-set sequence modelled — fixes the RCOSC frequency downshift that broke TSCH slot timing and the PM1/2 wedge. New fix-sensitive regression test configs/test-tsch-lpm-cc2538dk.json.
  • nRF52840/nRF54L15: clear psdu_being_received on aborted RX — multi-hop RPL chains now pass (chain-4node-nrf52840-dk, chain-4node-nrf52840-dongle, chain-3node-nrf54l15-dk leave the known-failing list).

Radio media (#6, by @highlunder)

  • Gilbert-Elliott two-state burst-loss radio medium plugin (CSIM_GE_* knobs, make test-ge statistical validation).

CI

  • GNU Lightning installed on both runners (source-built on Linux with the vendored upstream mprotect fix — vanilla 2.2.3 SIGBUSes on Apple Silicon); arm-jit fails on SKIP.
  • New PR gates: JIT on/off byte-identity, lockstep verification on real cc2538 firmware, TSCH association + sync canary, and a no-Lightning rebuild so the optional path keeps coverage.
  • Per-tag release workflow (#10) producing the tarballs above.

Full Changelog: v0.1.0...v0.2.0

v0.1.0: Cooja-NG (csim) 0.1.0 — first public release

Choose a tag to compare

@joakimeriksson joakimeriksson released this 26 Jul 09:49

Cooja-NG (csim) 0.1.0 — first public release

A fast, multi-architecture C re-implementation of Cooja and MSPSim: run the
upstream Contiki-NG test suite headlessly, with an emphasis on simulation
speed, deterministic timing, and faithful peripheral behaviour.

Emulation

  • MSP430 / MSP430X (interpreter + optional GNU Lightning JIT): F149, F1611,
    F2617, F5437, CC430F5137, FR5969, with the CC2420 radio.
  • ARM Cortex-M3/M4F/M33: CC2538, Zolertia Firefly (+ CC1200 sub-GHz), Nordic
    nRF52840 and nRF54L15 with on-chip 802.15.4.
  • RISC-V RV32EMC via the nRF54L15 FLPR coprocessor — unmodified Contiki-NG
    running dual-core with the M33 over shared SRAM.
  • Native Cooja motes (dlopen) and JS app motes (QuickJS).
  • Also boots stock Zephyr OS and RIOT OS on the nRF52840 (experimental).

Simulation

  • Single-threaded event-driven kernel, ns-precise clock, per-radio
    multi-channel medium, per-byte RF delivery.
  • Ports-and-adapters architecture; static registry plus a dlopen plugin ABI
    (v1 service, v2 radio medium, v3 live web-UI panel).

Tests

  • Contiki-NG Cooja suite: 93/93, zero failed and zero skipped — all 85
    headless tests plus all 8 TUN/border-router cases against a real tun0.
  • Instruction, firmware, radio-medium/bus, chip-driver and plugin suites;
    determinism and config-equivalence guards. Verified on macOS/arm64 and
    Linux/x86-64.

Includes a full pre-release subsystem audit — memory-safety fixes (WebSocket
frame parser, ELF loader bounds, native-mote clamps), CPU/peripheral
correctness fixes (MSP430 DADD/RRCM/timer/JIT, ARM NVIC, CC2538 GPTimer,
RISC-V WFI), end-to-end nRF 802.15.4 routing for 2-node and multi-hop chains
on both nRF radios, and host-link latency on the serial socket so the native
border router drains correctly (the last failing suite test).

Known limitations: SVC is a no-op; MSP430 CS HFXT returns the DCO frequency;
the serial socket carries a deliberate 40 ms host-link latency pending a
flow-controlled link. See CHANGELOG.md.