完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
笔者从事嵌入式软件开发有6,7个年头,bsp,驱动,应用软件,Android hall,framework等都有涉猎。平时除了关注嵌入式行业的发展,也多少对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模块中调用该接口。至此新需求已经“完美”的解决了。
下面先跑个题,谈谈多线程/多进程模型的优缺点,主要谈多进程的优点了: 教科书上的解释就不提了,首先我对大的项目是推崇多进程模型,无关性能,主要原因有: 模块的解耦:很多开发人员维护开发的多线程模型项目应该都多少会存在下面的问题:跨模块间的直接调用,如果不相信,好,你的项目一定是分模块的吧,现在随机的删掉一个模块,build下看能build通过吗(只需要build不需要运行),我相信大部分情况下一定会遇到某个函数调用,某个全局变量找不到的情况,这种情况说明你的模块间存在强耦合了。由于多线程天然的优势,地址空间的相互可见,导致直接调用十分容易,很多经验尚浅的工程师,很容易就写出直接调用的简单粗暴的接口,如果遇到个static接口的函数,图方便也会把static去掉,直接拿过来用了。这样整个工程随着功能不断的添加,模块间的交叉越来越多,耦合越高。 而我之所以推崇多进程的原因就是,多进程能从物理上隔绝了这种“方便”的通讯方式,导致在想实现一个模块交互时,会多思考下这个交互是必要的吗,如果是必要的,则会进一步思考接口定义是否简单明了(因为进程间的通讯相对会麻烦些,开发人员会本着能减少交互,明确接口的想法去仔细考虑接口,协议的定义,否则折腾的是自己了),这如同人生,如果一直顺风顺水,人们可能不会想太多,思考太多,而如果道路上有些坎坷,则会有另一种感悟吧。 所以我的想法是多进程的模型会逼迫你去更多的思考想程序的设计,物理上减少模块的耦合。 抽象通用组件,分离通用功能和业务逻辑功能:当把一个多线程模型修改为多进程模型的过程中,经常会发现有些接口代码重复的出现在多个进程模块中,因为之前接口函数是在一个进程空间,大家都可以直接调用的,比如接口A被模块a,b调用,模块a,b分离为两个独立的进程后,接口A需要在a,b中分别实现了,无需解释,重复代码这个在软件工程中是大忌,必须消除。做法也很简单,将这些被多个模块调用的接口分离处理做成lib,供其他模块调用,当你完成这部分工作后,你发现了什么,是不是剥离的接口,可以作为整个项目的通用组件存在了,完美的情况下,lib下的代码是通用基础组件,各个模块中是独立的业务处理模块。
方便性能测试:多线程种单个线程的资源占用不是很好查看(至少有些嵌入式系统没有完善的命令),当整个进程资源消耗很高时,如何判断定位时那个模块线程的问题,同3一样难以抉择,而如果是多进程的模型,谁的进程占了好多资源,谁就去查下吧,其实这个还是个颗粒度的问题,同样的系统,划分成多个进程,单个进程的复杂度一定比只有一个进程的复杂度低的多,复杂度降低,也就更容易定位查找各种问题。
方便公司的代码权限隔离:其实我鄙视这种做法,公司要相信自己的员工,但鉴于诚信在中国已经。。。。,做些隔离也无可厚非了。 多线程模型下,前面讲到如果去除一个模块,你可能都不能build了,那么是要把所有代码暴露给所有的工程师吗,显然不能,所以各个模块只能提供库的形式了,不过我觉得将通用功能接口组织成通用库是正常的做法,而如果把和业务相关的模块也提供成库,就有点。。。。 至此在补充一下,以上所有的优点,其实都不是很关键的点,都不能够让多进程有绝对的优势压倒多线程模型,只是从个人的角度觉得,多进程模型更能强迫工程师思考解决一些问题。(而这些问题有经验的工程师无论什么模型都会思考的) 上面说了这么多,该考虑下把之前项目的例子改成多进程模型,否则就只是纸上谈兵了,下面开始: 首当其冲的问题就是:选择多进程的通讯方式,多线程间的直接调用是不能用了,那么如何选择多进程的通讯方式呢? linux下提供很多ipc方式,此处不一一列举,对于非大数据量的控制,通讯消息的传递,比较好的方式是采用socket,本机上更多采用unix socket方式,(这种方式有什么好处?当你有需要把单一系统做成分布式系统时,优势就明显了)
上面的binder,ubus等原理很简单,就是建立一个消息中心,构建一个转发路由模型,所有其他模块之间不直接交互,而是采用消息中心转发,路由,而如何决定路由规则,则采用订阅/发布的观察者模式来进行规则的定义。(嵌入式开发或者C语言开发者,经常会误以为设计模式是和面向对象语言关联的,是面向对象语言独有,虽然有很多大牛做了这方面的普及,但鉴于有些开发者的信息渠道比较闭塞,导致这种想法仍然十分盛行) 基于这个模型,我们上面例子的需求就很好解决了,加入一个消息中心模块,所有需要通信的模块只同该消息中心模块连接,然后订阅自己感兴趣的事件,当事件发生时,只需要进行相应的处理就可以了。 这样上面的模块b,c订阅模块a的事件,当模块a检测到某事件时,发布该事件,该事件先到达消息中心,在由消息中心转发给模块b,c,而对于新加入的模块f,也只需要订阅该模块,而不需要在修改到模块a的代码,使功能的扩展十分方便。 同时对于前面提到的定制化开发同样得到了简化,如果定制化版本需要加入模块g,这样只需要定制化版本中将模块g作为一个独立进程启动,然后订阅模块a的事件即可,而定制版本和通用版的区别就在于是否启动模块g的进程,从而实现了软件工程的一个目标:功能的添加如同搭积木一样,只需要把一个模块插入(启动)或拔出(不启动)即可,功能的改变只局限在一个或某几个模块间,对主体框架不会有任何影响。 以上大概描述了对一个项目需求逐步优化的过程,例子看似是基于嵌入式项目,但貌似对软件工程同样适用。
在对照下互联网行业的负载均衡方案,仿佛那个负载均衡的前端也像一个消息中心了。 行文至此,只是想说明一个问题,软件的设计是相通的,基于的思想是相同的,虽然嵌入式行业的业务逻辑相对比较简单,但其实在仔细思考后,仍然会有很多架构上的改进,设计。 但是让我感到悲哀的是,有些嵌入式开发者,鉴于业务逻辑的简单,感觉采用一些不那么好的处理方式也能解决问题,不去思考如何去优化,改进。比如上面例子的方案一,如果在定制需求不多的情况下,维护起来也没太大问题,即使定制需求多了,再招些初级程序员也能维护的过来,一个人一套代码负责一个项目的公司也不是不存在。 同样互联网行业和嵌入式行业也不应该存在一个不可以逾越的高墙,我们更应该关注的是通用的软件工程思想。 |
|
|
|
只有小组成员才能发言,加入小组>>
800 浏览 0 评论
1156 浏览 1 评论
2531 浏览 5 评论
2863 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2714 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1092浏览 3评论
197浏览 2评论
463浏览 2评论
376浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
458浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 09:47 , Processed in 1.327124 second(s), Total 50, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号