Firmware development
Point MeshBench at a MeshCore checkout. It builds it, loads it, and assigns it to every node of that role. Nothing is added to your checkout and nothing in it is modified.
meshbench dev -from ~/src/MeshCorebuilding simple_repeater from /home/alex/src/MeshCore
simple_repeater local-fix-relay-suppression (native) 0.6 MB
in the workbench's firmware library
assigned to every simple_repeater nodeThat is the whole loop. Edit, run it again, and the network is running your change. It needs MeshBench installed and a C++ compiler; nothing else.
The build lands in the firmware library as a *native* build: MeshCore compiled for this machine, which is the deterministic arm and the one every measurement uses. Native and emulated is the two-minute version of that choice.
What the command does#
The first run also fetches the Crypto library MeshCore builds against, once, and caches it. There is nothing to install beforehand beyond a C++ compiler.
Watching for changes#
meshbench dev -from ~/src/MeshCore -watchRebuilds and reassigns whenever a source file under src/ or examples/ changes. Leave it running in a terminal beside your editor.
Choosing a role#
MeshCore is several applications from one tree. -role selects which:
| role | node kind it runs on |
|---|---|
simple_repeater | simple and advanced repeaters |
companion_radio | companions, the node a phone attaches to |
simple_room_server | room servers |
A build is assigned to the role it was built for. Assigning a repeater build to a companion would make it a different kind of node, not a different version of the same one.
Comparing your change against a baseline#
The reason to run a change on three hundred nodes is to find out whether it is an improvement. That is a sweep: two arms, the same network, the same seeds, only the firmware differing. Load a shipped -strict fixture as the arena, and Time and determinism is why the same seeds make a difference attributable to the firmware.
meshbench dev -from ~/src/MeshCore -name my-change -assign=falsethen, in the workbench, define a sweep whose two arms name my-change and the release you branched from. See Experiments.
Three things decide whether such a comparison means anything:
Node storage is isolated per arm. A node keeps its preferences across runs, as hardware does, so a node that has run before loads its stored value rather than your changed default. A sweep runs each arm in its own storage root, so no arm inherits another's state; only runs made by hand outside a sweep need the firmware library's wipe button.
Give every role a build. A network with companions or a room server needs a build for each of them. Roles you did not change take the published release.
Include a control. Two arms built from identical source must produce identical numbers. When they do, a difference between real arms is attributable to the firmware. Every run records the checksum of each binary it attached, so "which build produced this number" is answerable from the results.
Versions are per role#
MeshCore tags one role at a time. repeater-v1.17.0 and companion-v1.17.0 are different releases, and a bare v1.17.0 matches neither.
If you build with PlatformIO#
An optional post-build script hands each build over automatically, so a normal PlatformIO build appears in the library without a separate command:
extra_scripts = post:meshbench.pyThe environment name supplies the board and the role, for example Heltec_v3_companion_radio_usb. This is a convenience: meshbench dev needs nothing added to your tree.