十三、队列的特性

1、队列(Queue)概述

        队列可以用于"任务到任务"、"任务到中断"、"中断到任务"直接传输信息。队列涉及内容如下:

  • 怎么创建、清楚、删除队列
  • 队列中消息如何保存
  • 怎么向队列发送数据、怎么从队列读取数据、怎么覆盖队列的数据
  • 在队列上阻塞式什么意思
  • 怎么在多个队列上阻塞
  • 读写队列时如何影响任务的优先级

2、队列的特性

2.1、常规操作

(1)队列的简化操如入下图所示,从此图可知:

  • 队列可以包含若干个数据:队列中有若干项,这被称为“长度”(length)
  • 每个数据大小固定
  • 创建队列时就要指定长度、数据大小
  • 数据的操作采用先进先出的方式(FIFO,First In First Out):写数据时放到尾部,读数据时从头部读
  • 把数据写到队列头部,不会覆盖原来的数据。(队列中的数据使用环形缓冲区管理数据,把数据放到头部时,会先移动头部位置,并不会覆盖原来的数据)

十三、队列的特性_第1张图片

(2)更详细的操作如下图所示:

2.2、传输数据的两种方式

(1)使用队列传输数据时有两种方法:

  • 拷贝:把数据、把变量的值复制进队列里
  • 引用:把数据、把变量的地址复制进队列里

(2)FreeRTOS使用拷贝值的方法特点:

  • 局部变量的值可以发送到队列中,后续即使函数退出、局部变量被回收,也不会影响队列中的数据
  • 无需分配buffer来保存数据,队列中有buffer
  • 变量可以马上再次使用(赋予其他值,引用则不行)
  • 发送任务、接收任务解耦:接收任务不需要知道这数据是谁的、也不需要发送任务来解释数据
  • 队列的空间有FreeRTOS内核分配,无需任务操心
  • 对于有内存保护功能的系统,如果队列使用引用方法,也就是使用地址,必须确保双方任务对这个地址都有访问权限。使用拷贝方法时,则无此限制:内核有足够的权限,把数据复制进队列、再把数据复制出队列。

(3)引用的特点:

  • 如果数据实在太大,可以使用队列传输它的地址

2.3、队列的阻塞访问

(1)只要知道队列的句柄,谁都可以读、写队列。任务、ISR都可以读、写队列。可以多个任务读写队列。

(2)任务读写队列时,简单地说:如果读写不成功,则阻塞;可以指定超时时间。口语化地说,就是可以定个闹钟:如果能读写了就马上进入就绪态,否则就阻塞直到超时。

(3)某个任务读队列时,如果队列没有数据,则该任务可以进入阻塞状态:还可以指定阻塞的时间。如果队列有数据了,则该阻塞的任务会变为就绪态。如果一直都没有数据,则时间到之后它也会进入就绪态。

(4)既然读取队列的任务个数没有限制,那么当多个任务读取空队列时,这些任务都会进入阻塞状态:有多个任务在等待同一个队列的数据。当队列中有数据时,哪个任务会进入就绪态?

  • 优先级最高的任务。
  • 如果大家的优先级相同,那等待时间最久的任务会进入就绪态。

(5)跟读队列类似,一个任务要写队列时,如果队列满了,该任务也可以进入阻塞状态:还可以指定阻塞的时间。如果队列有空间了,则该阻塞的任务会变为就绪态。如果一直都没有空间,则时间到之后它也会进入就绪态。

(6)既然写队列的任务个数没有限制,那么当多个任务写"满队列"时,这些任务都会进入阻塞状态:有多个任务在等待同一个队列的空间。当队列中有空间时,哪个任务会进入就绪态?

  • 优先级最高的任务。
  • 如果大家的优先级相同,那等待时间最久的任务会进入就绪态。

你可能感兴趣的:(FreeRTOS,RTOS,C,嵌入式,iot)