环形缓冲区及实现原理

上传人:简****9 文档编号:55783195 上传时间:2022-02-18 格式:DOCX 页数:10 大小:47.60KB
收藏 版权申诉 举报 下载
环形缓冲区及实现原理_第1页
第1页 / 共10页
环形缓冲区及实现原理_第2页
第2页 / 共10页
环形缓冲区及实现原理_第3页
第3页 / 共10页
资源描述:

《环形缓冲区及实现原理》由会员分享,可在线阅读,更多相关《环形缓冲区及实现原理(10页珍藏版)》请在装配图网上搜索。

1、在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。1、环形缓冲区的实现原理环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。图1、图

2、2和图3是一个环形缓冲区的运行示意图。图1是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;图2是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块2的位置,而读指针没有移动;图3是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,r4V,甄 2H 卜H53图1环形缓冲因初始状态)工_L mi53 =图3环形缓冲区(施加和强已经读取了一个数据。 A 4即utC后 2 CU | 53图2环形覆件国添加数据)K1眼)2、实例:环形缓冲区的实现环形缓冲区是数据通信程序中使用最为广泛的数据结构之一,下面的代码,实现了一个环形缓冲区:/*ri

3、ngbuf.c*/includeinclude#defineNMAX8intiput=0;/*环形缓冲区的当前放入位置*/intiget=0;/*缓冲区的当前取出位置*/intn=0;/*环形缓冲区中的元素总数量*/doublebufferNMAX;/*环形缓冲区的地址编号计算函数,如果到达唤醒缓冲区的尾部,将绕回到头部。环形缓冲区的有效地址编号为:0到(NMAX-1)*/intaddring(inti)return(i+1)=NMAX?0:i+1;/*从环形缓冲区中取一个元素*/doubleget(void)intpos;if(n0)Pos=iget;iget=addring(iget);n

4、-;returnbufferpos;elseprintf(“Bufferisemptyn”);return0.0;/*向环形缓冲区中放入一个元素*/voidput(doublez)if(nNMAX)bufferiput=z;iput=addring(iput);n+;elseprintf(“Bufferisfulln”);intmainvoid)chatopera5;doublez;doprintf(“Pleaseinputp|g|e?”);scanf(“%s”,&opera);switch(tolower(opera0)casep:/*put*/printf(“Pleaseinputaflo

5、atnumber?”);scanf(“%lf”,&z);put(z);break;caseg:/*get*/z=get();printf(“%8.2ffromBuffern”,z);break;,一,casee:printf(“Endn”);break;default:printf(“%-sOperationcommanderror!n”,opera);/*endswitch*/while(opera0 !=e );return0;在CAN通信卡设备驱动程序中,为了增强CAN通信卡的通信能力、提高通信效率,根据CAN的特点,使用两级缓冲区结构,即直接面向CAN通信卡的收发缓冲区和直接面向系统调

6、用的接收帧缓冲区。通讯中的收发缓冲区一般采用环形队列(或称为FIFO队列),使用环形的缓冲区可以使得读写并发执行,读进程和写进程可以采用生产者和消费者”的模型来访问缓冲区,从而方便了缓存的使用和管理。然而,环形缓冲区的执行效率并不高,每读一个字节之前,需要判断缓冲区是否为空,并且移动尾指针时需要进行折行处理”(即当指针指到缓冲区内存的末尾时,需要新将其定向到缓冲区的首地址);每写一个字节之前,需要判断缓区是否为,并且移动尾指针时同样需要进行“折行处理”。程序大部分的执行过程都是在处理个别极端的情况。只有小部分在进行实际有效的操作。这就是软件工程中所谓的“8比2”关系。结合CAN通讯实际情况,在

7、本设计中对环形队列进行了改进,可以较大地提高数据的收发效率。由于CAN通信卡上接收和发送缓冲器每次只接收一帧CAN数据,而且根据CAN的通讯协议,CAN控制器的发送数据由1个字节的标识符、一个字节的RTR和DLC位及8个字节的数据区组成,共10个字节;接收缓冲器与之类似,也有10个字节的寄存器。所以CAN控制器收的数据是短小的定长帧(数据可以不满8字节)。于是,采用度为10字节的数据块业分配内存比较方便,即每次需要内存缓冲区时,直接分配10个字节,由于这10个字节的地址是线性的,故不需要进行折行”处理。更重要的是,在向缓冲区中写数据时,只需要判断一次是否有空闲块并获取其块首指针就可以了,从而减

8、少了重复性的条件判断,大大提高了程序的执行效率;同样在从缓冲队列中读取数据时,也是一次读取10字节的数据块,同样减少了重复性的条件判断。在CAN卡驱动程序中采用如下所示的称为“Block_Ring_t”的数据结构作为收发数据的缓冲区:typedefstructlongsignature;unsignedchar*head_p;unsignedchar*tail_p;unsignedchar*begin_p;unsignedchar*end_p;unsignedcharbufferBLOCK_RING_BUFFER_SIZE;intusedbytes;Block_Ring_t;该数据结构在通用的

9、环形队列上增加了一个数据成员usedbytes,它表示当前缓冲区中有多少字节的空间被占用了。使用usedbytes,可以比较方便地进行缓冲区满或空的判断。当usedbytes=0时,缓冲区空;当usedbytes=BLOCK_RING_BUFFER_SIZE时,缓冲区满。本驱动程序除了收发缓冲区外,还有一个接收帧缓冲区,接收帧队列负责管理经HilonA协议解包后得到的数据帧。由于有可能要同接收多个数据帧,而根据CAN总线遥通信协议,高优先级的报文将抢占总线,则有可能在接收一个低优先级且被分为好几段发送的数据帧时,被一个优先级高的数据帧打断。这样会出现同时接收到多个数据帧中的数据包,因而需要有个

10、接收队列对同时接收的数据帧进行管理。当有新的数据包到来时,应根据addr(通讯地址),mode(通讯方式),index(数据包的序号)来判断是否是新的数据帧。如果是,则开辟新的frame_node;否则如果已有相应的帧节点存地,则将数据附加到该帧的末尾;在插入数据的同时,应该检查接收包的序号是否正确,如不正确将丢弃这包数据。每次建立新的frame_node时,需要向frame_queue申请内存空间;当frame_queue已满时,释放掉队首的节点(最早接收的但未完成的帧)并返回该节点的指针。当系统调用读取了接收帧后,释放该节点空间,使设备驱动程序可以重新使用该节点。形缓冲区:环形缓冲队列学习

11、来源:发布时间:星期四,2008年9月25日浏览:117次评论:0项目中需要线程之间共享一个缓冲FIFO队列,一个线程往队列中添数据,另一个线程取数据(经典的生产者-消费者问题)。开始考虑用STL的vector容器,但不需要随机访问,频繁的删除最前的元素引起内存移动,降低了效率。使用LinkList做队列的话,也需要频繁分配和释放结点内存。于是自己实现一个有限大小的FIFO队列,直接采用数组进行环形读取。队列的读写需要在外部进程线程同步(另外写了一个RWGuar靛,见另一文)到项目的针对性简单性,实现了一个简单的环形缓冲队列,比STL的vector简单PS:第一次使用模板,原来类模板的定义要放

12、在.h文件中,不然会出现连接错误。templateclassCShareQueuepublic:CShareQueue();CShareQueue(unsignedintbufsize);virtualCShareQueue();_Typepop_front();boolpush_back(_Typeitem);/返回容量unsignedintcapacity()/warning:需要外部数据一致性returnm_capacity;/返回当前个数unsignedintsize()/warning:需要外部数据一致性returnm_size;/是否满/warning:需要外部控制数据一致性boo

13、lIsFull()return(m_size=m_capacity);boolIsEmpty()return(m_size=0);protected:UINTm_head;UINTm_tail;UINTm_size;UINTm_capacity;_Type*pBuf;templateCShareQueue:CShareQueue():m_head(0),m_tail(0),m_size(0)pBuf=new_Type512;/默认512m_capacity=512;templateCShareQueue:CShareQueue(unsignedintbufsize):m_head(0),m_t

14、ail(0)if(bufsize512|bufsize1)pBuf=new_Type512;m_capacity=512;elsepBuf=new_Typebufsize;m_capacity=bufsize;templateCShareQueue:CShareQueue()deletepBuf;pBuf=NULL;m_head=m_tail=m_size=m_capacity=0;/前面弹出一个元素template_TypeCShareQueue:pop_front()if(IsEmpty()returnNULL;_Typeitemtmp;itemtmp=pBufm_head;m_head=(m_head+1)%m_capacity;-m_size;returnitemtmp;/从尾部加入队列templateboolCShareQueue:push_back(_Typeitem)if(IsFull()returnFALSE;pBufm_tail=item;m_tail=(m_tail+1)%m_capacity;+m_size;returnTRUE;#endif/!defined(_DALY_CSHAREQUEUE_H_)

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!