【详细】FreeRTOS队列的内部机制
目录
一.核心
我认为队列的核心分为三点:关中断,环形缓冲区,链表。
二.链表结构体
1.Queue结构体:

2.环形缓冲区:
pcHead:指向队列存储区的起始地址。
pcTail:指向队列存储区的结束地址。
pcWriteTo:指向下一个将要写入数据的位置。
pcReadFrom:指向下一个将要读取数据的位置。

3.链表:
xTasksWaitingToSend:记录了所有因为队列满而阻塞、等待向该队列发送(入队)的任务。列表中的任务按优先级排序。
xTasksWaitingToReceive:记录了所有因为队列空而阻塞、等待从该队列接收(出队)的任务。同样按优先级排序。
当队列满或空的条件解除时,内核会从相应列表中取出优先级最高的任务并将其唤醒。

4.状态参数
uxMessagesWaiting:当前队列中已有的数据项数量(即队列中的消息数)。用 volatile 修饰,因为可能在中断服务例程中被修改。
uxLength:队列的最大容量,即能同时容纳的数据项个数(不是字节数)。
uxItemSize:队列中每个数据项的大小(字节数)。
如果 uxItemSize > 0,表明这是一个 队列,实际存储数据;
如果 uxItemSize == 0,则没有数据存储区,一般用作 信号量、互斥量(仅靠 uxMessagesWaiting 计数实现同步)。

5.锁定计数器(用于中断安全)
cRxLock:队列被锁定期间,实际发生的接收(出队)次数。
cTxLock:队列被锁定期间,实际发生的发送(入队)次数。

三.创建队列
这里需要注意一点的是,在xQueueCreate函数中malloc队列的函数不单单知识队列的大小,同时还包结构体的大小。

四.读取队列
1.互斥访问数据
简单粗暴:关中断

2.读取数据

无数据
1.如果等待时间为0,直接返回错误
2.如果等待时间不为0,休眠

这个函数执行的两个核心操作
1.将任务插入事件等待列表,这里就是xTasksWaitingToReceive List
2.将任务加入延迟列表,这里就是从Ready List移除,添加到Delay List 
有数据
1.开始读的时候就有数据,直接Copy Data

2.被唤醒时,有数据可以读取
这个函数执行的两个核心操作
1.将任务移除事件等待列表,这里就是xTasksWaitingToSend List
2.将任务加入就绪列表,这里就是从Delay List移除,添加到Read List

五.写队列
1.互斥访问数据
简单粗暴:关中断

2.写入数据
无空间
1.如果等待时间为0,直接返回错误

2.如果等待时间不为0,休眠

这个函数执行的两个核心操作
1.将任务插入事件等待列表,这里就是xTasksWaitingToSend List
2.将任务加入延迟列表,这里就是从Ready List移除,添加到Delay List

有空间
1.开始写的时候就有空间,直接Write Data

2.被唤醒时,有数据可以写入
这个函数执行的两个核心操作
1.将任务移除事件等待列表,这里就是xTasksWaitingToSend List
2.将任务加入就绪列表,这里就是从Delay List移除,添加到Read List

六.超时机制
1.读队列超时
超时返回错误

2.写队列超时
超时返回错误

创造不易,多加支持点赞!
更多推荐
所有评论(0)