(十六)FreeRTOS队列

本文介绍队列的基本知识,详细源码分析见《FreeRTOS高级篇5---FreeRTOS队列分析

1.FreeRTOS队列

      队列是主要的任务间通讯方式。可以在任务与任务间、中断和任务间传送信息。大多数情况下,队列用于具有线程保护的FIFO(先进先出)缓冲区:新数据放在队列的后面。当然,数据也可以放在队列的前面,在下一篇讲队列API函数时,会涉及到数据的存放位置。

 

图1-1:读写队列

      图1-1所示的队列中,最多能保存5个项目,并且假设队列永远不会满。任务A使用API函数xQueueSendToBack()向队列发送数据,每次发送一个数据,新入队的数据置于上一次入队数据的后面。任务B使用API函数xQueueReceive()将数据从队列取出,先入队的数据先出队。

2.使用模型:最简单、最灵活

      通常情况下,鱼和熊掌是不可兼得的,但FreeRTOS的队列用户模型管理却兼顾简单和灵活。发送到队列的消息是通过拷贝实现的,这意味着队列存储的数据是原数据,而不是原数据的引用。FreeRTOS队列具有以下特性:

 

  • C变量(整形、简单结构体等等)中的简单信息可以直接传送到队列。这样就不需要为信息分配缓存也不需要再进行什么拷贝工作。同样的,信息可以直接从队列读取到C变量中。用直接拷贝的方法入队,可以允许任务立即覆写已经入队的变量或者缓存,实际上队列中已经保存了这些变量或缓冲区携带的信息。因为变量中的数据内容是以拷贝的方式入队的,所以变量自身是允许重复使用的。发送信息的任务和接收信息的任务并不需要就哪个任务拥有信息、哪个任务释放信息(当信息不再使用时)而达成一致。
  • 队列是通过拷贝传递数据的,但这并不妨碍队列通过引用来传递数据。当信息的大小到达一个临界点后,逐字节拷贝整个信息是不实际的,可以定义一个指针队列,只拷贝指向消息的指针来代替整个信息拷贝。FreeRTOS+UDP IP栈例程正是使用这种方法向FreeRTOS协议栈传递大量网络数据的。
  • 队列内存区域分配由内核完成。
  • 变长消息可以通过定义保存一个结构体变量的队列实现,结构体一个成员指向要入队的缓存,另一个成员保存缓存数据的大小。
  • 单个队列可以接收不同类型信息,并且信息可以来自不同的位置。通过定义保存一个结构体变量的队列来实现,结构体的一个成员保存信息类型,另一个成员保存信息数据(或者指向信息数据的指针)。数据如何解读取决于信息类型。管理FreeRTOS+UDP IP栈的任务正是使用单个队列接收ARP定时器时间通知、以太网硬件传送来的数据包、从应用层传送来的数据包、网络关闭事件等等。
  • 天生适用于那些内存保护(MPU)场合。一个具有内存区域保护的任务可以向另一个具有内存区域保护的任务传递数据,因为调用队列发送函数会引起RTOS提升微控制器特权级别。只有RTOS(具有所有特权)才可以访问队列存储区域。
  • 在中断函数中使用独立的API。将RTOS任务API和中断服务例程API分来实现意味着可以避免执行时的上下文调用检查开销,还意味着在大多数情况下,与其它RTOS产品相比,用户创建中断服务例程会更简单。
  • API函数很简单。

 

3.队列阻塞

      API函数允许指定阻塞时间。

      每当任务企图从一个空的队列读取数据时,任务会进入阻塞状态(这样任务不会消耗任何CPU时间并且另一个任务可以运行)直到队列中出现有效数据或者阻塞时间到期。

      每当任务企图向一个满的队列写数据时,任务会进入阻塞状态,直到队列中出现有效空间或者阻塞时间到期。

      如果多个任务阻塞在一个队列上,那么最高优先级别的任务会第一个解除阻塞。

      注:中断程序中绝不可以使用不带“FromISR”结尾的API函数!

      总结一下队列的基本用法:

 

  1. 定义一个队列句柄变量,用于保存创建的队列:xQueueHandle xQueue1;
  2. 使用API函数xQueueCreate()创建一个队列。
  3. 如果希望使用先进先出队列,使用API函数xQueueSend()或xQueueSendToBack()向队列投递队列项。如果希望使用后进先出队列,使用API函数xQueueSendToFront()向队列投递队列项。如果在中断服务程序中,切记使用它们的带中断保护版本。
  4. 使用API函数xQueueReceive()从队列读取队列项,如果在中断服务程序中,切记使用它们的带中断保护版本。

      以上使用的API函数将在下一篇文章中介绍。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS队列一个FreeRTOS实时操作系统中提供的一种数据结构,用于在任务之间进行通信和共享数据队列一个先进先出(FIFO)的数据结构,任务可以向队列中发送数据项,也可以从队列中接收数据项。 队列的主要功能是实现任务之间的同步和通信。通过使用队列,任务可以将数据安全地传递给其他任务,而不需要直接访问共享内存或全局变量。这种方式可以有效地避免竞态条件和数据一致性问题。 FreeRTOS提供了以下几种类型的队列: 1. 二进制信号量队列(binary semaphore queue):用于在任务之间传递二进制信号量,只有两个状态,已获取(signaled)和未获取(not signaled)。 2. 计数信号量队列(counting semaphore queue):用于在任务之间传递计数信号量,可以有多个状态值。 3. 互斥量队列(mutex queue):用于实现任务之间的互斥操作,只有一个任务可以同时访问共享资源。 4. 消息队列(message queue):用于在任务之间传递消息或数据项,可以具有不同的数据类型和大小。 使用FreeRTOS队列时,任务可以通过发送到队列或从队列接收数据进行通信。发送和接收操作可以是阻塞或非阻塞的,具体取决于队列的配置和任务的需求。 总之,FreeRTOS队列是一种强大而灵活的机制,可用于实现任务之间的通信和数据共享,同时确保任务之间的同步和互斥操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值