本篇为:消息队列和队列集篇
消息队列
1、FreeRTOS中的消息队列是什么
答:
消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递)。
2、消息队列和全局变量的区别
答:
消息队列作用有点类似于全局变量,但消息队列在RTOS中比全局变量更安全可靠。
假设有一个全局变量a=0,现在有两个任务都要写这个变量a。
上图中任务1和任务2在RTOS中相互争取修改a的值,a的值容易受损错乱。
全局变量的弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损。
3、队列项目和队列长度
答:
在队列中可以存储数量有限、大小固定的数据。队列中的每个数据就叫做 “队列项目” ,队列能够存储 “队列项目” 的最大数量称为队列的长度。
需要注意的是:
在创建队列时,就要指定队列长度以及队列项目的大小!
4、FreeRTOS队列特点
答:
- 数据入队出队方式 : 队列通常采用 “先进先出(FIFO)” 的数据存储缓冲机制,即先入队的数据会先从队列中被读取,FreeRTOS中也可以配置为 “后进先出(LIFO)” 方式。
- 数据传递方式 : FreeRTOS中队列采用实际值传递,即将数据拷贝到队列中进行传递,FreeRTOS采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递。
- 多任务访问 : 队列不属于某个任务,任何任务和中断都可以向队列写入/读取消息。
- 出队、入队阻塞 : 当任务向一个队列发送/读取消息时,可以指定一个阻塞时间,假设此时当队列已满无法入队。
5、消息队列阻塞时间设置
答:
- 若阻塞时间为0 :直接返回不会等待。
- 若阻塞时间为 0 ~ port_MAXDELAY :等待设定阻塞时间,若在该时间内无法入队/出队,超时后直接返回不再等待。
- 若阻塞时间为 port_MAXDELAY :死等,一直等到可以入队/出队为止。
6、入队/出队阻塞过程
答:
入队阻塞:
队列满了,此时写不进去数据:
- 将该任务的状态列表项挂载在 pxDelayedTaskList;
- 将该任务的事件列表项挂载在 xTasksWaitingToSend;
出队阻塞:
队列为空,此时读取不了数据:
- 将该任务的状态列表挂载在 pxDelayedTaskList;
- 将该任务的事件列表项挂载在 xTasksWaitingToReceive;
7、当多个任务写入消息给一个 “满队列” 时,这些任务都会进入阻塞状态,也就是说有多个任务在等待同一个队列的空间。那当队列有空间时,哪个任务会进入就绪态?
答:
- 优先级最高的任务
- 如果大家的优先级相同,那等待时间最久的任务进入就绪态。
8、队列创建、写入和读出过程
答:
任务A写入,任务B读取:
队列集
1、队列集介绍
答:
- 一个队列只允许任务间传递的消息为同一种数据类型,如果需要再任务间传递不同数据类型的消息时,那么就可以使用队列集!!!
- 作用:用于对多个队列或信号量进行“监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态。
假设:有一个任务,使用到队列接收和信号量的获取,如下:
不使用队列集:
使用队列集:
2、队列集相关API函数
答: