diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2025-12-27 13:05:42 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2025-12-27 13:05:42 +0800 |
| commit | 023ea62a08492d9dda680cee3e706a988b1ae6f0 (patch) | |
| tree | 96bbf7ee6eb91ca33b98b63539e29394f194b441 /_log | |
| parent | 196cf07dff3e16f6c44bb2a6cca10c0af3652fe9 (diff) | |
| download | www-023ea62a08492d9dda680cee3e706a988b1ae6f0.tar.gz | |
Arduino due post.
Diffstat (limited to '_log')
| -rw-r--r-- | _log/arduino-due.md | 103 |
1 files changed, 38 insertions, 65 deletions
diff --git a/_log/arduino-due.md b/_log/arduino-due.md index 2cbd2f4..0d4f495 100644 --- a/_log/arduino-due.md +++ b/_log/arduino-due.md @@ -1,43 +1,27 @@ --- -title: How to set up ATSAM3X8E microcontrollers for bare-metal programming in C +title: ATSAM3X8E bare-metal programming date: 2024-09-16 layout: post --- -This article is a step-by-step guide for programming bare-metal ATSAM3X8E chips -found on Arduino Due boards. It also includes notes on the chip's memory layout -relevant for writing linker scripts. The steps described in this article were -tested on an OpenBSD workstation. +Notes on programming ATSAM3X8E chips (Arduino Due) without bootloader. Tested +on OpenBSD. ## Toolchain -To interact directly with a bare-metal ATSAM3X8E chips, we must bypass the -embedded bootloader. To do that, we need a hardware programmer capable of -communicating with the chip over the Serial Wire Debug (SWD) protocol. Since -the workstation we upload the program from presumably doesn't speak SWD, the -hardware programmer acts as a SWD-USB adapter. The <a -href="https://www.st.com/en/development-tools/st-link-v2.html" class="external" -target="_blank" rel="noopener noreferrer">ST-LINK/V2</a> programmer fits this -bill. - -The <a href="https://openocd.org/" class="external" target="_blank" -rel="noopener noreferrer">OpenOCD</a> on-chip debugger software supports -ATSAM3X8E chips. OpenOCD, on startup, runs a telnet server that we can connect to -to issue commands to the ATSAM3X8E chip. OpenOCD translates plain-text commands -into the binary sequences the chip understands, and sends them over the wire. - -Finally, we need the <a -href="https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain" -class="external" target="_blank" rel="noopener noreferrer">ARM GNU Compiler -Toolchain</a> to compile C programs for the chip. The ARM GNU compiler -toolchain and OpenOCD, as a consequence of being free software, are available -on every conceivable platform, including OpenBSD. +Need to bypass embedded bootloader—requires hardware programmer that speaks +Serial Wire Debug (SWD). ST-LINK/V2 works as SWD-USB adapter. + +OpenOCD translates commands to binary sequences the chip understands. Runs +telnet server on startup for issuing commands. + +ARM GNU Compiler Toolchain for compiling C programs. Both OpenOCD and ARM +toolchain available on OpenBSD. ## Electrical connections -The following photos illustrate the electrical connections between the Arduino -Due, PC, and the ST-LINK/V2 programmer required to transfer a compiled program -from a PC to the MCU. +Arduino Due exposes ATSAM3X8E's SWD interface via DEBUG port. ST-LINK/V2 +connects there. <table style="border: none; width: 100%;"> <tr style="border: none;"> @@ -55,11 +39,10 @@ from a PC to the MCU. Arduino Due exposes the ATSAM3X8E's SWD interface via its DEBUG port. The ST-LINK/v2 programmer connects to that to communicate with the chip. -## Uploading the program +## Upload procedure -The source.tar.gz tarball at the end of this page contains a sample C program -(the classic LED blink program) with OpenOCD configuration and linker scripts. -First, use the following command to build it: +Sample LED blink program with OpenOCD config and linker scripts in tarball +below. ``` $ arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T script.ld \ @@ -68,8 +51,7 @@ $ arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T script.ld \ -o a.elf main.c ``` -Then, open a telnet session with OpenOCD and issue the following sequence of -commands to configure the chip and upload the compiled program to it: +Upload: ``` $ openocd -f openocd-due.cfg @@ -81,42 +63,33 @@ $ telnet localhost 4444 $ openocd -f openocd-due.cfg -c "program a.elf verify reset exit" ``` -The first of the above commands starts OpenOCD. In the telnet session, the -first command halts the chip in preparation for receiving commands. Next, we -inspect the current GPNVM bit setting (more on this later). If the bit is unset -(the gpnvm show command returns 0), we set it to 1 and verify the update. - -The final command, issued from outside the telnet session, uploads the program -to the chip. Those are the bare minimum set of commands required to program the -chip. The AT91SAM3 flash driver section of the OpenOCD manual lists all -available commands for the ATSAM3X8E chip. +First command starts OpenOCD. Telnet session halts chip, checks GPNVM bit. If +unset (returns 0), set to 1 and verify. Final command uploads program. See +OpenOCD manual AT91SAM3 flash driver section for full command list. ## GPNVM bits -By design, ARM chips boot into address 0x00000. ATSAM3X8E's memory consists of -a ROM and a dual-banked flash (flash0 and flash1), residing in different -locations of the chip's address space. The GPNVM bits control which of them -maps to 0x00000. When GPNVM1 is cleared (the default), the chip boots from the ROM, -which contains Atmel's SAM-BA bootloader. +ARM chips boot into address 0x00000. ATSAM3X8E has ROM and dual-banked flash +(flash0/flash1) at different addresses. GPNVM bits control which maps to +0x00000. + +GPNVM1 cleared (default): boots from ROM (Atmel SAM-BA bootloader). GPNVM1=1, +GPNVM2=0: flash0 (0x80000) maps to 0x00000. Both cleared: flash1 maps to +0x00000. + +Program goes in flash0, so set GPNVM1=1 to boot our code instead of bootloader. -Conversely, when the GPNVM1 bit is 1 (and the GPNVM2 bit is 0), flash0 at -address 0x80000 maps to 0x00000. When both GPNVM bits are 0, flash1 maps to -0x00000. Since we place our program in flash0 in the linker script, we set the -GPNVM1 bit and leave the GPNVM2 bit unchanged to ensure the chip -executes our program instead of the embedded bootloader at startup. +## Linker script notes -## Linker script +Vector table must be at first flash address--mandatory for ARM chips unless +using VTOR register for relocation. -At a minimum, the linker script must place the vector table at the first -address of the flash. This is mandatory for ARM chips unless we relocate the -vector table using the VTOR register. +First vector table entry: stack pointer. Initialize to highest memory location +(ATSAM3X8E has descending stack). -The first entry of the vector table must be the stack pointer. The stack -pointer must be initialized to the highest memory location available to -accommodate the ATSAM3X8E's descending stack. +Second entry: reset vector. Place initialization code here (zero memory, set +registers) before jumping to main(). -The second entry of the vector table must be the reset vector. In the reset -vector, we can perform tasks such as zeroing out memory and initializing -registers before passing control to the main program. +Commit: +[3184969](https://git.asciimx.com/bare-metal-arduino-due/commit/?id=318496925ca76668dd9d63c3d060376f489276f8) -Files: [source.tar.gz](source.tar.gz) |
