FreeRTOS--队列

在讲队列前,先思考一下这个问题:
下面这个程序,如果用RTOS实现会出问题吗?

c:
int a = 0;
void fun_a(){
 a++;
}
void fun_b(){
 a++;
}
int main(){
	while(1){
	fun_a();
	fun_b();
	}

}
RTOS:
int a = 0;
void fun_a(){
 a++;
}
void fun_b(){
 a++;
}
int main()
{
	creat_Task(fun_a);
	creat_Task(fun_b);

}

对RTOS代码分析:
我们的期望是运行一次fun_a后a++运行1次,运行1次fun_b后a++运行1次,a = 2
fun_a和fun_b的a++:
1)读a: R0寄存器,读RAM的a的地址,得到a的值
2)修改:R0 自加 1
3)写a:R0寄存器,写RAM的a的地址,修改a的值
接下来模拟一下 RTOS运行
t0:
fun_a:
1)R0寄存器,读RAM的a的地址,得到a的值,R0 = 0,
2)此时到下一个tick,保存现场R0 = 0.
t1:
fun_b:
1)读a: R0寄存器,读RAM的a的地址,得到a的值,R0 = 0;
2)修改:R0 自加 1,R0 += 1,R0 = 1;
3)写a:R0寄存器,写RAM的a的地址,修改a的值;a = 1
t2:
fun_a:
1)恢复现场 R0 = 0
2)修改:R0 自加 1 R0 += 1,R0 = 1;
3)写a:R0寄存器,写RAM的a的地址,修改a的值;a = 1

由上面可知,不符合我们的期望,运行结果为 a = 1
根本问题在于,多个任务一起修改没有互斥机制保护数据。

队列提供了解决的方法,使用QueueSend可以将任务的tick中断关闭,实现裸机运行,修改完数据后再打开中断

接下来再举个栗子

void fun_a(){
 while(1){
 ...
 	达成某条件后
	flag = 1;
 ...
	}
}
void fun_b(){
 ...
	if(flag = 1){
	}
 ...
}

如果运行100w次就要判断100w次太过于浪费CPU

void fun_a(){
 while(1){
 ...
 	达成某条件后
	写队列:{
	1)写Data
	2)唤醒Queue.list里的任务,并将DelayList里的任务放进ReadyList

}
 ...
	}
}
void fun_b(){
 ...
	读队列:{
	1)有Data,返回做事
	2)无Data,休眠:
				  a.将该任务放进DelayList链表
				  b.将该任务插入Queue.List队列
	}
	
 ...
}

在这里插入图片描述
fun_a可以全速运行
fun_b可以不浪费CPU资源

通过链表队列实现唤醒休眠

环形缓冲区

在这里插入图片描述
在这里插入图片描述
这里很简单,就直接贴一下韦老师的图了

读队列

a.关中断
b.
有数据:
1)copy数据
2)唤醒Queue.list里的任务,移除Queue.list第一个任务
3)将DelayList里的任务放进ReadyList
无数据:
1.返回ERR
2.休眠:
1)将该任务放进DelayList链表
2)将该任务插入Queue.List队列

写队列

a.关中断
b.
有空间:
1)写数据
2)唤醒Queue.list里的任务,移除Queue.list第一个任务
3)将DelayList里的任务放进ReadyList
无空间:
1.返回ERR
2.休眠:
1)将该任务放进DelayList链表
2)将该任务插入Queue.List队列

超时唤醒

任务休眠,对于休眠的任务,每次tick中断都会累加计数,然后对DelayList的任务检查是否超时,超时则会移到ReadyList

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉山有客不自赏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值