From ee6a580cdc873857d1f96106f83a0761706d0709 Mon Sep 17 00:00:00 2001 From: Erik Strand <erik.strand@cba.mit.edu> Date: Wed, 4 Dec 2019 23:21:04 -0500 Subject: [PATCH] Move relevant sections of the README --- README.md | 101 ++-------------------------------- blink-openocd/README.md | 116 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 96 deletions(-) create mode 100644 blink-openocd/README.md diff --git a/README.md b/README.md index 2668067..4fcfff6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ As of Oct 13 2019, -> CBA :heart: D51 <-  [squidworks module](https://gitlab.cba.mit.edu/squidworks/moduleboard-atsamd51/) -## Toolchains +## Bootloader Based Toolchains ### Adafruit Bootloader / Platformio (or Arduino Compatible) @@ -39,98 +39,7 @@ One of the troubles with Arduino is that people forget that it is just a big C++ Indeed, in the PlatformIO environment, we even have wonderful autocomplete handles on the D51's core register map. For some examples of this kind of manipulation, check out the `hunks` in the [ponyo](https://gitlab.cba.mit.edu/squidworks/ponyo) project. -### Bare Metal development - -Okay, bare-ish metal development. If you want to work with the SAMD51 using the command line, a text editor, Makefiles, and a few open-source tools, it's possible to do so with a bit of setup. You should use Linux to do this work; your mileage may vary on other operating systems. - -Credit to Alex Kaspar for sorting through openocd setup in 2018. These instructions build on that work. - -First, install [openocd](http://openocd.org/getting-openocd/). Until recently, this tool didn't officially support the SAMD51 series, requiring the use of a [patch](http://openocd.zylin.com/#/c/4272/) and manual compilation to work with the chipset. According to the patch notes, the patch was merged in early 2019 so the standard installation should work fine. Put the program in directory such as ~/openocd. If you're building from source, navigate to this directory and run: -``` -./bootstrap -./configure --enable-cmsis-dap -make -make install -``` - -Second, install a handful of other helpful tools. Depending on your other work you may already have many of these on your machine: - -``` -sudo apt install autoconf build-essential cmake gdb-arm-none-eabi libtool libtool-bin libhidapi-dev libusb-dev libusb-1.0-0-dev pkg-config -``` -Third, clone this repo. Navigate to the `baremetal` directory and run `make`. You should see something like this result: - -``` -zach@crudite:~/Documents/atsamd51/baremetal$ make -Building file: main.c -ARM/GNU C Compiler -"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ --MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" "main.c" -Finished building: main.c -Building file: samd51/startup/system_samd51.c -ARM/GNU C Compiler -"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ --MD -MP -MF "samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.o" -o "samd51/startup/system_samd51.o" "samd51/startup/system_samd51.c" -Finished building: samd51/startup/system_samd51.c -Building file: samd51/startup/startup_samd51.c -ARM/GNU C Compiler -"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ --MD -MP -MF "samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.o" -o "samd51/startup/startup_samd51.o" "samd51/startup/startup_samd51.c" -Finished building: samd51/startup/startup_samd51.c -Building target: main.elf -Invoking: ARM/GNU Linker -"arm-none-eabi-gcc" -o main.elf main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o -Wl,--start-group -lm -Wl,--end-group -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 \ --Wl,-Map="main.map" --specs=nano.specs -Wl,--gc-sections \ - \ - \ --T"samd51/startup/samd51j19a_flash.ld" \ --L"samd51/startup" -/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: main.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail -/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/system_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail -/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/startup_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail -Finished building target: main.elf -"arm-none-eabi-objcopy" -O binary "main.elf" "main.bin" -"arm-none-eabi-objcopy" -O ihex -R .eeprom -R .fuse -R .lock -R .signature \ - "main.elf" "main.hex" -"arm-none-eabi-objcopy" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma \ - .eeprom=0 --no-change-warnings -O binary "main.elf" \ - "main.eep" || exit 0 -"arm-none-eabi-objdump" -h -S "main.elf" > "main.lss" -"arm-none-eabi-size" "main.elf" - text data bss dec hex filename - 968 0 49184 50152 c3e8 main.elf -Deleting intermediate files... -rm -f main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o -rm -f main.d samd51/startup/system_samd51.d samd51/startup/startup_samd51.d -rm -f main.a main.hex main.bin \ - main.lss main.eep main.map \ - main.srec -``` -Errors are not uncommon and are usually related to the directory structure of the Makefile. However, this repo includes all of the required SAMD51 libraries (from Atmel/Microchip's ASF4 framework, as shared by [Adafruit](https://github.com/adafruit/asf4)), so if you grabbed the entire repo you should be fine. Post an issue if it doesn't work. Note one modification to the Makefile is that it deletes all the intermediate files (.o, .eep, etc) after producing the .elf file. If you want them, remove the lines in the Makefile after the phrase 'Deleting intermediate files...'. - -Fourth, after you have your .elf file (in this case `main.elf`), connect your target board to power and an Atmel ICE programmer (make sure you use the correct pinout and the SAM port!) and run `openocd`. You should see the following: -``` -zach@crudite:~/Documents/atsamd51/baremetal$ openocd -Open On-Chip Debugger 0.10.0+dev-00409-g1ae106de-dirty (2019-10-14-20:41) -Licensed under GNU GPL v2 -For bug reports, read - http://openocd.org/doc/doxygen/bugs.html -none separate -adapter speed: 400 kHz -cortex_m reset_config sysresetreq -Info : Listening on port 6666 for tcl connections -Info : Listening on port 4444 for telnet connections -Info : CMSIS-DAP: SWD Supported -Info : CMSIS-DAP: JTAG Supported -Info : CMSIS-DAP: Interface Initialised (SWD) -Info : CMSIS-DAP: FW Version = 1.0 -Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1 -Info : CMSIS-DAP: Interface ready -Info : clock speed 400 kHz -Info : SWD DPIDR 0x2ba01477 -Info : at91samd51j18.cpu: hardware has 6 breakpoints, 4 watchpoints -Info : Listening on port 3333 for gdb connections -``` -If you see `Error: unable to open CMSIS-DAP device 0x3eb:0x2141`, it probably means openocd needs root privileges to access the programmer. You could run `sudo openocd`, but a better solution is to follow the instructions [here](https://forgge.github.io/theCore/guides/running-openocd-without-sudo.html) to create a new rule. Don't forget to restart `udev` after doing this with `sudo udevadm trigger`. - -Fifth, now that openocd is running, open a second terminal window and type `arm-none-eabi-gdb main.elf`. When gdb opens, type `tar ext :3333` (a shortcut for `target extended-remote :3333`), then `load`. This should flash the microcontroller with the new code, at which point you can exit gdb with `quit` and `y`. In the openocd window, close the connection with `Ctrl-C`. If you're flashing one of Jake's [moduleboards](https://gitlab.cba.mit.edu/squidworks/moduleboard-atsamd51/tree/master), the red and green LEDs should blink. + +## Bare(ish) Metal Toolchains + +[OpenOCD](blink-openocd) diff --git a/blink-openocd/README.md b/blink-openocd/README.md new file mode 100644 index 0000000..cdeac47 --- /dev/null +++ b/blink-openocd/README.md @@ -0,0 +1,116 @@ +# Bare Metal Development + +This is a minimalist blink program. No bootloader, and no IDE to build things for us. Just the +command line, a text editor, Makefiles, and a few open-source tools. You should use Linux to do this +work; your mileage may vary on other operating systems. + +This example assumes you're using a +[squidworks module](https://gitlab.cba.mit.edu/squidworks/moduleboard-atsamd51/), but if you're +using something else you'll just need to update which pins your LEDs are on. + +## Setup + +We'll use OpenOCD to program our board. Relevant docs live +[here](https://gitlab.cba.mit.edu/pub/hello-world/tools/tree/master/openocd). + +## Building + +Once that's done, clone this repo. Fire up your terminal, navigate to this directory, and run +`make`. You should see something like this result: + +``` +zach@crudite:~/Documents/atsamd51/baremetal$ make +Building file: main.c +ARM/GNU C Compiler +"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ +-MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" "main.c" +Finished building: main.c +Building file: samd51/startup/system_samd51.c +ARM/GNU C Compiler +"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ +-MD -MP -MF "samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.o" -o "samd51/startup/system_samd51.o" "samd51/startup/system_samd51.c" +Finished building: samd51/startup/system_samd51.c +Building file: samd51/startup/startup_samd51.c +ARM/GNU C Compiler +"arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \ +-MD -MP -MF "samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.o" -o "samd51/startup/startup_samd51.o" "samd51/startup/startup_samd51.c" +Finished building: samd51/startup/startup_samd51.c +Building target: main.elf +Invoking: ARM/GNU Linker +"arm-none-eabi-gcc" -o main.elf main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o -Wl,--start-group -lm -Wl,--end-group -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 \ +-Wl,-Map="main.map" --specs=nano.specs -Wl,--gc-sections \ + \ + \ +-T"samd51/startup/samd51j19a_flash.ld" \ +-L"samd51/startup" +/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: main.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail +/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/system_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail +/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/startup_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail +Finished building target: main.elf +"arm-none-eabi-objcopy" -O binary "main.elf" "main.bin" +"arm-none-eabi-objcopy" -O ihex -R .eeprom -R .fuse -R .lock -R .signature \ + "main.elf" "main.hex" +"arm-none-eabi-objcopy" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma \ + .eeprom=0 --no-change-warnings -O binary "main.elf" \ + "main.eep" || exit 0 +"arm-none-eabi-objdump" -h -S "main.elf" > "main.lss" +"arm-none-eabi-size" "main.elf" + text data bss dec hex filename + 968 0 49184 50152 c3e8 main.elf +Deleting intermediate files... +rm -f main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o +rm -f main.d samd51/startup/system_samd51.d samd51/startup/startup_samd51.d +rm -f main.a main.hex main.bin \ + main.lss main.eep main.map \ + main.srec +``` + +Errors are not uncommon and are usually related to the directory structure of the Makefile. However, +this repo includes all of the required SAMD51 libraries (from Atmel/Microchip's ASF4 framework, as +shared by [Adafruit](https://github.com/adafruit/asf4)), so if you grabbed the entire repo you +should be fine. Post an issue if it doesn't work. Note one modification to the Makefile is that it +deletes all the intermediate files (.o, .eep, etc) after producing the .elf file. If you want them, +remove the lines in the Makefile after the phrase 'Deleting intermediate files...'. + +## Programming + +Fourth, after you have your .elf file (in this case `main.elf`), connect an Atmel ICE programmer to +your SAMD51 board and power it up. Note: make sure you use the correct pinout and the SAM port! Then +run `openocd`. You should see the following: + +``` +zach@crudite:~/Documents/atsamd51/baremetal$ openocd +Open On-Chip Debugger 0.10.0+dev-00409-g1ae106de-dirty (2019-10-14-20:41) +Licensed under GNU GPL v2 +For bug reports, read + http://openocd.org/doc/doxygen/bugs.html +none separate +adapter speed: 400 kHz +cortex_m reset_config sysresetreq +Info : Listening on port 6666 for tcl connections +Info : Listening on port 4444 for telnet connections +Info : CMSIS-DAP: SWD Supported +Info : CMSIS-DAP: JTAG Supported +Info : CMSIS-DAP: Interface Initialised (SWD) +Info : CMSIS-DAP: FW Version = 1.0 +Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1 +Info : CMSIS-DAP: Interface ready +Info : clock speed 400 kHz +Info : SWD DPIDR 0x2ba01477 +Info : at91samd51j18.cpu: hardware has 6 breakpoints, 4 watchpoints +Info : Listening on port 3333 for gdb connections +``` + +If you see `Error: unable to open CMSIS-DAP device 0x3eb:0x2141`, it probably means openocd needs +root privileges to access the programmer. You could run `sudo openocd`, but a better solution is to +follow the instructions +[here](https://forgge.github.io/theCore/guides/running-openocd-without-sudo.html) to create a new +rule. Don't forget to restart `udev` after doing this with `sudo udevadm trigger`. + +Fifth, now that openocd is running, open a second terminal window and type `gdb-multiarch main.elf` +(if you're using an older gdb version, it's `arm-none-eabi-gdb main.elf`). When gdb opens, type `tar +ext :3333` (a shortcut for `target extended-remote :3333`), then `load`. This should flash the +microcontroller with the new code, at which point you can exit gdb with `quit` and `y`. In the +openocd window, close the connection with `Ctrl-C`. If you're flashing one of Jake's +[moduleboards](https://gitlab.cba.mit.edu/squidworks/moduleboard-atsamd51/tree/master), the red and +green LEDs should blink. -- GitLab