FreeRTOS: xTaskNotify / xTaskNotifyIndexed |
![]() |
Добавил(а) microsin | ||||||||||||
Если вы используете оповещения задач (RTOS task notifications) [2] для реализации поведения двоичного семафора или семафора со счетчиком, то используйте более простую API-функцию xTaskNotifyGive() вместо xTaskNotify(). BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction); BaseType_t xTaskNotifyIndexed(TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction); Значение оповещения (notification value). У каждой задачи есть массив 'оповещений задачи' (или просто 'оповещений'), в каждом таком оповещении хранится состояние и 32-битное значение. Направление задаче оповещения это событие, отправляемое в задачу напрямую, которое может разблокировать эту принимающую задачу, и опционально обновить одно из значений оповещения принимающей задачи, что можно сделать различными способами. Напртимер, оповещение может перезаписать одно из значений оповещений задачи, или просто установить один или большее количество бит в одном из значений оповешения задачи. Функция xTaskNotify() используется для отправки события напрямую, и потенциально может разблокировать задачу RTOS, и опционально обновить одно из значений оповещения задачи одним из следующих способов: · Запись 32-битного числа в значение оповещения. Функции xTaskNotify() и xTaskNotifyIndexed() эквивалентны - единственное их отличие в том, что xTaskNotifyIndexed() может работать с любым из значений оповещения массива (по указанному индексу), а xTaskNotify() всегда работает со значением оповещения в массиве по индексу 0. Функция xTaskNotify() не должна использоваться для вызова из обработчика прерывания (interrupt service routine, ISR). Для этого предназначена специальная функция xTaskNotifyFromISR(). Чтобы эти функции были доступны, опция конфигурации configUSE_TASK_NOTIFICATIONS (в файле FreeRTOSConfig.h) должна быть установлена 1 (или должна оставаться не определенной). Константа configTASK_NOTIFICATION_ARRAY_ENTRIES установит количество элементов (индексов) в массиве значений оповещения каждой задачи. Информация для обратной совместимости: до появления версии FreeRTOS V10.4.0 у каждой задачи было только одно "notification value", и все API-функции работали с этим значением. Замена одного значения оповещения на массив потребовало нового набора API-функций, которые могли бы адресовать определенные оповещения в этом массиве. Функция xTaskNotify() это оригинальная API-функция, которая была оставлена для обеспечения обратной совместимости по исходному коду, и она работает со значением оповещения по индексу 0 в массиве. Таким образом, вызов xTaskNotify() эквивалентен вызову xTaskNotifyIndexed() с параметром uxIndexToNotify, установленным в 0. Параметры: xTaskToNotify Дескриптор (handle) задачи RTOS, которой придет оповещение (это целевая задача, target task). Чтобы получить дескриптор задачи, создайте её вызовом xTaskCreate() и используйте параметр pxCreatedTask, или создайте задачу вызовом xTaskCreateStatic(), и тогда используйте возвращенное из неё значение, или используйте для получения дескриптора результат вызова функции xTaskGetHandle(), в которую передайте имя задачи. Дескриптор текущей выполняющейся задачи можно получить вызовом функции xTaskGetCurrentTaskHandle(). uxIndexToNotify Индекс в массиве оповещений целевой задачи, куда отправляется оповещение. Значение uxIndexToNotify должно быть меньше configTASK_NOTIFICATION_ARRAY_ENTRIES. У функции xTaskNotify() нет этого параметра, и она всегда посылает оповещения в массив по индексу 0. ulValue Используется для обновления значения оповещения целевой задачи. См. ниже описание параметра eAction. eAction Перечисляемый тип, который может принимать одно из значений, перечисленных в таблице ниже, чтобы выполнить определенное действие над значением оповещения.
Возвращаемое значение: pdPASS будет возвращено во всех случаях, кроме случая, когда eAction установлено в eSetValueWithoutOverwrite, значение оповещения целевой задачи не может быть обновлено из-за того, что эта задача еще не успела обработать свое предуыдущее оповещение. /* Установка бита 8 в 0-ом значении оповещения задачи, на которую производится
ссылка по дескриптору xTask1Handle. */ xTaskNotifyIndexed(xTask1Handle, 0, (1UL << 8UL), eSetBits); /* Отправка оповещения задаче с дескриптором xTask2Handle, что потенциально
выведет задачу из состояния Blocked, но без обновления значения оповещения. */ xTaskNotify(xTask2Handle, 0, eNoAction); /* Установка в 0x50 значения оповещения задачи с дескриптором xTask3Handle,
даже если задача еще не успела прочитать предыдущее значение оповещения. */ xTaskNotify( xTask3Handle, 0x50, eSetValueWithOverwrite ); /* Установка в 0xfff значения оповещения задачи с дескриптором xTask4Handle,
но только если оно не перезапишет предыдущее значение оповещения задачи,
которое целевая задача должна была бы перед этим получить (вызовом
xTaskNotifyWait() или ulTaskNotifyTake()). */
if(xTaskNotify(xTask4Handle, 0xfff, eSetValueWithoutOverwrite) == pdPASS) { /* Значение оповещения целевой задачи было обновлено. */ ... } else { /* Значение оповещения целевой задачи не было обновлено. */ ... } [Ссылки] 1. xTaskNotify / xTaskNotifyIndexed site:freertos.org. |