Skip to content
Snippets Groups Projects
README.md 6.82 KiB
Newer Older
  • Learn to ignore specific revisions
  • # 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.