Обзор
Дата появления микроконтроллеров STM32, судя по datasheet, 2007 год, и с тех пор они признаны как очень успешным и популярный чип. Поэтому для них уже написано множество готовых примеров с поддержкой почти всех технологий как самим вендором так и комьюнити. Это и всевозможные USB устройства включая флешку и звуковую карту, и целочисленные варианты кодеков (WMA, Speex), и даже готовые сборки под ethernet с lwip стеком так же в наличии. В это время комьюнити пытается догнать вендора и написало библиотеку libopencm3, уже в отличии от оригинала, основанную на make, а не привязанную к среде. И в ней есть так же примеры с USB. И вот, на фоне всего этого я представил что STM32 ничем не сложнее меги, вооружившись таблицей разметки памяти с адресами регистров начинаю писать еще один вариант стандартной библиотеки для STM32. Гораздо более наивный, но зато компактный. Смыл был однозначно, я вообще считаю что если не понравился любой стандартный продукт, то это повод переписать его полностью, хотя вы можете со мной не согласиться.
MAKE
Вот прям так с нуля, в руках текстовый редактор (Kate), компилятор и собственно сам камень. Чем то напоминает прошлое, какие нибудь 70е, никаких тебе лабораторий с кучей цифровых осциллографов отладочных плат и мониторов, сходил на базар (алик) за камушком расположился в гараже или уютненькой комнатке и вот он билет в IT. Весь тулчейн уже появился в репозиториях Ubuntu, пакеты: gcc-arm-none-eabi libnewlib-arm-none-eabi gdb-multiarch build-essential stlink-tools
. Из самого необходимого для сборки:
startup файл (тот что вызывает main)
файл компоновщика (gnu linker, разметка памяти)
system file (запускает тактирование контроллера)
Насчет стартапов и компоновщика помогли комментарии в коде библиотеки CMSIS (позиционируется как стандарт взаимодействия с ядром ARM), для make помог хелп на сайте ARM. По итогу получился 50~100 строчный мейк, гораздо компактнее чем все примеры на гитхабе, в который вполне можно добавить и стандартный STM32 HAL (проверял, собиралось). В startup нужно добавить адреса векторов прерываний из datasheet, в system написать функцию включения кварцевого генератора, в компоновщике заполнить адреса памяти, в мейке все это собрать. А также на первое время, пока не написан API (HAL) понадобятся регистры это почти весь datasheet, 5к+ строчек. И вот уже можно хеллоувордить и мигать диодиком, но мы пойдем дальше.
Железо
Готовая китайская отладочная плата категории за 300
Одна платка (контроллер для советского геймпада)
Вторая платка (переходник пульт-клавиатура)
st-link так же можно заказать на алике, но я паял сам, схема взята с документации по отладочным платам discovery. Не сбоящая на клонах прошивка скачана с форума ST. Все исходники для повторения на github. Помните шутку про драйвера дисковода на диске, так вот плата адаптирована под начальную прошивку через UART.
В остальных платах ничего примечательного нету, стандартная обвязка контроллера, одна плата однослойная вторая двухслойная, изготовлены в домашних условиях пленочным фоторезистом и трафаретом распечатанном на принтере. С применением 0,8 мм заклепок в качестве переходных отверстий. По разводке примечательно то что можно не брезговать выводить контакты из под чипа через неиспользуемые порты, главное не подать на них случайно единицу в коде, в остальном такой грязный хак помогает получить очень компактные платы. Схемы лежат в папке result в репозитории проекта.
USB
Как приятно жить во времена международных стандартов, никаких коммерческих тайн и прочей копирастии. Можно просто пойти на USB Implementers Forum и скачать там первоисточник стандарта. Пока писал ядро USB, с одной стороны могу сказать что понадобился весь томик стандарта, с другой только 9 раздел (конфигурационные запросы драйвера). В общем тут как и со всеми новыми концептуальными навороченными абстракциями: уровней вложенности, блок схем, новых терминов на увесистый том размером с аналоговую энциклопедию, а кода на пять килобайт. Все равно по итогу шина, либо пихаешь туда данные, либо забираешь из буфера по прерыванию. А все остальное как то пишется один раз, лишь бы система подхватила, а потом забывается и просто подключается в виде библиотечки. Хотя местами не хватило стандарта, понадобился ещё хелп ядра linux и хелп microsoft, нужно же понимать как понимают тот же самый стандарт программисты ОС. По итогу удалось реализовать следующие типы стандартных USB устройств:
геймпад
клавиатура (на самом деле USB ИК приемник, но драйвер от клавиатуры)
переходник USB-UART
Программатор флешек BIOS (работает поверх USB-UART)
Остальные устройства на очереди (в процессе разработки) это веб камера, флешка, звуковая карта, тыльная подсветка монитора, руль для гоночек и мышь.
Отладка
Многие любители мощных сред (Keil, ST Cube) и готовых комплектов отладочных плат считают главным преимуществом наличие отладчика. Но отладка возможна и в консоли по трем проводкам. Например для выяснения ошибок в момент инициализации USB. Я пользовался консольным GDB. Сложив весь поток данных в глобальный массив я считал его с помощью gdb. Так же и прослеживал за регистрами складывая их в цикле в переменные.
В тему документации все pdfки лежат в репозитории. Для написания дескрипторов USB HID устройств понадобилась стандартная утилита, раньше работала под вайном теперь в виртуальной XP.
Результат
Геймпад вполне играбелен, прошел на нем одну трассу в NFS, пультом удобно слушать музыку с youtube пока делаешь дела по дому. Программатором зашил таблетку от жадности для принтера. Демонстрацию работы всех устройств вы можете наблюдать на видео, расположены в соответствии со списком.
Очень приятно хотя бы чуть чуть дотянуться до текущего уровня технологий, а не оставаться ретро технарем поневоле, хорошо понимающим в параллельных шинах, мигалках на сдвиговых регистрах, но неспособным сделать ничего полезного в быту, работающего в современной экосистеме без плясок с бубном. Я даже настолько обнаглел что могу советовать вам свои разработки как example для быстрого старта ваших проектов. А вы какие бы еще посоветовали мне устройства для реализации, к тем что уже в разработке.
Комментарии (7)
svpcom
00.00.0000 00:00За то, если работает, то код получается в два раза компактнее (проверено на stm32f7 + usb). Там надо смотреть на многочисленные pull-реквесты и их выборочно применять, если что-то не работает
agalakhov
00.00.0000 00:00-2Сейчас состояние дел в Rust для STM32 лучше, чем в C для STM32. Из коробки работает не только периферия процессора, но и большая часть распространенных внешних устройств. Для USB из коробки поддержаны профили модема, HID, MIDI и может быть еще какие-то.
BobovorTheCommentBeast
Чет я смотрел этот либопенсм3, он скорее мёртв, чем жив. Апдейтов в репе почти нет, тяжёлая периферия поддерживается не вся, не везде и не полностью.
Может я не прав и не туда смотрел?
Пс подгон хала и лл под смейк делается за пару дней в первый раз.
dltex Автор
Меня в проекте libopencm3 их замашки впечатлили, столько много контроллеров. А в этом прожекте я замахнулся не на сборку а на написание еще одного такого же хала. Но пока готов разве что нормальный api под GPIO и три USB примера (HID клавиатура, геймпад, USB-UART). Вообще все такие проекты я считаю обреченными, т.к. ИМХО, невозможно создать мало мальски универсальный APi для работы с железом, тру вариант всегда ручками флаги в регистрах выставлять.
agalakhov
Это можно реализовать через хорошую систему типов языка, когда по сути те же флаги в регистрах превращаются в имена типов. Тогда можно на compile-time проверить допустимость комбинации флагов. Я когда-то реализовывал это на шаблонах C++, сейчас это же реализовано в экосистеме Rust (низкоуровневый набор библиотек там сгенерирован автоматически по SVD-файлам). А вот в libopencm3, к сожалению, так и не появилось, там предлагают только набор из большого количества функций под готовые варианты, а то, чего в этих вариантах нет, действительно приходится конфигурировать вручную флагами в регистрах. Примерно так же сделано в CMSIS, но в CMSIS код обычно генерируют тулкитом производителя чипов.
dltex Автор
Я тут не решаюсь обычный C++ подкинуть, потому что тащусь когда прошивка в 5 килобайт упихивается (а с плюсами будет все 8-10). А про rust не слышал, помню разве что попытки утолкать java в МК и те были неудачными, потому как те МК уже стоили как полноценный ARM с линуксом.
Кстати когда пересобирал speex, явно ощутил что оперативки в притык, и это на обычном Си. А еще я помню времена Attiny когда printf был непозволительной роскошью.
alex-open-plc
Да и rust к микроконтроллерам явно притащен "за уши". Чего только стоит генерация zero-time...