98 lines
2.9 KiB
Markdown
98 lines
2.9 KiB
Markdown
|
---
|
||
|
title: "Arduino, Big Builder, and Make"
|
||
|
date: 2024-01-05
|
||
|
tags:
|
||
|
- computers
|
||
|
- ci/cd
|
||
|
---
|
||
|
|
||
|
Last night,
|
||
|
I got Big Builder building Arduino sketches.
|
||
|
|
||
|
Big Builder is my Continuous Integration / Continuious Development (ci/cd)
|
||
|
solution for forgejo/gitea.
|
||
|
It's nothing revolutionary,
|
||
|
it's just a container with a bunch of pre-installed software,
|
||
|
and the gitea `act_runner` with a configuration to *not* try and use docker.
|
||
|
This means my builds are pretty quick,
|
||
|
and my network use is very low,
|
||
|
since I already have the tools I need to build stuff,
|
||
|
and don't have to download mulitple OS images every time I do a build.
|
||
|
|
||
|
## Automating embedded systems builds
|
||
|
|
||
|
Arduino, it turns out,
|
||
|
has been including command-line build tools for a long time now.
|
||
|
Since I'm using Debian's Arduino package,
|
||
|
I get the older, poorly-documented `arduino-builder`.
|
||
|
But the newer `arduino-cli` has better documentation,
|
||
|
that helped me understand how to use the older command.
|
||
|
|
||
|
Using `arduino-builder` lets me keep the source code structured
|
||
|
in a way that makes sense to amateur developers:
|
||
|
they can just load it up in the IDE and not worry about my automation.
|
||
|
But it also lets me automate builds on my forgejo server,
|
||
|
and use the command-line to build everything,
|
||
|
the way I've been doing since the 80s.
|
||
|
|
||
|
Here's what I wound up with,
|
||
|
to build a Leonardo image:
|
||
|
|
||
|
```sh
|
||
|
mkdir -p build/cache
|
||
|
arduino-builder \
|
||
|
-build-path $(pwd)/build/ \
|
||
|
-build-cache $(pwd)/build/cache/ \
|
||
|
-fqbn arduino:avr:leonardo \
|
||
|
-hardware /usr/share/arduino/hardware/ \
|
||
|
-tools /usr/share/arduino/tools/ \
|
||
|
-compile MockBand.ino
|
||
|
```
|
||
|
|
||
|
This results in `build/MockBand.ino.hex`,
|
||
|
which can then be given to `avrdude` to flash my board.
|
||
|
Easy!
|
||
|
|
||
|
----
|
||
|
|
||
|
For the mockband project,
|
||
|
I also needed to specify a custom USB VID/PID and a CPP definition.
|
||
|
After reading a lot of forums posts and code,
|
||
|
I discovered I could easily do this with `arduino-builder`,
|
||
|
with the `-prefs=` flag.
|
||
|
This allows you to override settings in `boards.txt`,
|
||
|
which is apparently what Arduino uses to build a gcc flags list.
|
||
|
|
||
|
Here's a trimmed-down version of what I implemented:
|
||
|
|
||
|
```sh
|
||
|
mkdir -p build/cache
|
||
|
arduino-builder \
|
||
|
-build-path $(pwd)/build/ \
|
||
|
-build-cache $(pwd)/build/cache/ \
|
||
|
-fqbn arduino:avr:leonardo \
|
||
|
-hardware /usr/share/arduino/hardware/ \
|
||
|
-tools /usr/share/arduino/tools/ \
|
||
|
-prefs="build.extra_flags=-DUSB_VID=0x1bad -DUSB_PID=0x0004 -DCDC_DISABLED" \
|
||
|
-compile MockBand.ino
|
||
|
```
|
||
|
|
||
|
---
|
||
|
|
||
|
My final step was to write a `Makefile` to do all this.
|
||
|
Since the build step is just one (long) command,
|
||
|
and the `-prefs` could easily use per-target variables,
|
||
|
`make` was an obvious tool.
|
||
|
Adding a target to run `avrdude` was simple enough, too.
|
||
|
|
||
|
I no longer need the Arduino IDE at all,
|
||
|
but the project still works with it!
|
||
|
|
||
|
The result was a
|
||
|
[Makefile](https://git.woozle.org/neale/mockband/src/commit/63bd0672500631b8c47f24f041693e642ab32533/Makefile)
|
||
|
which can compile, flash, and package
|
||
|
all three variants of the build.
|
||
|
It's 43 lines long,
|
||
|
including blank lines.
|
||
|
|