Tag Archives: bootloader

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:


# 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

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

# serial port
if [ $# -gt 1 ]; then

# the dot-org ide is installed here:

# the dot-cc ide is installed here:

# 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"

# 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} \


  • 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).