Tag Archives: Arduino M0

Burning Zero bootloader with Beaglebone as SWD programmer

 

OpenOCD has support for bitbanging the jtag or swd protocol over gpio’s. So if you have a board that can run OpenOCD and on which you have access to gpio’s, you can use that as a jtag or swd programmer. The following describes how to use a beaglebone for this purpose but any board with 3V3 gpio’s (e.g. raspberry pie) will do…

bb-m0-z

I followed these instructions to set up the beaglebone. I opted for the debian file system.

Following list of things to install before building OpenOCD will probably save you from having to iteratively install packages untill OpenOCD builds. Of coarse the exact list will change if the initial content of the debian file system changes:

apt-get install autoconf libtool make pkg-config 

Get the OpenOCD sources:

git clone git://git.code.sf.net/p/openocd/code openocd-code

Build openOCD:

cd openocd-code
./bootstrap
./configure --enable-sysfsgpio
make 
make install

openocd is now installed in /usr/local/bin and the scripts it uses are in /usr/local/share/openocd/scripts.

We need an extra config file to describe the beaglebone programmer. I added it here: /usr/local/share/openocd/scripts/interface/bb.cfg. The choice of the gpio’s is up to you, I picked gpio 38 (i.e. gpio1[6], pin header P8_03) and 39 (i.e. gpio1[7], pin header P8_04) as swd_io and swd_sck respectively, so bb.cfg looks like this:

#
# Config for beaglebone interface
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches bone's 3.3V
#
# Do not forget the GND connection.
#

interface sysfsgpio

# minimal swd setup
sysfsgpio_swdio_num     38
sysfsgpio_swclk_num     39

# (Did not manage to make srst work:)
# sysfsgpio_srst_num      45

Store dot-cc’s bootloader (samd21_sam_ba.bin) in a directory of your choice on the beaglebone.

In that dir, create a openocd.cfg file. OpenOCD will read this file to know what it has to do, and how. In our case the file instructs OpenOCD to use the beaglebone as interface (programmer) and tells it we’re programming a samd21 chip.

source [find interface/bb.cfg]
transport select swd

set CHIPNAME at91samd21g18
source [find target/at91samdXX.cfg]

# did not yet manage to make a working setup using srst
#reset_config srst_only
reset_config  srst_nogate

adapter_nsrst_delay 100
adapter_nsrst_assert_width 100

init
targets
reset halt

If you invoke openocd in this directory, you should see following output.

# openocd
Open On-Chip Debugger 0.10.0-dev-00040-gd52070c (2015-10-11-18:21)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
SysfsGPIO num: swdio = 38
SysfsGPIO num: swclk = 39
SysfsGPIO num: srst = 45
adapter speed: 500 kHz
adapter_nsrst_delay: 100
cortex_m reset_config sysresetreq
none separate
adapter_nsrst_delay: 100
adapter_nsrst_assert_width: 100
Info : SysfsGPIO JTAG/SWD bitbang driver
Info : SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)
Info : This adapter doesn't support configurable speed
Info : SWD IDCODE 0x0bc11477
Info : at91samd21g18.cpu: hardware has 4 breakpoints, 2 watchpoints
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* at91samd21g18.cpu  cortex_m   little at91samd21g18.cpu  running
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x21000000 pc: 0x000028f4 msp: 0x20002c00

OpenOCD is now constantly polling the device and it is ready to accept new instructions from us via telnet or gdb. You could log into openocd using telnet from your pc (or from the bone) and inspect memory, run code, start debugging…

If on the other hand you are just interested in burning the bootloader, you could add following line at the end of openocd.cfg and start openocd again.

at91samd bootloader 0; program samd21_sam_ba.bin verify reset; shutdown

OpenOCD should now produce following extra report about the flashing operation.

** Programming Started **
auto erase enabled
Info : SAMD MCU: SAMD21G18A (256KB Flash, 32KB RAM)
wrote 16384 bytes from file samd21_sam_ba.bin in 4.120137s (3.883 KiB/s)
** Programming Finished **
** Verify Started **
verified 6328 bytes in 0.575388s (10.740 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

The M0 is now ready to receive sketches from the dot-cc IDE.
Remark: if you previously made the modification to the dot-cc lnker script from my previous post, don’t forget to undo this change.

In case you want to restore the dot-org bootloader, use this line as last line in openocd.cfg instead:

at91samd bootloader 0; program Bootloader_D21_M0_150515.hex verify reset; shutdown

Using the Arduino M0 with the arduino.cc IDE and core.

This post is about the plain Arduino M0 from Arduino.org. I bought it at a time the Genuino Zero was not available in Europe. After waiting a few months, I got impatient to try one out and bought the M0… I must say I like this board: it has no on board programmer which makes it a lot more affordable. Moreover for a programmer enthusiast like me it was actually more fun to get this board up and running without the help of the edbg chip.

As a member of the Arduino.cc community, I wanted to use this board with the dot-cc IDE. The most practical way to do so, is to burn the dot-cc bootloader into it. After that, your M0 (or M0 Pro) is almost the same thing as an Arduino Zero.

The M0 Pro has an on board programmer, so burning the bootloader can simply be done via the ‘Burn Bootloader’ menu from the IDE, without the need for additional tools.

The plain M0 has no such on board programmer. You could burn it using an external programmer (see e.g. next post). However, you might not have such a programmer available, or you might just wonder whether sketches built with the dot-cc IDE can be sent to a stock dot-org M0 that still has its original boot loader in place.

That is what this post is about: use the dot-cc IDE to build sketches, pretend you have a Zero by selecting the Zero as board and then send it to the M0. The whole sequence cannot be completed from within the IDE. That is why towards the end of this post, a script is presented that executes the complete sequence of building the sketch, post process it and then send it to the M0. That script is also a good example of the Arduino CLI (Command Line Interface).

A good general approach with this technique is to first develop with the dot-cc ide (just as if you had a Zero). If your application requires extra libraries, just install them in the usual way.

In this process keep in mind there are after all a few hardware differences between the M0 and the Zero:

  • Digital pins 2 and 4 are swapped
  • ATN pin is not connected on the M0
  • Serial port selection is also a bit tricky:
    • Serial will print to the uart (pins 0 and 1) on the M0
    • SerialUSB prints to the native (only) usb port on the M0

The above differences could be streamlined by creating “variant” files, but I choose to not go that far…

Once your sketch compiles, it should work on the M0 too (modulo the hardware differences). You may want to use the m0.sh script to rebuild it and send it to the M0. You can move your sketch folder to a folder of your choice, it does not need to be in the sketchbook folder. Referenced libraries can stay in the sketchbook/libraries folder…

What is needed to compile a sketch, post process the compiled binary and send it off to the M0.

If you compile a sketch with the dot-cc IDE, just like that, it produces an image that does not end up in flash on the location where the dot-org bootloader expects it.

To create a suitable image, theĀ  linker script used by the dot-cc IDE must be modified. The dot-cc IDE’s board manager maintains files for a given core in the .arduino15 sub dir of your home dir (the description below this point is for linux but for windows, you can carry out an equivalent procedure). In there, locate the support package for the Zero in which you’ll find the linker script. Mine was at: .arduino15/packages/arduino-beta/hardware/samd/1.6.1-build-34/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld

Find the line describing the flash area:

FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */

And change it into:

FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00040000-0x4000

Now the dot-cc IDE will create an image suitable for the dot-org bootloader, be it that it is in the elf file format and we need a hex file. We can easily convert the elf image produced by the dot-cc IDE, using objcopy. I’ll explain that later, in the script presented below.

So, at this point we have a .hex file suitable for running on the M0. Let’s see how we can get it there.

The dot-org IDE uploads sketches to the M0’s bootloader using avrdude, whereas the dot-cc IDE uses bossac to upload to the Zero. So we’ll have to use avrdude. We need the avrdude provided by the dot-org IDE, a stock avrdude version does not work.

The dot-org avrdude version is compiled without support for elf images, this why we need to convert to .hex.

We’ll have to press the reset button ourselves before uploading the sketch. But that works very reliably: after pressing reset the bootloader waits about 10 seconds for a sketch to arrive. It indicates this condition by blinking the led rapidly. It is easy to synchronize pressing reset with firing up avrdude. Also, uploading the sketch is very fast.

The m0.sh script.

Because it is not very handy to compile the sketch in the IDE, find out where it has built the elf file, convert it and invoke avrdude manually, I wrote a script that automates this procedure. The sketch is built using the new CLI (Command Line Interface) of the IDE. This is actually practical, you can edit the sketch in any editor and build/upload it with the script.

Say you have a sketch named ArduinoISP.ino, the script expects it to be in a sub folder (of the current working directory) named ArduinoISP. The script places all build files in sub folder: build/ArduinoISP.

In this example, invoke the script as:

./m0.sh ArduinoISP

Here is the script:

#!/bin/bash

# m0.sh: compiles a sketch and sends it off to the arduino M0

if [ $# -lt 1 ]; then
        echo -e "\nUsage: $0 <sketch_dir> [serial_port]\n"
        exit 1
fi

# sketch dir, trim trailing slash:
SKETCH=$(echo $1 | sed 's:/*$::')

# serial port
if [ $# -gt 1 ]; then
        PORT=$2
else
        PORT=/dev/ttyACM0
fi

# the dot-org ide is installed here:
DOT_ORG=/opt/arduino-1.7.6-linux32

# the dot-cc ide is installed here:
DOT_CC=/opt/arduino-nightly

# compile sketch:
${DOT_CC}/arduino \
        --verify \
        --verbose-build \
        --board arduino-beta:samd:arduino_zero_native \
        --pref build.path=build/${SKETCH} ${SKETCH}/${SKETCH}.ino || exit

# create a hex file:
${DOT_ORG}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-objcopy \
        -O ihex -R .eeprom \
        build/${SKETCH}/${SKETCH}.ino.elf build/${SKETCH}/${SKETCH}.ino.hex

echo -e "\n\n\nPress the RESET button now..."
echo -e "Then press ENTER to continue...\n\n\n"
read

# upload sketch:
${DOT_ORG}/hardware/tools/avr/bin/avrdude \
        -C ${DOT_ORG}/hardware/tools/avr/etc/avrdude.conf \
        -v -v -patmega2560 -cstk500v2 -b57600 \
        -P ${PORT} \
        -Uflash:w:build/${SKETCH}/${SKETCH}.ino.hex:i

Remarks:

  • A script like this, that uses the CLI, risks to have a limited validity date. If the conventions change about where to place the various files needed by the IDE, this script will rapidly be broken…
  • note the script instructs the IDE to use ‘arduino-beta‘ as the ‘package’. At the time of writing the Zero core is still actively worked on. E.g. to be able to run ArduinoISP, I needed a beta version that fixes problems in the USB drivers. If you work with the latest stable version use ‘arduino‘ as package instead. (the package is the name of the sub folder of the .arduino15/packages folder).