嵌入式框架Zorb Framework搭建二:环形缓冲区的实现
我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮。
嵌入式框架Zorb Framework搭建过程
嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统
嵌入式框架Zorb Framework搭建二:环形缓冲区的实现
一、前言
在这一篇中,我们将为Zorb Framework提供环形缓冲区的功能。环形缓冲区主要应用在字节数据流传输上,如串口、网口的收发都可以通过环形缓冲区进行缓存。例如我要通过串口发送命令“LED ON”来控制开发板的led灯亮起来,但开发板串口接收不是一次把“LED ON”同时接收,而是一个字节一个字节地接收,因此需要使用缓冲区来缓存数据,然后解析器来解析缓冲区的数据。
二、环形缓冲区设计
我们先来看看要实现的缓冲区长什么样子,提供什么功能,这样方便我们设计。
初步要提供的功能如下:
1、要有可以缓存数据的空间
2、可以知道总空间的大小
3、可以知道已用空间的数量
4、可以压入数据
5、可以弹出数据
6、我也可以在不弹出数据的情况下,读到特定长度的数据
因此,初步设计的数据结构如下:
1 /* 环形缓冲区数据结构 */ 2 typedef struct _RingBuffer 3 { 4 bool IsExternBuffer; /* 是否外部缓冲区,是则销毁时不释放 */ 5 uint8_t *pBuf; /* 缓冲区指针 */ 6 uint32_t Head; /* 缓冲区头地址 */ 7 uint32_t Trail; /* 缓冲区尾地址 */ 8 uint32_t Size; /* 缓冲区大小 */ 9 uint32_t Count; /* 数据字节数 */ 10 11 /* 缓冲器是否已满 */ 12 bool (*IsFull)(struct _RingBuffer * const pRb); 13 14 /* 缓冲器是否空 */ 15 bool (*IsEmpty)(struct _RingBuffer * const pRb); 16 17 /* 压入一个字节 */ 18 bool (*SaveByte)(struct _RingBuffer * const pRb, uint8_t byte); 19 20 /* 取出一个字节 */ 21 bool (*GetByte)(struct _RingBuffer * const pRb, uint8_t *pByte); 22 23 /* 读取缓冲器已使用字节个数 */ 24 uint32_t (*GetCount)(struct _RingBuffer * const pRb); 25 26 /* 读取n个字节(n超过最大数据数时全部读出) */ 27 bool (*ReadBytes)(struct _RingBuffer * const pRb, uint8_t *pArray, 28 uint32_t n); 29 30 /* 丢弃n个字节(n超过最大数据数时全部丢弃) */ 31 bool (*DropBytes)(struct _RingBuffer * const pRb, uint32_t n); 32 33 /* 清空缓冲器 */ 34 bool (*Clear)(struct _RingBuffer * const pRb); 35 36 /* 释放缓冲器(不释放外部创建的缓冲区) */ 37 bool (*Dispose)(struct _RingBuffer * const pRb); 38 } RingBuffer;
其实按实际需要,可能远不止上面提到的6种情况,例如我可以丢弃特定数量的字节数据,也可以直接清空掉缓冲区数据,甚至可以设想提供动态缓冲区的功能,也就是说可以释放缓冲器自己。
缓冲区已经设计好了,具体实现请看附件代码或在文末的github地址拉框架源码。
三、环形缓冲区结果测试
简单的测试代码如下:
1 /** 2 ***************************************************************************** 3 * @file app_buffer.c 4 * @author Zorb 5 * @version V1.0.0 6 * @date 2018-06-28 7 * @brief 环形缓冲区测试的实现 8 ***************************************************************************** 9 * @history 10 * 11 * 1. Date:2018-06-28 12 * Author:Zorb 13 * Modification:建立文件 14 * 15 ***************************************************************************** 16 */ 17 18 #include "app_buffer.h" 19 #include "zf_includes.h" 20 21 /* 环形缓冲区指针 */ 22 RingBuffer *rb; 23 24 /****************************************************************************** 25 * 描述 :任务初始化 26 * 参数 :无 27 * 返回 :无 28 ******************************************************************************/ 29 void App_Buffer_init(void) 30 { 31 /* 创建500字节的缓冲区 */ 32 RB_create(&rb, 500); 33 } 34 35 /****************************************************************************** 36 * 描述 :任务程序 37 * 参数 :无 38 * 返回 :无 39 ******************************************************************************/ 40 void App_Buffer_process(void) 41 { 42 uint32_t i; 43 uint8_t buf[11]; 44 uint8_t byte; 45 46 ZF_DEBUG(LOG_D, "rb count before adding data is %d\r\n", rb->Count); 47 48 /* 填充10个字节数据(0-9) */ 49 for (i = 0; i < 10; i++) 50 { 51 rb->SaveByte(rb, i); 52 } 53 54 ZF_DEBUG(LOG_D, "rb count after adding data is %d\r\n", rb->Count); 55 56 /* 读出数据看是否正确 */ 57 rb->ReadBytes(rb, buf, 10); 58 59 ZF_DEBUG(LOG_D, "rb data is "); 60 61 for (i = 0; i < 10; i++) 62 { 63 ZF_DEBUG(LOG_D, "%d ", buf[i]); 64 } 65 66 ZF_DEBUG(LOG_D, "\r\n\r\n"); 67 68 /* 弹出数据 */ 69 for (i = 0; i < 10; i++) 70 { 71 rb->GetByte(rb, &byte); 72 73 ZF_DEBUG(LOG_D, "byte %d is %d\r\n", i, byte); 74 ZF_DEBUG(LOG_D, "rb count is %d\r\n", rb->Count); 75 } 76 77 while(1); 78 } 79 80 /******************************** END OF FILE ********************************/
结果:
rb count before adding data is 0 rb count after adding data is 10 rb data is 0 1 2 3 4 5 6 7 8 9 byte 0 is 0 rb count is 9 byte 1 is 1 rb count is 8 byte 2 is 2 rb count is 7 byte 3 is 3 rb count is 6 byte 4 is 4 rb count is 5 byte 5 is 5 rb count is 4 byte 6 is 6 rb count is 3 byte 7 is 7 rb count is 2 byte 8 is 8 rb count is 1 byte 9 is 9 rb count is 0
四、最后
本篇为Zorb Framework提供了环形缓冲区功能,只要涉及到字节流通信,基本都需要缓冲区来实现,可以说应用频率比较高。现在造了这个轮子,后面就可以直接造跑车了。
Zorb Framework github:https://github.com/54zorb/Zorb-Framework
版权所有,转载请打赏哟
如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟