当前位置:网站首页>C language -- ring buffer
C language -- ring buffer
2022-08-04 02:35:00 【Coder_Pixiu】
How the ring buffer works
Ring buffers are fixed-size buffers,Works like memory is contiguous and loopable.在生成和使用内存时,There is no need to clear all the original data,只要调整head/tail指针即可.当添加数据时,head指针前进.当使用数据时,tail指针向前移动.当到达缓冲区的尾部时,指针又回到缓冲区的起始位置.

优势:When there is a lot of data but you don't need to store it all,Computers process data first,After processing, the data will be released,Proceed to the next one.Then the memory for the processed data will be wasted.因为后来的数据只能往后排队,If the remaining data are moved forward once,Efficiency will be greatly reduced.Hence the circular queue.The core is to apply for a piece of memory,Connect them end to end by a special method,形成一个闭环的内存地址.这样既可以继续处理源源不断的数据,There is no need to apply for new memory space to temporarily store new data,效率大大提高.
劣势:One of the most important features of the ring buffer is the matching between the speed of writing and the speed of reading,环形缓冲区一般是将数据先写入缓冲区内,然后有个写的指针位置,但是不能超过读的位置,Because the data has not been read yet,write data,This will cause the data to be overwritten by new data before it has been read,造成数据的丢失.Reading data is the same principle,The read pointer cannot exceed the write location,这样就会读到之前读过的数据,造成数据的重复.空间如果设置的太大,会造成内存的浪费,有内存一直处于空闲状态,If the space is set too small,可能会造成读的速度快于写的速度,导致读的过程中会有短暂的等待时间,造成效率不是最高.
1、写入数据<缓冲区

2、写入数据>缓冲区

代码:
#include "RingBuffer.h"
static UINT16 validlen; //已使用的数据长度
static UINT8* pHead = NULL; //The first address of the ring buffer
static UINT8* pTail = NULL; //Ring buffer end address
static UINT8* pValid = NULL; //The first address of the used buffer
static UINT8* pValidTail = NULL; //The end address of the used buffer
//malloc申请空间
void initRingbuffer(void)
{
if(pHead == NULL)
{
pHead = (char*) malloc(BUFFER_SIZE);
}
pValid = pValidTail = pHead;
pTail = pHead + BUFFER_SIZE;
validlen = 0;
}
//Free the ring buffer
void releaseRingbuffer(void)
{
if(pHead != NULL)
free(pHead);
pHead = NULL;
}
/*************************************************************/
/******功能:Initializes the specified ring buffer *****/
/******param:@buffer:Defines the first address of the static buffer array
param:@size:The size of this buffer ******/
/************************************************************/
void InitRingBuffer(UINT8* buffer, UINT16 size)
{
if(pHead == NULL)
{
pHead = buffer;
}
pValid = pValidTail = pHead;
pTail = pHead + size;
validlen = 0;
}
/***********************************************************/
/******功能:向缓冲区写入数据 *****/
/******param:@buffer 写入的数据指针
@len 写入的数据长度 ******/
/******return:-1 The length of the data written is too large -2:The buffer is not initialized *****/
/***********************************************************/
int writeRingbuffer(UINT8* buffer, UINT32 len)
{
UINT16 len1, len2, movelen;
if(len > BUFFER_SIZE)
{
return -1;
}
if(pHead == NULL)
{
return -2;
}
assert(buffer);
//将要写入的数据copy到pVaildTaill处
if(pValidTail+len > pTail)
{
len1 = pTail - pValidTail; //放到尾部
len2 = len - len1; //The position where the rear can't be put down,从头开始放
memcpy(pValidTail, buffer, len1);
memcpy(pHead, buffer + len1, len2);
pValidTail = pHead + len2; //New valid data
}else
{
memcpy(pValidTail, buffer, len);
pValidTail += len; //End of new valid data area
}
//Recalculate the starting position of the used area
if(validlen + len > BUFFER_SIZE)
{
movelen = validlen + len - BUFFER_SIZE;
if(pValid + movelen > pTail) //需要分成两段
{
len1 = pTail - pValid;
len2 = movelen - len1;
pValid = pHead + len2;
}else
{
pValid += movelen;
}
validlen = BUFFER_SIZE;
}else
{
validlen += len;
}
return 0;
}
/*************************************************************/
/******功能:Reads the specified length of data from the buffer *****/
/******param:@buffer Pointer to receive read data
@length 读取的数据长度 ******/
/******return:-1 The buffer is not initialized >0:Valid data size read *****/
/*************************************************************/
int readRingbuffer(UINT8* buffer, UINT32 len)
{
UINT16 len1, len2;
if(pHead == NULL)
{
return -1;
}
assert(buffer);
if(len > validlen)
{
len = validlen;
}
if(validlen == 0)
{
return 0;
}
if(pValid + len > pTail) //需要分成两段copy
{
len1 = pTail - pValid;
len2 = len - len1;
memcpy(buffer, pValid, len1); //第一段
memcpy(buffer + len1, pHead, len2); //第二段 ,Wrap around to the beginning of the entire store
pValid = pHead + len2; //Update the start of the used buffer
}else
{
memcpy(buffer, pValid, len);
pValid += len; //Update the start of the used buffer
}
validlen -= len; //Update the length of the used buffer
return len;
}
/*************************************************************/
/******功能:Get the used buffer data length *****/
/******param:void ******/
/******return:The data length of the used buffer *****/
/************************************************************/
UINT32 getRingbufferValidLen(void)
{
return validlen;
}
边栏推荐
- Example 039: Inserting elements into an ordered list
- Engineering drawing review questions (with answers)
- 为什么用Selenium做自动化测试
- 融云「音视频架构实践」技术专场【内含完整PPT】
- Security First: Tools You Need to Know to Implement DevSecOps Best Practices
- LeetCode:899. 有序队列【思维题】
- Homemade bluetooth mobile app to control stm8/stm32/C51 onboard LED
- 阿里云国际版基于快照与镜像功能迁移云服务器数据
- TOML配置文件格式,YAML最有力的竞争者
- (cf)Codeforces Round #811 (Div. 3)A--E详细题解
猜你喜欢

系统太多,多账号互通如何实现?

Small Turtle Compilation Notes

实例038:矩阵对角线之和

STM8S105k4t6c--------------点亮LED

Web APIs BOM - operating browser: swiper plug-in

2022焊工(初级)上岗证题目模拟考试平台操作

APP电商如何快速分润分账?

Ant - the design of the Select component using a custom icon (suffixIcon attribute) suffixes, click on the custom ICONS have no reaction, will not display the drop-down menu

Security First: Tools You Need to Know to Implement DevSecOps Best Practices

Flink原理流程图简单记录
随机推荐
出海季,互联网出海锦囊之本地化
There are too many systems, how to realize multi-account interworking?
sqoop ETL工具
Flask Framework Beginner-06-Add, Delete, Modify and Check the Database
yum 仅下载包
参加Oracle OCP和MySQL OCP考试的学员怎样在VUE预约考试
共n级台阶,每次可以上1级或2级台阶,有多少种上法?
Big guys, it takes a long time to read mysql3 million single tables, what parameters can be discounted, or is there any way to hurry up
Multithreading JUC Learning Chapter 1 Steps to Create Multithreading
priority_queue元素为指针时,重载运算符失效
[Playwright Test Tutorial] 5 minutes to get started
关联接口测试
cdh6.x 集成spark-sql
贪吃蛇游戏Bug解析及功能扩展
Web APIs BOM - operating browser: swiper plug-in
QNX Hypervisor] 10.2 vdev 8259 2.2 user manual
大佬们,读取mysql300万单表要很长时间,有什么参数可以优惠,或者有什么办法可以快点
小程序+新零售,玩转行业新玩法!
Continuing to pour money into commodities research and development, the ding-dong buy vegetables in win into the supply chain
STM8S105k4t6c--------------点亮LED