【FreeRTOS】数据传输的方法-环形Buffer


参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》


1. 数据传输的方法

1.1 任务之间如何传输数据

数据传输的多种方法比较:

数据个数互斥措施阻塞-唤醒使用场景
全局变量1一读一写
环形缓冲区多个一读一写
队列多个多读多写

1.2 队列的本质

队列中,数据的读写本质就是环形缓冲区,在这个基础上增加了互斥措施、阻塞-唤醒机制

  • 如果这个队列不传输数据,只调整"数据个数",它就是信号量(semaphore)。
  • 如果信号量中,限定"数据个数"最大值为1,它就是互斥量(mutex)。

在这里插入图片描述

画图演示队列的"阻塞-唤醒"机制。


1.3 说明

全局变量就只能传递一个数据,或者一个结构体,还有可能传递错误数据

  • 假设有两个坐标x,y;x更新了,但是y未更新,现在要进行传参,现在就是错误的数据
  • 如果我们不适用阻塞和唤醒机制的话,CPU资源的利用率比较低

全局变量就只能传递一个数据,或者传递一个结构体
所以使用全局变量有很多隐患,效率低没有互斥,也没有阻塞唤醒


2 环形buffer 读写数据

环形缓冲区:在两个任务之间传递参数

环形缓冲区就是一个数组,最开始是空的,从0开始写,从0开始读, r=0,w=0

  • 怎么写入数据,怎么读取数据呢?
  • 首先得判断里面有没有数据,是否空,或者是否满(不能再写入了)

2.1 如何表示空?

  • r==w,读位置 = 写位置就表示空

2.2 如何表示满?

  • 先知道如何写入数据,才知道怎么表示满

2.3 写数据:

if(未满)
{
	buf[w] = value;
	w++;		//下次写入的位置
	
	if(w == 8)	//溢出
		w = 0;	//清零 
}

在这里插入图片描述

写到第8个了(溢出),赋值0


2.4 读数据

读取操作:

if(r != w)	//如果读位置不等于写位置,表示有数据
{
	value = buf[r];
	r ++;		//下次读取的位置
	
	if(r == 8)	//越界
		r = 0;	//清零 
}

在这里插入图片描述
所以:

  • 变量r和w表示:下次读写的位置

在这里插入图片描述

  • 在这个场景里面,假设我一直都不读取,r一直=0,不断的写,w指向7,如果我把最后的7给写了,那w=0,现在就是r=0,w=0,表示满,那不就和“空”冲突了吗!

2.5 满

所以满的表示方法如下:下一个写位置=读位置

  • 现在w=7,指向了7这个地方,但是现在不写,本来可以写8个数据 ,现在这里面只有7个数据,下一个写位置就是0,等于读位置就表示满!

在这里插入图片描述


2.6伪代码

用一段伪代码来演示,在写函数里判断满或者未满~

	int next_w = w+1;	//下一个写位置
	if (next_w == 8)
		next_w = 0;
	
	//这个时候就可以判断是否满了
	if(next_w == r)	//如果满(下一个写位置等于读位置)
	{}
	else if (next_w != r)	//如果不满(下一个写位置不等于读位置)
}

2.7 有缺陷的环形buffer

(新增一个)写的数量num

在这里插入图片描述

int buf[8];		//
int r=0,w=0;  //读写位置
int num;      //(新增一个)写的数量

读写操作

在这里插入图片描述
这个方法是有缺陷的!~

缺陷:num是全局变量两个任务都想修改它,这样就会有问题

假设num = 10

num++需要的操作

  1. 读入某个寄存器 R0
  2. 寄存器R0++
  3. 把新的值写入num所在的内存
    在这里插入图片描述
  • 任务A是num++,执行到圈1的时候就被切换了
  • 任务B成功读取数据,让num–,从10变成9了
  • 假设这时任务又切换了,执行圈2,数据++之后变成了11 !!!

这样就乱套了

所以不需要加这个num变量,

用 r 和 w ,就没有一个变量同时被改变没有一个变量同时被改变没有一个变量同时被改变,就不会出现上述问题了,不用考虑阻塞和唤醒,也不用考虑效率的问题。


3 学习视频

【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS(FreeRTOS教程 基于STM32,以实际项目为导向)】 【精准空降到 01:31】 https://www.bilibili.com/video/BV1Jw411i7Fz/?p=29&share_source=copy_web&vd_source=8af85e60c2df9af1f0fd23935753a933&t=91

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北国无红豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值