缓冲区的基本认识
在进行嵌入式的开发的时候,经常会使用串口,会用到对串口数据的接收或发送,比如log日志的打印,命令的接收,或者解析一些串口设备的数据。等等。
经常会有人碰到数据接收不全,或当串口设备发送的数据前后帧时间间隔比较短时,出现所谓的粘包,而没有办法完成完整的数据的解析。
环形缓冲区可以帮你完成这些操作。
要介绍的是环形缓冲区。先复制一个网上的图片,大家一个环形缓冲区的基本认识。
环形缓冲区,顾名思义就是一个环形。但其实呢,他还是一个线性的数组,是首尾相连的数组而已,所谓首尾相连,就是写或读到最后一个位置的时候,下一次开始操作第一个位置。
两个重要的操作
这其中有个重要的操作就是需要知道什么时候装满了。什么时候取空了。
空:当读的位置追上写的位置,两者相等,即代表空。
满:当写的位置追上读的位置,写的下一个位置和读相等,即代表满。
如果理解了上上面两句,就对这个缓冲的操作基本掌握了。
定义如下接口:
/*初始化全局指针变量*/
extern void buf_ring_init();
/*向缓冲区中写入一个Byte*/
extern int buf_ring_write_ch(const unsigned char ch);
/*从缓冲区中读出一个Byte*/
extern int buf_ring_read_ch(unsigned char *outch);
/*从缓冲区是否空*/
extern int buf_ring_is_empty();
/*从缓冲区是否满*/
extern int buf_ring_is_full();
在中断函数中调用 buf_ring_write_ch 将数据存入缓冲区,
在主函数中调用 ring_read_ch 将数据读出。
以上就是基本思路。
代码实现
==============直接上代码=================
定义一个枚举类型表示buf的状态
typedef enum
{
eBUF_NONE,
eBUF_EMPTY,
eBUF_FULL,
}ebuf_ring_status_t;
定义结构体类型对buf进行管理。
#define BUF_RING_LEN_MAX (1024*4)
typedef struct
{
unsigned char buf[BUF_RING_LEN_MAX];
unsigned short write_index;
unsigned short read_index;
ebuf_ring_status_t status;
}buf_ring_t;
定义缓冲区实体
buf_ring_t buf_ring;
函数实现
void buf_ring_init()
{
buf_ring_t *pbuf = &buf_ring;
pbuf->write_index = 0;
pbuf->read_index = 0;
pbuf->status = eBUF_NONE;
}
是否为空
/**
* @brief
*
* @return int
*/
int buf_ring_is_empty()
{
int ret = 0;
buf_ring_t *pbuf = &buf_ring;
/*when read equal write,buf is empty*/
if(pbuf->read_index == pbuf->write_index)
{
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
是否满
/**
* @brief
*
* @return int
*/
int buf_ring_is_full()
{
int ret = 0;
buf_ring_t *pbuf = &buf_ring;
unsigned short tmp_index = 0;
/*when next write (w+1), is equal read,buf is full*/
tmp_index = (pbuf->write_index+1)%BUF_RING_LEN_MAX;
if(tmp_index == pbuf->read_index)
{
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
还有就是读出和写入一个Byte的操作,这里就不展开了。
可以文末关注我,查看相关原文。有相应的代码。
===============分割线====================
扩展应用
思考一下,其实单片机或嵌入式的中断服务函数和主函数,类似于RTOS中的TASK,或者操作系统中的多线程。此环形缓冲的思路也可以用在上位机软件的多线程中。
一个线程对设备数据进行读取并放入缓冲区。
另一个线程对缓冲区中的数据进行读取然后进行解析。
相信作为开发者的你,读了之后也多少会有收获。同时也可以给出意见。
欢迎关注进行交流。