zoukankan      html  css  js  c++  java
  • 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮。

    嵌入式框架Zorb Framework搭建过程

    嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统

    嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    嵌入式框架Zorb Framework搭建三:列表的实现

    嵌入式框架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

      版权所有,转载请打赏哟

    如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

  • 相关阅读:
    魅力惠_百度百科
    新奢侈主义_百度百科
    FastSocket学习笔记~再说客户端与服务端的组成
    在线支付文章索引(支付宝_微信_银联)
    微信JSApi支付~微信支付代理模式的实现(原创)
    爱上MVC~ajax调用分部视图session超时页面跳转问题
    C#~异步编程再续~await与async引起的w3wp.exe崩溃-问题友好的解决
    poj-3895-Cycles of Lanes 简单DFS
    How to search a table in a store proc and open the store proc
    Github-Client(ANDROID)开源之旅(四) ------ 简介Roboguice
  • 原文地址:https://www.cnblogs.com/54zorb/p/9278680.html
Copyright © 2011-2022 走看看