(1)使用队列的流程:创建队列、写队列、读队列、删除队列。
队列的创建有两种方法:动态分配内存、静态分配内存。
(1)函数:xQueueCreate,队列的内存再函数内部动态分配。
(2)函数原型如下:
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
(3)参数说明
参数 | 说明 |
uxQueueLength | 队列长度,最多能存放多少个数据(item) |
uxItemSize | 每个数据(item)的大小:以字节为单位 |
返回值 | 非0:成功,返回句柄,以后使用句柄来操作队列 NULL:失败,因为内存不足 |
(1)函数:xQueueCreateStatic,队列的内存要事先分配好。
(2)函数原型如下:
QueueHandle_t xQueueCreateStatic(
UBaseType_t uxQueueLength,
UBaseType_t uxItemSize,
uint8_t *pucQueueStorageBuffer,
StaticQueue_t *pxQueueBuffer
);
(3)参数说明
参数 | 说明 |
uxQueueLength | 队列长度,最多能存放多少个数据(item) |
uxItemSize | 每个数据(item)的大小:以字节为单位 |
pucQueueStorageBuffer | 如果uxItemSize非0,pucQueueStorageBuffer必须指向一个 uint8_t数组,此数组大小至少为"uxQueueLength * uxItemSize" |
pxQueueBuffer | 必须执行一个StaticQueue_t结构体,用来保存队列的数据结构 |
返回值 | 非0:成功,返回句柄,以后使用句柄来操作队列 NULL:失败,因为pxQueueBuffer为NULL |
(4)示例代码
// 示例代码
#define QUEUE_LENGTH 10
#define ITEM_SIZE sizeof( uint32_t )
// xQueueBuffer用来保存队列结构体
StaticQueue_t xQueueBuffer;
// ucQueueStorage 用来保存队列的数据
// 大小为:队列长度 * 数据大小
uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
void vATask( void *pvParameters )
{
QueueHandle_t xQueue1;
// 创建队列: 可以容纳QUEUE_LENGTH个数据,每个数据大小是ITEM_SIZE
xQueue1 = xQueueCreateStatic( QUEUE_LENGTH,
ITEM_SIZE,
ucQueueStorage,
&xQueueBuffer );
}
(1)队列刚被创建时,里面没有数据;使用过程中可以调用 xQueueReset() 把队列恢复为初始状态。
(2)函数原型:
/* pxQueue: 复位哪个队列;
* 返回值: pdPASS(必定成功)
*/
BaseType_t xQueueReset( QueueHandle_t pxQueue);
(1)删除队列的函数为 vQueueDelete() ,只能删除使用动态方法创建的队列,它会释放内存。
(2)函数原型:
void vQueueDelete( QueueHandle_t xQueue );
(1)可以把数据写到队列头部,也可以写到尾部,这些函数有两个版本:在任务中使用、在ISR中使用。
(2)函数原型:
/* 等同于xQueueSendToBack
* 往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait
*/
BaseType_t xQueueSend(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);
/*
* 往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait
*/
BaseType_t xQueueSendToBack(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);
/*
* 往队列尾部写入数据,此函数可以在中断函数中使用,不可阻塞
*/
BaseType_t xQueueSendToBackFromISR(
QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
/*
* 往队列头部写入数据,如果没有空间,阻塞时间为xTicksToWait
*/
BaseType_t xQueueSendToFront(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);
/*
* 往队列头部写入数据,此函数可以在中断函数中使用,不可阻塞
*/
BaseType_t xQueueSendToFrontFromISR(
QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
(3)参数说明
参数 | 说明 |
xQueue | 队列句柄,要写哪个队列 |
pvItemToQueue | 数据指针,这个数据的值会被复制进队列, 复制多大的数据?在创建队列时已经指定了数据大小 |
xTicksToWait | 如果队列满则无法写入新数据,可以让任务进入阻塞状态, xTicksToWait表示阻塞的最大时间(Tick Count)。 如果被设为0,无法写入数据时函数会立刻返回; 如果被设为portMAX_DELAY,则会一直阻塞直到有空间可写。 |
返回值 | pdPASS:数据成功写入了队列 errQUEUE_FULL:写入失败,因为队列满了。 |
(1)使用 xQueueReceive() 函数读队列,读到一个数据后,队列中该数据会被移除。这个函数有两个版本:在任务中使用、在ISR中使用。
(2)函数原型:
BaseType_t xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait );
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxTaskWoken );
(3)参数说明
参数 | 说明 |
xQueue | 队列句柄,要读哪个队列 |
pvBuffer | bufer指针,队列的数据会被复制到这个buffer 复制多大的数据?在创建队列时已经指定了数据大小 |
xTicksToWait | 如果队列空则无法读出数据,可以让任务进入阻塞状态, xTicksToWait表示阻塞的最大时间(Tick Count)。 如果被设为0,无法读出数据时函数会立刻返回; 如果被设为portMAX_DELAY,则会一直阻塞直到有数据可写 |
返回值 | pdPASS:从队列读出数据入 errQUEUE_EMPTY:读取失败,因为队列空了。 |
(1)可以查询队列中有多少个数据、有多少空余空间。
(2)函数原型:
/*
* 返回队列中可用数据的个数
*/
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
/*
* 返回队列中可用空间的个数
*/
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
(1)当队列长度为1时,可以使用 xQueueOverwrite() 或 xQueueOverwriteFormISR() 来覆盖数据。注意,队列长度必须为1。当队列满时,这些函数会覆盖里面的数据,这也意味着这些函数不会被阻塞。
(2)函数原型:
/* 覆盖队列
* xQueue: 写哪个队列
* pvItemToQueue: 数据地址
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueueOverwrite(
QueueHandle_t xQueue,
const void * pvItemToQueue
);
BaseType_t xQueueOverwriteFromISR(
QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
(1)如果想让队列中的数据供多方读取,也就是说读取时不要移除数据,要留给后来人。那么可以使用"窥视",也就是 xQueuePeek() 或 xQueuePeekFromISR() 。这些函数会从队列中复制出数据,但是不移除数据。这也意味着,如果队列中没有数据,那么"偷看"时会导致阻塞;一旦队列中有数据,以后每次"偷看"都会成功。
(2)函数原型:
/* 偷看队列
* xQueue: 偷看哪个队列
* pvItemToQueue: 数据地址, 用来保存复制出来的数据
* xTicksToWait: 没有数据的话阻塞一会
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueuePeek(
QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait
);
BaseType_t xQueuePeekFromISR(
QueueHandle_t xQueue,
void *pvBuffer,
);