Что Должно Быть в Каждом FirmWare Pепозитории

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

В этом тексте я предлагаю порассуждать, что же должно быть в нормальном взрослом firmware репозитории (репе/общаке) безотносительно к конкретному проекту. То есть самые универсальные и переносимые программные компоненты (кирпичики), которые могут пригодиться в практически любой сборке.

Загрузчик

Загрузчик нужен для обновления прошивки без специализированного оборудования типа программаторов. Загрузчик обязательно должен уметь обновлять по UART. Остальные интерфейсы обновления по обстоятельствам.

Компонент управления логированием

Должен быть программный компонент для управления логированием в UART. Раскраска логов в TeraTerm/Putty, выбор/отмена TimeStamp выбор отмена логирования для конкретного компонента. Это поможет анализировать лог загрузки устройства и следить за событиями внутри прошивки в run-time(е), просто глядя в UART.

CLI (Command Line Interface) или Shell

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

Универсальная FIFO

В любом Firmware проекта рано или поздно понадобится FIFO. Например, FIFO нужна для предварительного хранения данных из UART Rx. FIFO нужна для того же CLI. Реализация FIFO должна подстраиваться пол любой тип данных: char, uint16_t, array[N]. Напишите в комментариях для чего использовали FIFO в прошивках вы.

Вычислители контрольных сумм CRC

При реализации протоколов понадобится целая куча разнообразных контрольных сумм (CRC8, CRC16, CRC24, CRC32). Также CRC нужны для энергонезависимых файловых систем.

BSP (Board Support Package) для каждого семейства микроконтроллеров

Кодовая база должна быть универсальной, однако для каждого семейства микроконтроллеров будет своя уникальная реализация BSP. В BSP надо прописать реализации универсального API. Например для управления GPIO, прописи OnChip FLASH, запуска таймеров, пуляния пакетов в I2C/SPI/I2S/UART, вычитывания ADC и прочего.

Циклический массив

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

Драйверы чипов

В каждой плате есть множество умных навороченных чипов с конфигурацией по I2C/SPI/MDIO. В репозитории должна быть папка с драйвером для каждого такого чипа и отдельная папка с модульными тестами для чипа. Напишите в комментариях драйверы каких умных SPI/I2C/MDIO чипов писали вы.

Компонент для поддержки каждого конкретного процессорного ядра

Для каждого конкретного процессорного ядра (Cortex-M3/Cortex-M33/PowerPC/Tensilica Xtensa и про) должна быть папка с сорцами описания этого ядра. Это функции вкл/откл прерываний, перезагрузка, печать таблицы прерываний, управление системным таймером и прочее.

Компонент для поддержки каждого конкретного микроконтроллера

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

Компонент для поддержки каждой конкретной платы (platform code)

Для каждой платы должна быть создана отдельная папка в репозитории. Там должны быть исходники конфигурации, которые говорят сколько в этой конкретной плате кнопок, LED(ов), SPI, I2C, SDIO. Какие там есть драйверы чипов и прочее.

Отдельная папка для каждой конкретной сборки

Все сборки должны делить общую кодовую базу. Поэтому в папке с проектом в принципе не должно быть *.с файлов. Максимум один Makefile, парочка конфигов в *.h, и еще пара скриптов.

Программный Таймер

Программный таймер это способ из одного аппаратного таймера сделать сотни программных таймеров. Очень полезно, если все аппаратные таймеры исчерпаны или их настройка очень трудна. Хороший программный таймер позволяет настраивать период и фазу счета и полностью конфигурируется в run-time из CLI.

Синтаксический разбор строчек

При реализации CLI нужны функции для синтаксического разбора чисел всех типов данных из текстовых ASCII строк. Поэтому для каждого типа данных следует реализовать парсеры типов данных. Своего рода интерпретатор чисел. Это очень большая часть кода.

Компонент компрессии-декомпрессии

Может случится, что битовая скорость трансивера очень низкая (LoRa), а данных надо передавать много. В этом случае может спасти сжатие или компрессия данных (например кодек LC3) и декомпрессия на стороне приемника. В репе должен быть программный компонент кодек сжатия данных.

Драйвер подавление дребезга кнопок

Часто в электронных платах есть тактовые кнопки и герконы. Они при замыкании создают дребезг. Поэтому в репозитории должен быть драйвер кнопки, который подавляет дребезг контактов, умеет отличать короткое нажатие от длинного, двойного. Всё это пригодится при отладке.

Программный Триггер Шмитта

Это звено для реализации гистерезиса. Очень полезно для подавления аналогового шума с датчиков при релейном управлении чем-либо.

Компонент limiter

Это функция, которая следит за тем, чтобы конкретная функция не вызывалась чаще чем установлено в параметрах. Очень полезно при реализации примитивов RTOS. Можно прямо в суперцикле пропускать все вызовы через limiter и таким образом выставлять период срабатывания каждой функции.

Реализация механизма выделения и освобождения памяти

Весьма вероятно, что придется накропать собственную надежную детерминированную и переносимую версию функций malloc и free, c возможностью расширенной диагностики и сборки мусора.

Математика

Немного линейной алгебры и численных методов. Например, в системах автоматического управления на MCU очень нужна функции для вычисления угла между векторами (с учетом знака). При работе с ЦАП/DAC(ами) пригодится вычисление семпла синуса, семпла PWM, Chirp, Saw, Fence. Еще может понадобится целочисленное возведение в степень и вычисление квадратного корня. А какую математику приходилось использовать в прошивках вам?

Программная реализация календаря

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

Цифровые фильтры

Цифровые фильтры нужны не только для обработки аудиопотока и радарных данных. ЦФ понадобится для реализации подавления дребезга контактов, для вычисления направлений движения RFID маяков и прочего.

Шифровальщик

Рано или поздно передаваемую прошивку по загрузчику придется шифровать или хранить в памяти в шифрованном виде. Поэтому надо выбрать доверенный и протестированный алгоритм шифрования данных

Парсеры протоколов

Устройство будет взаимодействовать с внешним миров. Ту же прошивку надо передеравать по какому то протоколу. Должна быть программная реализация какого то протокола или серии протоколов.

Энергонезависимый журнал

В любой крупное С программе накопится много параметров и констант, которые придется варьировать, настраивать, калибровать. Чтобы не пересобирать и перепрошивать каждый раз устройство надо реализовать энергонезависимый журнал прямо на Target.

Код генераторы

В программировании микроконтроллеров часто много повторяющегося по структуре кода. Например синтаксический разбор CAN матриц (8 байт полезных данных в пакете). Поэтому в репозиторий можно добавить утилиты кодогенераторы для генерации C-функций делающих синтаксический разбор пакетов с известной структурой.

Модульные тесты

Вся работа пойдет прахом, если ошибка в очередном коммите тихо останется незамеченной. Грош цена репозиторию без тестов. Поэтому надо покрывать код модульными тестами. Каждая нетривиальная функция должна быть покрыта тестами. Аппаратно-независимый код можно вообще тестировать прямо на PC.

Сборка из Make

Утилита Make это самый гибкий способ управлять циклопическими репозиториями. Можно одной строчкой добавлять/исключать тысячи файлов для тысяч сборок. Поэтому для каждой сборки надо делать Makefile для каждого компонента *.mk файл. Сборка из Make стимулирует придерживаться модульности и изоляции компонентов.

Скрипты автосборки

Каждая сборка должна собираться из скриптов. Скрипты должны записывать во OnChipFlash hash последнего коммита и название ветки. Это потом позволит откатиться назад и выявить причину бага.
Буквально открыл папку с проектом, жмакнул *.bat файл и максимум через 2 минуты получил артефакты *.hex *.bin *.elf *.map. Easy! Также сборка из скриптов позволит вам добавить сборки на сервер сборки Jenkins и каждое утро следить за тем, что собирается, а что нет.

Скрипты авто прошивки

Должна быть возможность автоматически прошивать Target. Жмакнул скрипт flash.bat из папки с проектом и скормил прошивку микроконтроллеру. И еще и лог сохранился в текстовый файлик.

Скрипты отчистки и автоматического форматирования

Это для причесывания кода утилитой clang-format. Чтобы отступы были предсказуемыми по всему проекту. Это позволит писать более просты регулярные выражения для навигации по коду утилитой grep.
Скрипт автоочистки в корне репозитория позволит удалить временные файлы c расширениям *.d *.o *.obj *.bak *.i *.pp и высвободить тонну места на диске.

Авто генерация документации

Надо относится как программированию не только к созданию артафактов. Надо относится как к программированию также для создания документации. При разработке Firmware документацией является схема toolchain, блок схемы плат, блок схемы комплексов, инструкции. Все эти *.pdf, *.svg можно синтезировать из кода на языке dot. Поэтому должны быть makefile(ы) для сборки документации. Текстовые документы можно авто генерировать на LaTeX

Вывод

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

Пользуйтесь CLI, системами контроля версий, системами авто сборок и модульными тестами и все у вас будет хорошо и предсказуемо.

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

Также буду признателен, если вы отметите в комментах какие экзотические микроконтроллеры и периферийные чипы программировали лично вы. Какие технологии управления репозиториями вы считаете перспективными, а какие у вас в черном списке.

Давайте строить хорошие репозитории.


Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы используете системы контроля версий?
100% да 5
0% нет 0
Проголосовали 5 пользователей. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы используете сервера сборки?
40% да 2
60% нет 3
Проголосовали 5 пользователей. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы в общем согласны с представленной структурой репозитория?
100% да 3
0% нет 0
Проголосовали 3 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы собираете сборки из скриптов?
75% да 3
25% нет 1
Проголосовали 4 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы практикуете коллективное владение кодовой базой?
33.33% да 1
66.67% нет 2
Проголосовали 3 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы практикуете инспекцию программ?
33.33% Да 1
66.67% Нет 2
Проголосовали 3 пользователя. Воздержавшихся нет.
Источник: https://habr.com/ru/post/689542/


Интересные статьи

Интересные статьи

Астропатический хор объявил неделю образования: Число статей и новостей про образование удвоилось. Отказ от ответственности: текст ниже написал с незначительной* долей сарказма, и предполагает, что пр...
Когда я пошла учиться на большой оффлайновый курс разработки ПО, дело стопорилось: начали мы с С/С++ и иногда доходило до того, что я клала голову на клавиатуру и плакала. Шутка ли, то 273 ошибки при ...
Все мы знаем про, или слышали про практики и паттерны проектирования SOLID, GRASP, MVC, MV** и даже применяем их с переменным успехом, стараясь нащупать эффективный подход к построению приложений. Но ...
Внедрение новой платформы базы данных требует тщательного исследования внутри компании. Приобретение СУБД — сложная процедура, если учитывать огромные вложения в необходимые аппаратные и программные...
В статье “Что должно быть в счёте на оплату, чего быть не должно и что дико бесит” мы разбирали содержимое счёта. По результатам той работы возникло желание оформить счёт...