Давно не было статей с использованием FreeRTOS на нашем сайте. Что еще более удивительно, если учесть, что в повседневной жизни эту ОС использую регулярно. Так что сегодня без лишних слов и предисловий создадим базовый пример с поддержкой FreeRTOS для STM32. Прошли те времена, когда для включения ее в свой проект приходилось перетаскивать кучу файлов, некоторые из которых оказывались несовместимы, некоторых просто не хватало... В STM32CubeMx все намного менее интересно и делается в пару кликов. В общем, приступаем.
При работе с FreeRTOS я чаще всего придерживаюсь следующей схемы. Создаются несколько задач (task'ов), каждая из которых вызывается через равные промежутки времени со своим собственным периодом, например:
- 1 мс
- 10 мс
- 50 мс
- 100 мс
Конкретные значения могут зависеть уже от конкретных целей конкретного проекта. И далее вся работа распределяется по этим task'ам. Соответственно, те действия, которые необходимо выполнять максимально часто вызываются из задачи, период вызова которой равен 1 мс. Например, сохранение значений АЦП для последующей обработки. Другие же действия напротив нужно выполнять намного реже, к примеру, обновлять информацию на дисплее. И в итоге вся программа распределяется по этим временным уровням.
Вот сегодня и реализуем базовый проект для STM32 с поддержкой FreeRTOS и нескольких задач. Пусть task'и будут вызываться каждые 1 мс, 10 мс и 50 мс. По аналогии можно будет легко и быстро добавить и другие.
Запускаем STM32CubeMx. Сразу уточню - не будем подробно погружаться во все нюансы настройки FreeRTOS и рассматривать каждую конкретную опцию, иначе получится не статья, а книга. Максимально быстрый старт ) Если возникнут какие-либо вопросы, смело задавайте их в комментариях или на форуме, я буду рад помочь, итак, первым делом активируем FreeRTOS:

Но тут сразу же есть важный нюанс. При использовании FreeRTOS, в качестве базового таймера для HAL рекомендуется выбрать не SysTick (стоит по умолчанию), а другой. Для этого переходим в категорию SYS и меняем SysTick на один из свободных таймеров:

Поскольку мы уже условились делать базовый проект, то оставляем на этом этапе все настройки FreeRTOS без изменений:

Но добавляем наши задачи в разделе Tasks and Queues и задаем их приоритет - Normal:

Полностью аналогичным образом добавляем остальные задачи:

Все готово, генерируем, открываем и собираем проект. Видим, что CubeMx создал наши task'и:
/* creation of Task1ms */ Task1msHandle = osThreadNew(Task1msHandler, NULL, &Task1ms_attributes); /* creation of Task10ms */ Task10msHandle = osThreadNew(Task10msHandler, NULL, &Task10ms_attributes); /* creation of Task50ms */ Task50msHandle = osThreadNew(Task50msHandler, NULL, &Task50ms_attributes);
Но сейчас единственное, что связывает эти функции с нашим планом вызывать их через равные промежутки времени - это их название. Так что необходимо доработать непосредственно код функций. И для того, чтобы обеспечить периодичность выполнения task'ов мы будем использовать функцию