FreeRTOS学习笔记(六)队列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

  队列(Queue) 是一种用于任务间通信和同步的重要机制。它允许不同任务或者中断服务例程之间交换数据,而无需直接共享变量。这种机制不仅确保数据在任务之间传递的安全性,还解决了多任务系统中的并发和同步问题。


一、队列的基本内容

1.1 队列的引入

  在以前的代码中,如果我们想让一个变量在不同函数中进行传递操作,下意识可能会想到全局变量,但是这种方式存在一个问题:当我们使用freertos时,低优先级的任务会被高优先级的任务打断,这意味着可能会导致变量的结果不可控。为了解决这个问题,我们引入了队列,他自带临界保护,我们只要进行相关的API操作即可。在队列中可以存储固定大小且有限的数据,其中每一个数据叫“队列项目”,而所能存储的最大“队列项目”的数量称为队列的长度。除了可以被多任务访问之外,队列还有以下的特性:

  • FreeRTOS 中的队列是先进先出的结构,即最先插入队列的数据会最先被读取;
  • 队列的长度和每个队列项的大小在创建时由用户指定
  • FreeRTOS 提供了阻塞模式和非阻塞模式的队列操作。如果任务需要立即返回,可以使用超时为 0 的非阻塞模式;如果任务愿意等待队列有空位或数据,可以设置阻塞时间(如 0~portMAX_DELAY)让任务进入阻塞状态;
  • FreeRTOS 中的队列在数据传递时通常会直接拷贝数据进行实值传输,当然也可以传递指针。

1.2 FreeRTOS 队列的功能与作用

  • 任务间通信:FreeRTOS 的队列可以让多个任务之间安全地传递数据。例如,一个任务可以向队列发送数据,另一个任务从队列读取数据。这使得不同任务之间可以高效地共享信息,而不需要频繁访问全局变量。
  • 任务与中断间通信:队列不仅适用于任务间通信,还适用于中断和任务之间的通信。FreeRTOS 提供了特定的 ISR(中断服务例程)函数,比如 xQueueSendFromISR() 和 xQueueReceiveFromISR(),可以让中断处理函数安全地与任务交换数据。
  • 同步与调度:当一个任务尝试从空队列中读取数据时,任务可以选择进入阻塞状态,直到有数据可读。当另一个任务或中断向队列中发送数据时,等待的任务会被唤醒并立即处理数据。这样,队列不仅传递数据,还能用作同步机制,协调任务间的执行顺序。
  • 队列引发的任务切换: 在 FreeRTOS 中,如果一个任务向队列发送数据,并唤醒了一个更高优先级的任务,该任务会立刻抢占当前任务进行执行。这使得队列不仅用于数据交换,还起到了一定的任务调度作用。

1.3 队列的结构体

  在 FreeRTOS 中,队列是通过一个结构体来实现的。虽然具体实现可能根据不同平台有所调整,但通常队列的结构体包含了队列长度、队列项大小、存储数据的缓冲区指针、队列的头尾指针、队列的同步机制(如等待队列的任务列表)等信息。在 FreeRTOS 的源码中,定义队列的结构体一般为 QueueDefinition,其在 queue.c 中实现,通常通过类型定义 QueueHandle_t 来间接引用该结构体。

struct QueueDefinition  
{
   
   
    int8_t *pcHead;          /* 指向队列存储区的指针(队列缓冲区的头部) */
    int8_t *pcTail;          /* 指向队列存储区的尾部 */
    int8_t *pcWriteTo;       /* 指向队列中下一个写入位置 */
    int8_t *pcReadFrom;      /* 指向队列中下一个读取位置 */
    
    UBaseType_t uxMessagesWaiting;  /* 队列中的消息数 */
    UBaseType_t uxLength
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值