Перевод может содержать ошибки. Читайте первоисточник: FreeRTOS Queue Set API Functions - xQueueCreateSet()
Назад: [FreeRTOS Home] | Вверх: [ИПП: Наборы очередей] | Вперёд: [xQueueAddToSet()] |
Функция объявляется в файле queue.h
QueueSetHandle_t xQueueCreateSet
(
const UBaseType_t uxEventQueueLength
);
Настройка configUSE_QUEUE_SETS в файле FreeRTOSConfig.h должна быть установлена в 1 для включения в код функций работы с наборами очередей.
Наборы очередей предоставляют механизм, позволяющий задачам РТОС блокироваться на чтении из нескольких очередей и семафоров РТОС одновременно. Заметьте, что есть более простая альтернатива использованию набора очередей (см. примечания).
Набор очередей должен быть явно создан с помощью вызова xQueueCreateSet(), прежде чем его можно будет использовать. После создания к набору можно добавлять стандартные очереди РТОС и семафоры с помощью вызова xQueueAddToSet(). После этого вызов xQueueSelectFromSet() может быть использован для определения того, какая из очередей или семафоров, содержащихся в наборе, находится в состоянии, в котором операция чтения из очереди или получения семафора, была бы успешной.
Примечания:
Параметры
uxEventQueueLength | Наборы очередей хранят события, происходящие в очередях и семафорах, входящих в набор. Параметр uxEventQueueLength определяет максимально возможное количество событий, которые могут быть поставлены в очередь одновременно.
Чтобы быть абсолютно уверенным, что события не потеряны, uxEventQueueLength должен быть задан как сумма длин очередей и семафоров, добавленных в набор. При этом длина двоичных семафоров и мьютексов принимается равной 1, а длина счетных семафоров имеет длину, заданную максимальным значением их счётчика. Например:
|
Возвращаемое значение
Если набор очередей успешно создан, возвращается указатель на хэндлер созданного набора. В противном случае возвращается NULL.
Пример использования:
/*----------------------------------------------------------------------------*/
/* Определяем длины очередей, которые будут добавлены к набору очередей. */
#define QUEUE_LENGTH_1 10
#define QUEUE_LENGTH_2 10
/* Двоичные семафоры имеют эффективную длину 1. */
#define BINARY_SEMAPHORE_LENGTH 1
/* Определяем размер элементов очередей 1 и 2 соответственно. Эти значения
используются в демонстрационных целях. */
#define ITEM_SIZE_QUEUE_1 sizeof( uint32_t )
#define ITEM_SIZE_QUEUE_2 sizeof( something_else_t )
/* Итоговая длина двух очередей и двоичного семафора, которые будут добавлены
к набору очередей. */
#define COMBINED_LENGTH ( QUEUE_LENGTH_1 +
QUEUE_LENGTH_2 +
BINARY_SEMAPHORE_LENGTH )
void vAFunction( void )
{
static QueueSetHandle_t xQueueSet;
QueueHandle_t xQueue1, xQueue2, xSemaphore;
QueueSetMemberHandle_t xActivatedMember;
uint32_t xReceivedFromQueue1;
something_else_t xReceivedFromQueue2;
/* Создаём набор очередей с длиной, достаточной для размещения событий
по всему объёму всех очередей и семафоров, добавляемыми в набор. */
xQueueSet = xQueueCreateSet( COMBINED_LENGTH );
/* Создаём очереди, которые будут добавлены в набор очередей. */
xQueue1 = xQueueCreate( QUEUE_LENGTH_1, ITEM_SIZE_QUEUE_1 );
xQueue2 = xQueueCreate( QUEUE_LENGTH_2, ITEM_SIZE_QUEUE_2 );
/* Создаём семафор, который будет добавлен в набор очередей. */
xSemaphore = xSemaphoreCreateBinary();
/* Проверяем создание всех объектов. */
configASSERT( xQueueSet );
configASSERT( xQueue1 );
configASSERT( xQueue2 );
configASSERT( xSemaphore );
/* Добавляем очереди и семафоры к набору очередей. В этот момент
очереде должны быть пусты, а семафор не выдан. После добавления
чтение из этих очередей и получение семафоров могут выполняться
только после того, как xQueueSelectFromSet() вернёт указатель на
очередь или семафор. */
xQueueAddToSet( xQueue1, xQueueSet );
xQueueAddToSet( xQueue2, xQueueSet );
xQueueAddToSet( xSemaphore, xQueueSet );
for( ;; )
{
/* Блокировка для ожидания доступности чего-либо из очередей
или семафоров, добавленных в набор. Блокировка не более чем
на 200мс. */
xActivatedMember = xQueueSelectFromSet( xQueueSet,
200 / portTICK_PERIOD_MS );
/* Проверяем, какой элемент набора был выбран. Можно указывать
нулевое время блокировки, т.к. xQueueSelectFromSet() не вернул бы
соответствующий дескриптор, если бы в объекте отсутствовали
доступные элементы. */
if( xActivatedMember == xQueue1 )
{
xQueueReceive( xActivatedMember, &xReceivedFromQueue1, 0 );
vProcessValueFromQueue1( xReceivedFromQueue1 );
}
else if( xActivatedMember == xQueue2 )
{
xQueueReceive( xActivatedMember, &xReceivedFromQueue2, 0 );
vProcessValueFromQueue2( &xReceivedFromQueue2 );
}
else if( xActivatedMember == xSemaphore )
{
/* Забираем семафор, чтобы убедиться, что он может быть снова выдан. */
xSemaphoreTake( xActivatedMember, 0 );
vProcessEventNotifiedBySemaphore();
break;
}
else
{
/* Истекло время блокировки (200мс), и за это время не появилось
одной очереди или семафора, готовых к обработке. */
}
}
}
/*----------------------------------------------------------------------------*/