查看: 1799|回复: 3

[其他] 使用队列进行串口收发

[复制链接]

该用户从未签到

9

主题

219

帖子

0

高级会员

Rank: 4

积分
653
最后登录
2017-11-19
发表于 2015-4-24 18:19:44 | 显示全部楼层 |阅读模式
在上一篇中,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去掉即可!!!!

我知道答案 目前已有3人回答

RingBuffer.c.tar

1.5 KB, 下载次数: 5, 下载积分: 威望 1

RingBuffer.h.tar

1.26 KB, 下载次数: 2, 下载积分: 威望 1

回复

使用道具 举报

  • TA的每日心情
    开心
    2017-1-4 14:54
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    5

    主题

    130

    帖子

    0

    高级会员

    Rank: 4

    积分
    585
    最后登录
    2017-2-11
    发表于 2015-4-24 19:26:02 | 显示全部楼层
    不错,学习了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-10 16:14
  • 签到天数: 1442 天

    连续签到: 1 天

    [LV.10]以坛为家III

    17

    主题

    3862

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    8291
    最后登录
    2021-12-10
    发表于 2015-4-24 19:55:31 | 显示全部楼层
    楼主的经验谈,学习了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    91

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    267
    最后登录
    2015-10-23
    发表于 2015-4-26 11:57:03 | 显示全部楼层
    感谢楼主分享!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-21 21:48 , Processed in 0.091788 second(s), 25 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表