Stm32 linux ������� ������

Записки программиста

Готовим «взрослую» среду разработки под STM32 в Linux

Ранее мы выяснили, как разрабатывать под микроконтроллеры STM32 с использованием знакомой и понятной многим Arduino IDE. Этот подход, впрочем, не лишен недостатков. В частности, он (1) вводит лишние слои абстракции, что не позволяет писать максимально эффективный и компактный код, (2) работает с весьма ограниченным множеством микроконтроллеров и плат, а также (3) привязан к конкретной среде разработки, и не самой лучшей. Поэтому сегодня мы научимся разрабатывать под STM32 по-взрослому.

Важно! Порог вхождения в мир STM32 довольно высокий. Если вы никогда раньше не работали с микроконтроллерами, я бы рекомендовал начинать с плат Arduino и микроконтроллеров AVR.

Необходимый софт

Нам понадобятся следующие пакеты, часть из которых уже упоминалась в предыдущем посте:

Здесь приведены названия пакетов для Arch Linux, но я довольно уверен, что в других дистрибутивах Linux они называются так же, или как-то похоже. Если вам не удастся найти готовый пакет с STM32CubeMX, программу можно скачать отсюда (потребуется регистрация). Для работы приложению требуется виртуальная машина Java. Несмотря на то, что программа имеет расширение .exe, она превосходно запускается в Linux через java -jar file.exe .

Опционально вы также можете загрузить программу STLinkUpgrade, доступную для скачивания здесь (также потребуется регистрация). Эта программа предназначена для обновления прошивки программаторов STLink, что нередко приводит к исправлению багов, ну или как минимум к лучшим сообщениям об ошибках. Как и STM32CubeMX, эта программа написана на Java.

Необходимое железо

Помимо профессионального софта нам также понадобится профессиональное железо. Плата Blue Pill, рассмотренная в прошлом посте, в целом неплоха, но пользоваться ею несколько неудобно. В частности, к ней приходится подсоединять внешний программатор с его лишними проводами. Плюс STM32CubeMX про эту плату ничего не знает, что также вносит свою долю неудобства. Наконец, если у вас этой платы еще нет, вам придется ждать ее доставки с AliExpress.

Компания STMicroelectronics производит собственные отладочные платы серий Discovery и Nucleo. Последние являются более новыми, поэтому сосредоточим свое внимание на них. Платы STM32 Nucleo имеют встроенный отладчик STLink v2.1, что избавляет нас от лишних проводов. Они до определенной степени совместимы с Arduino-шилдами, что может пригодиться. Цены на платы Nucleo в России начинаются от 19$ за плату Nucleo-F030R8, притом купить ее можно в любом Чип-и-Дипе хоть сегодня.

Лично я взял плату помощнее — Nucleo-F411RE, на вырост, так сказать:

Принимая во внимание разнообразие плат Nucleo, выбор первой платы может быть непростым делом для начинающих. Следует учитывать множество факторов, включая количество Flash-, SRAM- и EEPROM-памяти, максимальную рабочую частоту, используемое ядро Cortex-M, количество аппаратных реализаций SPI/I2C/I2S/UART/CAN-интерфейсов, наличие/отсутствие DAC, ADC и модуля FSMC, энергопотребление, стоимость отладочной платы и ее наличие в ближайших магазинах, и, конечно же, стоимость и доступность самого микроконтроллера. Так как сейчас я не работаю над каким-то конкретным проектом, а просто изучаю микроконтроллеры STM32, я выбрал плату Nucleo-F411RE из-за неплохого соотношения цены и качества. Также меня привлек тот факт, что в микроконтроллере STM32F411RET6, на котором основана эта плата, используется довольно мощное ядро Cortex-M4F со встроенным FPU.

Fun fact! Существуют платы Xnucleo от компании Waveshare, совместимые с платами Nucleo. Платы Xnucleo легко узнать по характерному сине-желтому дизайну. На вид они более продуманы, чем Nucleo, так как используют более общепринятый в наше время разъем micro USB вместо mini USB, лишены дизайнерских «линий надреза» (см предыдущее фото), делающих плату более хрупкой, и имеют впаянный HSE кварцевый резонатор. Также компания Waveshare является производителем множества шилдов для плат Nucleo и Xnucleo.

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

Имеется большое количество отладочных плат и микроконтроллеров, под каждый из которых может требоваться немного измененные версии заголовочных файлов и стандартной библиотеки. Это количество помножим на число всевозможных конфигураций этих микроконтроллеров, например, какие пины для чего используются, какая из внутренних шин на какой частоте работает, и так далее. В плане подобных настроек STM32 является очень гибкой платформой. Получается довольно сложно. Для борьбы с этой сложностью создание каркаса пустого проекта (так называемый scaffolding) для заданной платы или микроконтроллера осуществляется при помощи специальной GUI-программы, STM32CubeMX.

Читайте также:  Powershell start windows services что это

Запускаем программу, жмем New Project. Во вкладке Board Selector находим вашу плату и делаем по ней двойной клик. Если у вас еще нет платы Nucleo, но есть плата Blue Pill и программатор STLink v2, на этом шаге вы можете выбрать микроконтроллер STM32F103C8Tx во вкладке MCU Selector.

Появится интерфейс с несколькими вкладками, из которых наиболее интересной для нас сейчас является вкладка Pinout:

Эта вкладка позволяет настроить, какой пин микроконтроллера для чего будет использован (ввод, вывод, аналоговое чтение, SPI/I2C/UART-шина, и так далее). Так как STM32CubeMX знает про нашу плату, программа автоматически настроила пин PC13 на ввод (для чтения синей кнопки на плате), а пин PA5 — на вывод (для управления зеленым светодиодом на плате). В рамках этой заметки другие пины нам не потребуются, поэтому оставляем все, как есть. Если же вы используете незнакомую STM32CubeMX плату, здесь вам потребуется настроить пины вручную. Например, в случае с Blue Pill вы наверняка захотите настроить пин PC13 как GPIO_Output, так как он подключен к светодиоду на плате.

Важно! Если вы используете Blue Pill, в STM32CubeMX обязательно требуется включить SWD. По умолчанию для микроконтроллера STM32F103C8T6 он выключен. В связи с этим, плату вы без труда прошьете в первый раз, но прошить ее во второй будет довольно непросто (хотя возможно). Более подробное описание этой тонкости ищите в заметке Используем STM32 безо всяких отладочных плат.

На двух других вкладках с названиями Clock Configuration и Configuration в этот раз нам ничего менять не придется. На вкладке Power Consumtion Calculator можно оценить энергопотребление микроконтроллера и время его работы в зависимости от выбранного аккумулятора и рабочего напряжения. Надо сказать, довольно любопытная и полезная возможность.

На этом с настройкой покончено. Говорим Project → Generate Code. Во вкладке Project вводим имя проекта (Project Name), выбираем родительский каталог для этого проекта (Prоject Location), в выпадающем списке Toolchain / IDE выбираем вариант «Makefile». Во вкладке Code Generator стоит выбрать опцию «Add necessary library files as reference in the toolchain project configuration file». Иначе в ваш проект будут скопированы все библиотечные файлы, а это более 160 Мб. Затем жмем ОК. Проект STM32CubeMX автоматически сохранится в каталоге с исходным кодом (файл с расширением .ioc), поэтому отдельно сохранять его не требуется.

Makefile в получившемся проекте нужно немного подправить. Во-первых, нужно исправить значение переменных BINPATH и PREFIX :

В противном случае не будут найдены исполняемые файлы компилятора.

Во-вторых, стоит найти переменную OPT и дописать в нее флаг -Wall :

Иначе компилятор не будет ругаться на код, который скорее всего содержит ошибки — например, выражение if ( arr [ i ] = 1 ) , на месте которого почти наверняка должно быть if ( arr [ i ] == 1 ) .

В-третьих, если после этого шага сказать make , вы можете получить ошибки вроде следующих:

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

В-четвертых, Makefile умеет компилировать проект, но не содержит таргетов для прошивания платы, ее очистки, а также подключения по UART. Стоит дописать:

Наконец, из соображений скорее перфекционизма, чем острой надобности, я бы заменил все абсолютные пути на относительные, введя переменную вроде:

… а также прогнал бы Makefile через утилиту dos2unix.

На этом подготовку шаблона/каркаса можно считать завершенной! Чтобы не проделывать описанные выше шаги при создании каждого нового проекта, шаблон стоит сохранить где-нибудь в надежном месте. Дабы не приходилось при повторном использовании этого шаблона редактировать имя проекта, стоит также отредактировать значение переменной TARGET на какое-нибудь абстрактное main .

Пишем код!

Если вы откроете файл Src/main.c, то найдете в нем множество отметок вроде:

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

По задумке, код нужно вписывать между этими комментариями, чтобы при обновлении проекта в STM32CubeMX пользовательский код не был затерт. Лично я добавил вызов процедур init ( ) и loop ( ) в окрестностях основного цикла программы:

/* Infinite loop */
/* USER CODE BEGIN WHILE */
init ( ) ;
while ( 1 )
<
loop ( ) ;
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
>
/* USER CODE END 3 */

Читайте также:  Windows loader daz oem

… а сами процедуры объявил перед процедурой main ( ) :

/* USER CODE BEGIN 0 */

void init ( void ) <
/* do nothing, yet */
>

void loop ( void ) <
/*
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(500);
*/
if ( HAL_GPIO_ReadPin ( GPIOC , GPIO_PIN_13 ) == GPIO_PIN_RESET ) <
HAL_GPIO_TogglePin ( GPIOA , GPIO_PIN_5 ) ;
>

/* USER CODE END 0 */

Управление микроконтроллером осуществляется через библиотеку под названием HAL, Hardware Abstraction Layer. Как видите, что касается обычного чтения кнопок и мигания светодиодами, здесь все не намного сложнее, чем в случае с той же Arduino.

Подключаем плату и говорим make flash . Если все было сделано правильно, нажатие синей кнопки на плате будет приводить к переключению зеленого светодиода. Также можно оставить в процедуре loop ( ) только код, который в приведенном выше отрывке я закомментировал, и тогда программа превратиться в обычный Blink.

Важно! Иногда микроконтроллер не запускается с новой прошивкой без нажатия черной кнопки Reset. По идее, обновление прошивки программатора с помощью утилиты STLinkUpgrade и использование утилиты st-flash с флагом —reset , как в нашем Makefile, исправляет эту проблему. Но так как она воспроизводится нерегулярно, полной уверенности нет.

Заключение

Как видите, все не так уж и сложно. Полученных знаний уже вполне достаточно, например, для того, чтобы написать программу, выводящую что-то на ЖК-экранчик или декодирующую сигнал от джойстика Sega. Можно даже пообщаться с какими-то сторонними модулями по SPI или I2C, хотя и не слишком эффективно, если вспомнить о наличии в микроконтроллере аппаратной поддержки этих протоколов. Однако эти темы, ровно как и ШИМ, чтение аналогового сигнала, работа с прерываниями или отладка кода, увы, выходят за рамки этой и без того уже довольно длинной статьи.

Кстати, к вопросу о выходящем за рамки. Хотя приведенных выше сведений будет вполне достаточно тем, кто пишет в Vim, как в данное время суток это делаю я, или каком-нибудь Sublime Text, кто-то из читателей может предпочитать работать в IDE. Настройка Eclipse для разработки под STM32 подробно расписана в книге Mastering STM32 за авторством Carmine Noviello. Если же вы предпочитаете CLion, его настройку подробно описал Илья Моторный в статье JetBrains CLion для микроконтроллеров.

Полную версию исходников к этому посту, как обычно, вы найдете на GitHub.

Источник

STM32MP1 — ядра + Linux = идеальный микроконтроллер

По роду своей деятельности занимаюсь разработкой различных приборов: измерительных, управляющих, контролирующих и т.п. В подавляющем большинстве устройство делится на 2 части:

  1. Требующий больших ресурсов микроконтроллера и не требующий жесткого реального времени графический интерфейс пользователя (GUI).
  2. Потребляющая немного ресурсов и работающая в жестком реальном времени аппаратная часть прибора.

И как правило, переход на новую серию микроконтроллеров определялся улучшением GUI: больше цветов, выше разрешение, более сложные элементы дизайна. Одно время была мысль использовать в качестве графического интерфейса какую-нибудь плату Raspberry.

Но с появлением у STM новой линейки микроконтроллеров STM32MP1 мои терзания закончились и вот что пока получилось.

Идеальный контроллер

Идеальный контроллер для меня должен обладать следующими характеристиками:

  • иметь приличные графические возможности, такие как простая поддержка различных графических форматов, поддержка векторных шрифтов
  • большой объем памяти для графики
  • поддержка USB клавиатуры и мышей
  • поддержка Ethernet
  • большое количество аппаратных таймеров
  • генерация ШИМ
  • большое количество GPIO
  • 16 разрядный АЦП

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

И поэтому я очень обрадовался увидев новый серию от STM: STM32MP1.

Первое знакомство

Для ознакомления с новым чипом была приобретена плата STM32MP157C-DK2. Вот такая (фото из инета):

Демоплата построена на кристалле STM32MP157CAC, который имеет в своем составе:

  • 2 ядра А7, по 650 МГц
  • 1 ядро М4, 208 МГц

Память

Самое первое отличие, которое бросается в глаза — это отсутствие флеш памяти на кристалле. Для ядра А7, которое по сути микропроцессор, это нормальная ситуация и код всегда выполняется из DRAM. Микроконтроллеры на основе М4, обычно имеют в своем составе флеш память, в которой хранится исполняемый код.

В этом кристалле у ядра М4 есть только оперативная память и код выполняется из нее (из даташита):

708 Kbytes of internal SRAM: 256 Kbytes of
AXI SYSRAM + 384 Kbytes of AHB SRAM +
64 Kbytes of AHB SRAM in Backup domain
and 4 Kbytes of SRAM in Backup domain

The STM32MP157C/F devices embed a controller for external SDRAM which support the
following devices:

  • LPDDR2 or LPDDR3, 16- or 32-bit data, up to 1 Gbyte, up to 533 MHz clock.
  • DDR3 or DDR3L, 16- or 32-bit data, up to 1 Gbyte, up to 533 MHz clock.
Читайте также:  Windows мастер по ремонту

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

Организация рабочего места

Поскольку для работы с платой необходим Линукс, то пришлось установить дополнительный жесткий диск в свой комп и развернуть на нем Ubuntu 16.04. Эту ОС рекомендует STM.

Engineering & Production mode

Плата может стартовать в одном из двух режимов (определяется дип-свитчем). В режиме Engineering, ядро М4 работает обособленно. В Production mode ядро М4 работает под управлением ядра А7. Я не использовал режим Engineering, работал только в режиме Production. В этом режиме можно не заботиться о настройке тактирования ядер. Тактирование настраивается в процессе загрузки по максимальным величинам. Я проверил несколько регистров в отладчике, вывел часть частот на MCO и посмотрел осциллографом. A7 работает на частоте 650 МГц, М4 на частоте 208 МГц.

Ядро М4. Загрузка и запуск программ

Поскольку ядро М4 работает под управлением А7, значит под управлением OpenSTLinux. Для управления ядром М4 используется Linux remoteproc framework (RPROC). Этот фреймворк позволяет включать и отключать ядра, загружать и отлаживать программное обеспечение(ELF файлы).

Для загрузки программы в ядро M4 служит следующая команда:

echo -n > /sys/class/remoteproc/remoteproc0/firmware

Для старта программы:

echo start >/sys/class/remoteproc/remoteproc0/state

echo stop >/sys/class/remoteproc/remoteprocX/state

Ядро М4. SW4STM32

With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world.
And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.

То есть можно писать код как для ядра м4, так и для А7. Но это платная версия. А бесплатная, которая доступна для скачивания, позволяет писать и отлаживать код только для ядра М4.

IDE SW4STM32 была скачана, установлена и попробована. Все работает, процесс написания и компиляции не отличается от версии в Windows.
Отличается только загрузка кода и отладка, поскольку для записи софта используется Ethenet и соединение по SSH. Для отладки и остановки по точкам используется встроенный на плате ST LINK.

Ядро А7. Кросс-компилятор

Для компиляции программ на ПК STM предлагает кросс-компилятор. Процесс загрузки и запуска скрипта кросс-компилятора подробно описан в Вики STM32MP1, ссылка ниже. Все было сделано согласно инструкции, все работает как надо. 🙂

Запуск кросс-компилятора для экосистемы v1.1.0:

source SDK/environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi
ну далее команда
make
и исходный код, в соответствии с makefile, скомпилируется в коды ARM 🙂

Ядро А7. Загрузка и запуск программ

Чтобы загрузить программу в демо плату используется команда:

scp gtk_hello_world root@192.168.1.18:/usr/local

Эта команда загружает файл gtk_hello_world в раздел /usr/local, который находится на плате с IP адресом: 192.168.1.18. Root — пароль, который стоит на плате по умолчанию.

Обмен данными между ядрами

Больше всего времени ушло на понимание работы механизма обмена данными между ядрами. В примерах, которые поставляются STM, есть несколько вариантов реализации подобного обмена. Можно работать напрямик с драйвером из OpenSTLinux или использовать механизм виртуальных UARTов. Я решил сделать обмен через виртуальные порты, как более простой.

Со стороны Линукс это выглядит так:

fd = open(«/dev/ttyRPMSG0», O_RDWR);

Потом пишем в него или читаем:

write(fd, «LED_Toggle\r\0», 10);
len = read( fd, buf, sizeof(buf));

Все достаточно просто, но есть маленький нюанс. Чтобы появилось устройство ttyRPMSG0, нужно чтобы ядро М4 обратилось к ядру А7 в таком виде:

это строки кода ядра М4:

Прием данных из виртуального порта ядром М4:

Запись данных в виртуальный порт:

Все работает, но есть небольшой нюанс, который пока не могу понять. Прием данных ядром А7, которые передает ядро М4, не начинается, если предварительно ядро А7 не запишет в порт какие-либо данные.

Весь этот механизм реализуется набором сторонних библиотек OpenAMP. Эта библиотека должна быть включена в проект ядра М4 и соответственно проинициализирована.

Дальнейшие планы

Установить и настроить Eclipse для написания и отладки кода для А7.
Написать нормальное графическое демо, типа осцилоскопа из АЦП М4.
И наконец, сделать свою плату контроллера на основе этого чипа. 🙂

Источник

Оцените статью