在线时间44 小时
UID2107536
注册时间2014-9-16
NXP金币0
该用户从未签到
高级会员

- 积分
- 653
- 最后登录
- 2017-11-19
|
在上一篇中,https://www.nxpic.org.cn/module/forum/thread-598619-1-1.html ,说到了非缓冲串口收发的不足,下面就来说说如何使用缓冲收发。
恐怕很多人一提到缓冲,往往想到的是字符数组。这也是最简单有效的缓冲方法了。但是我们在使用数组的时候还要操作记录缓冲区长度,接受到的字符数量,但是更重要的是数组的利用效率低。举个例子:
一个可以存10个元素的数组:在某一时刻,接受到了5个元素,并填到了缓冲区中:
------------------------------------------------------
1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------------------
H e L L o |
------------------------------------------------------
某一时刻,程序从缓冲区中读取了两个元素,分别是H和e。此时缓冲区中数据如下所示:
------------------------------------------------------
1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------------------
L L o |
------------------------------------------------------
此时,又接受到了5个字符world,此时如下所示:
------------------------------------------------------
1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------------------
L L o w o r l d |
------------------------------------------------------
好了,现在问题来了,下一个元素往什么地方放呢?读取的时候应该从什么地方读呢?如果使用单纯的缓冲区的话,必然能够造成文件空洞(像图中的1,2),使缓冲区的效率不高。所以这时候队列产生了,队列本着一种先进先出的原则,提高了缓冲区的利用率。有的地方也称之为ringbuffer。
现在我们假定有三个变量维护这个缓冲区数组,int head,tail,count。其中head一直指向下一个要读的位置,而tail一直指向下一个要写的位置。count表明队列中一共有多少数据。自然的要想到下面几行代码:
int rbWrite(uint8_t *buffer,uint8_t data)
{
if(count ==10 ) //队列满,
{return 0;}
else
{
buffer[tail]=data;
tail++;
count++;
return 1;
}
}
请注意tail++这个语句,如果已经到了队尾,再次++,那么tail现在已经是10了,那么下一次访问buffer[10],由于buffer元素的索引时[0-9],那么必然导致溢出,产生错误。
所以可以使用下面的代码:
tail = (tail + 1) % 10; //10是buffer的长度。
下面是我实现的ringbuffer的代码,仅供参考:
由于社区不能上传.h .c文件,所以我将.c .h文件改成xxx.h.tar,所以大家在下载完之后,千万不要解压!!!!!!只需将后缀名的.tar去掉即可!!!!
|
|