概览
基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权
限的小程序。这些独立的任务之间很可能会通过相互通信以提供有用的系统功能。
FreeRTOS 中所有的通信与同步机制都是基于队列实现的。
本章期望让读者了解以下事情
如何创建一个队列
队列如何管理其数据
如何向队列发送数据
如何从队列接收数据
队列阻塞是什么意思
往队列发送和从队列接收时,任务优先级会有什么样的影响
本章仅涵盖任务之间的通信。任务与中断之间的通信将在第三章讲述。
队列的特性
数据存储
队列可以保存有限个具有确定长度的数据单元。队列可以保存的最大单元数目被称
为队列的“深度”。在队列创建时需要设定其深度和每个单元的大小。
通常情况下,队列被作为 FIFO(先进先出)使用,即数据由队列尾写入,从队列首读
出。当然,由队列首写入也是可能的。
往队列写入数据是通过字节拷贝把数据复制存储到队列中;从队列读出数据使得把
队列中的数据拷贝删除。图 图 19 展现了队列的写入与读出过程,以及读写操作对队列中
数据的影响。
可被多任务存取
队列是具有自己独立权限的内核对象,并不属于或赋予任何任务。所有任务都可以
向同一队列写入和读出。一个队列由多方写入是经常的事,但由多方读出倒是很少遇到。
读队列时阻塞
当某个任务试图读一个队列时,其可以指定一个阻塞超时时间。在这段时间中,如
果队列为空,该任务将保持阻塞状态以等待队列数据有效。当其它任务或中断服务例程
往其等待的队列中写入了数据,该任务将自动由阻塞态转移为就绪态。当等待的时间超
过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转移为就绪态。
由于队列可以被多个任务读取,所以对单个队列而言,也可能有多个任务处于阻塞
状态以等待队列数据有效。这种情况下,一旦队列数据有效,只会有一个任务会被解除
阻塞,这个任务就是所有等待任务中优先级最高的任务。而如果所有等待任务的优先级
相同,那么被解除阻塞的任务将是等待最久的任务。
写队列时阻塞
同读队列一样,任务也可以在写队列时指定一个阻塞超时时间。这个时间是当被写
队列已满时,任务进入阻塞态以等待队列空间有效的最长时间。
由于队列可以被多个任务写入,所以对单个队列而言,也可能有多个任务处于阻塞
状态以等待队列空间有效。这种情况下,一旦队列空间有效,只会有一个任务会被解除
阻塞,这个任务就是所有等待任务中优先级最高的任务。而如果所有等待任务的优先级
相同,那么被解除阻塞的任务将是等待最久的任务。