zoukankan      html  css  js  c++  java
  • 一个RingBuffer(C语言)

    也是用于STM32平台下. 通常用于串口通讯缓存.

    之前看到一些其他项目写的Buffer缓存. 实在是太不简洁了, 而且还可能有bug.

    例如

      当处理数据不够快时, 缓存会直接被覆盖, 而不产生任何提示.

      每次Update都判断 read指针 是否等于 write指针, 是的话又重新将 read和write指针置为数组的开头, 在我看来这是完全没有必要的.( 如果硬要说的话, 可以说是便于调试看数据)

    本文仅作简单记录.  代码不是我直接写的, 是我指导同事写的.

    头文件

    #ifndef __RingBuff_H
    #define __RingBuff_H
    
    #include <stdint.h>
    
    #define  RINGBUFF_LEN          512     //定义最大接收字节数 200
    
    
    typedef  struct
    {
      volatile uint32_t ReadCount;
      volatile uint32_t WriteCount;
      uint8_t Ring_Buff[RINGBUFF_LEN];
    }RingBuff_t;
    
    void RingBuff_Init(RingBuff_t *ringBuff);

    //写入RingBuffer缓存

    //返回写入字节数

    uint32_t RingBuffer_WriteBuf(RingBuff_t *ringBuff,uint8_t *buf, uint32_t length);

    //读取RingBuffer数据, 并清除在RingBuffer相关的缓存

    //返回读取到的字节数

    uint32_t RingBuffer_ReadBuf(RingBuff_t *ringBuff,uint8_t *buf, uint32_t length);

    //从RingBuffer中读取一个字节,如果没有读取到内容,则返回-1. int32_t RingBuffer_ReadByte(RingBuff_t
    *ringBuff); //-1 0~255
    //写入一个字节
    int32_t RingBuffer_WriteByte(RingBuff_t *ringBuff,uint8_t byte); //伪读取,因为真的读取的话,会清空读取到的缓存的. 这里是读取到后依然不清除缓存 uint32_t RingBuffer_PseudoReadBuf(RingBuff_t *ringBuff,uint8_t *buf, uint32_t length); #endif

    代码

    #include "RingBuff.h"
    #include "SEGGER_RTT.h"
    
    void _Assert(int a){
        int x=0;
        while(!a){
            x++;
        }
    }
    /*防止数组溢出函数*/
    int _Repeat(int t, int length)
    {
      return t % length;
    }
    /*获取已经写入的空间*/
    int GetReadableSize(RingBuff_t *ringBuff){
        return ringBuff->WriteCount - ringBuff->ReadCount;
    }
    /*获取可写入空间*/
    int GetWritableSize(RingBuff_t *ringBuff)
    {
        return RINGBUFF_LEN - GetReadableSize(ringBuff);
    }
    
    void RingBuff_Init(RingBuff_t *ringBuff)
    {
       //初始化相关信息
       ringBuff->ReadCount = 0;
       ringBuff->WriteCount = 0;
       //ringBuff->Length = 0;
    }
    
    /*断言函数 --
    参数:结构体指针
    数组指针
    数据长度
    1:判断接收到的数据是否为空,如果为空,返回断言 while(1)
    2:判断数据长度是否为空,如果为空,返回断言 while(1)
    3:判断接收的数据长度是否大于等于最大的缓存空间,如果是,返回断言 while(1)
    */
    
    static void CheckArguments(RingBuff_t *ringBuff,uint8_t *buffer,  int count){
        _Assert(buffer !=0);
        _Assert(count >=0);
        _Assert(RINGBUFF_LEN >= count);
    }
    
    //
    static uint32_t Min(uint32_t x,uint32_t y){
        return     x<y ? x:y;
    }
    
    /*函数:
    RingBuff_t* ringBuff --结构体指针
    *buf --指向数据的地址
    length -- 写入的长度
    */
    uint32_t RingBuffer_WriteBuf(RingBuff_t* ringBuff,uint8_t *buf, uint32_t length){
        uint32_t i=0;
        int writeOffset;
        static uint8_t temp=0;
        
        //断言
        CheckArguments(ringBuff, buf, length);
        //断言:判断接收的数据长度是否已经超过缓存数组中的剩余长度,如果是,返回断言 while(1)
        _Assert(GetWritableSize(ringBuff) >= length);
        for ( i = 0; i < length; ++i)
        {
            writeOffset = _Repeat(ringBuff->WriteCount, RINGBUFF_LEN);
        ringBuff->Ring_Buff[writeOffset] = buf[i];
        ++ringBuff->WriteCount;
            
            if(temp >20){
                temp =0;
                SEGGER_RTT_printf(0,"
    ");
            }    
            SEGGER_RTT_SetTerminal(1);
            SEGGER_RTT_printf(0,"[%x]",buf[i]);
            temp++;    
            
        }    
    
        return length;
    }
    uint32_t RingBuffer_ReadBuf(RingBuff_t *ringBuff,uint8_t *buf, uint32_t length){
        uint32_t canReadCount=0,i=0;
        int readOffset;
        CheckArguments(ringBuff,buf, length);    
    
        canReadCount = Min(length, GetReadableSize(ringBuff));
    
        for ( i = 0; i < canReadCount; ++i)
        {
            readOffset = _Repeat(ringBuff->ReadCount, RINGBUFF_LEN);
            buf[i] = ringBuff->Ring_Buff[readOffset];
            ++ringBuff->ReadCount;
        }
        return canReadCount;
    }
    /*  函数--读取数据存放到BUF中*/
    uint32_t RingBuffer_PseudoReadBuf(RingBuff_t *ringBuff,uint8_t *buf, uint32_t length){
        uint32_t canReadCount=0,i=0,readCount,readOffset;
        CheckArguments(ringBuff,buf, length);    
    
        readCount = ringBuff->ReadCount;
        canReadCount = Min(length, GetReadableSize(ringBuff));
        
        for ( i = 0; i < canReadCount; ++i)
        {
            readOffset = _Repeat(readCount, RINGBUFF_LEN);
            buf[i] = ringBuff->Ring_Buff[readOffset];
            ++readCount;
        }
        return canReadCount;
    }
    
    
    int32_t RingBuffer_ReadByte(RingBuff_t *ringBuff){
        uint8_t val;
        uint32_t readed = RingBuffer_ReadBuf(ringBuff,&val,1);
        if(readed ==0)
            return -1;
        return val;
    }
    
    /*
    函数:串口接收到的一个字节,写入到buf中
    参数: RingBuff_t *ringBuff--结构体指针
                byte -- 写入的数据
    返回--uint32_t ret
    */
    int32_t RingBuffer_WriteByte(RingBuff_t *ringBuff,uint8_t byte){
        uint32_t ret = RingBuffer_WriteBuf(ringBuff,&byte,1);
        return ret;
    }
  • 相关阅读:
    PAT (Advanced Level) 1060. Are They Equal (25)
    PAT (Advanced Level) 1059. Prime Factors (25)
    PAT (Advanced Level) 1058. A+B in Hogwarts (20)
    PAT (Advanced Level) 1057. Stack (30)
    PAT (Advanced Level) 1056. Mice and Rice (25)
    PAT (Advanced Level) 1055. The World's Richest (25)
    PAT (Advanced Level) 1054. The Dominant Color (20)
    PAT (Advanced Level) 1053. Path of Equal Weight (30)
    PAT (Advanced Level) 1052. Linked List Sorting (25)
    PAT (Advanced Level) 1051. Pop Sequence (25)
  • 原文地址:https://www.cnblogs.com/godzza/p/15062990.html
Copyright © 2011-2022 走看看