上一文链接:FreeRTOS笔记(九)任务相关的过渡
在第一篇概念的思维导图中,任务的下一个概念就是队列,一个实际的FreeRTOS系统肯定会有多个任务,这些任务经常需要协同运作,因此必然需要通信,不止任务和任务之间,任务和中断之间也需要通信。对于通信,需要了解通信介质、通信方式和通信操作。
01 - 通信介质
FreeRTOS的通信介质是队列,队列是一个先进先出的数据结构,一个相似的数据结构是栈(先进后出),FreeRTOS的队列包含2个信息,1是队列结构体,用于操作队列的句柄,2是实际储存区,消息真正存放的区域。队列的先进先出特性非常适用于处理”等待“类的事件。
创建队列一般都会规定一个长度length
以及元素的大小size
,而length×size
就代表队列的总容量,FreeRTOS提供创建队列的API如下
API | 功能 |
---|---|
xQueueCreate() | 动态创建,内存由编辑器负责分配 |
xQueueCreateStatic() | 静态创建,需要程序员提供结构体和实际储存区的地址 |
02 - 通信方式
通过对队列规定不同的约束条件,就可以产生不同的通信方式,FreeRTOS的通信方式有普通队列、信号、信号量、互斥量和共享内存,它们的区别如下
通信方式 | 长度 | 约束 | 作用 |
---|---|---|---|
普通队列 | >0 | 阻塞读写 | 用于任务之间传递数据 |
信号 | 1 | 一方只需要P申请,另一方只需要V添加 | 用于锁存1个中断代表资源的到达 / 用于任务的异步通知 |
信号量 | >1 | 一方只需要P申请,另一方只需要V添加 | 用于锁存若干个中断以免中断丢失 / 用于同步代表资源的数量 |
互斥量 | 1 | P申请的一方必须自己进行V添加 | 用于互斥访问机制 |
共享内存 | >0 | 阻塞读写 | 用于大块数据的高效传输 |
在普通任务之间的数据传输使用普通队列/共享内存即可,而任务之间的工作需要实现同步和异步的时候,就需要信号、信号量和互斥量的配合,这些通信方式更多地在中断和资源管理中使用。
03 - 通信操作
FreeRTOS提供一系列操作队列的API,常用如下
API | 功能 |
---|---|
xQueueCreate() | 动态创建队列 |
vQueueDelete() | 删除队列 |
pcQueueGetName() | 得到队列名称 |
xQueueOverwrite() | 写数据 |
xQueuePeek() | 读数据,但不出队 |
xQueueReceive() | 读数据,并出队 |
另外在中断里面操作队列,需要用特定的中断安全API,这些API一般在原来的API上加上后缀FromISR
04 - 总结
- FreeRTOS所有的通信方式都基于队列
- 队列包含队列结构体和实际储存区
- 通过约束队列,可以实现信号、信号量、互斥量等
- 在队列的操作中,任务和中断需要调用不同的API