Подобно многим любителям садистски потыкать раскаленным паяльником в нежные внутренности электронных девайсов я не избежал увлечения микроконтроллерами серии STM32 от STMicroelectronics, за их небольшую цену прозванные "убийцами" 8/16-битных микроконтроллеров, таких как AVR.

Поскольку основной операционной системой на моем компьютере является Линукс, а альтернативных операционных систем на нем нет и не предвидится, то встал вполне естественный вопрос — чем собирать программы под STM32 и чем их прошивать в имеющуюся у меня STM32VLDiscovery? Иначе говоря передо мной встал вопрос инструментального обеспечения.

Большинство руководств, найденных мною в Интернете, либо советовали перезагружаться в Windows, либо использовать утилиту stm32flash, которая прошивает кристалл при помощи встроенного bootloader’а через UART. При всем при этом, в некоторых руководствах еще и предлагалось немного пошаманить с состоянием выводов BOOT0 и BOOT1 или использовать такие громоздкие среды разработки как Eclipse.

Мне все вышеперечисленное показалось крайне неприемлемым и я стал искать свой способ работы с STM32VLDiscovery под Linux’ом. Результаты моих изысканий приведены далее.

Инструментальная цепочка

В деле программирования я предпочитаю минимализм — мне достаточно текстового редактора (хорошего текстового редактора, такого как vim или emacs), компилятора и утилиты make, которая будет собирать мой исходный код и мои инструментальные средства в один проект.

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

Для STM32VLDiscovery нам потребуется:

  • компилятор GNU GCC, ориентированный на работу с архитектурой ARM (обязательно arm-none-eabi-, не arm-linux-! Последний генерирует код под встраиваемый линукс на ARM’е, а не под сам ARM.)

  • отладчик GNU GDB (тоже arm-none-eabi-)

  • Утилита для заливки кода в STM32VLDiscovery через ST-Link — stlink

  • библиотека CMSIS — Cortex Microcontoller Software Interface Standard. Набор удобных макросов и функций, созданных для работы с внутренностями ядра Cortex-M3 — на этом ядре построен STM32F100RB, служащий сердцем STM32VLDiscovery

  • библиотека STM32 Standard Peripheral Library — еще один удобный набор макросов и функций от производителя чипа. Содержит в себе драйвера для работы со всей периферией STM32F100RB

Компилятор и отладчик ищите в репозиториях своего дистрибутива. На крайний случай можно скачать готовые бинарники от CodeSourcery (правда я не помню есть ли в них gdb). Библиотеки CMSIS и STM32StdPeriphLib можно взять единым архивом с сайта STMicroelectronics — http://www.st.com/internet/mcu/product/216844.jsp, вкладка "Design Support" и пункт ""STM32F 10X standard peripheral library".

Теперь перейдем к тому, как все это упаковать в один большой проект.

Шаблон проекта

Шаблонный проект для нашей отладочной платы будет иметь следующую структуру:

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

Итак, исходный код stlink’а и CMSIS лежит в соответствующих директориях, эти директории могут кочевать из проекта в проект без каких бы то ни было изменений.

Исходный код библиотеки стандартной периферии от STM32 лежит в подкаталоге stm32_lib. Содержимое этого подкаталога может варьироваться в зависимости от того, какие драйвера для программы нужны. Так, например, в нашем шаблонном проекте используются выводы общего назначения (чтобы зажечь светодиоды) — соответственно я скопировал из скачанного архива библиотеки файлы stm32f10x_gpio.c и stm32f10x_gpio.h. Остальные файлы в каталоге шаблонного проекта являются необходимыми для компиляции проекта, особенно стартовый ассемблерный код и скрипт для линкера.

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

Для драйверов периферии недостаточно скопировать их исходный код в дерево проекта — нужно еще подключить соответствующие заголовочные файлы. Делается это в файле stm32f10x_conf.h, раскомментированием соответствующих строк:

И еще нужно подтвердить использование библиотеки стандартной периферии, раскомментировав соответствующий макрос в stm32f10x.h:

В этом же файле нужно раскомментировать соответствующее макроопределение для используемого в проекте микроконтроллера. Так например, STM32F100RB относится к линейке "Medium density Value Line" и соответственно нам нужно раскомментировать строчку с макросом STM32F10X_MD_VL:

На этом настройка библиотек закончена и можно переходить к написанию своего кода. В шаблонном проекте весь код сосредоточен в файле main.c в корне дерева исходников, но вы вольны использовать любую другую компоновку, немного подправив Makefile.

Для того, чтобы использовать в вашем исходном коде какие-нибудь драйвера из библиотеки от STM32, достаточно подключить заголовочный файл stm32f10x.h. Всякие же подробности использования драйверов скрыты в комментариях к исходному коду этих драйверов.

Сборка проекта

Компиляция и загрузка проекта осуществляется при помощи одного большого Makefile. Я не буду приводить в блоге код полностью — его вы сможете посмотреть сами в исходниках проекта (ссылка приведена в конце статьи).

Отмечу лишь, что для своего проекта вам нужно указать имя бинарника, пути к исходным файлам проекта и, если потребуется, к заголовочным файлам, список получающихся объектных файлов, а также путь к ARM’овскому кросскомпилятору.

Прошивка проекта в микроконтроллер производится через make load, при этом собирается утилита stlink из исходников и запускается скрипт flashing_stm32vldiscovery.sh, проверяющий все ли на месте и запускающий сервер для gdb (необходимы привилегии root — sudo спрашивает пароль!). При удачном подключении к плате должен зажечься еще один красный светодиод на ней (следует подождать некоторые время — примерно 7-9 секунд). После этого, вы можете запустить gdb для ARM в другой консоли и выполнить для загрузки прошивки в чип:

target remote :1234
load stm32vldiscovery-linux-template.elf
Loading program
Загрузка прошивки в STM32VLDiscovery

Для запуска прошитой программы следует ввести команду continue, для остановки — нажать Ctrl+C.

Небольшой подводный камень — после выполнения make load лучше всего не прерывать работу запустившегося stlink’а, не выходить из gdb и не отсоединять STM32VLDiscovery от USB. Иначе возможна нестабильная работа системы, core dump’ы, kernel panic’и и прочие подобные вещи. Собирать ELF’ы лучше всего в отдельной вкладке консоли, а затем переходить на вкладку с GDB, чтобы залить изменения в чип.

Еще один подводный камень — для работы утилиты stlink необходим модуль ядра sg. Соответствующая опция расположена где-то в "Device drivers"→"SCSI drivers"→"…​.generic…​". Если этого модуля нет или он вкомпилирован в ядро — вы получите красивый crashdump и последующую перезагрузку системы.

Если все прошло удачно и шаблонный проект прошился - мы должны получить плату с горящими зеленым и синим светодиодами:

STM32VLDiscovery

Полезные ссылки

arm stm32