FreeRTOS(9)---FreeRTOS 队列

文章由 FreeRTOS 系列博客整理而来,仅为学习记录,如有不妥,请告知。

FreeRTOS 队列

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

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

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

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

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

队列阻塞

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

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

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

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

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

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

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

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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值