You are here

xQueueOverwriteFromISR

Перевод может содержать ошибки. Читайте первоисточник: xQueueOverwriteFromISR()

Назад: [xQueueOverwrite] Вверх: [ИПП: Очереди] Вперёд: [xQueuePeek]

 

xQueueOverwriteFromISR()

Функция объявляется в файле queue.h

BaseType_t xQueueOverwriteFromISR
    (
        QueueHandle_t   xQueue,
        const void      *pvItemToQueue
        BaseType_t      *pxHigherPriorityTaskWoken
    );

Этот макрос вызвает функцию xQueueGenericSendFromISR(). Является версией макроса xQueueOverwrite(), но предназначен для вызова из обработчиков прерываний.

Макрос предназначен для использования с очередями, длина которых равна 1 (иначе сработает макрос configASSERT()), а это означает, что очередь либо пуста, либо заполнена. Элемент размещается копированием (НЕ по ссылке).

Макрос xQueueOverwriteFromISR() похож на xQueueSendToBackFromISR(), но записывает в очередь, даже если она заполнена. Если очередь была заполнена, то уже сохранённое в очереди значение будет заменено на новое.

Параметры

xQueue Хэндлер очереди, в которую необходимо поместить элемент.
pvItemToQueue Указатель на элемент, который будет помещён в очередь. При этом количество байт, копируемое из pvItemToQueue в область хранения очереди, определяется размером элемента очереди. А собственно размер элемента указывается при создании очереди.
pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task to unblock, and the unblocked task has a priority higher than the currently running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then a context switch should be requested before the interrupt is exited. Refer to the Interrupt Service Routines section of the documentation for the port being used to see how that is done. === Если есть некая задача, заблокированная на ожидании данных в очереди xQueue, и приоритет этой задачи выше приоритета текущей запущенной задачи, вызов  xQueueOverwriteFromISR() может привести к разблокировке этой более высокоприоритетной задачи. В этом случае после возврата из xQueueOverwriteFromISR() значение переменной *pxHigherPriorityTaskWoken будет установлено в pdTRUE. В противном случае переменная *pxHigherPriorityTaskWoken будет оставлена без изменений. И если переменная *pxHigherPriorityTaskWoken была установлена в pdTRUE, необходимо запросить переключение контекста ДО выхода из прерывания. Тогда возврат из прерывания будет выполнен сразу в разблокированную задачу. Для подробностей обратитесь к документации по порту для вашего процессора, раздел "обработчики прерываний". Начиная с версии FreeRTOS V7.3.0 pxHigherPriorityTaskWoken является необязательным параметром, и может быть установлен в NULL

Возвращаемое значение

xQueueOverwriteFromISR() это макрос, который вызвает xQueueGenericSendFromISR(), следовательно мог бы иметь те же  возвращаемые значения, что и, например, xQueueSendToFrontFromISR(). Однако pdPASS это единственно возможное возвращаемое значение, т.к. xQueueOverwriteFromISR() будет отправлять элемент в очередь, даже если она уже заполнена.

Пример использования:

QueueHandle_t xQueue;

void vFunction( void *pvParameters )
{
    /* Создаём очередь, содержащую один элемент типа unsigned long.
       Строго рекомендуется НЕ использовать вызов xQueueOverwriteFromISR()
       для очередей, которые могут содержать более одного элемента.
       Дело в том, что если длина больше единицы, сработает макрос
       configASSERT(), если таковой определён в пользовательском проекте. */
    xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
}

void vAnInterruptHandler( void )
{
    /* Перед использованием переменная xHigherPriorityTaskWoken должна быть
       установлена в pdFALSE. */
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    unsigned long ulVarToSend, ulValReceived;

    /* Отправляем в очередь значение 10, используя xQueueOverwriteFromISR(). */
    ulVarToSend = 10;
    xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );

    /* Очередь уже заполнена, но если снова вызвать xQueueOverwriteFromISR() с другим
       значением, то старое значение в очереди будет заменено на новое. */
    ulVarToSend = 100;
    xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );

    /* Если теперь получить элемент из очереди, его значение будет равно 100. */

    /* ... */

    if( xHigherPrioritytaskWoken == pdTRUE )
    {
        /* Отправка элемента в очередь вызвала разблокировку некоторой задачи,
           и разблокированная задача имеет приоритет выше или равный приоритету текущей
           выполняющейся задачи (которая была прервана этим прерыванием). Поэтому
           необходимо принудительно переключить контекст для того, чтобы
           возврат из прерываний был осуществлён сразу в разблокированную
           высокоприоритетную задачу. */
        /* Макрос, используемый здесь, зависит от конкретной реализации порта ОС. */
        portYIELD_FROM_ISR(); /* или portEND_SWITCHING_ISR(), в зависимости от порта ОС. */
    }
}
Hobby's category: