TinyGo 0.42 получил поддержку семейства 32-разрядных Arm-микроконтроллеров Puya PY32. В новый порт вошли стартовый код, сгенерированные определения регистров устройств, скрипты компоновщика, поддержка GPIO и UART, а также цели сборки для 87 отдельных конфигураций микроконтроллеров. Добавлены и описания двух недорогих отладочных плат EmbedFire, доступных на AliExpress.

Порт разработал Павел Бургр; изменения приняты через соответствующий pull request проекта. Одной из мотиваций было создать надёжную и удобную платформу для прошивок небольших устройств интернета вещей, построенных вокруг сервиса Registry и маломощного радиопротокола BleRiot. Эти проекты существуют отдельно от TinyGo, но хорошо показывают тот класс задач с жёсткими ресурсными ограничениями, ради которого новые цели сборки и создавались.

Отладочная плата на микроконтроллере Puya PY32

Широкий охват микроконтроллеров PY32

TinyGo — компилятор языка Go для микроконтроллеров, WebAssembly и других систем с ограниченными ресурсами. Он использует LLVM для получения компактных нативных двоичных файлов и предоставляет слой аппаратной абстракции через пакеты вроде machine, сохраняя при этом привычный синтаксис и инструментарий Go. Запуск Go на чипе с 2 КБ оперативной памяти звучит почти как вызов — но именно ради таких вызовов TinyGo и создавался.

Порт PY32 охватывает устройства и на ядре Cortex-M0+, и на Cortex-M4. Таблица целей содержит 87 конкретных конфигураций памяти в рамках 40 семейств определений устройств — от чипов с 8 КБ флеш-памяти и 2 КБ ОЗУ до вариантов с 512 КБ флеш-памяти и 144 КБ ОЗУ.

реклама кормит Уточку 🦆

Поддерживаемые серии:

  • PY32E407
  • PY32F001, F002, F003, F021, F030, F031, F032, F040, F071, F072, F403 и F410
  • PY32L020 и L090
  • PY32M010, M020, M030, M031 и M070
  • PY32MD310, MD320, MD410, MD420 и MD430
  • PY32T020, T090 и T092

Каждая цель сборки выбирает корректную карту флеш-памяти и ОЗУ. Определения периферии генерируются из данных CMSIS производителя через вспомогательный репозиторий py32-svd, что даёт авторам драйверов типизированные имена регистров в пакете device/py32 вместо самодельных таблиц адресов.

Программный интерфейс machine в версии 0.42 покрывает запуск тактирования и таймеров, GPIO и UART, включая второй UART на отдельных чипах. Портируемых драйверов для АЦП, I2C, SPI и ШИМ пока нет, но сгенерированные регистры доступны низкоуровневому коду.

Микроконтроллеры семейства Puya PY32 на плате

реклама кормит Уточку 🦆

Две поддерживаемые платы EmbedFire

Две небольшие отладочные платы получили собственные цели сборки и псевдонимы выводов, что делает их простейшим способом опробовать порт. Обе продаются дешевле двух долларов на AliExpress, а плата на PY32F030 доступна на Amazon от 7 долларов.

Плата PY32F030 назначает светодиоды LED1, LED2 и LED3 на выводы PA2, PA3 и PA4, а две кнопки — на PA5 и PA6; UART по умолчанию использует PA7 для передачи и PA8 для приёма. Меньшая плата PY32F002B назначает светодиоды на PA1, PA5 и PA4, кнопки — на PA3 и PA0, а UART по умолчанию — на PA6 и PA7.

Обе платы определяют machine.LED как псевдоним второго светодиода, так что традиционная первая программа с миганием запускается на любой из них без изменений — меняется только цель сборки. При подключённом отладчике SWD и настроенном pyOCD под выбранный чип программа собирается и прошивается одной командой, без раскопок в самодельных Makefile.

Цели сборки для плат наследуют точные карты памяти py32f030x8 и py32f002bx5 и вызывают соответствующую цель pyOCD при прошивке. Для собственных плат доступны цели «голых» чипов. Небольшой шаблон проекта TinyGo для PY32 содержит дополнительные примеры мигания и стартовый Makefile.

Прошивка платы Puya PY32 через отладчик SWD

реклама кормит Уточку 🦆

От дешёвого микроконтроллера к узлу интернета вещей

Когда с традиционным миганием покончено, куда интереснее оказывается практическая мотивация порта. Автор разрабатывал поддержку PY32 параллельно с созданием BleRiot — простого и надёжного протокола «запрос — ответ» для маломощных радиоузлов.

Каждый узел выставляет наружу знаковые 32-разрядные регистры и понимает всего две операции: GET и SET. Этим словарь и исчерпывается — и это скорее достоинство, чем упущение. Хаб на Linux опрашивает регистры и берёт на себя имена, преобразование единиц, повторные попытки и тайм-ауты. Такой компактный и предсказуемый интерфейс удерживает прошивку маленькой, а восстановление после потерянного пакета реализуется один раз в хабе, а не в каждом приложении.

Один хаб общается с множеством узлов по собственному радиоканалу GFSK на скорости 250 кбит/с с совместимой с BLE структурой пакетов — хотя это ни Bluetooth LE, ни GATT. Эталонный узел сочетает чип PY32F030x8 с радиомодулем PAN211x на 2,4 ГГц, а хаб использует простой USB-донгл.

BleRiot публикует значения узлов в Registry — лёгком локальном сервисе, который присваивает каждому регистру имя, текущее значение, необязательные метаданные и время жизни. Устаревшие значения истекают автоматически. Приложения могут работать напрямую с его HTTP/JSON API; поставляемые узлы для Node-RED сочетаются со стандартными узлами MQTT для мостов, а встроенная точка Prometheus отдаёт числовые регистры в виде метрик, готовых для панелей Grafana. Иными словами, чтобы вывести температуру на дашборд, не требуется обучать микроконтроллер с тремя килобайтами памяти работе с Grafana.

реклама кормит Уточку 🦆

Контроллер проходит тот же путь в обратную сторону, когда запрашивает изменение. BleRiot разделяет типы устройств и определения регистров между прошивкой на TinyGo и хабом на Linux, а его инструментарий умеет сгенерировать идентичность узла, собрать прошивку и прошить её по SWD.

Registry и BleRiot не обязательны для использования TinyGo на PY32, а сама поддержка PY32 не привязана к конкретному радиомодулю. Это скорее наглядные примеры того, зачем дешёвым микроконтроллерам поддерживаемый компилятор, воспроизводимые цели сборки и стандартный аппаратный интерфейс со стороны Go.

Доступность и дальнейшие шаги

Поддержка PY32 доступна в TinyGo 0.42.0. Две платы EmbedFire дают самую прямую точку входа, а обширный список чипов служит основой для собственных плат — от миниатюрных датчиков до более крупных контроллеров на Cortex-M4.

Версия 0.42 делает упор на стабильность рантайма, корректные карты памяти, GPIO и последовательную связь, а не на заявку о полном покрытии периферии. Будущие вклады могут добавить портируемые АЦП, I2C, SPI, ШИМ и описания плат поверх сгенерированного слоя регистров. Для разработчиков, уже использующих Go на серверной стороне системы интернета вещей, порт делает недорогое семейство микроконтроллеров Puya куда более доступным конечным звеном. Следующей на очереди, судя по всему, станет поддержка микроконтроллеров AT32.