0
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心
发布
  • 发文章

  • 发资料

  • 发帖

  • 提问

  • 发视频

创作活动

完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>

3天内不再提示

基于C语言实现环形缓冲区/循环队列

玩点嵌入式 来源:技术让梦想更伟大 作者:技术让梦想更伟大 2023-04-11 10:39 次阅读

这里分享一个自己用纯C实现的环形缓冲区。

环形缓冲区有很多作用,比如嵌入式中的通信可以用环形缓冲区作为信道,一个线程往里放字节,一个线程取字节进行处理,只要保证取的速度大于读的速度,就可以保证通信顺畅进行,不丢一个字节。

简要介绍:

环形缓冲区其实就是一个队列,里头的元素是先入先出的,但是因为其(逻辑上)是环形的,所以不需要像很多队列的实现那样在内部元素变动的时候需要移动内部剩下的元素。这样就使元素出队入队的时间复杂度只有O(1)。具体实现一般有链表和数组两种方法,当不能确定需要的缓冲区大小时使用链表较好,能确定时使用数组可以节省很多动态分配内存的开销。

嵌入式开发中,一般不动态分配内存,而是使用静态分配的数组。所以这里我使用数组实现了环形缓冲区,为了能够在不同的程序中复用代码,使用结构体模拟了面向对象编程,这样就可以用一套代码管理不同的缓冲区了。

废话不多说,直接上代码。以下是.h 文件:

/*
*********************************************************************************************************
*
*
*RingQueueStruct
*环形队列结构
*
*File:RingQueue.h
*By:LinShijun(http://blog.csdn.net/lin_strong)
*Date:2018/02/23
*version:V1.2
*NOTE(s):这段程序用来对一个给定的缓冲区进行模拟环形队列的管理
*程序本身不会自动分配缓冲区空间,用户需要自己负责分配空间,并且要保证不直接访问缓存区
*//在某处分配内存空间
*RQTYPEbuffer[BUFFER_SIZE];
*RING_QUEUEque,*ptr_que;
*unsignedcharerr;
*//初始化
*ptr_que=RingQueueInit(&que,buffer,BUFFER_SIZE,&err);
*if(err==RQ_ERR_NONE){
*//初始化成功,使用其他函数
*}
*History:2017/04/25theoriginalversionofRingQueueStruct.
*2017/10/16putfunctionsusedfrequently,RingQueueInandRingQueueOut,innon-bankedaddress;
*modifysinglelinefunctionRingQueueIsEmptyandRingQueueIsFulltomarcofunction;
*togetbetterefficiency.
*2018/02/231.addthemarco(RQ_ARGUMENT_CHECK_EN)tocontrollargumentchecksousercansave
*morecode.
*2.addtheADDRESSINGMODEsothebuffercanbedefinedinbankedaddressingarea.
*********************************************************************************************************
*/


#ifndefRING_QUEUE_H
#defineRING_QUEUE_H

/*
********************************************************************************************
*MISCELLANEOUS
********************************************************************************************
*/

#ifndefFALSE
#defineFALSE0
#endif

#ifndefTRUE
#defineTRUE1
#endif

/*
*********************************************************************************************************
*ADDRESSINGMODE寻址模式
*********************************************************************************************************
*/

//uncommentthecorrespondinglinetoselecttheaddressingmodetothebufferofRingQueuemodule.
//ifyoudon'tunderstand.Justusetheextendedaddressingmode
//取消对应行的注释以选择环形缓冲区模块访问缓冲区时使用的寻址方式
//如果你不知道这是什么意思的话,那就用扩展寻址就行了,这是默认的方式

//extendedaddressingmode扩展区寻址(默认)
#defineRQ_ADDRESSING_MODE
//bankedRAMaddressingmodeRAM分页区寻址
//#defineRQ_ADDRESSING_MODE__rptr
//globaladdressingmode全局寻址
//#defineRQ_ADDRESSING_MODE__far

/*
*********************************************************************************************************
*CONFIGURATION配置
*********************************************************************************************************
*/

#defineRQ_ARGUMENT_CHECK_ENTRUE//TRUE:argumentswillbechecked,however,thiswill
//costalittlecodevolume.

/*
*********************************************************************************************************
*CONSTANTS常量
*********************************************************************************************************
*/
#defineRQ_ERR_NONE0u

#defineRQ_ERR_POINTER_NULL1u
#defineRQ_ERR_SIZE_ZERO2u

#defineRQ_ERR_BUFFER_FULL3u
#defineRQ_ERR_BUFFER_EMPTY4u

#defineRQ_OPTION_WHEN_FULL_DISCARD_FIRST0u//discardthefirstelementwhenringbufferisfull
#defineRQ_OPTION_WHEN_FULL_DONT_IN1u//discardnewelementwhenringbufferisfull
/*
*********************************************************************************************************
*DATATYPE数据类型
*********************************************************************************************************
*/

//definethedatatypethatstoresintheRingQueue.定义存在环形缓冲区内的数据的类型
typedefunsignedcharRQTYPE;
typedefRQTYPE*RQ_ADDRESSING_MODEpRQTYPE;
typedefstruct{
unsignedshortRingBufCtr;/*Numberofcharactersintheringbuffer*/
unsignedshortRingBufSize;/*RingbufferSize*/
pRQTYPERingBufInPtr;/*Pointertowherenextcharacterwillbeinserted*/
pRQTYPERingBufOutPtr;/*Pointerfromwherenextcharacterwillbeextracted*/
pRQTYPERingBuf;/*Ringbufferarray*/
pRQTYPERingBufEnd;/*Pointtotheendofthebuffer*/
}RING_QUEUE;

/*
*********************************************************************************************************
*FUNCTIONPROTOTYPES函数原型
*********************************************************************************************************
*/

RING_QUEUE*RingQueueInit(RING_QUEUE*pQueue,pRQTYPEpbuf,unsignedshortbufSize,unsignedchar*perr);
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
unsignedshortRingQueueIn(RING_QUEUE*pQueue,RQTYPEdata,unsignedcharoption,unsignedchar*perr);
RQTYPERingQueueOut(RING_QUEUE*pQueue,unsignedchar*perr);
#pragmaCODE_SEGDEFAULT
shortRingQueueMatch(RING_QUEUE*pQueue,pRQTYPEpbuf,unsignedshortlen);
voidRingQueueClear(RING_QUEUE*pQueue);

/*
*********************************************************************************************************
*RingQueueIsEmpty()
*
*Description:whethertheRingQueueisempty.环形队列是否为空
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*
*Return:TRUEtheRingQueueisempty.
*FALSEtheRingQueueisnotempty.
*Note(s):
*********************************************************************************************************
*/

#defineRingQueueIsEmpty(pQueue)((pQueue)->RingBufCtr==0)

/*
*********************************************************************************************************
*RingQueueIsFull()
*
*Description:whethertheRingQueueisfull.环形队列是否为空
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*
*Return:TRUEtheRingQueueisfull.
*FALSEtheRingQueueisnotfull.
*Note(s):
*********************************************************************************************************
*/

#defineRingQueueIsFull(pQueue)((pQueue)->RingBufCtr>=(pQueue)->RingBufSize)

#endif

然后下面是.c文件。

/*
*********************************************************************************************************
*
*
*RingQueueStruct
*环形队列结构
*
*File:RingQueue.c
*By:LinShijun(http://blog.csdn.net/lin_strong)
*Date:2018/02/23
*version:V1.2
*NOTE(s):
*
*History:2017/04/25theoriginalversionofRingQueueStruct.
*2017/10/16putfunctionsusedfrequently,RingQueueInandRingQueueOut,innon-bankedaddress;
*modifysinglelinefunctionRingQueueIsEmptyandRingQueueIsFulltomarcofunction;
*togetbetterefficiency.
*2018/02/231.addthemarco(RQ_ARGUMENT_CHECK_EN)tocontrollargumentchecksousercansave
*morecode.
*2.addtheADDRESSINGMODEsothebuffercanbedefinedinbankedaddressingarea.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*INCLUDES
*********************************************************************************************************
*/
#include"RingQueue.h"

/*
*********************************************************************************************************
*LOCALFUNCTIONDECLARATION
*********************************************************************************************************
*/

#if(RQ_ARGUMENT_CHECK_EN==TRUE)
#defineargCheck(cond,err,rVal)if(cond){*perr=(err);return(rVal);}
#else
#defineargCheck(cond,err,rVal)
#endif//of(SPI_ARGUMENT_CHECK_EN==TRUE)



/*
*********************************************************************************************************
*LOCALFUNCTIONDECLARE
*********************************************************************************************************
*/
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
//内部使用,给定将给定指针在环形缓冲区内向前移动一步(到尾了会移回头)
staticvoid_forwardPointer(RING_QUEUE*pQueue,pRQTYPE*pPointer);
#pragmaCODE_SEGDEFAULT
/*
*********************************************************************************************************
*RingQueueInit()
*
*Description:Toinitializetheringqueue.初始化环形队列
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*pbufpointertothebuffer(anarray);指向自定义的缓冲区(实际就是个数组)
*bufSizetheSizeofthebuffer;缓冲区的大小;
*perrapointertoavariablecontaininganerrormessagewhichwillbesetbythis
*functiontoeither:
*
*RQ_ERR_NONE
*RQ_ERR_SIZE_ZERO
*RQ_ERR_POINTER_NULL
*
*Return:thepointertotheringqueuecontrolblock;返回指向环形队列控制块的指针
*0x00ifanyerror;如果出错了则返回NULL
*
*Note(s):
*********************************************************************************************************
*/

RING_QUEUE*RingQueueInit(RING_QUEUE*pQueue,pRQTYPEpbuf,unsignedshortbufSize,unsignedchar*perr){
argCheck(pQueue==0x00||pbuf==0x00,RQ_ERR_POINTER_NULL,0x00);
argCheck(bufSize==0,RQ_ERR_SIZE_ZERO,0x00);
pQueue->RingBufCtr=0;
pQueue->RingBuf=pbuf;
pQueue->RingBufInPtr=pbuf;
pQueue->RingBufOutPtr=pbuf;
pQueue->RingBufSize=bufSize;
pQueue->RingBufEnd=pbuf+bufSize;
*perr=RQ_ERR_NONE;
returnpQueue;
}

/*
*********************************************************************************************************
*RingQueueIn()
*
*Description:Enqueueanelement.入队一个元素
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*datathedatatoenqueue;要入队的数据
*optionoptionwhenqueueisfull,youcanchoose:当队列满的时候的选项,你可以选择:
*RQ_OPTION_WHEN_FULL_DISCARD_FIRST抛弃队头的元素来填进去新的元素
*RQ_OPTION_WHEN_FULL_DONT_IN不入队新给的元素
*perrapointertoavariablecontaininganerrormessagewhichwillbesetbythis
*functiontoeither:
*
*RQ_ERR_NONEifnoerrhappen
*RQ_ERR_POINTER_NULLifpointeris0x00
*RQ_ERR_BUFFER_FULLifbufferisfull
*
*Return:theElementsCountafterenqueuetheelement
*调用函数后队列中的元素个数
*Note(s):
*********************************************************************************************************
*/
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
unsignedshortRingQueueIn(RING_QUEUE*pQueue,RQTYPEdata,unsignedcharoption,unsignedchar*perr){
argCheck(pQueue==0x00,RQ_ERR_POINTER_NULL,0x00);
if(pQueue->RingBufCtr>=pQueue->RingBufSize){
*perr=RQ_ERR_BUFFER_FULL;
if(option==RQ_OPTION_WHEN_FULL_DISCARD_FIRST){
_forwardPointer(pQueue,&pQueue->RingBufOutPtr);/*WrapOUTpointer*/
}else{//option==RQ_OPTION_WHEN_FULL_DONT_IN
returnpQueue->RingBufCtr;
}
}else{
pQueue->RingBufCtr++;/*No,incrementcharactercount*/
*perr=RQ_ERR_NONE;
}
*pQueue->RingBufInPtr=data;/*Putcharacterintobuffer*/
_forwardPointer(pQueue,&pQueue->RingBufInPtr);/*WrapINpointer*/
returnpQueue->RingBufCtr;
}
/*
*********************************************************************************************************
*RingQueueOut()
*
*Description:Dequeueanelement.出队一个元素
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*perrapointertoavariablecontaininganerrormessagewhichwillbesetbythis
*functiontoeither:
*
*RQ_ERR_NONEifnoerrhappen
*RQ_ERR_POINTER_NULLifpointeris0x00
*RQ_ERR_BUFFER_EMPTYifbufferisempty
*
*Return:0ifanyerrororthedatais0;
*othersthedata
*
*Note(s):
*********************************************************************************************************
*/
RQTYPERingQueueOut(RING_QUEUE*pQueue,unsignedchar*perr){
RQTYPEdata;
argCheck(pQueue==0x00,RQ_ERR_POINTER_NULL,0x00);
if(pQueue->RingBufCtr==0){
*perr=RQ_ERR_BUFFER_EMPTY;
return0;
}
pQueue->RingBufCtr--;/*decrementcharactercount*/
data=*pQueue->RingBufOutPtr;/*Getcharacterfrombuffer*/
_forwardPointer(pQueue,&pQueue->RingBufOutPtr);/*WrapOUTpointer*/
*perr=RQ_ERR_NONE;
returndata;
}
#pragmaCODE_SEGDEFAULT
/*
*********************************************************************************************************
*RingQueueMatch()
*
*Description:MatchthegivenbufferinRingQueue在环形队列中匹配给定缓冲区
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*pbufpointertothecharsneedtomatch;
*lenthelengthofthechars
*Return:-1Don'tmatch-1则没有匹配到
*>=0match>=0则匹配到了
*
*Note(s):
*********************************************************************************************************
*/

shortRingQueueMatch(RING_QUEUE*pQueue,pRQTYPEpbuf,unsignedshortlen){
pRQTYPEpPosQ,pCurQ,pCurB,pEndB;
unsignedshortrLen,Cnt;
if(len>pQueue->RingBufCtr)
return-1;
pPosQ=pQueue->RingBufOutPtr;
pEndB=pbuf+len;
Cnt=0;
rLen=pQueue->RingBufCtr;
while(rLen-->=len){//ifremianlengthofqueuebiggerthanbuffer.continue
pCurQ=pPosQ;
pCurB=pbuf;
while(pCurB!=pEndB&&*pCurQ==*pCurB){//compareonebyone,untilmatchall(pCurB==pEndB)orsomeonedon'tmatch
_forwardPointer(pQueue,&pCurQ);
pCurB++;
}
if(pCurB==pEndB)//ifmatchall
returnCnt;
Cnt++;
_forwardPointer(pQueue,&pPosQ);
}
return-1;
}

/*
*********************************************************************************************************
*RingQueueClear()
*
*Description:CleartheRingQueue.清空环形队列
*
*Arguments:pQueuepointertotheringqueuecontrolblock;指向环形队列控制块的指针
*
*Return:
*
*Note(s):
*********************************************************************************************************
*/

voidRingQueueClear(RING_QUEUE*pQueue){
#if(RQ_ARGUMENT_CHECK_EN==TRUE)
if(pQueue==0x00)
return;
#endif
pQueue->RingBufCtr=0;
pQueue->RingBufInPtr=pQueue->RingBufOutPtr;
}

/*
*********************************************************************************************************
*LOCALFUNCTION
*********************************************************************************************************
*/

#pragmaCODE_SEG__NEAR_SEGNON_BANKED
staticvoid_forwardPointer(RING_QUEUE*pQueue,pRQTYPE*pPointer){
if(++*pPointer==pQueue->RingBufEnd)
*pPointer=pQueue->RingBuf;/*WrapOUTpointer*/
}
#pragmaCODE_SEGDEFAULT

简单解释下。

在.h文件中定义了一个环形缓冲区的控制块,当然也可以当其为一个环形缓冲区对象,用户需要为每个环形缓冲区分配一个控制块和其缓冲区(也就是一个数组)。理想情况下,虽然用户知道控制块的结构,但也不应该直接访问内部字段,而应该通过提供的函数来访问。

队列中默认的元素是无符号字符,如果要改成缓存其他类型的话改下.h文件中的typedef unsigned char RQTYPE;这行就行了。

使用示例:

#include"RingQueue.h"
#defineRX_BUF_MAX_SIZE200//定义缓冲区的最大大小为200
staticunsignedcharRxBuffer[RX_BUF_MAX_SIZE];//定义缓冲区
staticRING_QUEUERxRingQ;//定义环形缓冲区的控制块
voidmain(){
unsignedcharerr;
//初始化缓冲区
RingQueueInit(&RxRingQ,RxBuffer,RX_BUF_MAX_SIZE,&err);
if(err!=RQ_ERR_NONE){
//初始化缓冲区失败的处理
}
……
}

然后调用所有方法都需要传递环形缓冲区控制块的指针。如入队就像:

//往RxRingQ缓冲区内入队一个元素c,如果满的话丢弃第一个元素
RingQueueIn(&RxRingQ,c,RQ_OPTION_WHEN_FULL_DISCARD_FIRST,&err);

出队就像:

//从RxRingQ缓冲区内提取一个字符
c=RingQueueOut(&RxRingQ,&err);

其他就不一 一举例了。要特别说明下的是RingQueueMatch()这个方法并不是队列应该有的方法,这是为了比如我需要在缓冲区中匹配到某一串字符后做某些事情而特别加上的,不需要的话删掉即可。比如我需要一旦出现“abc”就做某些事情,那我代码可以类似这么写:

staticconstunsignedchar*StringsWait="abc";
……
while(true){
//比如从某处获得了下一个字符c
……
//将字符c入队
RingQueueIn(&RxRingQ,c,RQ_OPTION_WHEN_FULL_DISCARD_FIRST,&err);
if(RingQueueMatch(&RxRingQ,StringsWait,3)>=0){//如果在缓冲区内找到"abc"
//RingQueueClear(&RxRingQ);//可能需要清空缓冲区
//做想要做的事
……
}
}

有什么建议或意见请留言,谢谢!

审核编辑:汤梓红

  • 缓冲区
    +关注

    关注

    0

    文章

    27

    浏览量

    8942
  • 嵌入式
    +关注

    关注

    4456

    文章

    15893

    浏览量

    272829
  • C语言
    +关注

    关注

    177

    文章

    6703

    浏览量

    117025
  • 队列
    +关注

    关注

    1

    文章

    36

    浏览量

    10715
  • 数组
    +关注

    关注

    1

    文章

    289

    浏览量

    25286
收藏 人收藏

    评论

    相关推荐

    【复旦微电子FM33LG0xx开发板免费试用】实现环形缓冲区串口驱动

    前言上一篇我们进行了串口的收发测试,要方便使用,需要给应用层提供好用的串口收发接口。这里通过环形缓冲区的方式实现串口的接收。过程临界段处理由于缓冲区的基本数据流是串口接收中断中写缓冲区,读接口函数读
    发表于 12-13 00:31

    DMA循环缓冲区如何重置起点?

    ){head_index = (head_index + dma_buffer_interrupt_size) % uartsize;}我遇到的问题是,当我设置一个循环缓冲区时,一旦它进入
    发表于 12-13 08:22

    IMX8M RPMSG Lite如何增加缓冲区大小?

    我正在尝试增加 rpmsg lite 的缓冲区大小,因为我无法在 M 和 A 内核之间实现更高的传输速率(我需要大约 200kBytes/s,达到大约 90kBytes/s
    发表于 03-21 07:34

    labview中 关于串口缓冲区的问题

    从虚拟串口软件中发送了字符串通过visa串口送到labview,要求设置接收缓冲区,并且将接收到的字符串显示到一个字符串显示控件中 不断累加,到一定字符数后清空缓冲区,想咨询一下:1.“设置接收
    发表于 10-17 21:26

    abview中VISA的读、写缓冲区是同一个缓冲区吗?

    labview中VISA的读、写缓冲区是同一个缓冲区吗?通过读缓冲区字节数,只能读出读数据的大小,而不能知道写进去数据的大小。
    发表于 10-27 13:08

    缓冲区的解释

    Read.vi的时候都是将内存中的所有数据读取进来。在一些特殊情况下才将这个输入设置为其它整数,但就得保证循环能尽快的执行,以免缓冲区溢出。如果设置为100的话,表示每次从缓冲区中读取100个数据回来
    发表于 04-07 15:56

    强大的环形缓冲区组件

    轻松应对数据缓冲区
    发表于 08-01 21:08

    labview缓冲区数据处理问题

    的时候将标黄,标红的两帧数据提取出来处理。用c语言的时候其实这个很容易就处理出来,但是labview刚入门没多久,希望有会的能教教我。我想着用队列的话应该可以,但是试了很久没搞出来。希望大神不吝赐教。最后能给个程序框图。作为刚入门选手有时候有思路也不一定能实现出来。
    发表于 08-03 11:17

    单片机应用简单技巧 - 环形缓冲

    了解了串口的相关操作,知道了环形缓冲在嵌入式系统中的重要作用,本次介绍下如何在单片机等小型嵌入式系统中引入环形缓冲区。 一、环形缓冲的结构。 环形缓冲区,我们知道,有一个读指针,一个写指针,还要
    发表于 09-18 11:01

    mico系统怎么采用串口DMA接收,用环形缓冲区

    mico系统怎么采用串口DMA接收,用环形缓冲区
    发表于 05-16 14:09

    STM32进阶之串口环形缓冲区实现

    完了数据,‘0’地址空间的数据进行释放掉,列队头指向下一个可以处理数据的地址‘1’。从而实现整个环形缓冲区的数据读写。看图,队列头就是指向已经存储的数据,并且这个数据是待处理的。下一个CPU处理的数据
    发表于 06-08 14:03

    杰杰带你解读【机智云】环形缓冲区源码

    ,人家既然能拿来做商业用,还是有很厉害的地方的,如果还不知道什么叫环形缓冲区环形队列)的同学,请看——STM32进阶之串口环形缓冲区实现好啦。多余的话不多说,看看他们的东西比我写的好在哪吧,原理都
    发表于 07-17 14:58

    MCU进阶之串口环形缓冲区实现

    是列队头的数据,处理完了数据,‘0’地址空间的数据进行释放掉,列队头指向下一个可以处理数据的地址‘1’。从而实现整个环形缓冲区的数据读写。看图,队列头就是指向已经存储的数据,并且这个数据是待处理的。下一个
    发表于 08-17 13:11

    UART上的FIFO循环缓冲区大小

    ?示例:{STX,Hello \ 0,RTX}和{STX,这是一个长文本\ 0,RTX}我一直在互联网上挖掘,我发现最好的方法是使用FIFO循环缓冲区。问题是BUFFER_SIZE在这种情况下如何解
    发表于 09-13 15:42

    STM32串口环形缓冲区实现

    是列队头的数据,处理完了数据,‘0’地址空间的数据进行释放掉,列队头指向下一个可以处理数据的地址‘1’。从而实现整个环形缓冲区的数据读写。看图,队列头就是指向已经存储的数据,并且这个数据是待处理
    发表于 10-16 11:40

    什么是缓冲区的功能

    嗨,大家好:我是FPGA设计的新手。什么是缓冲区的功能。如果我没有在应该使用它们的地方使用缓冲区,我可能面临什么样的问题。以上来自于谷歌翻译以下为原文hi guys: I'm a new
    发表于 01-24 09:44

    如何循环基于DMA必须适当的工作定义解决4096个字节的传输缓冲区的限制?

    、DMA开始aggain填满缓冲区1和2是通过UART发送缓冲区。这个过程是循环的。每笔交易以每2字节DMA突发ADC(ADC工作在12位分辨率)和传输数256(每个DMA
    发表于 02-25 15:21

    基于ARM和FPGA的环形缓冲区接口设计方案

    摘要:目前,基于ARM和FPGA架构的嵌入式系统在通信设备中得到广泛的应用。文章提出了一种基于ARM和FPGA的环形缓冲区接口设计方案,从而实现了ARM和FPGA之间的数据缓冲和速率匹配。实际测试
    发表于 05-30 05:00

    环形缓冲区的设计分享!

    数据在读取和写入的时候都可以在这个缓冲区循环进行,程序员可以根据自己需要的数据大小来决定自己使用的缓冲区大小。 环形缓冲区,顾名思义这个缓冲区环形的,那么何谓环形这个意思也很好理解,就是用一个指针
    发表于 10-28 23:29

    溢出队列缓冲区

    我用和谐建立了CDC的USB堆栈。如果我慢慢地发送数据,效果会很好。我想尽可能快地发送数据。当这样做时,我溢出队列缓冲区。USB_DEVICE_CDC_Write函数返回以下错误,USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL。是否有指定或可接受的方法来监视当前队列级别
    发表于 03-24 09:51

    STM32串口环形缓冲区实现方法

    STM32串口环形缓冲区实现
    发表于 12-24 07:30

    环形缓冲区简介

    程序中,经常使用环形缓冲器作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。  环形缓冲区的一个有用特性是:当一个数据元素被用掉后
    发表于 08-17 06:56

    如何使用C语言实现模糊PID控制?

    如何使用C语言实现模糊PID控制?
    发表于 09-24 08:54

    C语言实现常用排序算法是什么?

    C语言实现常用排序算法是什么?
    发表于 10-19 06:41

    嵌入式系统设计的相关资料分享

    /数据流图(CDFG)嵌入式程序组件考虑三种广泛应用于嵌入式软件的结构或组件的代码,这三种结构或组件分别是:状态机,循环缓冲器,队列。状态机状态机通过状态来表示系统的内部特性,状态的变化是基于输入的变化。应用:面向控制的代码;响应式系统;非周期性采样作为输入C语言实现的一个软件状
    发表于 11-09 08:25

    什么是STM32环形缓冲区

    什么是STM32环形缓冲区
    发表于 11-18 07:52

    怎么实现串口环形缓冲区

    怎么实现串口环形缓冲区
    发表于 12-06 06:01

    请问怎么实现串口环形缓冲区FIFO?

    请问怎么实现串口环形缓冲区FIFO?
    发表于 12-06 07:23

    环形队列在串口数据接收中的使用

    前言  书接上回,前文主要介绍了环形队列实现原理以及C语言实现及测试过程,本文将回归到嵌入式平台的应用中,话不多说,淦,上干货!实验目的HAL库下串口的配置及使用环形队列在串口数据接收中的使用硬件
    发表于 12-06 06:27

    如何使用队列实现STM32串口环形缓冲

    串口环形缓冲的好处是什么?如何使用队列实现STM32串口环形缓冲
    发表于 12-07 07:13

    STM32环形缓冲区怎么实现

    STM32环形缓冲区怎么实现
    发表于 12-07 07:25

    stm32是怎样使用环形缓冲区形式去接收数据的

    stm32是怎样使用环形缓冲区形式去接收数据的?如何去实现其代码呢?
    发表于 12-07 06:24

    如何实现STM32串口环形缓冲区

    如何实现STM32串口环形缓冲区
    发表于 12-08 06:13

    基于stm32串口环形缓冲队列处理机制是什么

    基于stm32串口环形缓冲队列处理机制是什么
    发表于 12-08 07:06

    请问串口DMA+环形缓冲区如何实现不定长度的数据收发?

    请问串口DMA+环形缓冲区如何实现不定长度的数据收发?
    发表于 12-08 06:13

    请问一下STM32F407的USART环形缓冲区该如何去实现

    请问一下STM32F407的USART环形缓冲区该如何去实现呢?
    发表于 12-08 07:18

    STM32从队列到串口缓冲区的代码该如何去实现

    队列的基本概念是什么?队列的特点有哪些?STM32从队列到串口缓冲区的代码该如何去实现呢?
    发表于 12-08 07:27

    怎样去使用STM32串口驱动不定长数据接收带环形缓冲区

    怎样去使用STM32串口驱动不定长数据接收带环形缓冲区呢?有哪些注意事项?
    发表于 12-08 08:08

    C语言面向对象开发的缓冲区模块

    这篇文章给出了我自己写的纯C语言面向对象开发的缓冲区模块
    发表于 12-15 07:46

    怎样去解决循环队列接收缓冲区出现bug的问题呢

    巡检机器人STM32控制板采用串口与工控机通信,循环队列接收缓冲区出现bug,导致循环获取历史数据包,怎么办呢?
    发表于 01-18 06:50

    怎样去创建一种环形缓冲区

    怎样去创建一种环形缓冲区呢?其程序代码该怎样去编写?
    发表于 02-14 07:32

    实现队列环形缓冲的方法

    串口队列环形缓冲区队列串口环形缓冲的好处代码实现队列  要实现队列环形缓冲,还需要一定的数据结构知识。队列是一种重要的数据结构,特点是FIFO(先进先出)的形式,在队首(fron
    发表于 02-21 07:11

    缓冲区溢出的危害及避免缓冲区溢出的三种方法

    1. 蠕虫病毒简介2. 缓冲区溢出3. 缓冲区溢出举例4. 缓冲区溢出的危害5. 内存在计算机中的排布方式6. 计算机中越界访问的后果7. 避免缓冲区溢出的三种方法7.1 栈随机化7.2 ...
    发表于 03-02 07:55

    请问串口的DMA接收缓冲区是不是环形缓冲区

    大家好!请问串口的DMA接收缓冲区是不是环形缓冲区?通过阅读串口部分的代码,我了解到这样几点:1、串口的DMA接收时循环接收,当缓冲区满了会重新从头开始覆盖掉之前的数据,和环形缓冲区是一样的;2
    发表于 08-30 14:27

    缓冲区溢出攻击模式及其防御的研究

    借助统一建模语言,概括近十年来利用缓冲区溢出进行攻击的攻击模式,从预防、发现、抵御缓冲区溢出攻击以及攻击后的程序恢复等方面对目前有代表性的防御、检测方法和攻
    发表于 12-18 16:42 7次下载

    基于状态图的缓冲区溢出攻击分析

    结合缓冲区溢出攻击产生的原理,分析缓冲区溢出攻击代码的结构,论述Snort规则对缓冲区溢出攻击的检测,在此基础上构建一个基于状态图的缓冲区溢出攻击的分析模型。该模型对
    发表于 04-10 08:46 32次下载

    环形缓冲区读写操作的分析与实现

    环形缓冲区是嵌入式系统中一种重要的常用数据结构。在多任务环境下实现时,如果有多个读写任务,一般需要用信号量来保护多个任务共享的环形缓冲区。但是如果只存在1 个读
    发表于 04-15 11:35 40次下载

    基于可执行代码的缓冲区溢出检测模型

    根据缓冲区溢出原理,提出一种基于可执行代码的缓冲区溢出检测模型,给出该模型的理论基础,描述模型构建的过程,提出新的缓冲区引用实例的识别方法。该模型将可执行代码
    发表于 04-20 09:26 31次下载

    Windows缓冲区溢出攻击的实例研究

    本文首先详细分析了Windows 缓冲区溢出的基本原理和具体流程。在此基础上,通过对一个Windows 网络缓冲区溢出攻击实例的详细调试分析,研究了Windows 缓冲区溢出攻击的整个过程,
    发表于 08-28 09:44 17次下载

    缓冲区溢出攻击的防护技术分析

    缓冲区溢出攻击已经成为网络攻击的主要方式。本文首先分析了缓冲区溢出攻击的基本原理,然后分析了形成缓冲区溢出攻击的必要条件,并详细讨论了溢出攻击的防护技术。
    发表于 09-02 10:50 9次下载

    DSP算法的c语言实现

    DSP算法的c语言实现,又需要的朋友下来看看。
    发表于 05-09 10:59 42次下载

    51单片机内核UART串行总线环形缓冲区驱动实现的程序免费下载

    驱动实现串口中断接收和发送数据,缓冲区使用环形缓冲区。发送:手动置RI中断标志位为1,发生中断,在中断发送函数中将需要发送的数据一一发送出去,具体见示例;接收:在中断接收函数中保存接收到满足
    发表于 07-19 17:38 2次下载
    51单片机内核UART串行总线<b>环形</b><b>缓冲区</b>驱动<b>实现</b>的程序免费下载

    使用单片机实现数码管循环左移的C语言实例免费下载

    本文档的主要内容详细介绍的是使用单片机实现数码管循环左移的C语言实例免费下载。
    发表于 11-17 17:42 4次下载
    使用单片机<b>实现</b>数码管<b>循环</b>左移的<b>C</b><b>语言实</b>例免费下载

    使用单片机实现数码管循环右移的C语言实例免费下载

    本文档的主要内容详细介绍的是使用单片机实现数码管循环右移的C语言实例免费下载。
    发表于 11-17 17:42 5次下载
    使用单片机<b>实现</b>数码管<b>循环</b>右移的<b>C</b><b>语言实</b>例免费下载

    使用单片机实现LED循环左移的C语言实例免费下载

    本文档的主要内容详细介绍的是使用单片机实现LED循环左移的C语言实例免费下载。
    发表于 01-26 17:16 4次下载

    使用单片机实现LED循环右移的C语言实例免费下载

      本文档的主要内容详细介绍的是使用单片机实现LED循环右移的C语言实例免费下载。
    发表于 01-26 17:23 7次下载

    STM32进阶之串口环形缓冲区实现资料下载

    电子发烧友网为你提供STM32进阶之串口环形缓冲区实现资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
    发表于 04-20 08:46 9次下载
    STM32进阶之串口<b>环形</b><b>缓冲区</b><b>实现</b>资料下载

    累加校验和C语言实现

    累加校验和C语言实现
    发表于 11-29 18:06 8次下载
    累加校验和<b>C</b><b>语言实现</b>

    环形缓冲区的创建

    创建实例//创建环形缓存
    发表于 12-14 19:05 2次下载
    <b>环形</b><b>缓冲区</b>的创建

    STM32串口环形缓冲--使用队列实现(开放源码)

    串口队列环形缓冲区队列串口环形缓冲的好处代码实现队列  要实现队列环形缓冲,还需要一定的数据结构知识。队列是一种重要的数据结构,特点是FIFO(先进先出)的形式,在队首(fron
    发表于 12-24 19:04 21次下载
    STM32串口<b>环形</b><b>缓冲</b>--使用<b>队列</b><b>实现</b>(开放源码)

    STM32串口数据接收 --环形缓冲区

    程序中,经常使用环形缓冲器作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。  环形缓冲区的一个有用特性是:当一个数据元素被用掉后
    发表于 12-28 19:24 26次下载
    STM32串口数据接收 --<b>环形</b><b>缓冲区</b>

    缓冲区-74LVC1G16

    缓冲区-74LVC1G16
    发表于 02-10 19:14 0次下载
    单<b>缓冲区</b>-74LVC1G16

    缓冲区-74LVC1G34

    缓冲区-74LVC1G34
    发表于 02-14 18:55 0次下载
    单<b>缓冲区</b>-74LVC1G34

    清除键盘缓冲区原理

    清除键盘缓冲区原理 有时用户的按键响应可能导致数据丢失或破坏了数据而不能挽回。在这种情况下,消除缓
    发表于 06-12 23:07 1564次阅读

    CPU与GPU维护数据结构来保证环形缓冲区的正确工作

    CPU 和 GPU 将各自维护一些数据结构来保证环形缓冲区的正确工作。这些 数据结构有缓冲区的基地址,缓冲区大小,写指针和读指针。其中写指针和读指针分别指向 CPU 将要写入命令的地址和 GPU 将要读取命令的地址。
    的头像 发表于 03-30 15:01 5710次阅读
    CPU与GPU维护数据结构来保证<b>环形</b><b>缓冲区</b>的正确工作

    队列的介绍和利用环形队列实现STM32进阶之串口环形缓冲区的概述

    队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO)的线性表,只允许在一端插入(入队),在另一端进行删除(出队)。
    的头像 发表于 06-10 11:15 1.6w次阅读
    <b>队列</b>的介绍和利用<b>环形</b><b>队列</b><b>实现</b>STM32进阶之串口<b>环形</b><b>缓冲区</b>的概述

    队列的基本概念!从队列到串口缓冲区实现

    串口环形缓冲区收发:在很多入门级教程中,我们知道的串口收发都是:接收一个数据,触发中断,然后把数据发回来。这种处理方式是没有缓冲的,当数量太大的时候,亦或者当数据接收太快的时候,我们来不及处理已经
    的头像 发表于 07-26 17:54 6306次阅读
    <b>队列</b>的基本概念!从<b>队列</b>到串口<b>缓冲区</b>的<b>实现</b>

    环形缓冲区实现原理

    在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。
    的头像 发表于 03-22 10:03 6376次阅读
    <b>环形</b><b>缓冲区</b>的<b>实现</b>原理

    C语言环形队列的原理和特点

    什么是环形队列环形缓冲区是一个非常典型的数据结构,这种数据结构符合生产者,消费者模型,可以理解它是一个水坑,生产者不断的往里面灌水,消费者就不断的从里面取出水。   那就可能会有人问,既然需要
    的头像 发表于 05-11 13:56 1541次阅读
    <b>C</b><b>语言</b><b>环形</b><b>队列</b>的原理和特点

    UART寄存器的循环缓冲区实现以及中断驱动的UART实现和硬件设置

    缓冲区通常用作临时数据存储,通常用于流式传输数据。UART 软件实现支持基本格式,即 8 个数据位、无奇偶校验和 1 个停止位。
    的头像 发表于 06-23 15:43 3048次阅读
    UART寄存器的<b>循环</b><b>缓冲区</b><b>实现</b>以及中断驱动的UART<b>实现</b>和硬件设置

    探索C语言入门基础之缓冲区

    01 — C标准库缓冲区探索 在计算机里缓存是一个很重要的概念,C标准库里大量使用了缓存,最为典型的就是标准输入和标准输出的缓存,关于C语言的输入和输出看这篇文章即可,利用好缓存可以大幅提高
    的头像 发表于 06-28 17:24 1433次阅读
    探索<b>C</b><b>语言</b>入门基础之<b>缓冲区</b>

    缓冲区是啥意思 STM32串口数据接收之环形缓冲区

    缓冲区顾名思义是缓冲数据用的。实现缓冲区最简单的办法时,定义多个数组,接收一包数据到数组A,就把接收数据的地址换成数组B,每个数据有个标记字节用于表示这个数组是否收到数据,收到数据是否处理
    的头像 发表于 07-22 15:33 7415次阅读

    基于宏高效实现环形缓冲区教程

    来源 | 小麦大叔 循环缓冲区是嵌入式软件工程师在日常开发过程中的关键组件。 多年来,互联网上出现了许多不同的循环缓冲区实现和示例。我非常喜欢这个模块,可以GitHub上找到这个开源的 CBUF.h
    的头像 发表于 09-02 09:24 6150次阅读
    基于宏高效<b>实现</b><b>环形</b><b>缓冲区</b>教程

    什么是缓冲区?有什么作用

    缓冲区其实就是一个存储区域,它是由专门的硬件寄存器所组成的。
    的头像 发表于 02-02 09:57 1.5w次阅读

    环形缓冲区简介 STM32环形缓冲区示例

    在单片机中串口通信是我们使用最频繁的,使用串口通信就会用到串口的数据接收与发送,环形缓冲区方式接收数据可以更好的保证数据丢帧率第。
    的头像 发表于 05-31 11:27 3267次阅读
    <b>环形</b><b>缓冲区</b>简介 STM32<b>环形</b><b>缓冲区</b>示例

    FreeRTOS流式缓冲区是指什么

    流式缓冲区是在队列的基础上,针对单一生产者和消费者场景,与队列类似,也是一个任务负责产生数据,另一个任务负责读取数据,但是字节流可以是任意长度,并且不一定具有开头或结尾。
    的头像 发表于 09-15 11:51 438次阅读

    怎么用C语言实现多态

    这里我想主要介绍下在C语言中是如何实现的面向对象。知道了C语言实现面向对象的方式,我们再联想下,C++中的class的运行原理是什么?
    的头像 发表于 10-12 09:12 712次阅读

    消除物联网上的缓冲区溢出漏洞

      黑客可以使用堆栈缓冲区溢出将可执行文件替换为恶意代码,从而使他们能够利用堆内存或调用堆栈本身等系统资源。例如,控制流劫持利用堆栈缓冲区溢出将代码执行重定向到正常操作中使用的位置以外的位置。
    的头像 发表于 12-02 11:57 253次阅读

    环形缓冲区实现思路

    单片机程序开发一般都会用到UART串口通信,通过通信来实现上位机和单片机程序的数据交互。通信中为了实现正常的收发,一般都会有对应的发送和接收缓存来暂存通信数据。这里使用环形缓冲区的方式来设计数据收发的缓存,即缓冲区溢出后,从缓冲区数组的起始索引处重新进行数据的存储,这样可以比
    的头像 发表于 01-17 15:07 431次阅读

    循环队列C语言面向对象实现

    而我已经按照更面向对象的方法大改了原来的那个环形缓冲区模块,考虑到整个结构已经完全不同了,所以直接弃用了原来那个模块,新模块直接重新开始记版本号。
    的头像 发表于 04-04 09:47 44次阅读

    基于C语言循环队列缓冲区原理、设计与实现

    在FPGA中,FIFO一般是使用RAM存储器作为缓冲区,可以分为同步FIFO或异步FIO,一般用于数据缓冲,或者不同时钟域之间的数据传递。
    发表于 04-10 09:30 48次阅读

    下载硬声App