zl程序教程

您现在的位置是:首页 >  工具

当前栏目

环形缓冲区的应用ringbuffer

应用 缓冲区 环形
2023-09-14 08:58:46 时间

在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法,
当读取速度大于写入速度时,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外)。


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

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. }  
  24. int read_data()  
  25. {  
  26.         printf("read data is : %d\t",*(ringbuf + realdx));  
  27.         realdx = next_data_handle(realdx);  
  28. }  
  29. int main(int argc, char *argv)  
  30. {  
  31.         int data;  
  32.         char cmd;  
  33.   
  34.         do{  
  35.         printf("select:\tw--write:\tr--read:\tq--quit\n");  
  36.         scanf("%s",&cmd);  
  37.         switch(cmd)  
  38.         {  
  39.                 case 'w':  
  40.                 printf("please input data:");  
  41.                 scanf("%d",&data);  
  42.                 write_data(data);  
  43.                 break;  
  44.                 case 'r':  
  45.                 data = read_data();  
  46.                 printf("read all \n");  
  47.                 break;  
  48.                 case 'q':  
  49.                 printf("quit\n");  
  50.                 break;  
  51.                 default:  
  52.                 printf("Command error\n");  
  53.                 break;  
  54.         }  
  55.         }while(cmd!='q');  
  56.         return 0;  
  57. }  

执行的结果如下:



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


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