结构示意图
#ifndef __RING_BUFFER_H__
#define __RING_BUFFER_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
/*
缓冲区示意图:
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,uint16_t max_len);
/*
环形缓冲区释放
*/
void FreeRingBuff(RingBuffer *p_ring);
/*
功能:
从缓冲区读数据 并移除已经读取到的数据
参数
pBuff 读取数据的存储控制起始地址
len 希望读取到的数据大小
返回值:
返回实际读取的数据
*/
int ReadRingBuff(RingBuffer *p_ring,char *pBuff, int len);
/*
功能:
向缓冲区写数据
参数
pBuff 待写入数据的存储控制起始地址
AddLen 希望写入缓冲区的到的数据大小
返回值:
返回实际写入的数据大小 返回0 写入失败
*/
int WriteRingBuff(RingBuffer *p_ring,char *pBuff, int AddLen);
/*
功能:
读取指定位置的数据 ,
参数:
index 位置都是处于有数据的位置开始
*/
uint8_t read_u8(RingBuffer *p_ring,uint16_t index);
/*
功能:
获取缓冲区有多少数据
返回值:
返回缓冲区已经存储的数据大小
*/
uint16_t get_count(RingBuffer *p_ring);
#endif //RING_BUFFER
第一版代码
分为两段两次分别填充
#include "ring_buffer.h"
//环形缓冲区初始化
void InitRingBuff(RingBuffer *p_ring, uint16_t max_len)
{
p_ring->buffer = (uint8_t*)malloc(max_len);
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,char *pBuff, int AddLen)
{
uint16_t len = 0;
uint16_t remain = 0;
if (p_ring->buffer == NULL)
{
printf("WriteRingBuff:RingBuff is not Init!\n");
return 0;
}
//计算最多可以写入的数据长度
if (AddLen >= p_ring->max - p_ring->len)
{
AddLen = p_ring->max - p_ring->len;
printf(" kong jian bu zu\n");
}
//先写入到缓冲区的后半部分;在写入缓冲区的前半部分;
if (AddLen >= p_ring->max - p_ring->len)
{
len = p_ring->max - p_ring->len;
remain = AddLen - len;
}
else
{
len = AddLen;
}
printf("write len =%d \n", len);
memcpy(p_ring->buffer + p_ring->write_ofs, pBuff, len);
p_ring->len += len;
p_ring->write_ofs += len;
if (p_ring->write_ofs >= p_ring->max)
{
p_ring->write_ofs = 0;
}
//处理剩余没有写入的数据
if (remain > 0 && p_ring->max - p_ring->len > 0)
{
memcpy(p_ring->buffer, pBuff, len);
p_ring->len += len;
p_ring->write_ofs = len;
}
if (p_ring->write_ofs >= p_ring->max)
{
p_ring->write_ofs = 0;
}
printf("write : ");
for (uint16_t i = 0; i < p_ring->max; i++)
{
printf("%02x ", p_ring->buffer[i]);
}
printf("\n ");
printf("read = %d write = %d len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
return AddLen;
}
/*
从缓冲区读数据 并移除已经读取到的数据
*/
int ReadRingBuff(RingBuffer *p_ring,char *pBuff, int read_len)
{
uint16_t len = 0;
uint16_t alread_read = 0;
uint16_t remain = 0;
if (p_ring->buffer == NULL)
{
printf("don't init RingBuffer\n");
return 0;
}
if (read_len > p_ring->len)
{
read_len = p_ring->len;
printf("read data only \n");
}
if (read_len > p_ring->max - p_ring->read_ofs)
{
len = p_ring->max - p_ring->read_ofs;
remain = read_len - len;
}
else
{
len = read_len;
}
memcpy(pBuff, p_ring->buffer + p_ring->read_ofs, len);
p_ring->read_ofs += len;
p_ring->len -= len;
alread_read += len;
if (p_ring->read_ofs >= p_ring->max)
{
p_ring->read_ofs = 0;
}
//处理尾端没有一次行读取完的
if (remain > 0)
{
memcpy(pBuff + alread_read, p_ring->buffer + p_ring->read_ofs, remain);
p_ring->read_ofs += remain;
p_ring->len -= remain;
}
if (p_ring->len == 0)
{
p_ring->read_ofs = 0;
p_ring->write_ofs = 0;
}
printf("read : ");
for (uint16_t i = 0; i < read_len; i++)
{
printf("%02x ", pBuff[i]);
}
printf("\n ");
printf("read = %d write = %d len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
return read_len;
}
/*
获取缓冲区有多少数据
*/
uint16_t get_count(RingBuffer *p_ring)
{
return p_ring->len;
}
/*
读取指定位置的数据 ,位置都是处于有数据的位置开始
*/
uint8_t read_u8(RingBuffer *p_ring,uint16_t index)
{
uint16_t real_index=0;
if(index>p_ring->len-1)
{
printf("index error\n");
}
real_index = (p_ring->read_ofs+index)%p_ring->max;
return p_ring->buffer[real_index];
}
第二版代码
使用取余的方式自动由尾到头
#include "ring_buffer.h"
//环形缓冲区初始化
void InitRingBuff(RingBuffer *p_ring, uint16_t max_len)
{
p_ring->buffer = (uint8_t *)malloc(max_len);
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, char *pBuff, int AddLen)
{
uint16_t len = 0;
uint16_t remain = 0;
if (p_ring->buffer == NULL)
{
printf("WriteRingBuff:RingBuff is not Init!\n");
return 0;
}
//计算最多可以写入的数据长度
if (AddLen >= p_ring->max - p_ring->len)
{
AddLen = p_ring->max - p_ring->len;
printf(" kong jian bu zu %d\n",AddLen);
}
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;
printf("write : ");
for (uint16_t i = 0; i < p_ring->max; i++)
{
printf("%02x ", p_ring->buffer[i]);
}
printf("\n ");
printf("read = %d write = %d len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
return AddLen;
}
/*
从缓冲区读数据 并移除已经读取到的数据
*/
int ReadRingBuff(RingBuffer *p_ring, char *pBuff, int read_len)
{
uint16_t len = 0;
uint16_t alread_read = 0;
uint16_t remain = 0;
if (p_ring->buffer == NULL)
{
printf("don't init RingBuffer\n");
return 0;
}
if (read_len > p_ring->len)
{
read_len = p_ring->len;
printf("read data only \n");
}
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;
printf("read : ");
for (uint16_t i = 0; i < read_len; i++)
{
printf("%02x ", pBuff[i]);
}
printf("\n ");
printf("read = %d write = %d len = %d\n", p_ring->read_ofs, p_ring->write_ofs, p_ring->len);
return read_len;
}
/*
获取缓冲区有多少数据
*/
uint16_t get_count(RingBuffer *p_ring)
{
return p_ring->len;
}
/*
读取指定位置的数据 ,位置都是处于有数据的位置开始
*/
uint8_t read_u8(RingBuffer *p_ring, uint16_t index)
{
uint16_t real_index = 0;
if (index > p_ring->len - 1)
{
printf("index error\n");
}
real_index = (p_ring->read_ofs + index) % p_ring->max;
return p_ring->buffer[real_index];
}
测试代码
#include "ring_buffer.h"
int main()
{
RingBuffer ring;
InitRingBuff(&ring, 7);
uint8_t readBuffer[8];
WriteRingBuff(&ring, "123456789", 9);
WriteRingBuff(&ring, "!@#$", 4);
ReadRingBuff(&ring, readBuffer, 3);
WriteRingBuff(&ring, "abcd", 4);
//ReadRingBuff(readBuffer,10);
printf("main read : ");
for (uint16_t i = 0; i < get_count(&ring); i++)
{
printf("%02x ", read_u8(&ring, i));
}
printf("\n ");
return 0;
}