自定义环形缓冲区2

该代码实现了一个环形缓冲区的数据结构,包括初始化、读取、写入、数据移除和清理等功能。RingBuffer结构体定义了缓冲区的核心属性,如读写索引、数据长度和最大容量。提供的函数用于在缓冲区中添加和提取数据,支持调试输出,确保数据操作的正确性。
摘要由CSDN通过智能技术生成

头文件:ring_buffer.h

#ifndef __RING_BUFFER_H__
#define __RING_BUFFER_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>

#define RING_BUFFER_DEGUG 1
/*
缓冲区示意图:
buffer                  是缓冲区的内存起始地址
read_ofs            读数据的索引
write_ofs           写数据索引
max_len             缓冲区最大数据大小
len                         已经存入数据的大小
-------- -----------------read_ofs---------------------------write_ofs --------------------
            *****************|***************************|***********************
            ********************************************************************
            ********************************************************************
-----buffer ---------------------------------- max---------------------------------------------|

*/
typedef struct
{
    uint16_t read_ofs;
    uint16_t write_ofs;
    uint16_t len;
    uint16_t max;
    uint8_t *buffer;
} RingBuffer;

/*

功能:环形缓冲区初始化
参数:
    max_len 预定义缓冲区大小

*/
void InitRingBuff(RingBuffer *p_ring, uint8_t *buffer, uint32_t max_len);

/*
环形缓冲区释放
*/
//void FreeRingBuff(RingBuffer *p_ring);

/*
 功能:
       从缓冲区读数据 并移除已经读取到的数据
参数
    pBuff       读取数据的存储控制起始地址
    len             希望读取到的数据大小
返回值:
    返回实际读取的数据
*/
int ReadRingBuff(RingBuffer *p_ring, uint8_t *pBuff, int len);

/*
 功能:
       向缓冲区写数据
参数
    pBuff       待写入数据的存储控制起始地址
    AddLen             希望写入缓冲区的到的数据大小
返回值:
    返回实际写入的数据大小 返回0 写入失败
*/
int WriteRingBuff(RingBuffer *p_ring, uint8_t *pBuff, int AddLen);
/*
 功能:
    读取指定位置的数据 ,
参数:
    index 位置都是处于有数据的位置开始

*/
uint8_t read_u8_from_index(RingBuffer *p_ring, uint16_t index);

/*
 功能:
    获取缓冲区有多少数据
返回值:
    返回缓冲区已经存储的数据大小
*/
uint16_t get_count(RingBuffer *p_ring);

/*
功能:
    从指定位置获取指定长度的数据,并移除其数据
参数:
    p_ring 待操作的缓冲区
    data 存储数据的缓冲区地址
    len 获取数据的长度
返回值:
    返回获取到的数据数量
*/
uint16_t read_data_ofs(RingBuffer *p_ring, uint8_t *data, const uint16_t len, const uint16_t offset);

/**
 * 从环形缓冲区内部移除指定长度的数据
 * @description 
 * @param {RingBuffer} p_ring 待移除的环形缓冲区
 * @param {uint16_t} remove_len 需要移除的长度
 * @return {*}  返回0:移除失败,可能是移除长度参数错误,返回>0 就是实际移除的数据长度
 */
uint16_t remove_data(RingBuffer *p_ring, uint16_t remove_len);
/*
	清除所有数据
*/
uint16_t ring_clean(RingBuffer *p_ring);

#endif //RING_BUFFER

源文件:ring_buffer.c

#include "ring_buffer.h"

//环形缓冲区初始化
void InitRingBuff(RingBuffer *p_ring, uint8_t *buffer,uint32_t max_len)
{
    //p_ring->buffer = (uint8_t *)malloc(max_len);
		p_ring->buffer = buffer;
    memset(p_ring->buffer, 0, max_len);
    p_ring->read_ofs = 0;
    p_ring->write_ofs = 0;
    p_ring->len = 0;
    p_ring->max = max_len;
}

环形缓冲区释放
//void FreeRingBuff(RingBuffer *p_ring)
//{
    if (NULL != p_ring->buffer)
    {
        free(p_ring->buffer);
    }
//}

//向缓冲区写数据
int WriteRingBuff(RingBuffer *p_ring, uint8_t *pBuff, int AddLen)
{
    //uint16_t len = 0;
    //uint16_t remain = 0;
    if (p_ring->buffer == NULL)
    {
			#if RING_BUFFER_DEGUG>1
        printf("%s %d WriteRingBuff:RingBuff is not Init!\r\n",__FILE__,__LINE__);
			#endif 
        return 0;
    }
    //计算最多可以写入的数据长度
    if (AddLen >= p_ring->max - p_ring->len)
    {
        AddLen = p_ring->max - p_ring->len;
				#if RING_BUFFER_DEGUG>1
        printf("%s %d  kong jian bu zu %d\r\n",__FILE__,__LINE__, AddLen);
				#endif 
    }
    for (uint16_t i = 0; i < AddLen; i++)
    {

        p_ring->buffer[p_ring->write_ofs] = pBuff[i];
        p_ring->write_ofs = (++p_ring->write_ofs) % p_ring->max;
    }
    p_ring->len += AddLen;
		#if RING_BUFFER_DEGUG>2
    printf("%s %d write : ",__FILE__,__LINE__);
		
    for (uint16_t i = 0; i < p_ring->max; i++)
    {
        printf("%02x ", p_ring->buffer[i]);
    }
    printf("\r\n ");
    printf("read = %d write =  %d  len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
		#endif 
    return AddLen;
}
/*
    从缓冲区读数据 并移除已经读取到的数据
*/
int ReadRingBuff(RingBuffer *p_ring, uint8_t *pBuff, int read_len)
{
   // uint16_t len = 0;
   // uint16_t alread_read = 0;
   // uint16_t remain = 0;
    if (p_ring->buffer == NULL)
    {
      	#if RING_BUFFER_DEGUG>1
        printf("%s %d don't init RingBuffer\r\n",__FILE__,__LINE__);
			#endif 
        return 0;
    }
    if (read_len > p_ring->len)
    {
        read_len = p_ring->len;
       	#if RING_BUFFER_DEGUG>1
        printf("%s %d read data only \r\n",__FILE__,__LINE__);
			#endif 
    }
    for (uint16_t i = 0; i < read_len; i++)
    {
        pBuff[i] = p_ring->buffer[p_ring->read_ofs];
        p_ring->read_ofs = (++p_ring->read_ofs) % p_ring->max;
    }
    p_ring->len -= read_len;

    	#if RING_BUFFER_DEGUG>2
        printf("%s %d read : ",__FILE__,__LINE__);
    for (uint16_t i = 0; i < read_len; i++)
    {
        printf("%02x ", pBuff[i]);
    }
    printf("\r\n ");
    printf("read = %d write =  %d  len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
		#endif 
    return read_len;
}

/*
    获取缓冲区有多少数据
*/
uint16_t get_count(RingBuffer *p_ring)
{
    return p_ring->len;
}

/*
    读取指定位置的数据 ,位置都是处于有数据的位置开始

*/
uint8_t read_u8_from_index(RingBuffer *p_ring, uint16_t index)
{
    uint16_t real_index = 0;
    if (index > p_ring->len - 1)
    {
       	#if RING_BUFFER_DEGUG>1
        printf("%s %d index error\r\n",__FILE__,__LINE__);
			#endif 
    }
    real_index = (p_ring->read_ofs + index) % p_ring->max;
    return p_ring->buffer[real_index];
}
/*
功能:
    从指定位置获取指定长度的数据,并移除其数据
参数:
    p_ring 待操作的缓冲区
    data 存储数据的缓冲区地址
    len 获取数据的长度
返回值:
    返回获取到的数据数量
*/
uint16_t read_data_ofs(RingBuffer *p_ring, uint8_t *data, const uint16_t len, const uint16_t offset)
{

    if ((len + offset) > p_ring->len)
    {
			#if RING_BUFFER_DEGUG>1
        printf("%s %d get data fail...\r\n", __FILE__, __LINE__);
			#endif 
    }
    p_ring->read_ofs +=offset; 
    for (uint32_t i = 0; i < len; i++)
    {
        
        data[i]= p_ring->buffer[p_ring->read_ofs];
        p_ring->read_ofs = (++p_ring->read_ofs)%p_ring->max;
    }
    p_ring->len -= (len+offset);
		#if RING_BUFFER_DEGUG>2
       printf("%s %d read = %d write =  %d  len = %d\r\n", __FILE__, __LINE__, p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
		#endif 
    return len;
}

uint16_t remove_data(RingBuffer *p_ring,uint16_t remove_len)
{
    if(remove_len >p_ring->len )
    {
			#if RING_BUFFER_DEGUG>1
        printf("%s %d param error \r\n",__FILE__,__LINE__);
			#endif 
        return 0;
    }
    p_ring->read_ofs= (p_ring->read_ofs+remove_len)%p_ring->max;
    p_ring->len-=remove_len; 

   	#if RING_BUFFER_DEGUG>2
        printf("%s %d remove later : ",__FILE__,__LINE__);
    for (uint16_t i = 0; i < p_ring->max; i++)
    {
        printf("%02x ", p_ring->buffer[i]);
    }
    printf("\r\n ");
    printf("read = %d write =  %d  len = %d\r\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
		#endif 
		return remove_len;
}
/*
	清除所有数据
*/
uint16_t ring_clean(RingBuffer *p_ring)
{
	if(p_ring!=NULL)
	{
		p_ring->len=0;
		p_ring->read_ofs=0;
		p_ring->write_ofs=0;
	}
	return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Car12

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值