嵌入式硬件通信接口:使用RingBuffer处理数据(二)详细设计过程

掘芯
关注

经过上一篇《嵌入式硬件通信接口-使用RingBuffer处理数据(一)》简单了解循环缓冲区,读代码后,接着开始设计自己的循环缓冲区功能模块。

设计思路

这里设计的难点在于,如何把控tail这个写地址,每增加一个数据时tail自增,在写的过程中,如果使用缓冲区的所有空间,那么head等于tail的时候,这个情况可能是空或者满,需要在程序设计时候,多加留意。

在实际项目使用中,仍需要考虑的两个问题:

读多个字节时,缓冲区内可读数量比用户想读的个数少,这时候是逐字节把可读的都读出来,还是直接报错?

写多个字节时,缓冲区内可写数量比用户想写的个数少,这时候是逐字节把可写的都写满,还是直接报错?

鉴于这样的问题,在读多字节和写多字节这两个接口上增加一个变量mode,用于设定接口在读写多字节时遇到长度超出范围,是逐字节继续处理还是直接报错。

还有,相比于上一篇文章中参考的源码,这里的设计思路采用的是地址指针的方式,而不是偏移量

并且为了区别于缓冲区空或者满,将牺牲掉一个字节的空间:当缓冲区空的时候head等于tail,当缓冲区满的时候head在tail相邻的后一个位置。

本次的设计,使用head指向缓冲区中可读数据的首地址,使用tail指向缓冲区中可读数据的末地址(同时这也是可写数据的首地址):

数据流是55 04 18 02 07 B7这样的一连串16进制数,接收端先收到的是0x55,后收到的是0x04,以这样的顺序逐字节通过物理层接口接收。这也是一个数据包的常规帧结构,也符合人从左到右的阅读顺序。

所以在这里以head指向的是数据包的头,tail指向数据包的尾,head到tail之间就是一个可读数据的范围,同时,tail指向的是可写区域的首地址,当有新的数据进来时,新的数据会被从tail地址继续写到内存,而后tail在环内递增。

知道了循环缓冲区的这几个属性:缓冲区大小、缓冲区在内存中的地址范围、存取数据时的读写地址。可根据这些属性,构造一个循环缓冲区的结构体:

typedef struct{

uint32_t    size;

uint8_t    *head;

uint8_t    *tail;

uint8_t    *buff;

}rb_t;

ringbuffer简写rb,其中

size表示用户申请成功的或定义的buffer空间大小;

head是一个地址指针,指向缓冲区读的首地址;

tail也是个地址指针,指向缓冲区读的末地址(也就是写的首地址);

buff还是一个指针,一直指向用户定义或者程序动态申请的内存buffer首地址。

当我们需要使用环形缓冲区前,需要定义数组变量或者申请内存,作为数据实际存储的地方,同时定义一个rb_t的结构体,用于关联数组变量或者内存空间。

功能模块将完成以下接口:

初始化

可读数量

可写数量

读一个字节

读多个字节

写一个字节

写多个字节

查看指定偏移的数据

查看指定数据是否在缓冲区并取其在内存的地址

复位清空

关于命名,暂且做个说明:dcclib是DigCore_Library的简写,这是功能模块库层的代码;rb是ringbuffer模块简写。

初始化

初始化的目的是把用户定义的将要使用的数组,与结构体变量关联起来,后续的操作脱离数组,直接操作结构体变量,正如此,结构体变量的初始化后,将对size、head、tail、buff各个成员赋值。

(截图略.)

可读数量

head指向的是可读数据的首地址,该地址内是有数据可以读的;

tail指向的是可读数据的末地址,该地址内没有数据可读,同时tail指向的是一个空的字节,作为写的首地址。

可写数量

这个需要留意的是总有一个字节空间不可写,因此size大小的空间内,除了可读,剩下就是一个空字节和可写数量

读一个字节

读一个字节时,基于指针地址的操作模式,需要留意的是读指针自增后超过缓冲区的范围时,将读指针折返回到缓冲区的起始位置。

读多个字节

读多个字节,必然是基于读一个字节的基础上实现的。这里相比于前一篇文章提到的参考项目源码,不同的是增加了读模式的选择,当要读的数据个数大于可读数量时,可以利用mode来选择是否仍然逐字节地把能读的都读出来。

如果在调用接口时mode设为FORCE的强制读取,要读的数据个数大于可读数量时,将以RET_RB_RDWRN的错误返回码,旨在说明读取的数据不足,但是也已经把可读的都读出了

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存