feat(build): per-board memory.x override with MCU-family fallback

build.rs resolves the linker layout in two steps: per-board override
`ld/{board}-memory.x` first, MCU-family default second. Lets a board
deviate from the family default without a per-board build matrix.

Adds `ld/wio_tracker_l1-memory.x` with `ORIGIN = 0x1000` (no-SD
layout). The Wio Tracker L1 ships from Seeed with s140 SoftDevice, but
our earlier `ORIGIN = 0x1000, LENGTH = 0xE9000` linker silently
overwrote it across many UF2 flashes; the bootloader now reports
`SoftDevice: not found`. Until s140 is restored via SWD, the WIO
needs the no-SD layout to match the bootloader's actual boot chain.

Delete the per-board file once SD is restored -- the build will then
fall back to the SD-aware `ld/nrf52840-memory.x` and the WIO matches
every other nRF52840 board.
This commit is contained in:
swaits committed 2026-04-28 11:03:46 -06:00
1 parent 16374ca241
commit 1c98786ce6
2 files changed
+43 -6

No files matched your search

+18 -6
View File
@@ -108,19 +108,31 @@ fn main() {
println!("cargo:rerun-if-changed=src/board/mod.rs.j2");
println!("cargo:rerun-if-changed={}", board_dir);
// cortex-m-rt's link.x does `INCLUDE memory.x`. Copy the correct layout
// into OUT_DIR based on the target MCU family.
// cortex-m-rt's link.x does `INCLUDE memory.x`. Resolve the layout
// in two steps:
// 1. Per-board override: `ld/{board}-memory.x` if it exists.
// 2. MCU-family default by target triple.
// The override path is for boards that deviate from the family
// default (e.g. WIO Tracker L1 currently has no SoftDevice in flash
// and needs ORIGIN=0x1000 instead of the SD-aware 0x26000). Drop
// the per-board file once the layout matches the family default.
let target = std::env::var("TARGET").unwrap_or_default();
let memory_x = match target.as_str() {
"thumbv7em-none-eabihf" => Some("ld/nrf52840-memory.x"),
"thumbv6m-none-eabi" => Some("ld/rp2040-memory.x"),
let board_specific = format!("ld/{}-memory.x", enabled[0]);
let memory_x: Option<String> = if std::path::Path::new(&board_specific).exists() {
Some(board_specific.clone())
} else {
match target.as_str() {
"thumbv7em-none-eabihf" => Some("ld/nrf52840-memory.x".to_string()),
"thumbv6m-none-eabi" => Some("ld/rp2040-memory.x".to_string()),
_ => None,
}
};
if let Some(src) = memory_x {
let out_dir = std::env::var("OUT_DIR").unwrap();
fs::copy(src, format!("{out_dir}/memory.x")).expect("failed to copy memory.x");
fs::copy(&src, format!("{out_dir}/memory.x")).expect("failed to copy memory.x");
println!("cargo:rustc-link-search={out_dir}");
}
println!("cargo:rerun-if-changed=ld/nrf52840-memory.x");
println!("cargo:rerun-if-changed=ld/rp2040-memory.x");
println!("cargo:rerun-if-changed={}", board_specific);
}
+25
View File
@@ -0,0 +1,25 @@
/* Wio Tracker L1 memory layout — UF2 bootloader, NO SoftDevice
*
* 0x00000 – 0x01000 MBR (Master Boot Record)
* 0x01000 – 0xEA000 Application ← we live here (no SD present)
* 0xEA000 – 0xF4000 Reserved (app data)
* 0xF4000 – 0xFC000 UF2 Bootloader
* 0xFF000 – 0x100000 Bootloader settings
*
* Background: Seeed factory firmware ships s140 SoftDevice at
* 0x01000–0x26000, but our earlier UF2 flashes (with the original
* `ORIGIN = 0x1000` layout) silently overwrote that region. The WIO
* bootloader now reports `SoftDevice: not found`; until we restore
* s140 via SWD, the app must live at 0x1000 to match the bootloader's
* no-SD boot chain.
*
* Delete this file once SD is reinstalled — `build.rs` will then fall
* back to `ld/nrf52840-memory.x` (the SD-aware default at 0x26000)
* and the WIO matches every other nRF52840 board.
*/
MEMORY
{
FLASH : ORIGIN = 0x00001000, LENGTH = 0xE9000
RAM : ORIGIN = 0x20000008, LENGTH = 255K
}