forked from jappel/VersaMCU
Fix bootloader hardware bring-up and add key-based boot entry
Hardware-tested the UF2 bootloader end to end on a real VersaPad v2 board. Found and fixed a real bug: the bootloader's jump into the app (__set_MSP -> SCB->VTOR -> bx) hard-faulted on every standalone boot, even with the debugger fully disconnected; identical register/VTOR values injected directly by a halted debugger ran fine, which pointed at the missing __DSB()/__ISB() barriers ARM's own guidance requires for this exact pattern. Also fixed a USB PID collision (0x0011 is Adafruit's own Gemma M0 bootloader PID, misidentified by Windows as a Circuit Playground COM port instead of exposing VERSABOOT). This board has no dedicated reset/boot button, so add a hardware boot entry that doesn't need one: holding the bottom-right Cherry MX key (key_id 24) during reset/power-on drives its matrix row and reads its column directly in the bootloader, before the app is even validated. Also corrected the app-side flash_with_bootloader.ld (was missing the NVM carve-out flash_without_bootloader.ld already has) and boards/versapad.json (wrong flash/RAM size, wrong MCU macro, stale PID), and enabled the previously-commented-out env:versapad_usb. Documented findings in bootloader/README.md, bootloader/TESTING.md, and doc/09_known_limitations.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
4749adcd1d
commit
f60a29137c
8 changed files with 234 additions and 82 deletions
|
|
@ -10,9 +10,9 @@
|
|||
"extra_flags": "-DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS -D__SAMD21G18A__",
|
||||
"f_cpu": "48000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x0011"]
|
||||
["0x239A", "0x0042"]
|
||||
],
|
||||
"mcu": "samd21g18a",
|
||||
"mcu": "samd21g17d",
|
||||
"usb_product": "VersaPad v2",
|
||||
"usb_manufacturer": "Custom"
|
||||
},
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
"frameworks": ["arduino"],
|
||||
"name": "VersaPad v2 (USB bootloader)",
|
||||
"upload": {
|
||||
"maximum_ram_size": 32768,
|
||||
"maximum_size": 253952,
|
||||
"maximum_ram_size": 16384,
|
||||
"maximum_size": 120832,
|
||||
"disable_flushing": true,
|
||||
"native_usb": true,
|
||||
"offset": "0x2000",
|
||||
|
|
|
|||
|
|
@ -3,8 +3,19 @@
|
|||
USB-Bootloader für das VersaPad-v2-Makropad. Wird per Atmel-ICE/SWD einmalig
|
||||
auf den ATSAMD21G17D geflasht und belegt `0x0000..0x1FFF` (8 KiB). Danach
|
||||
lässt sich die App-Firmware ohne SWD über USB aktualisieren: Bootloader-Modus
|
||||
aktivieren (Doppel-Tap Reset), Board erscheint als USB-Laufwerk `VERSABOOT`,
|
||||
`.uf2`-Datei drauf kopieren.
|
||||
aktivieren, Board erscheint als USB-Laufwerk `VERSABOOT`, `.uf2`-Datei drauf
|
||||
kopieren.
|
||||
|
||||
Der Bootloader selbst (Flash, USB-Enumeration, Massenspeicher-Modus,
|
||||
Rücksprung in die App) ist auf echter Hardware verifiziert, siehe
|
||||
[Hardwaretest](#hardwaretest-2026-08-05). Der App-seitige `.uf2`-Schreibweg
|
||||
(Firmware tatsächlich über das Laufwerk aktualisieren) ist noch nicht gebaut,
|
||||
siehe [Bekannte Einschränkungen](#bekannte-einschränkungen).
|
||||
|
||||
Diese Platine hat keinen dedizierten Reset-/Boot-Taster. Bootloader-Modus
|
||||
aktivieren heißt hier: unterste rechte Cherry-MX-Taste (key_id 24) beim
|
||||
Einstecken/Reset gedrückt halten. Siehe
|
||||
[Hardware-Bootloader-Einstieg](#hardware-bootloader-einstieg-ohne-reset-taster).
|
||||
|
||||
## Herkunft
|
||||
|
||||
|
|
@ -37,15 +48,72 @@ da nur `0x0000..0x1FFF` beschrieben wird)
|
|||
pio run -e versapad_bootloader --target upload
|
||||
```
|
||||
|
||||
## Hardware-Bootloader-Einstieg ohne Reset-Taster
|
||||
|
||||
Die Platine hat keinen dedizierten Reset-/Boot-Taster (Custom-PCB-Design).
|
||||
Der klassische UF2-"Doppel-Tap-Reset" braucht aber gar keinen physischen Pin —
|
||||
`check_start_application()` in `src/main.c` prüft ein RAM-Flag
|
||||
(`DBL_TAP_PTR`/`DBL_TAP_MAGIC`), das bei jedem Reset gesetzt wird, unabhängig
|
||||
von der Reset-Quelle.
|
||||
|
||||
Statt eines eigenen Tasters wird die unterste rechte Cherry-MX-Taste
|
||||
(`key_id 24` in der App-Firmware, siehe `../src/config/pins.h`) missbraucht:
|
||||
|
||||
- `key_id 24` liegt auf COL4 (`PA08`) × ROW4 (`PA15`)
|
||||
- `boot_key_pressed()` in `src/main.c` treibt ROW4 kurz auf LOW und liest
|
||||
COL4 zurück — kein voller Matrixscan nötig, nur ein Drei-Pin-Check
|
||||
- der Check läuft ganz am Anfang von `check_start_application()`, noch vor
|
||||
der App-Adress-Validierung und vor der RCAUSE-/DBL-TAP-Logik: funktioniert
|
||||
also auch bei kaputter/gelöschter App-Firmware und bei normalem Power-On
|
||||
(Stecker ziehen/reinstecken), kein Software-Trigger in der App nötig
|
||||
- Pin-Konstanten stehen in `include/board_config.h`
|
||||
(`BOOT_KEY_ROW_PIN`/`BOOT_KEY_COL_PIN`)
|
||||
|
||||
Bedienung: USB-Kabel ziehen, unterste rechte Taste gedrückt halten, Kabel
|
||||
wieder einstecken (Taste dabei weiter halten) → Board bootet direkt in
|
||||
`VERSABOOT`. Ohne gehaltene Taste startet die App normal.
|
||||
|
||||
## Hardwaretest (2026-08-05)
|
||||
|
||||
Erster vollständiger Hardwaretest auf einem echten VersaPad-v2-Board über
|
||||
Atmel-ICE/SWD. Ergebnisse:
|
||||
|
||||
- Bootloader-Build/-Flash/-Verify laufen sauber (89,9 % Flash, 7364/8192 Byte).
|
||||
- USB-Enumeration und `VERSABOOT`-Massenspeicher-Modus funktionieren nach dem
|
||||
PID-Fix (siehe unten) korrekt, inklusive korrektem `INFO_UF2.TXT`.
|
||||
- Der Tastencheck (oben) funktioniert wie vorgesehen: gehaltene Taste beim
|
||||
Boot → `VERSABOOT`, sonst normaler App-Start.
|
||||
- **Kritischer Bug gefunden und behoben:** Der Sprung vom Bootloader in die
|
||||
App (`__set_MSP` → `SCB->VTOR` → `bx`) führte bei jedem echten,
|
||||
eigenständigen Boot (auch bei komplett getrenntem Debugger) zu einem
|
||||
Hard-Fault/Lockup der CPU. Identische Register-/VTOR-Werte, vom Debugger
|
||||
bei angehaltener CPU direkt injiziert, liefen dagegen einwandfrei — das
|
||||
grenzte den Fehler auf die *Ausführung* der Sprungsequenz selbst ein, nicht
|
||||
auf falsche Werte. Fix: `__DSB(); __ISB();` zwischen dem `SCB->VTOR`-Schreib-
|
||||
zugriff und dem `bx` in `check_start_application()` (`src/main.c`) — von ARM
|
||||
für genau dieses Bootloader-Pattern vorgeschrieben, hat im vendorten Code
|
||||
gefehlt. Nach dem Fix bootet die App-Firmware zuverlässig, mit und ohne
|
||||
angeschlossenen Debugger.
|
||||
|
||||
## Bekannte Einschränkungen
|
||||
|
||||
- Flash-Auslastung ~89 % (7292 von 8192 Byte). Wenig Puffer für Änderungen.
|
||||
- Kein physischer Boot-Pin definiert, nur Doppel-Tap-Reset (RAM-Magic-Wert).
|
||||
Ein Hardware-Fallback-Pin wäre für die Wiederherstellung bei kaputter
|
||||
App-Firmware sinnvoll, ist aber noch nicht eingerichtet.
|
||||
- Flash-Auslastung ~90 % (7364 von 8192 Byte). Wenig Puffer für Änderungen.
|
||||
- Kein Status-LED-Feedback im Bootloader-Modus, da die Platine nur eine
|
||||
WS2812-Kette (kein einfaches GPIO-LED oder DotStar) hat und der
|
||||
Original-Code dafür nicht ausgelegt ist.
|
||||
- USB_PID `0x0011` ist unverifiziert übernommen (siehe
|
||||
`../doc/09_known_limitations.md`), noch nicht auf echter Hardware getestet.
|
||||
- Ungetestet auf echter Hardware, siehe Branch `feature/usb-bootloader`.
|
||||
- USB_PID war ursprünglich `0x0011` (Adafruit Gemma M0s eigene
|
||||
Bootloader-PID, unverändert aus der Vorlage übernommen) — kollidierte auf
|
||||
Rechnern mit installiertem Adafruit-Treiber, wurde als `Adafruit Circuit
|
||||
Playground`-COM-Port statt als Massenspeicher gebunden. Verifiziert am
|
||||
2026-08-05, seither `0x0043`. Bleibt ein Wert ohne echte Registrierung
|
||||
(kein offiziell zugeteilter PID unter Adafruits VID); ein sauber eigener
|
||||
VID (z. B. über pid.codes) wäre die langfristig korrekte Lösung, ist aber
|
||||
nicht Teil dieses Branches.
|
||||
- Die App-Firmware erzeugt noch keine `.uf2`-Datei, nur `.bin`/`.elf`
|
||||
(SWD-Weg). Der geplante Weg über das `VERSABOOT`-Laufwerk ist damit noch
|
||||
nicht nutzbar.
|
||||
- `env:versapad_usb` in der Haupt-`platformio.ini` verwendet
|
||||
`upload_protocol = sam-ba` — das klassische Arduino/Atmel-SAM-BA-Protokoll,
|
||||
nicht das UF2/Massenspeicher-Verfahren dieses Bootloaders. Für echtes
|
||||
USB-Flashen wird stattdessen ein `.bin`→`.uf2`-Konvertierungsschritt plus
|
||||
einfaches Kopieren aufs Laufwerk benötigt, kein spezielles Upload-Protokoll.
|
||||
|
|
|
|||
|
|
@ -1,67 +1,65 @@
|
|||
# Bootloader-Testflash -- Anleitung für Hardware-Zugriff
|
||||
# Bootloader-Testflash -- Ergebnis
|
||||
|
||||
Der UF2-Bootloader (siehe [README.md](README.md)) ist fertig gebaut, aber noch
|
||||
nie auf echter Hardware gelaufen. Diese Anleitung ist für jemanden mit
|
||||
Atmel-ICE-Zugriff aufs VersaPad-v2-Board, um das einmal zu testen.
|
||||
Der UF2-Bootloader (siehe [README.md](README.md)) wurde am 2026-08-05 auf
|
||||
einem echten VersaPad-v2-Board über Atmel-ICE/SWD getestet. Zusammenfassung
|
||||
der Ergebnisse steht im [Hardwaretest-Abschnitt der README](README.md#hardwaretest-2026-08-05).
|
||||
Dieses Dokument hält den Testablauf und die Antworten auf die ursprünglichen
|
||||
Prüffragen fest.
|
||||
|
||||
**Wichtig zur Sicherheit:** Dieser Flash schreibt nur `0x0000..0x1FFF`
|
||||
(8 KiB). Die App-Firmware liegt ab `0x2000` und bleibt unangetastet. Falls
|
||||
etwas schiefgeht, ist das jederzeit per SWD neu beschreibbar, das Board kann
|
||||
dabei nicht dauerhaft "gebrickt" werden, solange der Atmel-ICE-Zugriff
|
||||
funktioniert.
|
||||
**Sicherheitsrahmen, der eingehalten wurde:** Der Bootloader-Flash schreibt
|
||||
nur `0x0000..0x1FFF` (8 KiB). Die App-Firmware ab `0x2000` blieb dabei
|
||||
unangetastet. Über SWD war der Chip jederzeit neu beschreibbar; ein Brick war
|
||||
zu keinem Zeitpunkt möglich, solange der Atmel-ICE-Zugriff funktionierte.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Board per Atmel-ICE/SWD angeschlossen, genau wie beim normalen
|
||||
App-Firmware-Flashen (`pio run -e versapad --target upload` in
|
||||
`doc/08_development.md`)
|
||||
- PlatformIO Core installiert. Falls nicht:
|
||||
```bash
|
||||
pip install -U platformio
|
||||
- Board per Atmel-ICE/SWD angeschlossen, wie beim normalen
|
||||
App-Firmware-Flashen (`pio run -e versapad --target upload`,
|
||||
siehe `../doc/08_development.md`)
|
||||
- PlatformIO Core (hier: PlatformIO-IDE-penv unter
|
||||
`%USERPROFILE%\.platformio\penv\Scripts\pio.exe`)
|
||||
|
||||
## Ablauf
|
||||
|
||||
1. `git checkout feature/usb-bootloader`
|
||||
2. `cd bootloader && pio run -e versapad_bootloader` — Build sauber
|
||||
(89,9 % Flash, 7364/8192 Byte)
|
||||
3. `pio run -e versapad_bootloader --target upload` — Flash + Verify über
|
||||
Atmel-ICE/SWD
|
||||
|
||||
## Ursprüngliche Prüffragen und Antworten
|
||||
|
||||
- **Ist der Flash-Befehl ohne Fehler durchgelaufen?** Ja, `** Verified OK **`
|
||||
bei jedem Flash.
|
||||
- **Erscheint nach dem Bootloader-Einstieg ein Laufwerk `VERSABOOT`?** Ja.
|
||||
Getestete Board-Revision hat **keinen physischen Reset-/Boot-Taster**
|
||||
(Custom-PCB) — der ursprünglich geplante Doppel-Tap-Reset-Test war damit
|
||||
nicht durchführbar. Stattdessen wurde ein Hardware-Bootloader-Einstieg über
|
||||
eine gehaltene Cherry-MX-Taste ergänzt, siehe
|
||||
[README.md](README.md#hardware-bootloader-einstieg-ohne-reset-taster).
|
||||
Mit dieser Ergänzung: gehaltene Taste beim Power-On → `VERSABOOT`.
|
||||
- **Was steht in `INFO_UF2.TXT`?**
|
||||
```
|
||||
|
||||
## 1. Repo auf diesem Branch auschecken
|
||||
|
||||
```bash
|
||||
git clone https://git.jappel.io/jappel/VersaMCU.git
|
||||
cd VersaMCU
|
||||
git checkout feature/usb-bootloader
|
||||
UF2 Bootloader versapad-1 SFHWRO
|
||||
Model: VersaPad v2
|
||||
Board-ID: SAMD21G17D-VersaPad-v2
|
||||
```
|
||||
- **Reagiert das Board normal als App-Firmware, wenn man es ohne gehaltene
|
||||
Taste ansteckt?** Ja, nach dem in der README beschriebenen DSB/ISB-Fix.
|
||||
Vor dem Fix: nein, siehe unten.
|
||||
- **Ungewöhnliches?** Ja, ein echter Bug: siehe
|
||||
[Hardwaretest-Abschnitt der README](README.md#hardwaretest-2026-08-05) für
|
||||
die Fehlersuche (Bootloader-eigener Sprung faultete zuverlässig, obwohl vom
|
||||
Debugger injizierte identische Register-/VTOR-Werte einwandfrei liefen) und
|
||||
den Fix (fehlende `__DSB()`/`__ISB()` vor dem `bx` in
|
||||
`check_start_application()`).
|
||||
- **USB-Identität korrekt, kein Fremdtreiber-Konflikt?** Nach PID-Wechsel von
|
||||
`0x0011` auf `0x0043` ja (siehe README, "Bekannte Einschränkungen" zum
|
||||
ursprünglichen Adafruit-PID-Konflikt).
|
||||
|
||||
## 2. Bootloader bauen und flashen
|
||||
## Noch NICHT getestet
|
||||
|
||||
```bash
|
||||
cd bootloader
|
||||
pio run -e versapad_bootloader --target upload
|
||||
```
|
||||
|
||||
Der erste Aufruf lädt automatisch den ARM-Toolchain und OpenOCD herunter
|
||||
(einmalig, braucht Internet). Der Build sollte ohne Fehler durchlaufen
|
||||
(erwartete Größe: ~7,3 von 8 KB Flash).
|
||||
|
||||
## 3. Prüfen, ob der Bootloader läuft
|
||||
|
||||
Nach dem Flash: Board kurz vom USB trennen und wieder anstecken, dann
|
||||
**Reset-Taste zweimal kurz hintereinander drücken** (Doppel-Tap, wie bei
|
||||
Arduino-Zero-artigen Boards üblich).
|
||||
|
||||
Erwartung: Das Board sollte sich als **USB-Massenspeicher-Laufwerk namens
|
||||
`VERSABOOT`** melden (in Windows z. B. im Explorer als neues Laufwerk).
|
||||
|
||||
## 4. Ergebnis zurückmelden
|
||||
|
||||
Bitte notieren und zurückgeben:
|
||||
|
||||
- Ist der Flash-Befehl ohne Fehler durchgelaufen? (ggf. komplette
|
||||
Fehlermeldung kopieren)
|
||||
- Erscheint nach dem Doppel-Tap-Reset ein Laufwerk `VERSABOOT`?
|
||||
- Falls ja: was steht in der Datei `INFO_UF2.TXT` auf dem Laufwerk?
|
||||
- Falls nein: reagiert das Board überhaupt noch normal als App-Firmware
|
||||
(Tasten/LEDs), wenn man es normal per USB ansteckt ohne Doppel-Tap?
|
||||
- Alles, was ungewöhnlich aussieht (USB-Gerät mit falschem Namen, Windows
|
||||
fragt nach Treiber, Laufwerk lässt sich nicht öffnen, etc.)
|
||||
|
||||
Noch NICHT testen: Firmware tatsächlich über das `VERSABOOT`-Laufwerk
|
||||
flashen. Der Firmware-Build erzeugt noch keine `.uf2`-Datei (nur `.bin`
|
||||
für den bisherigen SWD-Weg), das ist der nächste Schritt, nachdem der
|
||||
Bootloader selbst bestätigt läuft.
|
||||
Firmware tatsächlich über das `VERSABOOT`-Laufwerk flashen. Der
|
||||
Firmware-Build der App erzeugt noch keine `.uf2`-Datei (nur `.bin`/`.elf` für
|
||||
den SWD-Weg) — das ist der nächste Schritt, siehe README, "Bekannte
|
||||
Einschränkungen".
|
||||
|
|
|
|||
|
|
@ -15,9 +15,16 @@
|
|||
#define BOARD_ID "SAMD21G17D-VersaPad-v2"
|
||||
|
||||
/* Same VID as the app firmware (platformio.ini), distinct PID so the
|
||||
* bootloader enumerates as a different USB device than the app. */
|
||||
* bootloader enumerates as a different USB device than the app.
|
||||
*
|
||||
* NOT 0x0011: that's Adafruit's own Gemma M0 bootloader PID (this file's
|
||||
* upstream template), and Windows machines with an Adafruit driver already
|
||||
* installed silently bind it as a "Adafruit Circuit Playground" COM port
|
||||
* instead of exposing the VERSABOOT mass-storage volume. Confirmed on real
|
||||
* hardware 2026-08-05. 0x0043 is app PID (0x0042) + 1, not a known
|
||||
* third-party assignment. */
|
||||
#define USB_VID 0x239A
|
||||
#define USB_PID 0x0011
|
||||
#define USB_PID 0x0043
|
||||
|
||||
/* No plain GPIO status LED on this board, only a WS2812 chain on PB22.
|
||||
* The bootloader's LED_PIN code just toggles a digital output, that would
|
||||
|
|
@ -29,4 +36,21 @@
|
|||
//#define BOARD_RGBLED_CLOCK_PIN
|
||||
//#define BOARD_RGBLED_DATA_PIN
|
||||
|
||||
/* Hardware bootloader entry, no dedicated reset/boot button on this PCB.
|
||||
* Reuses the bottom-right Cherry MX key (key_id 24 in the app firmware,
|
||||
* see src/config/pins.h) as a boot-hold key: held while the board resets
|
||||
* or powers up -> stay in the bootloader. Checked in check_start_application()
|
||||
* before the app is even validated, so it works regardless of app firmware
|
||||
* state.
|
||||
*
|
||||
* Pin numbers are PORT-flat (group*32 + pin), matching PINOP()/PINCFG() in
|
||||
* uf2.h: PA15 = 15, PA08 = 8.
|
||||
*
|
||||
* Matrix wiring (src/config/pins.h, src/hal/matrix.cpp): key_id 24 = COL4 x
|
||||
* ROW4. COL4 has an external 10k pull-up to 3V3 (idle HIGH); ROW4 is driven
|
||||
* LOW during the check, matching the app's own scan polarity.
|
||||
*/
|
||||
#define BOOT_KEY_ROW_PIN 15 // PA15 -- ROW4, driven LOW during the check
|
||||
#define BOOT_KEY_COL_PIN 8 // PA08 -- COL4, read back; LOW = key pressed
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -87,6 +87,38 @@ extern int8_t led_tick_step;
|
|||
#define RESET_CONTROLLER RSTC
|
||||
#endif
|
||||
|
||||
#if defined(BOOT_KEY_ROW_PIN) && defined(BOOT_KEY_COL_PIN)
|
||||
/**
|
||||
* \brief Check whether the boot-hold key (bottom-right Cherry MX button) is
|
||||
* held down. Drives its matrix row low and reads its matrix column back,
|
||||
* the same polarity the app firmware's own matrix scan uses.
|
||||
*/
|
||||
static bool boot_key_pressed(void) {
|
||||
PORT_PINCFG_Type col_cfg = {0};
|
||||
col_cfg.bit.PMUXEN = false;
|
||||
col_cfg.bit.INEN = true; // external 10k pull-up already on the board
|
||||
|
||||
PORT_PINCFG_Type row_cfg = {0};
|
||||
row_cfg.bit.PMUXEN = false;
|
||||
row_cfg.bit.DRVSTR = true;
|
||||
|
||||
PINCFG(BOOT_KEY_COL_PIN) = col_cfg.reg;
|
||||
PINOP(BOOT_KEY_COL_PIN, DIRCLR); // column stays an input
|
||||
|
||||
PINOP(BOOT_KEY_ROW_PIN, OUTCLR); // pre-set drive level before enabling output
|
||||
PINCFG(BOOT_KEY_ROW_PIN) = row_cfg.reg;
|
||||
PINOP(BOOT_KEY_ROW_PIN, DIRSET); // row -> output, driving low
|
||||
|
||||
for (volatile int i = 0; i < 200; i++) {
|
||||
} // let the row settle through the diode/pull-up RC
|
||||
|
||||
bool pressed = (PINIP(BOOT_KEY_COL_PIN) == 0);
|
||||
|
||||
PINOP(BOOT_KEY_ROW_PIN, DIRCLR); // release row back to high-Z
|
||||
return pressed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Check the application startup condition
|
||||
*
|
||||
|
|
@ -94,6 +126,13 @@ extern int8_t led_tick_step;
|
|||
static void check_start_application(void) {
|
||||
uint32_t app_start_address;
|
||||
|
||||
#if defined(BOOT_KEY_ROW_PIN) && defined(BOOT_KEY_COL_PIN)
|
||||
if (boot_key_pressed()) {
|
||||
/* Stay in bootloader */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if there is an IO which will hold us inside the bootloader.
|
||||
#if defined(HOLD_PIN) && defined(HOLD_STATE)
|
||||
PORT_PINCFG_Type pincfg = {0};
|
||||
|
|
@ -167,6 +206,14 @@ static void check_start_application(void) {
|
|||
/* Rebase the vector table base address */
|
||||
SCB->VTOR = ((uint32_t)APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);
|
||||
|
||||
/* Ensure the MSP/VTOR writes are visible before jumping; without these
|
||||
* barriers the app's first fetch can race the pipeline (observed on
|
||||
* real hardware: identical MSP/VTOR/PC values injected by a halted
|
||||
* debugger boot fine, but the bootloader's own running jump hard-faults
|
||||
* every time). */
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
/* Jump to application Reset Handler in the application */
|
||||
asm("bx %0" ::"r"(app_start_address));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,23 @@ Robustheitskorrekturen. Sie ist keine Liste bereits umgesetzter Features.
|
|||
## Bootloader-Ziel bleibt nicht unterstützt
|
||||
|
||||
Das aktive Ziel `versapad_nobl` reserviert den kompletten Bereich
|
||||
`0x1FB00..0x1FFFF` für Makros und Config. Das auskommentierte
|
||||
USB-Bootloader-Environment verwendet dagegen weiterhin eine historische
|
||||
Board-/Linker-Konfiguration und ist nicht als Produktionsziel verifiziert.
|
||||
`0x1FB00..0x1FFFF` für Makros und Config.
|
||||
|
||||
Ein USB-Bootloader-Pfad wird im Branch `feature/usb-bootloader` aufgebaut
|
||||
(`bootloader/`, App-Environment `env:versapad_usb`). Der Bootloader selbst
|
||||
(UF2, `bootloader/`) ist dort auf echter Hardware verifiziert — inklusive
|
||||
eines gefundenen und behobenen Bugs beim Sprung in die App (fehlende
|
||||
`__DSB()`/`__ISB()` vor dem `bx`, siehe `bootloader/README.md`,
|
||||
"Hardwaretest"). `env:versapad_usb`s Linkerskript
|
||||
(`variants/versapad/linker_scripts/gcc/flash_with_bootloader.ld`) reserviert
|
||||
inzwischen denselben NVM-Bereich wie `flash_without_bootloader.ld`.
|
||||
|
||||
Trotzdem noch kein Produktionsziel: `env:versapad_usb` verwendet
|
||||
`upload_protocol = sam-ba`, das klassische Arduino/Atmel-SAM-BA-Protokoll —
|
||||
das spricht der UF2-Bootloader nicht. Die App-Firmware erzeugt außerdem noch
|
||||
keine `.uf2`-Datei. Vor einem Merge nach `master` fehlen also noch die
|
||||
`.uf2`-Erzeugung und ein Ende-zu-Ende-Test des tatsächlichen USB-Flashwegs
|
||||
(Datei aufs `VERSABOOT`-Laufwerk kopieren).
|
||||
|
||||
Die aktive Boarddatei benennt die MCU als `samd21g17d`, setzt für den
|
||||
Arduino-Core aber weiterhin das Kompatibilitätsmakro `__SAMD21G18A__`. Der
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ extra_scripts = upload_openocd.py
|
|||
debug_tool = openocd
|
||||
|
||||
; ── USB SAM-BA (nur wenn Bootloader geflasht ist) ─────────────────────────────
|
||||
; [env:versapad_usb]
|
||||
; extends = common
|
||||
; board = versapad
|
||||
; upload_protocol = sam-ba
|
||||
[env:versapad_usb]
|
||||
extends = common
|
||||
board = versapad
|
||||
upload_protocol = sam-ba
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ SEARCH_DIR(.)
|
|||
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x00002000, LENGTH = 0x0001E000 /* 120K (128K - 8K bootloader) */
|
||||
rom (rx) : ORIGIN = 0x00002000, LENGTH = 0x0001D900 /* 118.25K – Firmware (128K - 8K bootloader - 1.25K NVM) */
|
||||
nvm (rx) : ORIGIN = 0x0001FB00, LENGTH = 0x00000500 /* 1.25K – Makros + Config, same layout as flash_without_bootloader.ld */
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* 16K */
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue