MSIM-560 the emulators hold the chip, and radioserver is gone - #567
Merged
Merged
Conversation
An emulated node ran in two processes: the emulator, and a radioserver that owned the SX1262 and forwarded SPI to it over a socket. The chip moved into its own repository, MeshBench/virtual-sx1262, and both emulators now load it directly. That leaves one process per node and one socket, to the RF engine, which is genuinely elsewhere because the channel is shared with every node in the scenario. What the socket cost, beyond the round trips: It framed SPI a byte at a time, a path less exercised than the buffered one. That is how GetRssiInst came to answer correctly for a native node and zero for an emulated one for months, which is where the firmware takes its entropy: every emulated board derived its identity from a constant. DIO1 could only be polled, because the protocol was request-response. A millisecond is a long time to hold a receive interrupt, and a packet delivered and acknowledged inside one sampling gap raised the pin never. And it put three clocks in three processes in front of anybody asking what happened when. Protocol implementations go down rather than up: four, counting SPI in QEMU, Renode and radioserver plus the engine's, become two. Renode's peripheral is rewritten around the library it loads, in three files because one was 548 lines and the limit is 500: the loader and the ABI, the line to the engine, and the pins and SPI the firmware can see. It resolves the library by path from MESHBENCH_RADIO_LIB rather than by DllImport name, because Renode may be running on Mono or .NET and NativeLibrary is not on both. Two things found on the way: A release bundle never carried Renode's platform descriptions or our own peripherals, so an nRF52 board could not start from one at all. SupportDir looks beside the binary first, every bundle now copies them there, and verify-bundle refuses a bundle without them. heltec_t096 carries a front-end module and no .repl wires its pin, so its FEM reports as never switched in. That is unchanged here and said out loud at the call site; wiring it means a pin per board profile, read from each variant. Measured, one board at a time on an idle machine, with no radioserver process in either run: Generic_E22_sx1262 under QEMU and RAK_4631 under Renode both pass every row of the board probe, flood included, at 2 of 2 attempts. This must not merge before a QEMU release carrying the new device exists and QEMU_RELEASE names it. The pinned v9.2.2-meshbench-sx1262-10 still has the socket device and does not know radio-bridge, so a fetched QEMU would refuse to start. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6
The package comment named a Renode file that has never existed under that name and described a socket the SX1262 was on the far end of. The chip is inside the emulator now, on both backends; this socket carries the air. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6
Every emulated board used to come up with the same keypair, so a mesh of them was one node repeated (#556). The mechanism is fixed - per-node receiver noise, and the random-number registers generated rather than stored - but nothing asserted the thing the issue is actually about. noiseSeedFor is unit tested for distinct seeds per name and the chip is tested for distinct noise per seed; the link from noise to the key real firmware derives can only be seen by booting two of them. emu-a 9261FD8CAEED53DF07A62903D0D9D45A7F393E61BFCCE3D7F95E7A377B2D5A3A emu-b A858425E10AD9FA03A84444DCF769CAEE58B2931D9AB59A1B9D29B3A543B07C8 Determinism was checked by hand across two runs and is byte-identical, and the test says plainly that it does not assert that itself: pinning expected keys would break on a MeshCore version rather than on a fault of ours. The README's measurement note also said the matrix was measured against virtual-sx1262 v1.3.0, which an earlier edit of mine made untrue - those rows were measured through the radio server. Nine of them have now been re-measured against the chip loaded inside the emulator, one board at a time on an idle machine, and every one reproduced. LilyGo_TDeck is named as the exception. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6
The device in -10 forwards SPI to a radioserver process and does not know radio-bridge, so a fetched QEMU would refuse to start against this branch even though a locally built one works. That is the whole reason this pin moves in the same change. -11 also carries a portability fix worth naming, because nothing local could have caught it: upstream resolves gmodule only when modules or plugins are enabled, and the sx1262 device calls g_module_open. The release configures with neither, so it linked every target and then failed on qemu-system-xtensa alone, on macOS, with an undefined _g_module_error. This machine had plugins on. Digests taken from the published assets and checked by fetching them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6
A13xB0
force-pushed
the
emulators-hold-the-chip
branch
from
September 4, 2026 00:06
510e6c1 to
c088dc3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An emulated node ran in two processes: the emulator, and a
radioserverthatowned the SX1262 and forwarded SPI to it over a socket. The chip moved into
MeshBench/virtual-sx1262, and
both emulators now load it directly. That leaves one process per node and
one socket, to the RF engine, which is genuinely elsewhere because the channel
is shared with every node in the scenario.
What the socket cost, beyond the round trips
one. That is how
GetRssiInstcame to answer correctly for a native node andzero for an emulated one for months, which is where the firmware takes its
entropy: every emulated board derived its identity from a constant.
millisecond is a long time to hold a receive interrupt, and a packet delivered
and acknowledged inside one sampling gap raised the pin never.
happened when.
Renode's peripheral
Rewritten around the library it loads, in three files because one was 548 lines
and the limit is 500: the loader and the ABI, the line to the engine, and the
pins and SPI the firmware can see.
It resolves the library by path from
MESHBENCH_RADIO_LIBand binds eachentry point through
dlopen/LoadLibraryplusMarshal.GetDelegateForFunctionPointer, rather than byDllImportname. Renodemay be running on Mono or on .NET and
NativeLibrary's resolver is not on both;a name would also need a library search path set three different ways for a file
whose location we already know.
Two things found on the way
peripherals, so an nRF52 board could not start from one at all. Fixed here,
because it sits inside making bundles work:
SupportDir()looks beside thebinary first, every bundle copies them there, and
verify-bundle.shrefuses abundle without them.
heltec_t096carries a front-end module and no.replwires its pin, soits FEM reports as never switched in. Unchanged by this and said out loud at
the call site rather than half-fixed; wiring it means a pin per board profile,
read from each variant.
Measured
One board at a time on an idle machine, with no
radioserverprocess ineither run. Every row of the board probe passes:
Generic_E22_sx1262RAK_4631dlopenMerge order matters
This must not merge before a QEMU release carrying the new device exists and
QEMU_RELEASEnames it. The pinnedv9.2.2-meshbench-sx1262-10still has thesocket device and does not know
radio-bridge, so anyone who fetches QEMUrather than building it would get a machine that refuses to start.
QEMU_RELEASEand its digests hereMeshBench/meshcore-native#18
retires
radioserverat the source and is independent of the order above.🤖 Generated with Claude Code
https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6