A deeper look into Arduino IDE — How to customize Arduino IDE for any MCU

Many people started to use arduino hardware as well as arduino IDE because of its simplicity and convenience in coding and programming a microcontroller, unlike other professional embedded software which usually takes days or weeks to learn the basics of using it. However, despite Arduino IDE’s simplicity in design, it’s also powerful enough to program some of the very sophisticated embedded hardware like Ameba RTL8722 which has 2 cores, tons of peripherals and most importantly dual-band WiFi and BLE 5.0. Today, I want to show you just a little how this was accomplished on Arduino IDE.

Introduction
According to Arduino IDE’s official release history, Arduino IDE start supporting 3rd party hardware starting from version 1.5.x series [1] . This works by letting 3rd party vendor provide a file to be unzipped into the hardware folder of Arduino’s sketchbook folder in which contains the compilation toolchain, drivers, libraries and some tools. But most importanly, 3 text files that instruct Arduino IDE on how to process 3rd party hardware’s code using the libraries/tools they provided. These 3 text files can usually be found in the hardware folder of Arduino’s sketchbook folder that was just unzipped into and they are,

platform.txt contains definitions for the CPU architecture used (compiler, build process parameters, tools used for upload, etc.)
boards.txt contains definitions for the boards (board name, parameters for building and uploading sketches, etc.)
programmers.txt contains definitions for external programmers (typically used to burn bootloaders or sketches on a blank CPU/board)
The key to customize Arduino IDE lays within the platform.txt file.

Customization via platform.txt
According to Arduino IDE’s official documentation,

“The platform.txt file is used to configure the build process. This is done through a list of recipes. Each recipe is a command line expression that explains how to call the compiler (or other tools) for every build step and which parameter should be passed.” [2].

A simple example is like this,

————————————————————————

##Compiler global definitions

compiler.path={runtime.ide.path}/tools/avr/bin/

compiler.c.cmd=avr-gcc

compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD

[……]

##Compile c files

recipe.c.o.pattern=”{compiler.path}{compiler.c.cmd}” {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.extra_flags} {includes} “{source_file}” -o “{object_file}”

————————————————————————

How platform.txt works
If you are familiar with GNU make, you should have no problem understanding this format. It basically comprises of two main components, definition and recipe.

Definition is like variable declaration

Recipe is like a command line

Let’s say, if you want to add some new library into the 3rd party hardware folder, you may make a definition of your new library in your platform.txt and add this definition into the existing recipe if exist or create your own recipe whichever desirable. Same also applies if you want to add new flags into the build process and even wish to switch to a new toolchain. The details of how to write/edit a proper platform.txt can be found here.

Hope with this simple introduction to Arduino IDE’s advanced feature, you can better understand how it works with not only arduino’s hardware but also hundreds of other 3rd party hardware and how it is done.

Useful link
https://arduino.github.io/arduino-cli/latest/platform-specification/

Actually, this is very useful :slight_smile:
Thanks

There was a recent article On HackADay.com that also went into some depth WRT creating a customized boards.txt ...

There was a recent article On HackADay.com that also went into some depth WRT creating a customized boards.txt

Although I normally love Al Williams's articles, I think this was not a great one because he doesn't have an in depth understanding of how the Arduino platform system works.

As mentioned in the article's comments, it would have been much better to do this in boards.local.txt. That would have eliminated the need to merge the customizations back in to boards.txt after every release of MightyCore.

Far better would have been to make a custom board platform for the Z80-MBC. That might sound like a lot of work, but really it's only a little more initial effort than the approach Al took in the article. This is because the Arduino platform system allows you to reference components from other platforms. So you can make a platform that's nothing more than a boards.txt, with all the other components referenced from MightyCore.

That little extra initial effort pays off over time because your custom platform persists through updates to MightyCore. Even with the boards.local.txt, you still need to have a copy of the file saved somewhere outside the platform and then copy it back in after every update. If it's been 6 months since the last release, an infrequent user like Al is probably going to have trouble remembering the process and where that boards.local.txt was stored. So more likely you just don't update MightyCore.

Then we have the fact that the whole point of the project was to share the work with the users of the Z80-MBC, as well as Hackaday's huge audience. That custom platform is by far the best option for distributing this. Take a little extra time to create a package index file for Boards Manager and you make it even more convenient.

It seems Al was vaguely aware of the option of making a custom platform:

It would have probably been better for me to make a custom boards.txt file with the same information in it but then I’d need to take the rest of Mighty Core with me.

but clearly missed the section of the documentation about referencing.


This part was also disturbing to me:

So this is easy, right? Just define those symbols before HardwareSerial.h loads. Uh oh. That file is loaded by Arduino.h. The IDE wants to add that to your program and it forces it to be first. There seems to be some IDE versions that check if you already included it so they don’t include it twice, but version 1.8.5 didn’t seem to do that.

First of all, I think it's absolutely ridiculous to base an article on a version of free software that's two years out of date!!!

Second, that feature works perfectly in Arduino IDE 1.8.5.

Third, this has no chance of working because the sketch is a separate translation unit from HardwareSerial.cpp, where the buffers are defined. I'm certain Al Williams understands the concept of translation units, so I don't know what is going on here.