Skip to content

Instantly share code, notes, and snippets.

@reznikmm
Created March 8, 2025 16:24
Show Gist options
  • Save reznikmm/ec8877db9479bb3591d9d27b584a31d2 to your computer and use it in GitHub Desktop.
Save reznikmm/ec8877db9479bb3591d9d27b584a31d2 to your computer and use it in GitHub Desktop.

Введение в программирование встраиваемых систем на Ada

Вступление

К встраиваемым относятся программные системам исполняемые на устройствах с ограниченной мощьностью. Часто к таким системам выдвигаются особые требования надежности, работы в реальном времени, ограниченное потребление и пр.

Ada отлично подходит для реализации таких систем в силу свойственных языку возможностей. Поскольку Ada это компилируемый язык, программы на нем очень энерго эффективны. Изначальная ориентация языка на надежность и безопасность гармонирует с целями разработки встраиваемых систем. Гибкие возможности спецификации представления позволяют легко взаимодействовать с железом на низком уровне. В то же время, мощная система типов позволяет естественно выражать понятия понятия прикладной области. Наконец, в стандарте языка есть отдельный раздел посвященный поддержке встраиваемых систем и систем реального времени. Реализуя требования стандарта, Ada позволяет программировать устройства без необходимости использования универсальных операционных систем, в тоже время предлагая эффективную поддержку многозадачного окружения на устройствах с ограниченными возможностями.

Целью этой статьи является помочь начинающим разобраться с существующим инструментарием программирования встраиваемых систем на Ada на примере создания простой программы. Мы рассмотрим установку и настройку ПО на примере платы разработчика STM32F40x.

Необходимые инструменты и компоненты

Для разработки встраиваемых систем нам нужны следующие инструменты

  • Кросс-компилятор
  • Библиотека времени исполнения (Runtime Library)
  • Библиотеки драйверов (например Ada Drivers Library)

Кросс-компилятор

Кросс-компилятор позволяет собирать исполняемые модули для процессора отличного от текущего. Например, построить код для ARM используя рабочую станцию на AMD64. Пакетный менеджер Alire имеет несколько готовых к использованию кросс-компиляторов для следующих архитектур процессоров:

  • ARM
  • AVR
  • RISC-V
  • xtensa_esp32 (экспериментальный, не рекомендуется для начинающих)

Библиотека времени исполнения (RTL)

Для поддержки нетривиальных конструкций языка нужна библиотека времени исполнения. Обнаружив такую конструкцию в коде пользователя компилятор ищет в библиотеке времени исполнения соответствующие типы и подпрограммы и использует их. Таким образом, RTL тесно связана с кросс-компилятором и выход новой версии компилятора требует библиотеки времени исполнения соответствующей версии.

Не все конструкции языка Ada востребованы во встраиваемых системах. Например, обработка исключений считается слищком наклажной, чтобы реализовать ее в полном объеме. В зависимости от реализуемых конструкций языка библиотеки времени исполнения делятся на несколько типов. В данный момент с GNAT доступны три типа RTL

  • light - минимальная версия библиотеки, без поддержки многозадачности и других конструкций
  • light-tasking - с ограниченной поддержкой многозадачности, так называемые Ravenscar, jorvik профили
  • embedded - еще более жирная библиотека времени исполнения

Библиотеки времени исполнения расчитаны на использования расчитаны на конкретное железо, поскольку включают в себя код инициализации и распределение ресурсов. Кросс-компиляторы для ARM и RISC-V идут с набором библиотек RTL для наиболее популярных устройств разработки. Поддержка других устройств может распространятся, как отдельные Alire crates.

Библиотеки драйверов

Для микропроцессоров встраиваемых систем свойственно иметь богатый ассортимент вспомогательных устройств таких как порты ввода-вывода общего назначения, таймеры, UART, SPI, I2C и пр. Для работы с этими устройствами нужны соответствующие драйвера. Наверное, наиболее полной поддержкой драйверов может похвалится Ada Drivers Library (ADL). ADL распространяется под BSD лицензией и включает в себя код драйверов устройств микропроцессоров, а также драйвера внешних стройств, таких как датчики, дисплеи, камеры и пр. Также репозиторий ADL предоставляет примеры использования драйверов для некоторых плат разработки.

Поскольку ADL был создан до появления Alire, эти два инструмента плохо совместимы. Часть кода ADL была скопирована в Alire как отдельные crates, чтобы еще больше всех запутать.

Практический пример: STM32F407

Давайте рассотрим создания минимального приложения на примере микроконтроллера STM32F407. На рынке есть несколько плат разработчика на основе этого недорогого процессора, начиная от Discovery Board и заканчивая китайскими STM32 F4VE. Библиотека времени исполнения для этого чипа носит название light-tasking-stm32f4.

Мы начнем с создания приложения в терминале без использования среды разработки, чтобы осветить, как все устроено внутри, а затем отдельно остановимся на поддержке таких проектов в GNAT Studio.

Создание проекта

Alire помогает нам создать подходящую заготовку для проекта:

alr init --bin test
cd test

Следующий шаг - указать кросс-компилятор в зависимостях проекта:

alr with gnat_arm_elf

Чтобы проектный менеджер gprbuild знал, что нужно использовать кросс-компилятор необходимо указать Target. Проще всего это сделать в проектном файле. За одно укажем какая библиотека времени исполнения нам нужна. Отредактируем test.gpr добавив следующие строки:

   for Target use "arm-eabi"; 
   for Runtime ("Ada") use "light-tasking-stm32f4";

Код программы (test.adb) сделаем максимально простым:

with Ada.Text_IO;

procedure Test is
begin
   loop
      Ada.Text_IO.Put_Line ("Hello");
      delay 1.0;
   end loop;
end Test;

Все готово, чтобы собрать исполняемый файл:

alr build

Преобразуем получившийся ELF в бинарный файл подходящий для прошивки

alr exec -- arm-eabi-objcopy -Obinary bin/test bin/test.bin

Для прошивки процессоров STM32 обычно используется аппаратный отладчик ST Link v2. Discovery board имеет его интегрированным прямо на плате. (Подойдет также и DAPLINK.) Для управления аппаратным отладчиком можно использовать программное обеспечение st-util, либо пакет с открытым исходным кодом OpenOCD (который умеет также управлять DAPLINK).

Команда для прошивки:

st-flash --connect-under-reset write bin/test.bin 0x08000000
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c 'program bin/test.bin verify reset exit 0x08000000' 

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

stutil --semihosting # или
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg

А в другом запустим GDB:

alr exec arm-eabi-gdb ./bin/test
target extended-remote :4242

target extended-remote :3333
monitor arm semihosting enable # только для OpenOCD

Интеграция с GNAT Studio

Чтобы заставить GNAT Studio запускать st-util для прошивки и отладки достаточно в файл проекта добавить следующий код:

   package Ide is
      for Program_Host use "localhost:4242";
      for Communication_Protocol use "remote";
      for Connection_Tool use "st-util";
   end Ide;

Теперь запустим студию:

alr exec gnatstudio

Студия распознает что этот проект для встраиваемых систем и позволит вам собирать, прошивать и отлаживать его с помощью GUI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment