FreeRTOS: xTaskNotifyWait / xTaskNotifyWaitIndexed |
![]() |
Добавил(а) microsin |
Замечание: если вы используете оповещения задач (RTOS task notifications) для реализации поведения двоичного семафора или семафора со счетчиком, то используйте более простую API-функцию ulTaskNotifyTake() вместо xTaskNotifyWait(). Заголовочный файл: task.h. BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); У каждой задачи есть массив оповещений, 'task notifications' (или просто 'оповещения'), каждое из оповещений имеет состояние и 32-битное значение. Уведомление об оповещении задачи это событие, отправляемое непосредственно принимающей событие задаче, чтобы разблокировать её, и опционально обновить одно из значений оповещения принимающей событие задачи несколькими разными способами. Например, оповещение может перезаписать одно из значений оповещения принимающей задачи, или просто установить один или большее количество бит в одном из значений оповещения принимающей задачи. Функция xTaskNotifyWait() ждет в вызывающей задаче, в течение опционального таймаута, поступления оповещения. Если принимающая задача RTOS была уже в состоянии Blocked, ожидая поступления оповещения, то принимающая задача будет удалена из состояния Blocked, и оповещение очищается. Замечание: каждое оповещение в массиве работает независимо – задача может быть заблокирована одновременно только на одном оповещении в массиве, и не будет разблокирована оповещением, отправленным по другому индексу в массиве. xTaskNotifyWait() и xTaskNotifyWaitIndexed() это эквивалентные макросы - единственное их отличие в том, что xTaskNotifyWaitIndexed() может работать на любом оповещении в массиве, а xTaskNotifyWait() всегда работает с оповещением в массиве по индексу 0. xTaskNotifyGive() не должна вызываться из обработчика прерывания для этого предназначена специальная версия функции выдачи оповещения vTaskNotifyGiveFromISR(). Константа конфигурации времени компиляции configUSE_TASK_NOTIFICATIONS в файле FreeRTOSConfig.h должна быть установлена в 1 (или просто не должна быть определена), чтобы эти макросы были доступны. Константа configTASK_NOTIFICATION_ARRAY_ENTRIES установит количество индексов в каждом массиве оповещений задачи. Информация для обратной совместимости: до версии FreeRTOS V10.4.0 каждая задача имела единственное "notification value", и все API-функции оповещений задачи работали только с этим одним значением. Замена одиночного значения оповещения массивом потребовала нового набора API-функций, которые могли бы адресовать оповещения в массиве. xTaskNotifyWait() это оригинальная API-функция, и она оставляет возможность обратной совместимости, работая со значением оповещения в массиве по индексу 0. Вызов xTaskNotifyWait() эквивалентен вызову xTaskNotifyWaitIndexed() с установленным в 0 параметром uxIndexToWaitOn. Параметры: uxIndexToWaitOn Индекс в массиве значений уведомлений вызывающей задачи, по которому вызывающая задача ожидает получения уведомления. Значение uxIndexToWaitOn должно быть меньше значения опции конфигурации configTASK_NOTIFICATION_ARRAY_ENTRIES. У xTaskNotifyWait() нет этого параметра, и она всегда ждет поступления оповещения на значении с индексом 0. ulBitsToClearOnEntry Любой набор бит, установленный в ulBitsToClearOnEntry, будет очищен в значении оповещения вызывающей функции (перед тем, как задача начнет ждать нового оповещения) при входе в xTaskNotifyWait(), при условии, что уведомление еще не ожидает при условии, что уведомление еще не ожидает вызова xTaskNotifyWait(). Например, если ulBitsToClearOnEntry 0x01, то бит 0 в значении оповещения задачи будет очищен при входе в функцию. Установка ulBitsToClearOnEntry в 0xffffffff (ULONG_MAX) очистит все биты значения оповещения, что дает эффект обнуления значения оповещения. ulBitsToClearOnExit Любой набор бит, установленный в ulBitsToClearOnExit, будет очищен в значении оповещения вызывающей задачи перед выходом из функции xTaskNotifyWait(), если оповещение было получено. Биты очищаются после того, как значение оповещения было сохранено в *pulNotificationValue (см. далее описание параметра pulNotificationValue). Например, если ulBitsToClearOnExit 0x03, то бит 0 и бит 1 значения оповещения будут очищены перед выходом из функции. Установка ulBitsToClearOnExit в 0xffffffff (ULONG_MAX) очистит все биты значения оповещения, что дает эффект обнуления значения оповещения. pulNotificationValue Используется для передачи наружу значения оповещения задачи. Значение, скопированное в * pulNotifityValue, является значением уведомления задачи RTOS, как и до того, как какие-либо биты были очищены из-за настройки ulBitsToClearOnExit. Если значение оповещения не используется, то установите pulNotificationValue в NULL. xTicksToWait Максимальное время ожидания, в течение которого вызывающая задача находится в состоянии Blocked, ожидая получения оповещения, если если уведомление еще не ожидается при вызове xTaskNotifyWait(). Задача RTOS не потребляет никакое время CPU, когда находится в состоянии Blocked. Время ожидания указывается в тиках RTOS. Может использоваться макрос pdMS_TO_TICKS() для преобразования в тики указанного времени в миллисекундах. Возвращаемое значение: pdTRUE, если оповещение было получено, или если уже ожидается вызов оповещения от вызова xTaskNotifyWait(). /* Эта задача показывает биты в значении оповещения задачи RTOS, которое используется
для передачи различных событий задаче таким же способом, как для той же цели могут
использоваться флаги группы событий (event group flags). */
void vAnEventProcessingTask( void *pvParameters ) { uint32_t ulNotifiedValue; for( ;; ) { /* Бесконечная блокировка (без таймаута, так что не нужно проверять значение возврата из функции) в ожидании оповещения.
Биты в этом значении оповещения устанавливаются оповещающими задачами
и обработчиками прерывания, чтобы оповестить задачу о возникновении
событий. */ xTaskNotifyWaitIndexed( 0, /* Ожидание на 0-ом значении оповещения. */ 0x00, /* Не очищать никакие биты на входе. */ ULONG_MAX, /* Сбрасывать значение оповещения на 0 при выходе. */ &ulNotifiedValue, /* Значение оповещения передается наружу в ulNotifiedValue. */ portMAX_DELAY ); /* Ожидать бесконечно. */ /* Обработка любых событий, которые были защелкнуты в значении оповещения. */ if( ( ulNotifiedValue & 0x01 ) != 0 ) { /* Был установлен бит 0 - обработать все, что соответствует биту 0. */ prvProcessBit0Event(); } if( ( ulNotifiedValue & 0x02 ) != 0 ) { /* Был установлен бит 1 - обработать все, что соответствует биту 1. */ prvProcessBit1Event(); } if( ( ulNotifiedValue & 0x04 ) != 0 ) { /* Был установлен бит 2 - обработать все, что соответствует биту 2. */ prvProcessBit2Event(); } /* И так далее. */
...
}
}
Другие примеры можно посмотреть на страничке с описанием оповещений задач [2]. [Ссылки] 1. xTaskNotifyWait / xTaskNotifyWaitIndexed site:freertos.org. |