diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2026-02-22 14:32:31 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2026-02-23 20:17:23 +0800 |
| commit | 05e9ffff4362e31db761e268ae0735d2a1fd231a (patch) | |
| tree | b333822d5af5b9c0b5841abe18df881c1338b41d | |
| parent | 931c7a4f2422c1499bfabcc5d6063b40b9c1dabe (diff) | |
| download | www-05e9ffff4362e31db761e268ae0735d2a1fd231a.tar.gz | |
Improve arduino due post to make it more journal-like.
| -rw-r--r-- | _log/arduino-due.md | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/_log/arduino-due.md b/_log/arduino-due.md index 8176b3b..1881547 100644 --- a/_log/arduino-due.md +++ b/_log/arduino-due.md @@ -4,19 +4,22 @@ date: 2024-09-16 layout: post --- -Bypassing ATSAM3X8E (Due) bootloader via Serial Wire Debug (SWD). +Bought an Arduino Due to play with ARM Cortex chips. Locked out of the chip for +days—no dev tools (Arduino IDE, Microchip Studio) for OpenBSD. Need to find a +way to bring up the bare-metal ATSAM3X8E. -Toolchain: ST-LINK/V2 programmer, OpenOCD, ARM GNU Compiler Toolchain. - -ARM chips boot into 0x00000. GPNVM bits map one of ROM, flash0, flash1 to -0x00000: +Three on-chip memories: ROM, flash0, flash1. ARM Cortex-M chips boot into +0x00000. GPNVM bits map one of them to 0x00000: - GPNVM1=0 → ROM (default). - GPNVM1=1 and GPNVM2=0 → flash0. - GPNVM1=1 and GPNVM2=1 → flash1. -By default, control jumps to Atmel's SAM-BA bootloader in ROM. To bypass, set -GPNVM1=1 and place vector table at 0x80000 (flash0). +On power-up, control jumps to ROM. Without a user program, Atmel's SAM-BA +bootloader traps execution in ROM. Must remap memory via SWD to force chip to +boot from flash, bypassing factory bootloader. + +Toolchain: ST-LINK/V2 programmer, OpenOCD, ARM GNU Compiler Toolchain. Connect ST-LINK/v2 to Arduino Due's DEBUG port: @@ -33,7 +36,7 @@ Connect ST-LINK/v2 to Arduino Due's DEBUG port: </tr> </table> -Remap memory: +Remap memory using OpenOCD: ``` $ openocd -f openocd-due.cfg @@ -44,9 +47,59 @@ $ telnet localhost 4444 > at91sam3 gpnvm show ``` -Full command list is in OpenOCD manual AT91SAM3 (flash driver section). +Full command list in OpenOCD manual AT91SAM3 (flash driver section). -Compile and upload program: +At a minimum, vector table must be initialized with stack pointer and reset +vector: + +``` +__attribute__((noreturn)) void _reset(void) +{ + unsigned long *dst, *src; + extern unsigned long _sbss, _ebss; + extern unsigned long _sdata, _edata, _sidata; + + for (dst = &_sbss; dst < &_ebss; dst++) + *dst = 0; + for (dst = &_sdata, src = &_sidata; dst < &_edata;) + *dst++ = *src++; + + main(); +} + +extern const unsigned int _sp; + +__attribute__ ((section(".vtor"))) const void* _tab[] = { &_sp, _reset }; +``` + +Linker script places vector table at start of flash0 and initializes stack +pointer to top of RAM (descending stack): + +``` +MEMORY +{ + rom (rx) : ORIGIN = 0x00080000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +SECTIONS +{ + .text : + { + KEEP(*(.vtor)) + *(.text*) + *(.rodata*) + } > rom +} + +_sp = ORIGIN(ram) + LENGTH(ram); +``` + +Getting linker script right wasn't easy—long hours with the datasheet, OpenOCD +manual. David Barrass from OpenBSD and folks at OpenOCD mailing lists (bless +them!) helped generously. + +Build and upload program: ``` $ arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T script.ld \ @@ -56,6 +109,8 @@ $ arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T script.ld \ $ openocd -f openocd-due.cfg -c "program a.elf verify reset exit" ``` +Chip unlocked. I'm in. + Commit: <a href="https://git.asciimx.com/bare-metal-arduino-due/commit/?id=318496925ca76668dd9d63c3d060376f489276f8" class="external" target="_blank" rel="noopener noreferrer">3184969</a>. |
