0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

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

3天内不再提示

嵌入式软件工程师在日常开发过程中的关键组件

Linux阅码场 来源:小麦大叔 作者:菜刀和小麦 2021-09-24 10:47 次阅读

大家好,周末快乐,我是小麦,今天分享一下CBUF。

循环缓冲区是嵌入式软件工程师在日常开发过程中的关键组件。

多年来,互联网上出现了许多不同的循环缓冲区实现和示例。我非常喜欢这个模块,可以GitHub上找到这个开源的 CBUF.h 模块。

地址:https://github.com/barraq/BRBrain/blob/master/firmware/CBUF.h

CBUF.h 模块使用宏实现循环缓冲区,具体源码如下所示;

#if !defined( CBUF_H )#define CBUF_H /**《 Include Guard *//* ---- Include Files ---------------------------------------------------- *//* ---- Constants and Types ---------------------------------------------- *//**

* Initializes the circular buffer for use.

*/

#define CBUF_Init( cbuf ) cbuf.m_getIdx = cbuf.m_putIdx = 0/**

* Returns the number of elements which are currently contained in the

* circular buffer.

*/#define CBUF_Len( cbuf ) ((typeof( cbuf.m_putIdx ))(( cbuf.m_putIdx ) - ( cbuf.m_getIdx )))/**

* Appends an element to the end of the circular buffer

*/#define CBUF_Push( cbuf, elem ) (cbuf.m_entry)[ cbuf.m_putIdx++ & (( cbuf##_SIZE ) - 1 )] = (elem)/**

* Retrieves an element from the beginning of the circular buffer

*/#define CBUF_Pop( cbuf ) (cbuf.m_entry)[ cbuf.m_getIdx++ & (( cbuf##_SIZE ) - 1 )]/**

* Retrieves the i‘th element from the beginning of the circular buffer

*/#define CBUF_Get( cbuf, idx ) (cbuf.m_entry)[( cbuf.m_getIdx + idx ) & (( cbuf##_SIZE ) - 1 )]/**

* Retrieves the i’th element from the end of the circular buffer

*/#define CBUF_GetEnd( cbuf, idx ) (cbuf.m_entry)[( cbuf.m_putIdx - idx - 1 ) & (( cbuf##_SIZE ) - 1 )]/**

* Determines if the circular buffer is empty

*/#define CBUF_IsEmpty( cbuf ) ( CBUF_Len( cbuf ) == 0 )/**

* Determines if the circular buffer is full.

*/#define CBUF_IsFull( cbuf ) ( CBUF_Len( cbuf ) == ( cbuf##_SIZE ))/**

* Determines if the circular buffer is currenly overflowed or underflowed.

*/#define CBUF_Error( cbuf ) ( CBUF_Len( cbuf ) 》 cbuf##_SIZE )#if defined( __cplusplus )template 《 class IndexType, unsigned Size, class EntryType 》

class CBUF

{public

CBUF()

{

m_getIdx = m_putIdx = 0;

}

IndexType Len() const { return m_putIdx - m_getIdx; }

bool IsEmpty() const { return Len() == 0; }

bool IsFull() const { return Len() == Size; }

bool Error() const { return Len() 》 Size; }

void Push( EntryType val )

{

m_entry[ m_putIdx++ & ( Size - 1 )] = val;

}

EntryType Pop()

{

return m_entry[ m_getIdx++ & ( Size - 1 )];

}

private:

volatile IndexType m_getIdx;

volatile IndexType m_putIdx;

EntryType m_entry[ Size ];

};

#endif // __cplusplus/* ---- Variable Externs ------------------------------------------------- *//* ---- Function Prototypes ---------------------------------------------- *//** @} */#endif // CBUF_H

现在一般我不喜欢以这种方式使用宏,但实现已被证明是快速、高效且工作相对良好的,这是很难争论的。

循环缓冲区的设置非常简单。首先,需要定义循环缓冲区的大小。这是通过定义宏 myQ_SIZE 来完成的,同时记住缓冲区大小需要是 2 的幂。

然后通过创建一个 myQ 类型的变量来声明循环缓冲区。例如,如果 myQ_SIZE 定义为 64 字节,则可以定义 UART 的发送和接收缓冲区,如下面的图 1 所示。

994a0046-11e5-11ec-8fb8-12bb97331649.png

图 1 – 定义循环缓冲区

在此示例中,myQ 被定义为静态以限制缓冲区的范围并声明为易失性,因为它们在中断内被修改。定义循环缓冲区只是第一步。为了分配缓冲区,必须将这些变量传递给 CBUF_INIT 宏,如下图 2 所示。

99790ca6-11e5-11ec-8fb8-12bb97331649.png图 2 – 缓冲区初始化

除了这个初始设置之外,缓冲区相当简单且易于使用。例如,可以使用 CBUF_PUSH 将通过串行接口接收 UART接收的字符推送到循环缓冲区,如图 3 所示。

99a3eb4c-11e5-11ec-8fb8-12bb97331649.png

图 3 – 推入缓冲区

开发人员不仅希望将数据推送到循环缓冲区上,还希望从缓冲区弹出或获取数据。看到这一点的一个简单示例是需要获取字符并通过 UART 传输的串行发送器。图 4 中可以看到一个示例传输函数。

99bd6ee6-11e5-11ec-8fb8-12bb97331649.png

图 4 – 从缓冲区弹出数据

在健壮的应用程序中,还应检查循环缓冲区长度和溢出状态。CBUF 模块确实提供了能够检查这些重要指标的宏。

要记住的一个重要问题是,如果需要对 CBUF 本身进行任何调试,这是不可能的。无法为宏设置断点,因此如果出现问题,则需要对模块进行功能化以逐步执行和调试。

多年来使用这个模块虽然我没有发现任何问题。循环缓冲区是在嵌入式系统中与串行设备通信的一个重要方面。

循环缓冲区也很好理解,应该创建它们以便它们可以模块化并从一个应用程序到下一个应用程序重复使用。

到目前为止,CBUF 模块已被证明是这样一个模块,所以在这里,我强烈推荐一下这个模块。好了,今天的文章就到这里,我们下期再见。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2713

    浏览量

    47483
  • 嵌入式
    +关注

    关注

    5082

    文章

    19126

    浏览量

    305272

原文标题:优雅地用宏实现环形缓冲区

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式工程师常用的开发工具有哪些?

    仿真器可以模拟复杂的微控制器和外设,帮助工程师早期阶段进行软件开发和调试。这大大缩短了开发周期,降低了开发成本。 总之,
    发表于 12-20 15:29

    AM6254开发常见问题之「烧写问题排查」——飞凌嵌入式

    项目的开发过程中,各位工程师小伙伴们可能会遇到各种类型的问题,其中“烧写问题”就是非常典型的一种。本篇文章,将以飞凌嵌入式OK6254-C开发
    的头像 发表于 11-08 11:51 1109次阅读
    AM6254<b class='flag-5'>开发</b>常见问题之「烧写问题排查」——飞凌<b class='flag-5'>嵌入式</b>

    名单公布!【书籍评测活动NO.42】 嵌入式Hypervisor:架构、原理与应用

    ,以及PRTOS社区的愿景等内容。 作者简介 孙陈伟 某大厂资深编译器团队编译器开发工程师,曾任华为技术软件公司高级软件工程师,梅特勒-托利多仪器仪表(中国)有限公司
    发表于 08-23 15:17

    嵌入式QT常见开发方式有哪些?

    Unit): 对于资源极其有限的微控制器应用场景,Qt提供了专门针对MCU的解决方案,允许低功耗、小内存的嵌入式系统上开发图形化界面。 总之,嵌入式
    发表于 08-12 10:05

    嵌入式软件开发招聘

    本帖最后由 jf_19082533 于 2024-7-26 13:56 编辑 寻求:嵌入式软件工程师 要求:3年以上开发经验,音视频领域应用层开发 地址:北京市昌平区 邮箱:10
    发表于 07-26 13:44

    找STM32硬件开发兼职工程师

    上海做传感器的公司,找STM32硬件开发兼职工程师,会硬件开发嵌入式软件开发,可项目外包。有意联系:15900460170
    发表于 06-22 19:12

    嵌入式硬件VS软件,到底哪个更难?

    :挑战与精密嵌入式硬件开发涉及到威廉希尔官方网站 设计、电子元器件选型、PCB设计等诸多方面。在这个过程中工程师需要具备扎实的电子知识和丰富的实践经验。硬件开发
    的头像 发表于 06-13 08:10 1208次阅读
    <b class='flag-5'>嵌入式</b>硬件VS<b class='flag-5'>软件</b>,到底哪个更难?

    嵌入式软件工程师如何提升自己?

    的发展打下坚实的基础。 2.掌握专业技能 除了基础知识外,嵌入式软件工程师还需要掌握专业的技能。这包括熟练掌握嵌入式系统的开发工具、硬件平台和软件开
    发表于 06-12 11:20

    从事嵌入式方向,一定要软硬件通吃?

    嵌入式系统开发领域,软件和硬件的界限常常模糊不清。一个常见的问题是,嵌入式软件工程师是否需要了
    的头像 发表于 06-05 08:10 1186次阅读
    从事<b class='flag-5'>嵌入式</b>方向,一定要软硬件通吃?

    嵌入式软件工程师和硬件工程师的区别?

    ,并且了解嵌入式系统的工作原理。此外,他们还需要具备良好的逻辑思维能力,能够快速解决复杂的软件问题。嵌入式软件工程师
    发表于 05-16 11:00

    嵌入式工程师需要掌握哪些技术?

    嵌入式工程师需要掌握哪些技术? 嵌入式系统是当今科技领域中的重要组成部分,它们存在于我们生活的方方面面,从智能手机到汽车控制系统,从家电到医疗设备。因此,对于那些想要进入嵌入式行业的
    发表于 03-04 16:38

    嵌入式人工智能的就业方向有哪些?

    的发展方向有很多,门槛高低不一样。下面给大家列举一些相应岗位所需具备的技能: 一:嵌入式Linux,C语言开发工程师,Linux软件开发工程师
    发表于 02-26 10:17

    优秀电源工程师需要哪些必备技能?

    /Verilog。嵌入式功能涵盖了电压电流采样、通讯、滤波处理、PWM信号控制、闭环控制算法、软件保护等多个方面。实际嵌入式程序开发过程中
    发表于 01-29 11:29

    嵌入式软件开发软件开发的区别

    嵌入式软件开发软件开发是两个不同的概念,它们一些关键方面有着明显的区别。嵌入式
    的头像 发表于 01-22 15:27 2292次阅读