目录
一、消息队列简介
消息队列的运作过程:
二、消息队列常用相关函数
1、队列创建
(1)动态创建xQueueCreate()
(2)静态创建xQueueCreateStatic()
(3)函数xQueueGenericCreate()
2、队列删除函数
3、入队函数
(1)任务级入队函数
(2)中断级入队函数
4、出队函数
(1)任务级
(2)中断级
一、消息队列简介
消息队列是FreeRTOS中一种常用于任务间通信的数据结构,可以在任务与任务间、中断与任务间传递信息,所有任务都可以访问队列中的数据,相当于一个全局变量。任务从队列里面读取消息,当队列的消息为空时,读取消息的任务将被阻塞,阻塞时间可以自定义,阻塞时间内当队列有消息时任务将退出阻塞态,阻塞时间到达时也会退出阻塞态。
消息队列内的消息支持先进先出原则(FIFO),也支持后进先出原则(LIFO)。消息数据可以是不同长度(不超过队列节点最大值)的任意类型消息。
消息队列的运作过程:
二、消息队列常用相关函数
1、队列创建
(1)动态创建xQueueCreate()
该函数是一个宏,最终调用的是xQueueGenericCreate()函数。
QueueHandle_t xQueueCreate ( const UBaseType_t uxQueueLength, //队列长度,队列的项目数
const UBaseType_t uxItemSize) //每个项目(消息)的大小,字节为单位
返回值是QueueHandle_t类型的消息队列句柄,返回NULL则创建失败。
(2)静态创建xQueueCreateStatic()
该函数是一个宏,最终调用的是xQueueGenericCreateStatic ()函数。
QueueHandle_t xQueueCreateStatic ( const UBaseType_t uxQueueLength, //队列长度,队列的项目数
const UBaseType_t uxItemSize, //每个项目(消息)的大小,字节为单位
uint8_t *pucQueueStorage, //队列项目存储区,需定义,uint8_t类型的数组
StaticQueue_t *pxQueueBuffer,)//指向StaticQueue类型的变量,保存队列结构体
返回值也是一个队列句柄,返回NULL则创建失败。
(3)函数xQueueGenericCreate()
这是动态创建的最终调用函数。
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, //队列长度,队列的项目数
const UBaseType_t uxItemSize, //每个项目(消息)的大小,字节为单位
const uint8_t ucQueueType )//队列类型
队列类型定义:
#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U )//普通的消息队列
#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )//队列集
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )//互斥信号量
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )//计数型信号量
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )//二值信号量
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )//递归互斥信号量
由此,相关的信号量的创建都是此函数完成的。
静态创建函数xQueueGenericCreate()也与此类似。
2、队列删除函数
void vQueueDelete( QueueHandle_t xQueue );
入口参数为队列句柄。
3、入队函数
(1)任务级入队函数
xQueueSend()、
xQueueSendToBack()、
xQueueSendToFront();
三个函数都有相同的入口参数,且最终实现函数都是xQueueGenericSend()。
BaseType_t xQueueSend( QueueHandle_t xQueue,
const void * pvItemToQueue,
TickType_t xTicksToWait
);
BaseType_t xQueueSendToBack( QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);
BaseType_t xQueueSendToToFront( QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);
入口参数:
xQueue : 队列句柄;
pvItemToQueue: 发送的消息(地址)
xTicksToWait : 阻塞时间,当队列满的时候,该函数进入阻塞状态等待的时间,为0时不等待立即返回,为portMAX_DELAY时会一直等待。
返回值:
pdPASS: 发送信息成功
errQUEUE_FULL: 队列满发送失败
xQueueOverwrite():
BaseType_t xQueueOverwrite( QueueHandle_t xQueue,
const void * pvItemToQueue
);
该函数没有阻塞时间,也不需要阻塞。
通用入队函数xQueueGenericSend()
BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
const void * pvItemToQueue,
TickType_t xTicksToWait
BaseType_t xCopyPosition
);
入口参数:(其余与前面相同)
xCopyPosition:入队方式:
queueSEND_TO_BACK 后向入队
queueSEND_TO_FRONT 前向入队
queueOVERWRITE 覆写入队
(2)中断级入队函数
xQueueSendFromISR ()、
xQueueSendToBackFromISR ()、
xQueueSendToFrontFromISR ()、
xQueueOverwriteFromISR()。
BaseType_t xQueueSendFromISR( QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
BaseType_t xQueueSendToFrontFromISR( QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
入口参数:
xQueue : 队列句柄;
pvItemToQueue: 发送的消息(地址)
pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,只需提供变量保存即可。当此值为pdTRUE时需要进行一次任务切换。
返回值:
pdPASS: 发送信息成功
errQUEUE_FULL: 队列满发送失败
中断函数需要快进快出,因此中断函数里面不允许调用带有阻塞的函数。
4、出队函数
出队即读取消息,读的都是消息队列的最后一项。
(1)任务级
xQueueReceive()、
xQueuePeek():
BaseType_t xQueueReceive( QueueHandle_t xQueue,
void *pvBuffer,
TickType_t xTicksToWait
);
BaseType_t xQueuePeek( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait
);
入口参数:
xQueue 队列句柄
pvBuffer 保存数据地址
xTicksToWait 阻塞时间
返回值:
pdPASS: 读取信息成功
errQUEUE_FULL: 读取信息失败
(2)中断级
xQueueReceiveFromISR()、
xQueuePeekFromISR():
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxTaskWoken
);
BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
void *pvBuffer,
);
入口参数:
xQueue 队列句柄
pvBuffer 保存数据地址
pxTaskWoken 标记退出此函数以后是否进行任务切换,只需提供变量保存即可。当此值为pdTRUE时需要进行一次任务切换
返回值:
pdPASS: 读取信息成功
errQUEUE_FULL: 读取信息失败