Программирование ARM FreeRTOS: xTaskNotifyWait / xTaskNotifyWaitIndexed Sat, May 18 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

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().
pdFALSE, если вызов 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.
2. FreeRTOS: оповещения задач.
3FreeRTOS: семафоры со счетчиком и оповещения задач.
4ESP-IDF FreeRTOS Task API.
5. FreeRTOS: указатели в TLS.

 

Добавить комментарий


Защитный код
Обновить

Top of Page