Задачи в операционной системе FreeRTOS
Все задачи, выполняемые FreeRTOS, строятся по достаточно простому шаблону: как функция на языке С, которой в качестве аргументов можно передать указатель (адрес)
void vUserTask(void *pvParam)
{
//- объявление/определение, инициализация переменных
//- однократно выполняемый код
...
for(;;)
{
//- код выполняемой задачи
...
}
vTaskDelete(NULL);
}
Большинство задач проектируется так, что они не могут никогда закончиться и функционируют всё время работы микроконтроллера. Задачи могут быть заблокированы или остановлены, но нет особых причин удалять задачу, чтобы через некоторое время пытаться снова её создать и запустить. Связано это прежде всего с памятью: с распределением памяти при создании задачи, освобождением памяти и "уборкой мусора" при завершении задачи. Освобождаемая память должна очищаться, дефрагментироваться и учитываться операционной системой для последующего выделения без потерь. Это достаточно сложный алгоритм, к тому же требущий определённой вычислительной мощности от ядра микроконтроллера.
Для переключения между задачами можно (как один из вариантов):
- разбить всё время работы микроконтроллера на некоторые равные промежутки времени - кванты
- выделять каждой задаче для работы свой квант времени
- по истечении выделенного кванта времени передать выполнение следующей в очереди задаче
Для реализации такого механизма разумно:
- выделить один из таймеров микроконтроллера для отсчета квантов времени (системный таймер)
- разбить все задачи по важности на группы и раздать им приоритеты
- разбить задачи по статусу для оптимального управления: помещаемые в очередь, не помещаемые в очередь (заблокированные) в течении какого-то определённого времени, остановленные и не учитываемые системой до особого разрешения.
- каждый раз при срабатывании системного таймера (системный тик, или просто - тик) вызывать обработчик прерывания: планировщик задач (shediler)
- в планировщике реализовать механизм очерёдности выполнения задач исходя из их приоритетов
- потребовать от задач, заканчивающих работу раньше окончания выделенного кванта, возвращать неиспользованное время планировщику для вызова других задач из очереди.
Планировщик является основой операционной системы и реализует алгоритм работы с задачами, заложенный в операционную систему.
Планировщик должен:
- знать какие вообще задачи существуют в операционной системе
- знать приоритет каждой задачи и её статус и формировать очередь на выполнение
- запускать задачи в порядке очереди.
Для этого планировщик может воспользоваться любым таймером микроконтроллера. Таймер подойдёт любой, т.к. нужна только базовая возможность: формирование прерываний через определённые промежутки времени. В созданом прерывании от таймера планировщик выгружает работающую задачу и запускает на выполнение задачу, стоящую первой в очереди.