Обзор

Дата появления микроконтроллеров 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. Из самого необходимого для сборки:

Насчет стартапов и компоновщика помогли комментарии в коде библиотеки CMSIS (позиционируется как стандарт взаимодействия с ядром ARM), для make помог хелп на сайте ARM. По итогу получился 50~100 строчный мейк, гораздо компактнее чем все примеры на гитхабе, в который вполне можно добавить и стандартный STM32 HAL (проверял, собиралось). В startup нужно добавить адреса векторов прерываний из datasheet, в system написать функцию включения кварцевого генератора, в компоновщике заполнить адреса памяти, в мейке все это собрать. А также на первое время, пока не написан API (HAL) понадобятся регистры это почти весь datasheet, 5к+ строчек. И вот уже можно хеллоувордить и мигать диодиком, но мы пойдем дальше.

Железо

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)


  1. BobovorTheCommentBeast
    00.00.0000 00:00
    +2

    Чет я смотрел этот либопенсм3, он скорее мёртв, чем жив. Апдейтов в репе почти нет, тяжёлая периферия поддерживается не вся, не везде и не полностью.

    Может я не прав и не туда смотрел?

    Пс подгон хала и лл под смейк делается за пару дней в первый раз.


    1. dltex Автор
      00.00.0000 00:00

      Меня в проекте libopencm3 их замашки впечатлили, столько много контроллеров. А в этом прожекте я замахнулся не на сборку а на написание еще одного такого же хала. Но пока готов разве что нормальный api под GPIO и три USB примера (HID клавиатура, геймпад, USB-UART). Вообще все такие проекты я считаю обреченными, т.к. ИМХО, невозможно создать мало мальски универсальный APi для работы с железом, тру вариант всегда ручками флаги в регистрах выставлять.


      1. agalakhov
        00.00.0000 00:00

        Это можно реализовать через хорошую систему типов языка, когда по сути те же флаги в регистрах превращаются в имена типов. Тогда можно на compile-time проверить допустимость комбинации флагов. Я когда-то реализовывал это на шаблонах C++, сейчас это же реализовано в экосистеме Rust (низкоуровневый набор библиотек там сгенерирован автоматически по SVD-файлам). А вот в libopencm3, к сожалению, так и не появилось, там предлагают только набор из большого количества функций под готовые варианты, а то, чего в этих вариантах нет, действительно приходится конфигурировать вручную флагами в регистрах. Примерно так же сделано в CMSIS, но в CMSIS код обычно генерируют тулкитом производителя чипов.


        1. dltex Автор
          00.00.0000 00:00

          Я тут не решаюсь обычный C++ подкинуть, потому что тащусь когда прошивка в 5 килобайт упихивается (а с плюсами будет все 8-10). А про rust не слышал, помню разве что попытки утолкать java в МК и те были неудачными, потому как те МК уже стоили как полноценный ARM с линуксом.
          Кстати когда пересобирал speex, явно ощутил что оперативки в притык, и это на обычном Си. А еще я помню времена Attiny когда printf был непозволительной роскошью.


          1. alex-open-plc
            00.00.0000 00:00

            Да и rust к микроконтроллерам явно притащен "за уши". Чего только стоит генерация zero-time...


  1. svpcom
    00.00.0000 00:00

    За то, если работает, то код получается в два раза компактнее (проверено на stm32f7 + usb). Там надо смотреть на многочисленные pull-реквесты и их выборочно применять, если что-то не работает


  1. agalakhov
    00.00.0000 00:00
    -2

    Сейчас состояние дел в Rust для STM32 лучше, чем в C для STM32. Из коробки работает не только периферия процессора, но и большая часть распространенных внешних устройств. Для USB из коробки поддержаны профили модема, HID, MIDI и может быть еще какие-то.