嵌入式软件开发工程师谈软件架构的设计

嵌入式软件工程师学习路线图 嵌入式技术关键在于理论和实践的结合,要能够学以致用,完成了以上的所有阶段的知识点学习后,到底有没有学会,会不会用,能不能应用所学知识来解决实际开发中的问题,我们需要来完成一个综合的嵌入式实训项目,例如: 基于嵌入式Linux平台实现的飞行器、 基于嵌入式Linux平台实现的智能机器人等,这些项目都综合应用了嵌入式开发当中的应用,驱动和QT开发技术。这一阶段重点打好嵌入式软件编程的基础,包括学习Linux系统的基本应用,Linux的常用命令、C语言编程基础、常用的数据结构。3、学习嵌入式系统的构建。 阅读详情

嵌入式软件开发工程师谈软件架构的设计

注:此处嵌入式特指基于linux平台,单片机和其他rtos不在讨论范围

  • 笔者从事嵌入式软件开发有6,7个年头,bsp,驱动,应用软件,android hall,framework等都有涉猎。平时除了关注嵌入式行业的发展,也多少对Web,后台服务端,分布式等方向的技术有一些关注。

  • 近期有萌生换个行业方向的想法,想做做后台服务器相关的开发,由于之前工作中并没有这方面的实际需求,只是自己平时关注,了解了些知识,比如:NIO,epoll,ngnix,zeromq,libevent,libuv,高并发,分布式,redis,python,tornado,django,涉猎比较杂,都了解个皮毛,不精。意外的是屡屡被互联网行业鄙视,面试机会都寥寥无几。

  • 此时我想到底是什么问题呢,难道嵌入式出身的已经这么不受待见了吗?想当初,嵌入式,驱动开发,可是趋之若鹜的行业(有点夸张,不过8,9年前嵌入式可是听着比做java web的要牛逼些哦)

问题总是有原因的,我说下自己的理解:

嵌入式是否真的高大上之为什么没有嵌入式软件架构师?

  • 打开拉勾等招聘网站,搜索架构师,会出现各种系统架构师,web架构师,后台服务端架构师等等,但是唯独很难看到嵌入式软件架构师。嵌入式软件不需要架构吗,驱动不需要架构吗?答案是当然需要,不过为什么没有这方面的职位?

    我的看法:目前国内的嵌入式开发主要分为嵌入式底层开发和嵌入式应用开发,嵌入式的底层开发一般叫做驱动开发,或者bsp开发,有时也有称之为linux内核开发,名字听着都很高大上的感觉。

    这么高大上的名字为什么没有架构师呢:linux kernel的架构师是linus等一众linux kernel开发维护者,因为本身linux kernel或者操作系统就是一个通用的平台,解决通用的问题,linux开源届的大牛都已经制定好了架构规则,留给可发挥的地方并不多,大部分工作只需要按照规则框架填充就可以了,而且以目前国内大部分公司的业务需求,只是在做外围设备的集成,嵌入式平台的porting,搭建裁剪,业务需求完全不会超过kernel里提供的功能范围。导致没有什么新的架构需要开发人员去设计,实现。那嵌入式bsp开发人员都在做什么:除了调试多种多样的外设,替硬件擦屁股,就是解些稳定性的bug了(这里对具体工作不详细描述了,调试外设只会增加一些经验,增加广度,对提高深度贡献不大,只是按不会调试-》会调试-》调试的快这个路线发展,而解稳定性问题确实是需要一些积累经验)

    而嵌入式上的应用开发,一般业务逻辑比较简单,被很多人忽略,所以招聘方也会感觉没有什么必要找架构师级别的了。

至此感觉嵌入式行业的确不需要架构师,被互联网行业的鄙视也没什么大惊小怪的。

  • 但的确是这样子的吗?对于嵌入式底层的开发,有能力对kernel,驱动架构提出架构层优化的,国内的开发人员应该不多,所以对于大部分普通人,还是不要“妄想”做Linux kernel的架构师了(当然我相信国人中一定存在有这个能力的大牛),发现,解决一些bug,到更靠谱些。

那么对于嵌入式应用层的开发,我们真的不需要架构吗?

  • 以自己的实际经历讲述下曾经对一个嵌入式设备应用软件的架构设计和优化:
    笔者曾经接手过一个项目,项目采用单进程多线程的模型,项目中包括几个模块,以a, b, c, d,e代表。这个项目的业务逻辑决定这几个模块有不少关联。
    例如:最初的设计中a模块是一个状态监测模块,它会基于监测到的状态调用b,c模块的接口实现一些功能(多线程的好处就是直接调用很方便,所以开发人员大多这么干,简单粗暴),但是需求总是千变万化,加入一个f模块,f模块也需要对a模块监测的状态进行一个处理,按照之前的套路,完成这个功能分两步:1,在f模块提供个接口,2,在a模块中调用该接口。至此新需求已经“完美”的解决了。

  • 前面提到需求总是千变万化的,新的需求又来了,客户提出定制需求,需要加入另一个g模块,同样处理a模块监测的状态,但是该定制需求不需要刚刚加入的f模块,此时最简单粗暴的方式是,定义一个宏,区分该定制需求和之前的通用需求,build两个程序版本。这样的做法看似简单,但后面如果定制需求逐渐增多,维护这么多定制版本程序就是个噩梦,代码管理和通用性也会是很大的问题,同时代码中充斥着对不同宏定义的差异化处理,#ifdef xxx;do_something;#endif比较好的做法是加入设备型号版本的动态监测,用一个build程序版本动态支持所有的定制需求,这样减少了对不同build程序的维护。但是这种做法只解决build程序的版本维护工作,没有解决宏定义差异化处理的问题,只是会将之前的宏判断,改为动态设备版本号判断,如果这些差异化的判断只集中在一处进行,也不会引起大的复杂化的问题,但显然这个是不好保证,有可能这些差异化的处理会蔓延到整个项目的各个角落,这样项目维护起来就会变成一场噩梦。

  • 不需要什么高深的软件思想,大部人都会想到把差异化的部分提取出来,放在一个统一的地方集中管理,对差异化的修改只集中在这个统一管理的地方。
    通用做法就是采用callback设置钩子,然后在callback中定制差异化的需求,对callback的处理做差异化的配置,对应到上面例子,就是在a模块添加一个钩子,然后在系统初始化时,根据设备版本号的不同,差异化定制callback处理函数,同时要将这些定制callback处理函数放在同一地方处理,否则仍然分散在各个角落里就没有意义(前一种方式不放置钩子是无法将这些差异化配置放在一起的),这样处理带来的另外一个好处是,我们对功能性需求的改变,不会影响到a模块的处理,也就是我们添加功能,不需要修改a模块的代码了(前一种方式要修改a模块的调用流程),这样也就实现了一个模块的分离。

  • 至此第二种的方案的架构(其实也谈不上架构了)相比第一种方案已经有了不少提升,至少让开发人员稍微轻松了些,对于其他定制需求,开发人员之需要修改这个callback处理,关注差异化部分就可以了。

软件是需要不断进化的,第二种方案是最优解吗,当然不是,还有优化空间吗?

下面先跑个题,谈谈多线程/多进程模型的优缺点,主要谈多进程的优点了:

教科书上的解释就不提了,首先我对大的项目是推崇多进程模型,无关性能,主要原因有:

  • 模块的解耦:很多开发人员维护开发的多线程模型项目应该都多少会存在下面的问题:跨模块间的直接调用,如果不相信,好,你的项目一定是分模块的吧,现在随机的删掉一个模块,build下看能build通过吗(只需要build不需要运行),我相信大部分情况下一定会遇到某个函数调用,某个全局变量找不到的情况,这种情况说明你的模块间存在强耦合了。由于多线程天然的优势,地址空间的相互可见,导致直接调用十分容易,很多经验尚浅的工程师,很容易就写出直接调用的简单粗暴的接口,如果遇到个static接口的函数,图方便也会把static去掉,直接拿过来用了。这样整个工程随着功能不断的添加,模块间的交叉越来越多,耦合越高。

    而我之所以推崇多进程的原因就是,多进程能从物理上隔绝了这种“方便”的通讯方式,导致在想实现一个模块交互时,会多思考下这个交互是必要的吗,如果是必要的,则会进一步思考接口定义是否简单明了(因为进程间的通讯相对会麻烦些,开发人员会本着能减少交互,明确接口的想法去仔细考虑接口,协议的定义,否则折腾的是自己了),这如同人生,如果一直顺风顺水,人们可能不会想太多,思考太多,而如果道路上有些坎坷,则会有另一种感悟吧。

    所以我的想法是多进程的模型会逼迫你去更多的思考想程序的设计,物理上减少模块的耦合。

  • 抽象通用组件,分离通用功能和业务逻辑功能:当把一个多线程模型修改为多进程模型的过程中,经常会发现有些接口代码重复的出现在多个进程模块中,因为之前接口函数是在一个进程空间,大家都可以直接调用的,比如接口A被模块a,b调用,模块a,b分离为两个独立的进程后,接口A需要在a,b中分别实现了,无需解释,重复代码这个在软件工程中是大忌,必须消除。做法也很简单,将这些被多个模块调用的接口分离处理做成lib,供其他模块调用,当你完成这部分工作后,你发现了什么,是不是剥离的接口,可以作为整个项目的通用组件存在了,完美的情况下,lib下的代码是通用基础组件,各个模块中是独立的业务处理模块。

  • 方便定位问题:多线程模型中当又一个线程异常退出,会导致整个进程退出,当然通过一些crash信息,可以定位是那个线程死掉,但如果这些线程模块是由多个小组,人员维护,当整个进程崩溃掉后,如何判断由那个小组解决,会是一个大的问题,而且有时还会出现的现象是挂在一个线程,但其实是另外一个线程模块引起的(耦合的祸端),遇到这种情况,难免出现小组间的扯皮,推诿。(自信的工程师都认为我的代码没有问题)

    而如果采用多进程的模型,好吧,你的服务进程挂了,你自己找原因吧,没什么可争辩的了。

  • 方便性能测试:多线程种单个线程的资源占用不是很好查看(至少有些嵌入式系统没有完善的命令),当整个进程资源消耗很高时,如何判断定位时那个模块线程的问题,同3一样难以抉择,而如果是多进程的模型,谁的进程占了好多资源,谁就去查下吧,其实这个还是个颗粒度的问题,同样的系统,划分成多个进程,单个进程的复杂度一定比只有一个进程的复杂度低的多,复杂度降低,也就更容易定位查找各种问题。

  • 分布式部署:互联网行业一直强调的分布式,云啊什么的,嵌入式行业就很苦逼了,貌似不需要什么分布式吧,其实也对,大部分情况下,嵌入式采用单芯片,独立运行,分布式遇到的很少。但如果万一那天你在一个设备中,将本来一个芯片完成的功能分散到两个芯片中处理呢,多进程的扩展就容易的多了。

    这只是举个特殊的例子,其实嵌入式设备就是个分布式的行业,只是一开始就已经实现分离了,而不是从集中到分布式的路线发展起来的。

  • 方便公司的代码权限隔离:其实我鄙视这种做法,公司要相信自己的员工,但鉴于诚信在中国已经。。。。,做些隔离也无可厚非了。
    多线程模型下,前面讲到如果去除一个模块,你可能都不能build了,那么是要把所有代码暴露给所有的工程师吗,显然不能,所以各个模块只能提供库的形式了,不过我觉得将通用功能接口组织成通用库是正常的做法,而如果把和业务相关的模块也提供成库,就有点。。。。

至此在补充一下,以上所有的优点,其实都不是很关键的点,都不能够让多进程有绝对的优势压倒多线程模型,只是从个人的角度觉得,多进程模型更能强迫工程师思考解决一些问题。(而这些问题有经验的工程师无论什么模型都会思考的)

上面说了这么多,该考虑下把之前项目的例子改成多进程模型,否则就只是纸上谈兵了,下面开始:

首当其冲的问题就是:选择多进程的通讯方式,多线程间的直接调用是不能用了,那么如何选择多进程的通讯方式呢?

  • linux下提供很多ipc方式,此处不一一列举,对于非大数据量的控制,通讯消息的传递,比较好的方式是采用socket,本机上更多采用unix socket方式,(这种方式有什么好处?当你有需要把单一系统做成分布式系统时,优势就明显了)

  • 但是仅仅采用socket来实现前面例子的功能,同样会存在一些问题:
    还是前面的例子,首先说明前面我们优化后的第二种方案在多进程模型已经不能在继续使用了,原因比较简单,应该不需要解释。。。

  • 简单的做法即基于方案一,把直接调用改为socket通信(定义好通信协议即可),但是熟悉socket开发的工程师都清楚,开始socket通信要先进行一些前期的工作(主要就是连接,将两个模块关联起来),所以前面的例子会变成这个样子,模块a要和模块b,c建立连接,如果加入f模块,模块a还要和f模块建立连接。这样情况在心里画一张连接图就会发现好像我们织了一张蜘蛛网,节点间的关系错综复杂,而且和方案一一样,我们添加一个和a关联的模块,就要修改模块a的代码,而且这种情况比多线程模型还有繁琐复杂的多了。这种做法绝对是个噩梦。

    好吧如何解决,我想很多人一定想到了采用总线分发的方式。了解android系统开发的会想到binder,了解openwrt的会想到ubus,了解桌面会想到dbus,互联网行业的开发者一定也知道redis里提供的sub/pub模块。

    上面的binder,ubus等原理很简单,就是建立一个消息中心,构建一个转发路由模型,所有其他模块之间不直接交互,而是采用消息中心转发,路由,而如何决定路由规则,则采用订阅/发布的观察者模式来进行规则的定义。(嵌入式开发或者c语言开发者,经常会误以为设计模式是和面向对象语言关联的,是面向对象语言独有,虽然有很多大牛做了这方面的普及,但鉴于有些开发者的信息渠道比较闭塞,导致这种想法仍然十分盛行)

    基于这个模型,我们上面例子的需求就很好解决了,加入一个消息中心模块,所有需要通信的模块只同该消息中心模块连接,然后订阅自己感兴趣的事件,当事件发生时,只需要进行相应的处理就可以了。

    这样上面的模块b,c订阅模块a的事件,当模块a检测到某事件时,发布该事件,该事件先到达消息中心,在由消息中心转发给模块b,c,而对于新加入的模块f,也只需要订阅该模块,而不需要在修改到模块a的代码,使功能的扩展十分方便。

    同时对于前面提到的定制化开发同样得到了简化,如果定制化版本需要加入模块g,这样只需要定制化版本中将模块g作为一个独立进程启动,然后订阅模块a的事件即可,而定制版本和通用版的区别就在于是否启动模块g的进程,从而实现了软件工程的一个目标:功能的添加如同搭积木一样,只需要把一个模块插入(启动)或拔出(不启动)即可,功能的改变只局限在一个或某几个模块间,对主体框架不会有任何影响。

以上大概描述了对一个项目需求逐步优化的过程,例子看似是基于嵌入式项目,但貌似对软件工程同样适用。

  • 来到互联网行业:
    查看下各大网站架构师对本网站技术架构变革分享的文章,首先提到的一般都是,基于业务将之前的一个应用服务器功能拆分,更加细化(比如电商对登录,注册,交易,商品,卖家等业务服务的拆分),然后将拆分出来的服务部署在多台服务器上,来提供并发。这里是否有些耳熟,和前面讲到的多线程到多进程的划分是否有相似呢。

    拆分后同样遇到通信的问题,此时很多消息中间件应运而生,比如阿里的duboo,简单了解下这些中间件的原理,无外乎订阅发布,RPC等机制,可以说大同小异,而难点在于协议的制定和性能处理的提升。

    在对照下互联网行业的负载均衡方案,仿佛那个负载均衡的前端也像一个消息中心了。

行文至此,只是想说明一个问题,软件的设计是相通的,基于的思想是相同的,虽然嵌入式行业的业务逻辑相对比较简单,但其实在仔细思考后,仍然会有很多架构上的改进,设计。

但是让我感到悲哀的是,有些嵌入式开发者,鉴于业务逻辑的简单,感觉采用一些不那么好的处理方式也能解决问题,不去思考如何去优化,改进。比如上面例子的方案一,如果在定制需求不多的情况下,维护起来也没太大问题,即使定制需求多了,再招些初级程序员也能维护的过来,一个人一套代码负责一个项目的公司也不是不存在。

同样互联网行业和嵌入式行业也不应该存在一个不可以逾越的高墙,我们更应该关注的是通用的软件工程思想。

单片机嵌入式软件架构 有些单片机可以使用编译器自带的功能或插件实现选择配置,生成C语言函数,但大多数单片机没有这个功能,所以需要将底层核心驱动和配置文件分开,核心驱动可以封装成库,配置文件则可以开放给应用工程师,设计如下。层设计时,一定要功能模块化,一个功能对应一个文件,一个功能文件下可以包含多个实现C文件和 h文件,能让人一眼就知道哪些文件实现了哪些功能,相关的C文件在哪。在一些大型项目中,会要求减少模块间耦合,进行变量隔离,即A模块的变量B模块只能调用,但不能修改,所以需要用创建一个函数来返回A模块的变量。 阅读详情

相关推荐

嵌入式软件架构中抽象层设计方法

软件架构这东西,众说纷纭,各有观点。什么是软件架构,我们能在网上找到无数种定义。比如,我们可以这样定义:软件架构是软件系统的基本结构,体现在其组件、组件之间的关系、组件设计与演进的规则,以及体现这些规则的基础设施。怎么定义一般来说,基本上不重要,我们不是在写学术书籍,工程人员嘛,只关心软件架构能解决什么问题。软件架构不是制定出来的,而是产品和业务需求所决定的,架构师所做的,只是忠于需求,并合理的表达了需求。软件架构也从来都不是一成不变的。

嵌入式技术开发 1612

关于嵌入式, 知乎上的一些回答

嵌入式开发的门槛相对较高,对程序员的要求一般都是对底层感兴趣,学习能力、动手能力要强,对问题能够从全局和细节去把握,有很强的系统分析和设计能力。从工程师起步,一般有几个发展方向,一个是成为技术方面的核心,领域内的专家;另一个是从项目中锻炼起来,成为项目主管或是管理型人才;再有就是利用自己的技术及行业经验去创业。 硬件和软件的发展方向是不同的。说说软件需要学习的知识。 虽然说搞嵌入式软件

guozhichao94的专栏 3566

单细胞实战之数据净化三部曲:细胞周期校正、双胞体剔除与RNA污染清理——技术解析与实战指南

本文深入解析单细胞数据分析中至关重要的数据净化步骤,即细胞周期校正、双胞体剔除与RNA污染清理。通过实战代码演示与原理剖析,指导读者如何有效识别并去除技术噪音,从而获得更纯净、可靠的数据,为后续的细胞分群、差异表达等高级分析奠定坚实基础。

weixin_29274337的博客 205

嵌入式Linux+Android学习路线图

本文目录 1. 程序员的三大方向 1.1 专业领域 1.1.1 学术研究 1.1.2 工程实现 1.2 业务领域 1.2.1 界面显示 1.2.2 业务逻辑 1.3 操作系统领域 1.4 嵌入式Linux+Android系统包含哪些内容 2. 怎么学习嵌入式Linux操作系统 2.1 入门路线图 2.2 学习驱动程序之前的基础知识 2.2.1 C语

wed110的专栏 4675

阿里云导出的镜像raw转换成vmdk格式工具

阿里云导出的镜像raw转换成vmdk格式工具 1.安装java环境,安装教程不介绍了 2.raw2vmdk软件下载: 在我的链接里面: 3.使用 打开cmd.bat软件: java -jar raw2vmdk.jar (原镜像)C:\\images\\raw\\disk.img (转换的镜像)D:\\images\\vmdk\\disk.vmdk 4.vmware打开vmdk文件 ...

3843

Stata: 空间面板数据模型及Stata实现

  作者:游万海 (福州大学) Stata 连享会: 知乎 | 简书 | 码云 | 优快云   来源:Golgher 和 Voss (2016)   1. 背景介绍 由于面板数据模型所具有的众多优点 (刻画个体异质性,减弱模型共线性和增加自由度等),其被广泛应用于实证计量中。在 「 Stata: 面板数据模型-一文读懂」 文中,我们已对面板数据模型进行了介绍。 然而,当研究样本涉及到多个...

Stata连享会 7万+

作为计算机专业学生,最应该学习的课程前五位是什么?【知乎】

http://www.zhihu.com/question/19628851#answer-100293 对于目前排在首位的兵哥哥的答案,不敢苟同。 本人软件工程专业。 关于计算机专业和软件工程专业,实际上还是大相径庭的,远不是别人所说的软硬件的偏重问题。计算机专业本科应该不需要读人月这类的东西吧,然而出门就业又是相通的,这是大环境我们就暂且不表。 回到主题

MopTrain的博客 8万+

海康威视工业相机SDK二次开发实战:多相机同步采集与图像存储

本文详细介绍了海康威视工业相机SDK二次开发实战,包括多相机同步采集与图像存储的优化方案。通过MVS软件搭建开发环境,实现硬件与软件触发同步采集,并提供高效的图像存储管理技巧,帮助开发者提升工业视觉项目的效率与稳定性。

weixin_29168813的博客 666

【FPGA干货】想去一线大厂做FPGA芯片开发?这些是你该学的知识(进阶)

想去一线大厂做FPGA芯片开发?这些是你该学的知识 https://www.bilibili.com/video/BV11y4y1i7Lv

zhaogoudan的博客 601

AHP层次分析法在项目风险评估中的实战应用(含Excel模板)

本文详细介绍了AHP层次分析法在项目风险评估中的实战应用。通过构建风险层次模型、利用判断矩阵量化主观判断,并结合Excel工具进行权重计算与一致性检验,将模糊的定性风险转化为清晰的量化排序。文章以新产品上线项目为例,提供了完整的分析流程和可操作的Excel模板,帮助项目经理高效识别并优先处理核心风险。

weixin_29061465的博客 570

UE5 VlcMedia 插件编译与流媒体播放实战

本文详细介绍了在虚幻引擎5中编译并集成VlcMedia插件以解决流媒体播放难题的实战指南。针对UE5不再默认支持Win32 API导致的编译错误,文章提供了核心的构建配置文件修改步骤,并指导如何启用插件、创建VLC媒体播放器,最终成功播放如.m3u8等格式的网络直播流或点播视频。

weixin_29013129的博客 339

STM32真的很难学吗?

大家好,我是张巧龙,最近看知乎有一个问题,是关于嵌入式入门的,看到几个回答,还不错,分享给大家。回答一:作者:听心跳的声音链接:https://www.zhihu.com/question...

张巧龙的博客 4643

【Spreadsheet】香港规范结构设计电子表格库开发方案

深入理解香港本地规范特点和要求结合国际先进标准(Eurocode) 的技术内容考虑香港地理环境特殊性 (台风、地质等)建立完善的质量控制体系保持持续更新维护的能力。

hmywillstronger的博客 1362

嵌入式软件开发工程师谈软件架构的设计 - 知乎

写文章 嵌入式软件开发工程师谈软件架构的设计 iMage 不再追求梦想的感觉太可怕 40 人赞同了该文章 嵌入式软件开发工程师谈软件架构的设计 注:此处嵌入式特指基于Linux平台,单片机和其他rtos不在讨论范围 笔者从事嵌入式软件开发有6,7个年头,bsp,驱动,应用软件,Android ...

weixin_30363981的博客 459

化工管道设计软件:CAESAR II二次开发_(6).API接口与函数库

自定义函数库是开发者根据特定需求编写的函数集合。这些函数可以扩展CAESAR II的功能,实现更复杂的管道设计任务。自定义函数库通常需要开发者具备一定的编程基础,能够理解和编写与CAESAR II接口兼容的代码。定义函数:在Python或其他编程语言中定义所需的函数。注册函数:将自定义函数注册到CAESAR II的函数库中。调用函数:在CAESAR II中调用自定义函数,实现特定功能。假设我们需要创建一个自定义函数库,用于批量修改管道节点的坐标。定义函数:在Python中定义一个函数,用于批量修改节点坐标。

kkchenjj的博客 1729

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

嵌入式软件架构的设计

嵌入式软件架构的设计 大多数嵌入式程序员学习编程,都是从开发板的附带例程开始。之后工作也会继续参考那些例程,很多编程习惯、方式也会受之影响。 其实开发板式的编程方式与工作中实际需求的并不完全一致。 开发板的通常卖给初学者,注重“即插即用”,兼容各种模块,讲究功能的全面而不讲究性能、效率、成本、功耗等。很多时候为了兼容各种型号IC或者显示屏之类,程序累赘,逻辑混乱。开发板的程序往往是一个人完成...

wangzibigan的博客 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

嵌入式软件代码架构详解,超清晰图解为什么需要软件架构,以及告诉你怎么实现软件架构

文章摘要 本文通过嵌入式开发中的典型案例,阐述了软件架构的重要性与实现方法。首先对比了"面条代码"和结构化代码在可维护性、可移植性等方面的差异,指出嵌入式系统尤其需要良好架构设计。文章随后提出了分层、模块化、接口定义和事件驱动四大架构原则,并以STM32项目为例展示了具体实现。通过硬件抽象层隔离业务逻辑与底层硬件,使用消息队列实现任务间通信,最终构建出可读性强、易于维护和扩展的嵌入式系统。作者强调架构思维应从小项目培养,通过刻意练习掌握这一降低复杂性的核心技能。

m0_59359233的博客 8466

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

嵌入式软件开发工程师与FPGA开发工程师

我是一名初入职场的萌新,工作不久从嵌入式软件工程师转到了FPGA工程师,这篇文章简单讲讲两者的区别。 嵌入式软件工程师无非分为两大类,在Windows平台下做嵌入式软件开发和在Linux平台下做嵌入式软件开发,我起初是在Windows平台下基于STM32做小型电机的软件控制,语言方面需要掌握C或python或java等软件语言,这里推荐一个快速学习语言的网站——菜鸟教程https://www.runoob.com/。在Linux平台下做嵌入式软件开发主流是基于Ubuntu系统,推荐大家在优快云上多问多学

ProNeverFake的博客 7476

嵌入式软件工程师学习路线

大家选择学习嵌入式,最后是都要做嵌入式相关工作的,所以在学习的时候真的要用心,如果你三心二意的话,那么很可能就学不好嵌入式了,因为嵌入式的确很难,不过,下面可以先来了解下嵌入式软件工程师学习路线,对你学习还是有帮助的。 嵌入式软件工程师学习路线 1、打好嵌入式软件编程的基础 这一阶段重点打好嵌入式软件编程的基础,包括学习Linux系统的基本应用,Linux的常用命令、C语言编程基础、常用的数据结构。 特别是C语言中对指针的理解和应用。这一阶段的主要目的是学习编程语言、开发环境、和培养自己的编程思维,

hqyjzsb的博客 1万+

嵌入式软件架构的六个步骤(一)抽象层

软件架构这东西,众说纷纭,各有观点。什么是软件架构,我们能在网上找到无数种定义。比如,我们可以这样定义:软件架构是软件系统的基本结构,体现在其组件、组件之间的关系、组件设计与演进的规则,以及体现这些规则的基础设施。怎么定义一般来说,基本上不重要,我们不是在写学术书籍,工程人员嘛,只关心软件架构能解决什么问题。软件架构不是制定出来的,而是产品和业务需求所决定的,架构师所做的,只是忠于需求,并合理的表达了需求。软件架构也从来都不是一成不变的。

moderncode的博客 5199

嵌入式软件工程师是干啥的?

当今社会已经进入知识大爆发的年代,各种智能化设备层出不穷,软件开发成为当前最受追捧的技术,我们首先从了解嵌入式软件工程师开始吧!

WenDao_Engineer的博客 5万+

菜鸟应该如何开始设计一个项目的嵌入式软件架构

优快云,GIT等各大论坛上很多文章都有讲,如何设计项目的嵌入式软件架构,But门槛实在太高了,需要懂什么软件架构设计的生命周期,画用例图,写用例描述,画鲁棒图,归纳子系统,分层,分模块等等,实不相瞒这些没有半年八载的项目经验根本做不出来的,刚好经过这周的嵌入式架构培训,分享下最近在做项目的嵌入式软件架构的设计经验吧,不喜勿碰,谢谢。 6步走战略: 第0步——嵌软需求:功能/接口/质量/硬件约束/方案约束 第1步——粗粒度分层 第2步——中粒度分模块 第3步——绅粒度分ISR/周期仸务/事件驱劢...

weixin_43495433的博客 3055

嵌入式软件架构的六个步骤(三) 识别和管理系统数据

数据决定设计,是现代嵌入式软件设计的第一原则。Linux的创始人Linus Torvalds在一次演讲中也曾经说过说: "烂程序员关心的是代码,好程序员关心的是数据结构和它们之间的关系。"他在谈到Git时,也曾表达过类似的观点,“好程序员和烂程序员之间的差别,就在于他们认为是代码更重要还是数据结构更重要。”我们上学时,就学过一个公式:程序 = 数据结构 + 算法。如果从嵌入式程序的宏观视角去理解这个公式:所谓的数据结构,就是数据结构与处理机制;而所谓的算法,就是代码逻辑。好的数据结构,总是会简化代码。

moderncode的博客 3158

嵌入式软件架构设计资源下载

嵌入式软件架构设计资源下载 【下载地址】嵌入式软件架构设计资源下载分享 本仓库提供了一个名为“嵌入式软件架构设计”的资源文件下载。该资源文件专注于电机控制的数字信号处理器(DSP)的嵌入式软件架构分析与设计 项目地址: https...

gitblog_06681的博客 330

嵌入式硬件工程师与嵌入式软件工程师的区别(详细版)

随着嵌入式技术的不断发展,嵌入式硬件工程师的角色已经发生了显著变化。嵌入式硬件工程师与传统的硬件工程师有所不同,除了具备硬件设计的基本技能外,还需要涉足一部分软件工作。底层驱动的开发:包括开发设备驱动程序,确保硬件与操作系统之间能够有效通信。嵌入式操作系统的裁剪和移植:根据项目需求定制操作系统,移植到目标硬件平台上。GUI与文件系统的移植:负责图形界面和文件系统的集成,使系统能够以更直观的方式与用户交互。基于操作系统的底层驱动设计。

qq_46187594的博客 9308
下一篇: 基于pjsip实现p2p语音对讲
voidreturn
博客等级 码龄10年 53粉丝 45原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值