Перевод может содержать ошибки. Читайте первоисточник: xQueueReceiveFromISR()
| Назад: [xQueueReceive] | Вверх: [ИПП: Очереди] | Вперёд: [uxQueueMessagesWaiting] |
Функция объявляется в файле queue.h
BaseType_t xQueueReceiveFromISR
(
QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxHigherPriorityTaskWoken
);
Функция принимает элемент из очереди. Элемент забирается копированием (НЕ по указателю), поэтому необходимо предоставить буфер достаточного размера. Количество копируемых байт зависит от размера элемента очереди. А размер элемента определяется при создании очереди.
Данная функция предназначена для вызова из обработчиков прерываний. Если необходимо принять элемент из очереди, не находясь в обработчике прерывания, следует использовать xQueueReceive().
Параметры
| xQueue | Хэндлер очереди, из которой необходимо принять элемент. |
| pvBuffer | Указатель на буфер, в который будут скопированы данные из области хранения очереди. При этом количество байт, скопированное из области хранения очереди в буфер, определяется размером элемента очереди. А собственно размер элемента указывается при создании очереди. |
| pxHigherPriorityTaskWoken | Если есть некая задача, заблокированная на ожидании места в очереди xQueue, и приоритет этой задачи выше приоритета текущей запущенной задачи, вызов xQueueReceiveFromISR() может привести к разблокировке этой более высокоприоритетной задачи. В этом случае после возврата из xQueueReceiveFromISR() значение переменной *pxHigherPriorityTaskWoken будет установлено в pdTRUE. В противном случае переменная *pxHigherPriorityTaskWoken будет оставлена без изменений. И если переменная *pxHigherPriorityTaskWoken была установлена в pdTRUE, необходимо запросить переключение контекста ДО выхода из прерывания. Начиная с версии FreeRTOS V7.3.0 pxHigherPriorityTaskWoken является необязательным параметром, и может быть установлен в NULL |
Возвращаемое значение
pdTRUE если элемент был получен из очереди. Иначе возвращается pdFALSE .
Пример использования:
QueueHandle_t xQueue;
/* Функция, в которой создаётся очередь, а затем в неё помещаются некоторые переменные. */
void vAFunction( void *pvParameters )
{
char cValueToPost;
const TickType_t xTicksToWait = (TickType_t)0xff;
/* Создаём очередь, которая может содержать до 10 элементов типа char. */
xQueue = xQueueCreate( 10, sizeof( char ) );
if( xQueue == 0 )
{
/* Ошибка при попытке создания очереди. */
}
/* ... */
/* Отправляем в очередь несколько элементов, которые должны быть использованы
внутри обработчика прерывания. Если очередь уже заполнена, задача будет
заблокирована, но не более, чем на xTicksToWait тиков ядра ОС. */
cValueToPost = 'a';
xQueueSend( xQueue, (void*) &cValueToPost, xTicksToWait );
cValueToPost = 'b';
xQueueSend( xQueue, (void*) &cValueToPost, xTicksToWait );
/* ... Продолжаем отправлять символы в очередь ... эта задача
может быть залокирована, если очередь окажется заполненной. */
cValueToPost = 'c';
xQueueSend( xQueue, (void*) &cValueToPost, xTicksToWait );
}
/* Обработчик прерывания, который получает из очереди все содержащиеся в ней
элементы типа char и выводит их при помощи вызова vOutputCharacter(). */
void vISR_Routine( void )
{
BaseType_t xTaskWokenByReceive = pdFALSE;
char cRxedChar;
while( xQueueReceiveFromISR( xQueue,
(void*) &cRxedChar,
&xTaskWokenByReceive) )
{
/* Элемент был получен из очереди. Выводим его. */
vOutputCharacter( cRxedChar );
/* Если удаление элемента из очереди привело к возобновлению задачи,
отправляющей данные в очередь, переменная xTaskWokenByReceive
будет установлена в pdTRUE. При этом независимо от того, сколько
итераций цикла было выполнено, будет возобновлена только одна задача. */
}
if( xTaskWokenByReceive != pdFALSE )
{
/* Здесь необходимо принудительно переключить контекст для того,
чтобы возврат из обработчика прерываний осуществился сразу
в возобновлённую задачу.
Примечание: как это реализуется зависит от конкретной реализации
порта ОС для используемого типа процессора. Подробности должны быть
описаны в документации на порт для вашего процессора. */
taskYIELD ();
}
}