切换到v6引导

This commit is contained in:
2026-07-19 17:46:04 +08:00
parent e25f4ee2d1
commit 4d919d13c1
2 changed files with 58 additions and 38 deletions
@@ -1,8 +1,9 @@
; Moonshine NRF52 mini - minimal DIY variant (nRF52840 + RA-01S-P SX1262)
; Uses S140 v6 SoftDevice (matches nice!nano / Adafruit Feather factory bootloader).
; Inherits the default v6 ldscript from [nrf52840_base] (app start at 0x26000).
[env:moonshine_NRF52_node_mini]
extends = nrf52840_base
board = adafruit_feather_nrf52840
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/diy/moonshine_NRF52_mini
-D PRIVATE_HW
@@ -4,6 +4,11 @@ Minimal DIY Meshtastic node variant: nRF52840 + RA-01S-P (SX1262) LoRa module
with a single status LED on P0.15. No display, GPS, button, or battery ADC -
LoRa-only minimal system.
Tested on a **nice!nano** board (nRF52840, S140 SoftDevice v6.1.1, Adafruit UF2
bootloader 0.9.2). Also compatible with any nRF52840 board that has the Adafruit
UF2 bootloader with S140 v6.x SoftDevice (e.g. Adafruit Feather nRF52840 Express
factory bootloader).
## Hardware
- **MCU**: nRF52840 (512 KB flash / 128 KB RAM)
@@ -29,7 +34,8 @@ LoRa-only minimal system.
| SPI_MOSI | P1.15 | LORA_MOSI |
Only the status LED on P0.15 is wired (no button, battery ADC, GPS, or display).
The board has no user button, so DFU entry is via the 1200 bps touch or SWD.
The board has no user button, so DFU entry is via double-tap reset or the
1200 bps touch.
## Build & Flash
@@ -42,59 +48,72 @@ pio run -e moonshine_NRF52_node_mini
Uses `PRIVATE_HW` (HardwareModel 255) - no protobuf or `architecture.h` changes
required.
The build links against `nrf52840_s140_v7.ld`, so the application is linked to
start at `0x27000` and requires the S140 SoftDevice v7.x to be present on the
chip at `0x0`-`0x26FFF` (or the Adafruit nRF52 UF2 "bright-future" bootloader,
which bundles its own SoftDevice). The build output (`firmware-*.hex` / `.uf2`)
contains **only the application**, not the SoftDevice.
The build inherits the default v6 ldscript from `[nrf52840_base]`
(`src/platform/nrf52/nrf52840_s140_v6.ld`), so the application is linked to
start at `0x26000` and requires the S140 SoftDevice v6.x to be present on the
chip at `0x0`-`0x25FFF`. The Adafruit nRF52 UF2 bootloader bundles its own
SoftDevice (v6.1.1 on the nice!nano), so if UF2 mode works the SoftDevice is
already present. The build output (`firmware-*.hex` / `.uf2`) contains **only
the application**, not the SoftDevice.
### Flash (first time on a bare nRF52840)
### Flash via UF2 (recommended - no SWD required)
Prerequisite: the board has the Adafruit UF2 bootloader installed (factory
default on nice!nano and Adafruit Feather nRF52840 Express). Confirm by entering
UF2 mode and reading `INFO_UF2.TXT` on the bootloader USB volume - it should
show `SoftDevice: S140 6.1.1` (or similar v6.x).
**First-time install (clean flash):**
1. Double-tap the Reset button to enter UF2 bootloader mode. A USB mass storage
volume appears (e.g. `NICENANO` or `FTHR840BOOT`).
2. Drag-and-drop `bin/Meshtastic_nRF52_factory_erase_v3_S140_6.1.0.uf2` onto the
volume. This erases any stale LittleFS/NodeDB/config from a prior firmware.
The board reboots when the copy completes.
3. Double-tap Reset again to re-enter UF2 mode.
4. Drag-and-drop
`.pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.uf2`
onto the volume. The board reboots into Meshtastic.
**App-only update (SoftDevice already present, config already clean):**
Skip steps 2-3 above - just double-tap Reset and drag-and-drop the application
`.uf2`.
### Flash via SWD (for a bare nRF52840 without bootloader)
A factory-fresh nRF52840 has **no SoftDevice and no bootloader**. The SoftDevice
must be flashed once via SWD before the application; otherwise `Bluefruit.begin()`
fails, `sd_flash_*` calls (LittleFS, NodeDB, config persistence) return errors,
and the node appears dead.
The S140 v7.3.0 SoftDevice hex is shipped in this repo at
`bin/s140_nrf52_7.3.0_softdevice.hex`. Flash via SWD with OpenOCD (CMSIS-DAP /
J-Link / ST-Link). The `nrf52_recover` command does a chip-wide ERASEALL through
the nRF52 CTRL-AP and clears APPROTECT, so it is the recommended first step on a
fresh module (ebyte/Raytac modules ship with APPROTECT engaged).
For a v6 SoftDevice layout, use the combined bootloader+SoftDevice hex at
`bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex` (this installs
both the UF2 bootloader and the SoftDevice in one SWD pass, enabling UF2
updates thereafter). Flash via SWD with OpenOCD (CMSIS-DAP / J-Link / ST-Link).
The `nrf52_recover` command does a chip-wide ERASEALL through the nRF52 CTRL-AP
and clears APPROTECT, so it is the recommended first step on a fresh module
(ebyte/Raytac modules ship with APPROTECT engaged).
```sh
# Full flow: recover (erase all + unlock) -> SoftDevice -> app -> reset
# Full flow: recover (erase all + unlock) -> bootloader+SoftDevice -> app -> reset
C:/openocd/bin/openocd.exe -s C:/openocd/share/openocd/scripts \
-f interface/cmsis-dap.cfg -f target/nrf52.cfg \
-c "init; nrf52_recover; \
program bin/s140_nrf52_7.3.0_softdevice.hex verify; \
program .pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.hex verify; \
reset run; exit"
```
### Flash (app only, SoftDevice already present)
When the SoftDevice is already on the chip and only the application changed
(e.g. after editing the variant and rebuilding), skip `nrf52_recover` and the
SoftDevice line:
```sh
C:/openocd/bin/openocd.exe -s C:/openocd/share/openocd/scripts \
-f interface/cmsis-dap.cfg -f target/nrf52.cfg \
-c "init; \
program bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex verify; \
program .pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.hex verify; \
reset run; exit"
```
### Notes
- The firmware hex filename contains a commit hash (e.g. `2.8.0.421838f`); use
the actual file produced by `pio run` or a shell glob.
- The SoftDevice hex occupies `0x0`-`0x26498` (~156 KB) and does **not** write
UICR, so `nrf52_recover` is safe (UICR resets to defaults).
- The firmware hex/uf2 filename contains a commit hash (e.g. `2.8.0.fbbfcf0`);
use the actual file produced by `pio run` or a shell glob.
- The combined bootloader+SoftDevice hex occupies `0x0`-`0x26000` and does
**not** write UICR, so `nrf52_recover` is safe (UICR resets to defaults).
- Swap `interface/cmsis-dap.cfg` for `interface/jlink.cfg` or
`interface/stlink.cfg` if using a different SWD probe.
- No UF2 bootloader is installed in this flow, so subsequent updates must go
through BLE DFU (secure DFU service) or SWD again. To enable UF2 drag-and-drop
updates, flash an Adafruit nRF52 UF2 bootloader
(https://github.com/adafruit/Adafruit_nRF52_Bootloader) at `0x0` in place of
the bare SoftDevice - the bootloader bundles its own SoftDevice.
- To switch to the S140 v7 SoftDevice (app start at `0x27000`, slightly larger
app region), add `board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld`
to `platformio.ini` and flash `bin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.hex`
via SWD. The v6 SoftDevice cannot be upgraded via UF2 - SWD is required.