Как стать автором
Обновить

FreeRTOS + STM32F4 на С++ под Linux

Время на прочтение 5 мин
Количество просмотров 52K
Доброго дня! Прошло много времени с тех пор как я последний раз программировал под AVR и вот, решил восстановить в памяти такую, без сомнения интересную и увлекательную область разработки — разработку под микроконтроллеры. В качестве платформы был выбран ARM STM32, и, чтобы не мелочиться, сразу Cortex-M4. Отладочная плата STM32F4DISCOVERY с STM32F407 на борту. Мегабайт флеша и 128 кб памяти дает возможность не сильно заморачиваться экономией ресурсов и писать на C++.

Итак, задача: научиться с нуля моргать светодиодами под STM32 во FreeRTOS, но делать это модно — на C++, а не на чистом C.

Подразумевается, что вы уже работаете с Eclipse, знаете, как ставить в него дополнения и знаете в общих чертах, как работает Linux.

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

Тулчейн

Установка и настройка среды разработки заняла у меня два дня. Поэтому я приведу набор, который у меня реально заработал и детально опишу проблемы, с которыми столкнулся:
Eclipse Kepler (для C/C++)
— GCC
— texane / stlink

Заморочка была с GCC для arm-none-eabi. Вариантов тулчейна существует очень много, я пробовал два и реально заработали оба. Однако небольшая разница между ними все же есть:
— GNU Arm toochain можно взять тут
— Mentor Graphics CodeSourcery EABI можно взять тут, попросят ввести свои данные, пришлют ссылку для скачивания на почту..

Кстати, сначала я поставил arm-linux-gnueabi их своего дистра Linux. Не стоит, для наших целей не подойдет, а вот если на вашем ARM стоит Linux — то да, самое оно.

Итак, компилятор ставим, куда вздумается, но обязательно пропишем путь к нему в PATH пользователя. Как это сделать — зависит от операционки, с которой вы работаете. Я закинул в /opt эту пару тулчейнов и сделал симлинк /opt/arm-toolchain — как-бы по-умолчанию.

Программатор

Далее клонируем stlink с Github'a любым удобым способом. Собирается как обычно:

# git clone github.com/texane/stlink
# cd stlink
# ./automake
# ./configure --prefix=/usr/bin

Не забудем про libusb-dev, у меня в Debian Wheezy он не был установлен. Если еще каких-то либ не хватает, ставим их как это делается в вашей системе.

Среда разработки

Далее, самое интересное для меня — настройка клипсы под разработку. Настроить проект так, чтобы все компилировалось и работало на чистом Eclipse у меня не получилось. Поэтому можно поставить полезные плагины. Однако после того, как будет достигнута определенная степень ясности настроек — можно поковыряться и сделать настройку проекта под себя без плагинов.

Есть достаточно разных плагинов для разработки под ARM, вот парочка:
— GNU Arm Eclipse можно взять тут
— Zylin CDT — здесь

Для обоих есть апдейт-сайты, ставятся плагины стандартным для клипсы способом из менюшки. Ставим оба.

Далее, создаем C++ проект в Eclipse, выбираем, что он будет под ARM (тулчейн ARM Cross GCC), далее выбираем тип тулчейна в зависимости от того, какой компилятор вы выбрали: CodeSourcery или ARM GCC. Вообще плагины поддерживают всякие разные наборы компиляторов — можно поиграться и с ними.





Вот тут есть одна проблема — в CodeSourcery я не нашел libnosys.a. Пришлось взять его из GNU Arm GCC. В общем полет нормальный.



Выводы

Теперь, небольшое лирическое отступление о том, какие проблемы решает плагин. С этим придется столкнуться, если вы будете настраивать проект под себя и вы — новичок. Для меня все это было открытием, т.к. прошивок я никогда не писал до этого.

— на контроллере нет libc. Firmware компонуется статически.
— и нет операционной системы (она будет встроена в проект), нет загрузчика — программа начнет выполняться сразу после включения.

Плагин решает кучку задач — он предоставляет сразу нужные нам либы CMSIS и Standard Perepherials в проекте, который мы только что создали. Эти библиотеки нужны, чтобы работать с переферией контроллера.

Можно, конечно, прикрутить libopencm3 вместо библиотек предоставленных производителем, но это тема отдельной статьи.

Также ппагин предоставляет набор linker scripts. Честно говоря, я с ними столкнулся впервые. В linker script'е описывается структура бинарного файла, секции, точка входа и много чего еще. Собирать все это по кусочкам вручную муторно и безынтересно, пока проект еще даже не завелся на железке, зато потом — какой простор для изучения.

Настраивается плагин из свойств проекта, собственно, в проекте они и хранит свои настройки.

Настраиваем отладчик

Вообще, этот кусок можно сделать в самом конце, но то, что отладка заработала — уже является признаком того, что все настроено. Поэтому мы сделаем это заранее.

В качестве отладчика, естественно, используется GDB. Настроим приложение сервера GDB, в качестве которого будет выступать утилита от texane/stlink.

Идем в External Tools и добавляем инструментарий. Его надо будет запускать каждый раз, если нам нужна будет отладка, при подключенной плате. Утилита будет заливать отладочный образ и служить сервером. Ключик -m как раз говорит ей не отваливаться каждый раз, когда соединение с отладчиком будет прервано, что очень удобно на мой взгляд.



Далее создадим таргет отладки. Тут все просто, берем отладчик из тулчейна, указываем порт 4242 — это порт GDB сервера по-умолчанию.



Запускаем сервер отладки, подключаемся к таргету — он соберет проект, зальет бинарник в железку и запустит. Можно отлаживаться.

FreeRTOS

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

Структура проекта, созданного плагином будет иметь каталог libs, где уже лежат CMSIS, StdPeriph и прочее. Вот туда мы и закинем FreeRTOS. Далее, чтобы операционка работала надо ее сконфигруровать. Мануалов (в том числе официальных) по настройке FreeRTOS в интернете валом, поэтому описывать я его тут не буду. Если вкратце, надо сделать следующее:

1) создать FreeRTOSConfig.h и положить его к хидерам от RTOS
2) взять из portable порт для нашей железки и положить файлы порта вместе с остальными исходниками RTOS.
3) найти с исходниках RTOS memory manager, например heap_2.c и положить туда же.

Кстати, в конфиге от RTOS надо указать реальную тактовую процессора, такую же какая была указана при создании проекта. У меня это 168000000.

#define configCPU_CLOCK_HZ ( ( unsigned long ) 168000000 )
#define configTICK_RATE_HZ   ( ( portTickType ) 1000 )


А также добавить вот это:

#define vPortSVCHandler			SVC_Handler
#define xPortPendSVHandler 		PendSV_Handler
#define vPortSVCHandler			SVC_Handler
#define xPortSysTickHandler		SysTick_Handler


И включить vTaskDelay так как он у нас будет исползоваться для ожидания между морганиями светодиода:

#define INCLUDE_vTaskDelay              1


Не забудем в клипсе прописать в настройках проекта пути к нашей FreeRTOS:



Вообще в проекте много всяких настроек, из которых формируются параметры компилятора, ассемблера и компоновщика. Можно поиграться, посмотреть что будет ;)

Минимум настроен, теперь можно пытаться собирать. Если что-то забыли — просто не соберется или не будет работать.

А теперь танцы приложение!

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

Проект на гитхабе.

С тасками есть один ньюанс, с которым я, при переходе на С++ немного промучался:

void Application::attach(Task *task) {
	FNMETHOD impl = &Task::impl;

	pdTASK_CODE proc = ((pdTASK_CODE)(task->*impl));
	xTaskCreate(
		proc,
		(signed char *) "test",
		configMINIMAL_STACK_SIZE,
		task,
		2,
		(xTaskHandle *) 0);

}


Первый параметр — указатель на метод, в котором реализована задача. Четвертый параметр в xTaskCreate — указатель на экземпляр класса Task. Передать указатель на экземпляр необходимо, иначе в методе реализации не будет доступа к переменным класса Task — в данном случае, пину светодиодика и задержке.

Ну а в остальном там все просто. Удачного дня и успешных сборок. Вопросы welcome!

P.S. А какой средой под Linux для этих целей пользуетесь вы? ;)

P.P.S. Надо понимать, что данный пост написан не системным программистом и призван помочь «высокоуровневым» товарищам, желающим войти в мир разработки firmware. Поэтому гуру ассемблера прошу не серчать ^-^
Теги:
Хабы:
+15
Комментарии 7
Комментарии Комментарии 7

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн