Arduino

Важная часть профессионального программирования — это конвейеры автоматизации сборок. Вы, конечно, можете считать несерьезным свое увлечение проектами на Arduino. Но давайте представим, что вы создаёте библиотеку Arduino для других пользователей. Может быть, это даже целый проект с открытым кодом, который рано или поздно станет полезным целому сообществу.

Конвейер автоматизации сборок выступает как непрерывная интеграция. Так вы гарантируете определенный уровень качества своего проекта. Открою два ответа на вопрос о том, как именно вам поможет непрерывная интеграция:

  • Ваш код в итоге компилируется на всех необходимых платформах.
  • В проекте устанавливается красивый стиль программирования.

Первый пункт особенно помогает проектам Arduino, когда нужна гарантия совместимости с целым набором разных микроконтроллеров. Второй станет важным для вас, как только вы расширите свою команду и пригласите одного и более товарищей. Жизнь каждого в команде станет намного проще, если у вас будет понятный стиль программирования на всем проекте. И это еще не все — непрерывная интеграция может намного больше, в том числе:

  • Выполнять автоматизированные юнит-тесты.
  • Автоматически обновлять документацию.

Последнее касается того, что обычно документация нечасто обновляется надлежащим образом. Вы можете создать лучшую библиотеку, но если вы не собираетесь её описать, люди, скорее всего, не станут ею пользоваться.

Настройка проекта

Проект Arduino

Ваш проект на Arduino — это всего лишь папка со скетчем Arduino внутри:

MyArduinoProject
└── MyArduinoProject.ino

Если вам достаточно малого, то непрерывная интеграция и не нужна. Тем не менее от экспериментов с ней хуже не будет. Если вы хотите перейти на продвинутый уровень, подумайте над настройкой проекта на PlatformIO.

Проект в PlatformIO

Среда PlatformIO хорошо интегрируется с Visual Studio Code и стала отличной альтернативой окружению Arduino IDE. В неё встроена поддержка многих микроконтроллеров и вы даже сможете выйти за границы экосистемы Arduino, но это уже отдельная тема. Стандартный проект в PlatformIO состоит из двух частей:

MyPlatformIOProject
├── platformio.ini
└── src
    └── main.cpp

Тем не менее вы не ограничены этими файлами, это только начальная точка. По мере продвижения проект может вырасти во что-то большее, чем только два файла. И это уже определённо вариант для применения непрерывной интеграции.

Библиотека Arduino

Может быть, вы работаете не только над личным проектом, а над целой библиотекой Arduino, чтобы потом поделиться результатами в сообществе. В таком случае непрерывная интеграция — отличный вариант. Стандартная библиотека в Arduino, скорее всего, будет выглядеть так:

MyArduinoLibrary
├── examples
│   └── HelloWorld
│       └── HelloWorld.ino
├── library.properties
└── src
    ├── MyArduinoLibrary.cpp
    └── MyArduinoLibrary.h

У вас есть минимум: один заглавный файл, один файл имплементации, а также один или больше скетчей Arduino.

А потом вы захотите убедиться, что ваша библиотека совместима с максимальным количеством плат Arduino. И вот тут конвейер автоматизированной сборки действительно пригодится.

GitHub и контроль версий

Дальше я буду предполагать, что ваш проект хранится в системе контроля версий git и опубликован на GitHub. Если вы еще не публиковали там ничего, я очень рекомендую этот сервис для всех ваших проектов в программировании.

В нашем случае GitHub подходит потому, что мы собираемся пользоваться его рабочими процессами, которые позволяют создавать конвейерные сборки без дополнительных внешних сервисов. Похожим образом можно работать и на других платформах, например GitLab, или используя инструменты непрерывной интеграции, такие как Travis или CircleCI. Я советую вам посмотреть все возможности, чтобы найти те, которые вам подойдут. Я остановился на GitHub.

Базовый рабочий процесс в GitHub

Применяя рабочие процессы GitHub, мы будем работать с виртуальной машиной последней версии Ubuntu и выполнять стек предварительно определенных задач, когда бы ни вносились изменения в код. Звучит ошеломительно. И пока будут происходить интересные события, мы будем собирать кусочки шаг за шагом.

Виртуальная машина работает на серверах GitHub. Всё, что нам нужно сделать, — создать конфигурационный файл внутри директории проекта .github/workflows. Давайте назовем его build.yml:

MyArduinoLibrary
├── .github
│   └── workflows
│       └── build.yml
…

У файла будет такое содержимое:

name: build

on: [pull_request, push]

jobs:
  build:
    runs-on: ubuntu-latest

steps:
    - name: Checkout
      uses: actions/checkout@v2

В нём есть параметр имени name— он может быть любым от самого короткого build и до изощренного My awesome automated build. Я возьму вариант попроще. Команда on: [pull_request, push] говорит GitHub выполнять этот процесс всякий раз, когда происходит добавление обновлений в репозиторий или создается новый запрос на добавление изменений. Есть и другие события, а также сложносоставные триггеры, но это другой разговор.

Весь написанный нами процесс происходит на последней Ubuntu, и выполняется проверка кода. Последний шаг важен, потому что код должен попасть в рабочий поток.

Автоматизированные сборки Arduino

После проверки добавим еще один шаг в build.yml:

…
  steps:
    - name: Checkout
      uses: actions/checkout@v2

- name: Build on Arduino CLI
      run: bash ci/build-arduino.sh

Этот шаг называется Build on Arduino CLI, и он запускает скрипт оболочки ci/build-arduino.sh. А теперь мы создадим такой файл в папке проекта:

MyArduinoLibrary
├── .github
│   └── workflows
│       └── build.yml
├── ci
│   └── build-arduino.sh
…

Этот скрипт установит Arduino CLI на нашу виртуальную машину и скомпилирует код для нескольких плат Arduino. Если компиляция падает, автоматизированный конвейер сборок тоже ломается. А если компиляция проходит успешно, это значит, что код корректен для всех протестированных платформ Arduino.

Для установки Arduino CLI мы будем следовать гайду:

#!/bin/bash

# Немедленный выход, если у команды не нулевой статус
set -e

# Включает опцию оболочки globstar
shopt -s globstar

# Переход в рабочее пространство github
cd $GITHUB_WORKSPACE

# Создаем директории
mkdir $HOME/Arduino
mkdir $HOME/Arduino/libraries

# Устанавливаем Arduino IDE
export PATH=$PATH:$GITHUB_WORKSPACE/bin
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
arduino-cli config init
arduino-cli core update-index

Добавляем ядро Arduino AVR:

# Установка ядра Arduino AVR
arduino-cli core install arduino:avr

До компиляции кода осталось немного. Если ваш проект — это библиотека, вам надо сначала подключить ее к директории библиотек Arduino. Иначе компилятор не сможет найти ваш код.

# Подключаем библиотеку Arduino
ln -s $GITHUB_WORKSPACE $HOME/Arduino/libraries/CI_Test_Library

А теперь компилируем скетчи для ядра AVR. Компиляция для Uno:

# Компилируем все файлы с расширением *.ino для Arduino Uno
for f in {,**/}*.ino ; do
    arduino-cli compile -b arduino:avr:uno $f
done

Вот и всё. С этой установкой можно создать конвейер сборок, который автоматически компилирует все Arduino Sketches для Arduino Uno по каждому пакету изменений или запросу на их проверку в репозитории на GitHub.

Добавлять другие платформы очень просто, ведь вам всего-то нужно скопировать и изменить код, который устанавливает новые ядра и компилирует ваш проект.

Продолжение следует…

Читайте также:

Читайте нас в телеграмме, vk и Яндекс.Дзен


Перевод статьи Raphael Stäbler: How to Create an Automated Build Pipeline for Your Arduino Project

Предыдущая статьяУтиная типизация в Python - 3 примера
Следующая статьяРаспознаём 50 видов текста на C++ с Plywood