Arduino Hardware Cores migration guide from 1.0 to 1.6

Kees Bakker edited this page Jun 28, 2015 · 4 revisions

Arduino 1.6 is the stable release of the changes that have been made and tested through the Arduino 1.5.x series (and which have been stable for a while now). These changes greatly increased the flexibility of the Arduino IDE, allowing it to support boards with different microcontroller architectures, different tool-chains, and different build and upload processes. The third-party hardware support in Arduino 1.6 is the same as that in the last few Arduino 1.5.x versions and should remain stable for the foreseeable future (apart from small, backwards-compatible additions to extend its flexibility).

This tutorial provides a list of useful hints to migrate hardware cores for Arduino 1.0.x to a format suitable for the new Arduino IDE 1.5.x/1.6.x. (See also the full specification of the Arduino 1.5.x / 1.6.x third-party hardware format.).

We'll use as an example the core for Sparkfun 34u2 boards and, step by step, we'll transform it into a core for the latest Arduino IDE 1.5.x/1.6.x.

Starting situation

The following is a snapshot of the SparkFun core made for Arduino 1.0:

sparkfun/boards.txt
sparkfun/bootloaders/caterina/...
sparkfun/driver/...
sparkfun/signed_driver/...
sparkfun/variants/promicro/pins_arduino.h
sparkfun/variants/minibench/pins_arduino.h
sparkfun/README.md

Step 1: Move core files into a vendor/architecture folder structure.

The new Arduino IDE introduced support for boards that use CPU architectures different from AVR. Cores for each architecture now reside in their own folder. Therefore we must move the core files inside a folder structure where the first folder is the name of the vendor and the second folder is the name of the architecture, that is: move everything into sparkfun/avr/

sparkfun/avr/boards.txt
sparkfun/avr/bootloaders/caterina/… 
sparkfun/avr/driver/… 
sparkfun/avr/signed_driver/… 
sparkfun/avr/variants/promicro/pins_arduino.h
sparkfun/avr/variants/minibench/pins_arduino.h
sparkfun/avr/README.md

sparkfun is the vendor folder and it's supposed to be exclusively maintained by the vendor itself. This allows a vendor to provide support for custom hardware across multiple architectures (e.g. sparkfun/avr and sparkfun/sam).

Step 2: Define board ID

If we try to start the Arduino IDE now, we'll get the following warnings:

Board sparkfun:avr:promicro16 doesn't define a 'build.board' preference. Auto-set to: AVR_PROMICRO16
Board sparkfun:avr:promicro8 doesn't define a 'build.board' preference. Auto-set to: AVR_PROMICRO8
Board sparkfun:avr:fiov3 doesn't define a 'build.board' preference. Auto-set to: AVR_FIOV3
Board sparkfun:avr:minibench doesn't define a 'build.board' preference. Auto-set to: AVR_MINIBENCH

The IDE is telling us that we didn't define Board IDs. These identifiers are used in C source code to create conditions for #ifdef. The IDE is also suggesting some good defaults, so let's add them explicitly in the boards.txt file to silence the warnings:

promicro16.build.board=AVR_PROMICRO16
...
promicro8.build.board=AVR_PROMICRO8
...
fiov3.build.board=AVR_FIOV3
...
minibench.build.board=AVR_MINIBENCH

Step 3: Add build definitions for USB Device stack (only for Atmega32u4 based boards)

If we try to build a sketch now, we may get some errors related to USB VID/PID if the board is based on a Atmega32u4 CPU. The Arduino USB Stack for AVR has had a number of improvements over the last year and now needs an explicit declaration for USB Product and USB Manufacturer strings. This is accomplished by adding the following lines in file boards.txt:

promicro16.build.usb_product="ProMicro 16"
promicro16.build.usb_manufacturer="Sparkfun"
promicro16.build.extra_flags={build.usb_flags}

After adding these lines we should be able to successfully build a sketch. The complete build section related to USB now looks like:

promicro16.build.vid=0x1B4F
promicro16.build.pid=0x9206
promicro16.build.usb_product="ProMicro 16"
promicro16.build.usb_manufacturer="Sparkfun"
promicro16.build.extra_flags={build.usb_flags}

For the curious the current build.usb_flags line is defined in the Arduino's AVR platform.txt file as:

build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'

Step 4: Add tools for "upload" and "burn bootloader"

The next step is uploading. If we try to upload or burn bootloader now we get the following error:

Error while uploading: missing 'upload.tool' configuration parameter

or

Error while burning bootloader: missing 'bootloader.tool' configuration parameter

The upload.tool and bootloader.tool keys are missing from our configuration. (In Arduino 1.0.x, the same tool, avrdude, was used for all boards, so there was no need to specify the tool in the boards.txt file). For AVR boards this is a very simple fix, since we use only avrdude, just add the following lines to file boards.txt:

promicro16.upload.tool=arduino:avrdude
...
promicro16.bootloader.tool=arduino:avrdude

Note that the tool is named arduino:avrdude and not simply avrdude, because the IDE should use the avrdude configuration found in the Arduino's AVR cores (note that the reference only specifies the target vendor and tool name, the platform is assumed to be the same as that for the boards.txt -- in this case, avr). Boards that need a custom tool (or custom parameters for an existing tools) can specify one in a platform.txt file. See the 1.5.x platform specification for details.

Step 5: Fix bootloader path (and weird upload feature in 1.0)

This is accomplished by merging the following two configuration properties:

promicro16.bootloader.path=caterina
promicro16.bootloader.file=Caterina-promicro16.hex

into a single:

 promicro16.bootloader.file=caterina/Caterina-promicro16.hex

But there is more: Arduino IDE 1.0 used to check if bootloader.path contains the word "caterina" to perform a special 1200 bps-touch operation on the serial port before uploading the sketch. This is a special feature needed only by Arduino Leonardo (mega32u4) or derivative boards, and was a dirty hack. IDE 1.5 removed the hack by explicitly specifying that the 1200bps touch is needed using the following configuration keys:

 promicro16.upload.use_1200bps_touch=true
 promicro16.upload.wait_for_upload_port=true

The upload.use_1200bps_touch key tells the IDE to open the user-selected serial port at 1200 baud, and then close it, before attempting an upload. The upload.wait_for_upload_port tells the IDE to wait for a new serial port to appear before uploading, and to upload to that new port. If both are enabled, the 1200bps touch happens first. Some USB based boards may need only one feature and not both: it's perfectly legit to set one of them to false.

Step 6: Add USB identifiers for Port List menu

This a very nice feature of the new Arduino IDE: it detects automatically the board connected to each serial port and shows the name of the board in front of each port listed in the ports menu. To make this work we need only to list the USB PID/VID associated with the board:

promicro16.vid.0=0x1B4F
promicro16.pid.0=0x9206

And that's it! Some boards may have different vid/pid depending on their state (for example the Arduino Leonardo shows a different PID while in bootloader mode), in this case we can specify all the VID/PID pairs by incrementing the last number 0, for example the Leonardo board has the following configuration:

leonardo.vid.0=0x2341
leonardo.pid.0=0x0036
leonardo.vid.1=0x2341
leonardo.pid.1=0x8036

If your board doesn't have a unique VID/PID (e.g. because you're using an FTDI chip with a shared VID/PID) you shouldn't include it here.

Step 7. Verify Everything is Working

You should now be able to run Arduino 1.5.8 or 1.6.x, upload to your board, burn the bootloader, and have the board automatically detected and its name listed in the serial port menu (assuming it has a unique USB VID/PID).

For more information, see the third-party hardware specification for Arduino 1.5.x and 1.6.x. If you have any problems, please open an issue on github