简介(野火P17.5)
①消息队列是一种常用于任务间通信的数据结构,队列可以实现任务与任务、中断与任务间传递信息。同时消息队列也支持延时阻塞(读写都支持),当消息队列消息为空然后此时任务要读取(写入--即入队操作)该消息队列的消息,则可以设置指定阻塞的任务时间 xTicksToWait,若在此指定时间内消息队列一直为空,阻塞时间结束则任务将阻塞状态恢复至就绪态;若有新消息(若有其他任务读取该消息队列,则允许入队),则任务会读取消息并恢复就绪态。这是异步通信方式。同时也是FreeRTOS里任务间主要的通讯方式。
②消息队列遵从FIFO原则(也支持LIFO)。使用消息队列可以使一个/多个任务/中断例程发送一条或多条消息放入消息队列中,同时一个/多个任务可以从消息队列获取消息。当有多个任务阻塞在同一个消息队列时,若有新消息入队,则会以任务优先级来进行排序,任务优先级高的先出队。一般来说一个队列由多任务或中断写入是经常的事,但由多个任务读 出倒是用的比较少。
PS;中断只能发送消息,不能接收消息。因为接收消息需要设置阻塞时间,中断不需要阻塞。
- 可以允许不同长度(不超过队列节点最大值)的任意类型消息。
- 队列使用结束若此队列已经没有用了,可以使用队列删除函数删除(永久删除)。
③消息队列的内存空间大小在创建消息队列的时候就已经固定好了--即消息队列长度*单个消息大小。发送紧急消息时可以直接发送到队首,而发送普通消息时则发送的是队尾。发送到队列的消息是通过拷贝的方式实现的,说明队列中储存的是原始数据而不是数据的引用。
消息队列通用函数
①xQueueCreate() 消息队列创建函数(动态)
说明:使用该函数必须将把configSUPPORT_DYNAMIC_ALLOCATION 定义为 1 来使能,因为该, 数使用的是动态内存来分配消息队列的空间。在分配的RAM中,需要使用一部分的内存来储存队列的状态,剩下的作为队列消息的储存区域。
函数原型:
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
1·消息大小是以字节为单位。2·该函数返回的是该消息队列的任务句柄。若创建失败,则返回NULL。原因可能是RAM分配失败。
②xQueueCreateStatic()消息队列创建函数(静态)
函数原型:
③vQueueDelete(QueueHandle_t xQueue) 消息队列删除函数
注意:在有任务等待消息时,不应删除队列。同时消息队列删除函数也可以删除信号量。
④xQueueSend()发送消息函数(等同于xQueueSendToBack())
⑤xQueueSendFromISR()与 xQueueSendToBackFromISR()
函数原型:
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);如果入队导致一个任务解锁,并且解锁的任务优先级高 于当前被中断的任务,则将*pxHigherPriorityTaskWoken 设置成 pdTRUE,然后在中断退出前需要进行一次上下 文切换, 去 执 行 被 唤醒 的 优 先 级 更高 的 任 务 。
⑥xQueueSendToFront()向队首发送消息
函数原型:
BaseType_t xQueueSendToFront( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );如果 INCLUDE_vTaskSuspend 设置成 1,并且指定延时 为 portMAX_DELAY 将导致任务无限阻塞(没有超时)。
⑦xQueueSendToFrontFromISR()
函数原型:
BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue, const void*pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
⑧xQueueReceive() 函数接收消息数据并删除
函数原型:
⑨xQueuePeek() 函数接收消息且不删除
函数原型:
⑩xQueueReceiveFromISR() 消息会被删除
函数原型:
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken);
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *pvBuffer); 不会删除消息。