在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法,

当读取速度大于写入速度时,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外)。

在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。

1、环形缓冲区的实现原理

环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。

图 1、图 2 和图 3 是一个环形缓冲区的运行示意图。

图1 初始状态

图二 向环形缓冲区中添加了一个数据

图三环形缓冲区进行了读取和添加

图 1 是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;

图 2 是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块 2 的位置,而读指针没有移动;

图 3 是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,已经读取了一个数据。

这个只是示意图

下面是用C语言写的代码:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #define MAXSIZE 8
  4. int ringbuf[MAXSIZE];
  5. int realdx = 0;
  6. int writeldx = 0;
  7. int next_data_handle(int addr)
  8. {
  9. return (addr+1) == MAXSIZE ? 0 : (addr + 1);
  10. }
  11. int write_data(int data)
  12. {
  13. int i;
  14. *(ringbuf+writeldx)=data;
  15. writeldx = next_data_handle(writeldx);
  16. for(i = 0; i < MAXSIZE; i++)
  17. {
  18. printf("%4d\t",*(ringbuf + i ));
  19. if(MAXSIZE-1 == i)
  20. printf("\n");
  21. }
  22. }
  23. int read_data()
  24. {
  25. printf("read data is : %d\t",*(ringbuf + realdx));
  26. realdx = next_data_handle(realdx);
  27. }
  28. int main(int argc, char *argv)
  29. {
  30. int data;
  31. char cmd;
  32. do{
  33. printf("select:\tw--write:\tr--read:\tq--quit\n");
  34. scanf("%s",&cmd);
  35. switch(cmd)
  36. {
  37. case 'w':
  38. printf("please input data:");
  39. scanf("%d",&data);
  40. write_data(data);
  41. break;
  42. case 'r':
  43. data = read_data();
  44. printf("read all \n");
  45. break;
  46. case 'q':
  47. printf("quit\n");
  48. break;
  49. default:
  50. printf("Command error\n");
  51. break;
  52. }
  53. }while(cmd!='q');
  54. return 0;
  55. }

执行的结果如下:

主要是要理解这个环形设计的思想。

转自:http://blog.csdn.net/u011046042/article/details/51853535

环形缓冲区的应用ringbuffer的更多相关文章

  1. 物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区

    物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区 随着5G的普及,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Applicatio ...

  2. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  3. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  4. 35.Linux-分析并制作环形缓冲区

    在上章34.Linux-printk分析.使用printk调试驱动里讲述了: printk()会将打印信息存在内核的环形缓冲区log_buf[]里, 可以通过dmesg命令来查看log_buf[] 1 ...

  5. input子系统事件处理层(evdev)的环形缓冲区【转】

    在事件处理层(evdev.c)中结构体evdev_client定义了一个环形缓冲区(circular buffer),其原理是用数组的方式实现了一个先进先出的循环队列(circular queue), ...

  6. 环形缓冲区-模仿linux kfifo【转】

    转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...

  7. linux网络编程--Circular Buffer(Ring Buffer) 环形缓冲区的设计与实现【转】

    转自:https://blog.csdn.net/yusiguyuan/article/details/18368095 1. 应用场景 网络编程中有这样一种场景:需要应用程序代码一边从TCP/IP协 ...

  8. linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4262445.html 操作系统:ubuntu10.04 前言:     在嵌入式开发中,只要是带操作系统的 ...

  9. STM32进阶之串口环形缓冲区实现(转载)

    转载自微信公众号“玩转单片机”,感谢原作者“杰杰”. 队列的概念 在此之前,我们来回顾一下队列的基本概念:队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO) ...

随机推荐

  1. 派派和京东的paipai域名之争

    最近有一款叫“派派”的APP很火,微博上.电梯里.群里到处都是推广广告.不仅如此,还有大张伟.关晓彤.王祖蓝等十几个明星发帖为“派派”站台.有消息称,派派这段时间仅线上推广就花去了约1600万. 总融 ...

  2. Mssql 比较好的写法

    DECLARE @date DATETIME= '2016-11-01'; DECLARE @date2 DATETIME= DATEADD(day, 1, @date); Declare @1 Ta ...

  3. Spring初学之annotation实现AOP前置通知和后置通知

    实现两个整数的加减乘除,并在每个计算前后打印出日志. ArithmeticCalculator.java: package spring.aop.impl; public interface Arit ...

  4. bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Descripti ...

  5. (转) Nova是如何统计OpenStack资源

    引言 运维的同事常常遇到这么四个问题: Nova 如何统计 OpenStack 计算资源? 为什么 free_ram_mb, free_disk_gb 有时会是负数? 即使 free_ram_mb, ...

  6. db2数据导出导入del与ixf格式区别

    之前做数据迁移的时候遇到乱码的一些坑,总结一下.  一般导入导出: db2 export to /home/xxxx.del of del select * from tablename db2 im ...

  7. R语言可视化

    R语言基础(一) 可视化基础   ##数据获取 x1=round(runif(100,min=80,max=100)) x2=round(rnorm(100,mean=80, sd=7)) x3=ro ...

  8. 2017-02-20 可编辑div中如何在光标位置添加内容

    之前做了一个可编辑div需要在里面插入内容,搜了好多代码,就这个能实现我的功能,记录一下,以备以后用 <!DOCTYPE HTML> <html> <head> & ...

  9. C#中List<object>.Clear()方法和实例化new List<object>()操作的结果分析

    本文主要的目的是想简单的探讨一下C#中List针对内存的操作过程,以便以后遇到该种情况可以避免走进误区,内容非常简单,只是在此作为记录.能帮到人最好,帮不到就当给自己提个醒.C#将复杂的指针操作全都隐 ...

  10. os.path.abspath()的作用

    语法 os.path.abspath(path) 作用 返回绝对路径 实例 import os print(os.path.abspath(".")) #当前目录的绝对路径 pri ...