Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кармин Новиелло - Освоение STM32.pdf
Скачиваний:
2751
Добавлен:
23.09.2021
Размер:
47.68 Mб
Скачать

Запуск FreeRTOS

609

Это всего лишь введение в сложные темы, лежащие в основе ОСРВ. Мы проанализируем несколько других концепций, в основном связанных с синхронизацией конкурентных задач, далее в этой главе. А сейчас мы начнем знакомство с наиболее важными функци-

ями FreeRTOS.

23.2. Введение во FreeRTOS и в оболочку

CMSIS-RTOS

Как говорилось в начале данной главы, FreeRTOS – это ОС, выбранная ST в качестве официальной ОСРВ для распространяемого ей Cube. Новейшие выпуски CubeMX предлагают хорошую поддержку этой ОС, и очень просто включить ее в качестве компонента

промежуточного программного обеспечения (middleware) в проект. Многие дополнитель-

ные модули CubeHAL (например, стек LwIP) полагаются на предоставляемые им сервисы.

Тем не менее, ST не ограничилась интеграцией поставляемой FreeRTOS в своем дистрибутиве CubeHAL. Над ней встроена полноценная оболочка (или, как говорят, «обертка», англ. wrapper) CMSIS-RTOS, позволяющая разрабатывать приложения, совместимые с CMSIS-RTOS. Мы говорили о CMSIS-RTOS в Главе 1, когда рассматривали весь стек CMSIS. Идея, лежащая в основе «инициативы CMSIS», заключается в том, чтобы, используя общий стандартизированный набор API-интерфейсов между несколькими производителями интегральных схем и поставщиками программного обеспечения, можно было бы «легко» перенести наше приложение на разные микроконтроллеры других производителей. По этой причине мы рассмотрим функциональные возможности FreeRTOS, используя как можно больше API-интерфейсов CMSIS-RTOS.

23.2.1. Структура файлов с исходным кодом FreeRTOS

Исходный код FreeRTOS организован в виде компактной структуры исходных файлов, которая разворачивается более чем на дюжину файлов. На рисунке 4 показано, как FreeRTOS организована внутри CubeHAL14. Файлы .c, находящиеся в корневой папке, содержат основные функции ОС (например, файл tasks.c содержит все процедуры, связанные с управлением потоками). Вложенная папка include содержит несколько включаемых файлов, используемых для определения большей части структур Си и макросов, используемых ОС. Наиболее важным из этих файлов является файл FreeRTOSConfig.h, который включает в себя все пользовательские макросы, используемые для конфигурации ОСРВ в соответствии с потребностями пользователя. Другой важной вложенной папкой, содержащейся в корневой папке, является portable. FreeRTOS предназначена для работы примерно с 30 различными аппаратными архитектурами и компиляторами, обеспечивая при этом один и тот же согласованный API-интерфейс. Все специфичные для платформы функции организованы в два файла15: port.c и portmarco.h, которые, в свою очередь, собраны во вложенной папке, специфичной для используемой архитек-

туры. Например, папка portable/GCC/ARM_CMO содержит файлы port.c и portmarco.h,

предоставляющие код, специфичный для архитектуры Cortex-M0/0+ и компилятора

GCC.

14FreeRTOS доступна во всех CubeHAL, в папке Middleware/Third_Party/Source.

15Эта часть FreeRTOS считается отделенной от структуры исходных файлов ядра FreeRTOS, и, как говорят,

она реализует уровень платформозависимого кода (port layer) FreeRTOS.

Запуск FreeRTOS

610

Наконец, папка CMSIS-RTOS содержит уровень, совместимый с CMSIS-RTOS, разработан-

ный ST поверх FreeRTOS.

Рисунок 4: Организация структуры файлов с исходным кодом FreeRTOS в CubeHAL

В следующих двух параграфах показано, как импортировать дистрибутив FreeRTOS в проект Eclipse: вручную или с помощью инструмента CubeMXImporter.

23.2.1.1.Как импортировать FreeRTOS вручную

Если вы хотите импортировать структуру файлов с исходным кодом FreeRTOS в существующий проект, вы можете действовать следующим образом.

1.Создайте папку Eclipse с именем Middleware/FreeRTOS в корне проекта.

2.Перетащите в эту папку содержимое STM32Cube_FW/Middlewares/Third_Party/FreeRTOS/Source, за исключением вложенного каталога Portable.

3.Теперь создайте вложенную папку с именем portable/GCC16 в папке Eclipse

Middleware/FreeRTOS и папку с именем portable/MemMang.

4.Перетащите папку STM32Cube_FW/Middlewares/Third_Party/FreeRTOS/Source/porta-

ble/GCC/ARM_CMx, соответствующую архитектуре вашего микроконтроллера STM32 (например, если у вас STM32F4, основанный на ядре Cortex-M4, выберите папку

ARM_CM4F) в папку Eclipse portable/GCC.

5.Перетащите только один17 из файлов, содержащихся в папке STM32Cube_FW/Mid-

dlewares/Third_Party/FreeRTOS/Source/portable/MemMang, в папку Eclipse porta-

ble/MemMang. Эта папка содержит 5 различных схем выделения памяти

(memory allocation schemes), используемых FreeRTOS. Мы рассмотрим их более подробно позже. На данный момент можно использовать heap_4.c.

В конце процесса импорта у вас должна быть структура проекта, подобная той, что показана на рисунке 5.

16Если вы используете другой инструментарий, то вы должны соответствующим образом переорганизовать инструкции.

17Можно импортировать все схемы управления памятью (memory management schemes) и исключить из компиляции ненужные. Как наилучшим образом организовать проект зависит от вас.

Запуск FreeRTOS

611

Рисунок 5: Структура проекта Eclipse после импорта FreeRTOS

Прочитайте внимательно

Когда мы создаем новые папки в проекте Eclipse, по умолчанию Eclipse автоматически исключает их из процесса сборки. Таким образом, нам нужно разрешить компиляцию папки Middlewares, щелкнув правой кнопкой мыши в панели с деревом проекта Project Explorer, затем выбрав Resource configuration → Exclude from build и сняв флажки со всех определенных конфигураций проекта.

Теперь нам нужно определить конфигурационный файл FreeRTOS и включить заголовочные файлы FreeRTOS в настройки проекта. Итак, переименуйте файл Middlewares/FreeRTOS/include/FreeRTOSConfig_template.h в Middlewares/FreeRTOS/include/FreeRTOSConfig.h. Далее перейдите в раздел Project Settings → C/C++ Build → Settings → Cross ARM C Compiler → Include и добавьте записи:

"../Middlewares/FreeRTOS/include"

"../Middlewares/FreeRTOS/CMSIS_RTOS"

"../Middlewares/FreeRTOS/portable/GCC/ARM_CMx"18

как показано на рисунке 6.

Рисунок 6: Пути включаемых файлов для их добавления в настройки проекта

18 Переорганизуйте этот каталог в соответствии с вашим конкретным уровнем платформозависимого кода.

Запуск FreeRTOS

612

23.2.1.2.Как импортировать FreeRTOS с использованием CubeMX и CubeMXImporter

Инструмент CubeMXImporter позволяет автоматически импортировать проект, созданный с помощью CubeMX с промежуточным программным обеспечением FreeRTOS. После того, как вы сконфигурировали периферийные устройства микроконтроллера в CubeMX, вы можете легко включить промежуточное ПО FreeRTOS, установив флажок Enabled в соответствующем пункте в представлении IP Tree, как показано на рисунке 7.

Рисунок 7: Как включить промежуточное ПО FreeRTOS в CubeMX

После генерации проекта CubeMX вы можете следовать тем же инструкциям, что были в Главе 4.

В представлении Configuration можно установить параметры конфигурации FreeRTOS. Мы проанализируем наиболее важные из них в этой главе. Когда вы генерируете проект CubeMX, CubeMX спросит вас, хотите ли вы выбрать отдельный генератор временного отсчета для HAL, оставив SysTick только в качестве генератора временного отсчета для ОСРВ (см. рисунок 8). CubeMX спрашивает об этом, потому что FreeRTOS спроектирован так, что он автоматически устанавливает приоритет IRQ таймера SysTick на самый низкий (самый высокий номер приоритета). Это архитектурное требование FreeRTOS, которое, к несчастью, противоречит тому, как спроектирован HAL.

Рисунок 8: Сообщение предлагает выбрать другой генератор временного отсчета для HAL

Как уже было несколько раз сказано ранее, HAL STM32Cube построен на основе уникального источника временного отсчета, которым обычно является таймер SysTick. ISR SysTick_Handler() автоматически инкрементирует глобальный счетчик тиков каждые 1 мс. HAL пользуется этим свойством, очень часто используя функцию HAL_Delay() в нескольких процедурах HAL. Они, в свою очередь, вызываются функциями HAL_<PPP>_IRQHandler(), которые выполняются в контексте ISR (например, HAL_TIM_IRQHandler() вызывается из ISR таймера). Если IRQ таймера SysTick не сконфигурирован на выполнение с самым высоким приоритетом прерывания (который равен 0 в процессорах на базе Cortex-M), то вызов HAL_Delay() из контекста ISR может привести