消息队列
消息队列是一种用于线程间通信的技术,在FreeRTOS
中则用于任务间通信,其中的任务可以视为线程。
支持先进先出、后进先出
消息队列运行机制
创建消息队列单独划分一个内存空间,内存大小=控制块大小+单个消息空间*队列长度,然后初始化消息队列,空间大小无法更改。
初始化后,内存空间中会包含头指针等信息,消耗部分内存,删除消息队列后空间释放。
每个空间存放不大于
uxItemSize
的任意类型数据。队列未满,消息会被拷贝到队列末尾。紧急消息则发送至队列首。
当有任务请求队列消息时,任务变为阻塞态在等待时间内等待消息,若消息空间内无消息直至超时,则任务变为就绪态,否则接收消息变为就绪态。
消息队列不再使用后,应该及时删除,释放资源。
任务等待消息的几种状态
即刻型:任务等待消息,若队列中没有消息,任务直接变为就绪态,不再等待消息。
等待型:任务变为阻塞态,在等待时间内等待队列消息,若有消息则接收并变为就绪态,若无就超时变为就绪态。
无限型:任务一直等待消息,直到消息出现。
- 注意事项:只有任务才能进入阻塞态,中断不能进入阻塞态,中断有单独的消息函数
队列常见函数
xQueueCreate()
创建一个队列返回一个指针类型的句柄- 使用的是动态内存,需要开启
configSUPPORT_DYNAMIC_ALLOCATION 1
宏定义 - 创建的时候,申请内存是连续的,保证队列控制块和消息空间的连续
- 使用的是动态内存,需要开启
xQueueStaticCreate()
使用静态内存创建一个队列vQueueDelete()
队列删除xQueueSend()
向队列发送消息,以拷贝的形式在队列尾部加入一个消息,不能在中断中使用xQueueSendToBack()
和xQueueSend()
等效xQueueSendFromISR()
用于中断中向队列尾部发送一个消息xQueueSendToBackFromISR()
和xQueueSendFromISR()
等效xQueueGenericSend()
通用消息队列发送,是上述发送的原型xQueueGenericSendFromISR()
中断通用消息队列发送,中断发送的原型xQueueReceive()
从队列中接收消息,并将消息删除,将消息拷贝至缓冲区xQueuePeek()
从队列中接收消息,不删除消息xQueueReceiveFromISR()
中断中使用xQueuePeekFromISR()
中断中使用xQueueGenericReceive()
通用接收消息,上述的原型
创建队列
设计2个Button
任务,通过按键发送不同的Data
数据,然后将发送的Data
数据在另一个任务中接收,最终在串口显示
队列消息句柄,创建一个引用,并不是创建一个真实的队列消息,同时设置队列的属性
1 | //创建一个Queue句柄 |
创建一个真实的队列
1 | //创建一个Queue队列 |
接收数据任务
1 | static void Receive_Task(void *paramter) |
Button控制发送数据任务
1 | static void Send_Task(void *paramter) |