Приоритеты задач

Планировщик задач, опираясь на приоритет, определяет, какая задача должна быть запущена раньше других. Данное свойство — не что иное, как число от 0 до configMAX_PRIORITIES (определена в FreeRTOSConfig.h), причем приоритет 0 строго зарезервирован под idle-задачу. Чем больше число, тем выше приоритет. То, как ведут себя задачи с одинаковым приоритетом при разной настройке системы, мы рассматривали выше. Отметим лишь, что за временное разделение отвечает параметр configTICK_RATE_HZ в файле FreeRTOSConfig.h.

В FreeRTOS нет механизмов, предотвращающих ситуации, когда одна задача оккупирует все процессорное время; это задача программиста.

Приоритет задается при создании задачи и может быть изменен во время ее выполнения через функции vTaskPriorityGet() и vTaskPrioritySet().

CMSIS-RTOS определяет приоритеты по-другому.

typedef enum {
    osPriorityIdle          = -3,          ///< priority: idle (lowest)
    osPriorityLow           = -2,          ///< priority: low
    osPriorityBelowNormal   = -1,          ///< priority: below normal
    osPriorityNormal        =  0,          ///< priority: normal (default)
    osPriorityAboveNormal   = +1,          ///< priority: above normal
    osPriorityHigh          = +2,          ///< priority: high
    osPriorityRealtime      = +3,          ///< priority: realtime (highest)
    osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
} osPriority;

Планировщик задач

Для хранения параметров задачи, таких как ее приоритет, идентификатор, указатель на стек, его вершину или название (нужно исключительно для отладки), FreeRTOS использует структуру tskTCB (сокр. с англ. Task Control Block). Планировщик создает из таких структур двусвязные списки xList (из файла list.c) для контроля за состоянием задач. Каждому состоянию соответствует собственный список, который поддерживается в отсортированном видеlinked_list. Изменение состояния осуществляется простым переносом задачи из одного списка в другой.[linked_list]  Структура данных «двухсвязный список» используется не случайно — так как список поддерживается в отсортированном виде, требуется переписать пару указателей при добавлении или удалении задачи из списка.

static xList pxReadyTasksLists[ configMAX_PRIORITIES ];

Здесь pxReadyTasksLists[0] содержит все задачи с приоритетом 0, pxReadyTasksLists[1] — с приоритетом 1 и так далее вплоть до pxReadyTasksLists[configMAX_PRIORITIES-1]. Как только наступает системный тик (или задача возвращает управление), вызывается функция vTaskSwitchContext(). Ее миссия — просмотреть все списки задач, перенести заблокированные задачи в состояние готовности, если их пора выполнить, а затем выбрать наиболее приоритетную задачу и сменить контекст. Для того чтобы всё это работало, планировщик необходимо запустить через функцию vTaskStartScheduler() (osKernelStart()).


Изменено: