Skip to content

Persistent storage does not work on emulated nRF52 boards #565

Description

@A13xB0

Every emulated nRF52 board comes up with no filesystem. The firmware says so on
the third line of boot:

DEBUG: Generating new keypair
DEBUG: IdentityStore::save() failed

It regenerates a keypair on every boot because it cannot load one, and it cannot
save the one it made. Nothing a repeater stores survives a restart: its identity,
its preferences, its region and transport keys, its contacts.

What is known

  • The controller was missing. Renode's nrf52840 platform maps flash as
    plain writable memory with no NVMC behind it — the emulator log shows
    NVMC:ICACHECNF … unimplemented register … generated from SVD. NVMC is what
    LittleFS drives to erase and program pages. Modelled in
    tools/renode/peripherals/NRF52840_NVMC.cs (PR MSIM-560 every nRF52 board forwards: two faults, and they were masking each other #564).
  • That was not sufficient. With NVMC in place IdentityStore::save() still
    fails, and the firmware never touches the NVMC registers at all. With the
    SoftDevice present, Adafruit's InternalFS writes through the SoftDevice's
    flash API (sd_flash_write / sd_flash_page_erase), not the controller
    directly — those are SVC calls the SoftDevice services on its own schedule and
    signals through the SoC event queue. Something in that path does not complete
    under Renode.

Why it is worth fixing

MyMesh::allowPacketForward reads its region transport codes, loop-detect table
and hop caps out of preferences. It currently works on defaults, which is why
forwarding is fine — but any test of region scoping, loop detection or a
configured repeater is testing defaults rather than what an operator set.

It also means an emulated node cannot be provisioned and rebooted, and every
board regenerates its identity each run.

Where to start

The SoftDevice's flash operations are queued around radio activity and completed
asynchronously. Tracing the SVC path and the SoC event that should report
completion is the next step. MESHBENCH_RENODE_TRACE now covers the interrupt
path as well as the buses.

ESP32 boards are unaffected — their flash was fixed separately (the quad-enable
bit and the dummy-phase width) and their filesystem works.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Q9HbD44EKWWTRYgxbFGxf6

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions