Программный таймер FreeRTOS (или просто "таймер") позволяет автоматически выполнить функцию (callback таймера) в некоторый установленный момент в будущем. Время между моментом запуска таймера (вызов xTimerStart) и вызовом callback-функции таймера называется периодом таймера. По-простому, callback-функция таймера выполнится, когда истечет период таймера. Обратите внимание, что программный таймер перед использованием должен быть явным образом создан (вызовом xTimerCreate или xTimerCreateStatic).
Программные таймеры предназначены для реализации простых повторяющихся действий, либо для отслеживания интервалов времени, например таймаута операции.
Опции и конфигурационные константы FreeRTOS (макроопределения с префиксом config), упомянутые в этом описании, определены в заголовочном файле FreeRTOSConfig.h. Для того, чтобы API-функции таймеров были доступны, должна быть установлена в 1 опция конфигурации configUSE_TIMERS. Функционал программного таймера обеспечивает задача демона (служба) таймеров. Многие API-функции таймеров FreeRTOS посылают команды этой службе через очередь команд таймеров. Эта очередь приватна для ядра RTOS, и она недоступна напрямую для кода приложения. Длина очереди команд таймеров устанавливается конфигурационной константой configTIMER_QUEUE_LENGTH.
Что следует учитывать при внедрении программных таймеров. Функционал программного таймера легко использовать, но трудно сделать это эффективно. Реализация программного таймера во FreeRTOS не выполняет callback-функции в контексте прерывания и не потребляет процессорное время до момента истечения периода программного таймера, не добавляет лишней обработки в прерывание тика, и не прокручивает никакие структуры связанного списка когда прерывания запрещены.
Задача службы программных таймеров (главным образом) использует существующий функционал FreeRTOS, позволяя добавлять функционал таймера в приложение с минимальным влиянием на размер исполняемого кода приложения.
Важная информация для написания callback-функций таймера. Функции обратного вызова всех запущенных таймеров выполняются в одном контексте задачи службы таймера (timer service task). Поэтому важно понимать, что код callback-функций таймера не должен делать никаких блокировок. Например, callback-функция не должна вызывать vTaskDelay(), vTaskDelayUntil() или указывать ненулевое время блокировки при обращении к очереди или семафору.
[API-функции программных таймеров]
API-функции и типы программных таймеров определены в заголовочном файле timers.h. Здесь приведен краткий справочник по программным таймерам, полное описание и примеры использования см. в оригинале [1].
Функция |
Описание |
xTimerGetTimerDaemonTaskHandle |
Возвратит дескриптор задачи, связанный с демоном программных таймеров (сервисом). Если установлена в 1 опция configUSE_TIMERS, то задача демона таймеров создается автоматически, когда запускается планировщик RTOS. |
pcTimerGetName |
Возвратит понятное имя таймера, которое было присвоено в момент создания таймера. Имя возвращается в виде стандартной ASCIIZ-строки. |
xTimerCreate |
Создает экземпляр нового программного таймера, и возвратит дескриптор, по которому к этому таймеру можно обращаться с помощью API-вызовов. |
xTimerCreateStatic |
То же самое, что и xTimerCreate, отличие только в том, что память для служебных данных таймера выделяется и предоставляется пользователем, а не выделяется из RTOS. |
xTimerIsTimerActive |
Опрашивает состояние таймера, и возвратит информацию о том, активен ли таймер, или он бездействует. Таймер считается бездействующим, если он создан, но не запущен, либо если это однократный таймер, у которого истек таймаут. |
vTimerSetTimerID |
Установит идентификатор таймера. Идентификатор предназначен для случая, когда к нескольким таймерам присвоена одна и та же callback-функция, чтобы можно было определить, какому таймеру соответствует обратный вызов. Также через идентификатор можно сохранять данные в таймер, чтобы передавать их между вызовами callback-функции таймера. |
pvTimerGetTimerID |
Возвратит идентификатор, присвоенный таймеру при его создании, либо при вызове функции vTimerSetTimerID. |
vTimerSetReloadMode |
Обновит режим работы таймера. Режим определяет, будет ли таймер автоматически перезапускаемым или однократным. |
xTimerStart |
Запуск программного таймера. |
xTimerStartFromISR |
То же самое, что и xTimerStart, но этот вариант функции предназначен для вызова из тела обработчика прерывания (ISR). |
xTimerStop |
Остановит таймер, который был ранее запущен командой xTimerStart. |
xTimerStopFromISR |
То же самое, что и xTimerStop, но этот вариант функции предназначен для вызова из тела обработчика прерывания (ISR). |
xTimerChangePeriod |
Изменит период времени таймера, который был ранее установлен при его создании функцией xTimerCreate (или xTimerCreateStatic). |
xTimerChangePeriodFromISR |
То же самое, что и xTimerChangePeriod, но этот вариант функции предназначен для вызова из тела обработчика прерывания (ISR). |
xTimerDelete |
Удалит таймер, который был ранее создан вызовом xTimerCreate (или xTimerCreateStatic). Обратите внимание, что когда удаляется таймер, память для которого была выделена статически пользователем (при использовании xTimerCreateStatic), эта память не может быть использована повторно, пока вызов функции xTimerIsTimerActive не покажет, что таймер находится в неактивном состоянии. |
xTimerReset |
Перезапустит таймер, который был ранее создан вызовом xTimerCreate (или xTimerCreateStatic). Если таймер уже запущен и находится в активном состоянии, то xTimerReset приведет к тому, что отсчет времени таймером начнется заново. Если таймер бездействует, то вызов xTimerReset делает то же самое, что и xTimerStart. |
xTimerResetFromISR |
То же самое, что и xTimerReset, но этот вариант функции предназначен для вызова из тела обработчика прерывания (ISR). |
xTimerPendFunctionCall |
Используется для привязки выполнения функции к демону таймеров RTOS (сервисной задаче обслуживания таймеров). Чтобы xTimerPendFunctionCall была доступна, должны быть установлены в 1 обе опции INCLUDE_xTimerPendFunctionCall() и configUSE_TIMERS. |
xTimerPendFunctionCallFromISR |
То же самое, что и xTimerPendFunctionCall, но этот вариант функции предназначен для вызова из тела обработчика прерывания (ISR). |
xTimerGetPeriod |
Возвратит период программного таймера (в тиках RTOS). |
xTimerGetExpiryTime |
Возвратит абсолютное время в тиках, на котором истечет таймаут программного таймера, и когда будет вызвана его callback-функция. Если значение, которое возвратила xTimerGetExpiryTime, меньше чем текущее абсолютное время, то задержка таймера истечет после того, как счетчик тиков переполнится и вернется к 0. Переполнения тиков обрабатываются самой RTOS, поэтому callback-функция таймера все равно выполнится в правильное время, несмотря на переполнение счетчика тиков системы. |
[Ссылки]
1. FreeRTOS Software Timers site:freertos.org. 2. FreeRTOS xTimerCreate. |