??消息队列简称队列,是一种常用于任务间通信的数据结构。
??如下图:消息队列可以在任务与任务间、中断与任务间传递消息,实现任务接收来自其它任务或中断的不固定长度的消息。
< 队列用于任务与任务间 >
< 队列用于任务与中断间 >
相比于裸机的全局数组,使用消息队列有如下优势:
??消息队列是一种异步的通信方式。
??任务能够从队列中读取消息,当队列中的消息为空时,读取消息的任务将被阻塞。用户可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过指定的阻塞时间,即使队列中没有有效数据,任务也会自动从阻塞态转为就绪态。
??通过消息队列服务,任务或中断服务可以将一条或多条消息放入消息队列中。同样,一个或多个任务可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常是将先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则 (FIFO),FreeRTOS 的队列也支持后进先出原则 (LIFO)。
??消息支持先进先出方式排队,支持异步读写工作方式
??消息队列可用于发送不定长消息的场合。
??队列是 FreeRTOS 主要的任务间通信方式,可以在任务与任务间、中断和任务间传送信息,发送到队列的消息是通过复制方式实现的,这意味着队列存储的数据是原始数据,而不是原始数据的引用。
消息队列全部 API 函数:
使用消息队列的典型流程如下:
说明:句柄中的各个成员,稍微了解即可,Keil 工程中有详细注释
函数原型:
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, // 队列长度,即消息个数
UBaseType_t uxItemSize ); // 类目大小,即消息大小,单位字节
函数描述:
函数 xQueueCreate 用于创建消息队列
队列创建示意图:
应用举例:
函数原型:
??void vQueueDelete( QueueHandle_t xQueue); // 队列句柄
函数描述:
??函数 vQueueDelete 用于删除消息队列
?? 第 1 个参数是需要删除的消息队列句柄
说明:
??消息队列删除后,系统会清空此队列的全部消息,且不能再次使用此队列。
函数原型:
BaseType_t xQueueSend( QueueHandle_t xQueue, /* 消息队列句柄 */
const void * pvItemToQueue, /* 要传递数据地址 */
TickType_t xTicksToWait /* 等待消息队列有空间的最大等待时间 */);
函数描述:
??函数 xQueueSend 用于任务中消息发送。
使用这个函数要注意以下问题:
应用举例:
函数原型:
BaseType_t xQueueSendFromISR ( QueueHandle_t xQueue, /* 消息队列句柄 */
const void *pvItemToQueue, /* 要传递数据地址 */
BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */ );
函数描述:
??函数 xQueueSendFromISR 用于中断服务程序中消息发送。
使用这个函数要注意以下问题:
FreeRTOS 的消息传递是数据的复制,而不是传递的数据地址。正因为这个原因,用户在创建消息队列时单个消息大小不可太大,因为一定程度上面会增加中断服务程序的执行时间。
此函数是用于中断服务程序中调用的,故不可以在任务代码中调用此函数,任务代码中使用的是 xQueueSend。
消息队列还有两个函数 xQueueSendToBackFromISR 和 xQueueSendToFrontFromISR,函数 xQueueSendToBackFromISR 实现的是 FIFO 方式的存取,函数 xQueueSendToFrontFromISR 实现的是 LIFO 方式的读写。我们这里说的函数 xQueueSendFromISR 等效于 xQueueSendToBackFromISR,即实现的是 FIFO 方式的存取。
应用举例:
函数原型:
BaseType_t xQueueReceive( QueueHandle_t xQueue, /* 消息队列句柄 */
void *pvBuffer, /* 接收消息队列数据的缓冲地址 */
TickType_t xTicksToWait /* 等待消息队列有数据的最大等待时间 */ );
函数描述:
??函数 xQueueReceive 用于接收消息队列中的数据。
使用这个函数要注意以下问题:
应用举例:
现场讲解
现场讲解