赞
踩
嵌入式的软件设计所面临的问题,软件的问题,主要是人的问题。软件危机的爆发,也是由于人与人之间的问题,由个人完成的“小”程序,和一个由团队完成的“大”程序,有根本性的不同,其问题在于复杂的人员关系,各种人员的配合和沟通都会对整个项目造成极大的影响。
架构分层
在嵌入式开发领域,尤其是在mcu方面,总有种软件开发理念要慢其他领域一步。即使多年以来,硬件的发展早已日新月异。然而,很多的底软程序员依赖守着老旧的开发理念。我们正处于一个技术快速革新的时代,新需求带来新的技术,新的技术带来新的理念。
不过技术的不断更迭,总有些东西是不变的,那就是开发的价值观念。硬件的快速发展,使得软件开发不得不面对众多的硬件选型,为选定的硬件开发相应的驱动。然而很多软件功能其实是相对稳定的,若软件和硬件的驱动深入捆绑时,往往硬件稍有变动,软件也要需要有一些调整。最近我们团队就在面临这个问题,由于项目最初采用mcu作为开发平台,但是随着项目越做越大,代码越来越多,硬件资源的限制越加明显,无论是rom还是ram都面临严重不足的情况。基于此,项目决定采用cpu来进行项目的下一阶段开发。操作系统从嵌入式的实时操作系统,转向基于linux裁剪的RTOS系统。然后就发现,mcu的那一套代码,根本无法迁移到新的平台上,只能重写,将原来的代码重构。当然新的平台的开发,并不意味老的平台要放弃维护,如果两边的代码不能归一化,这就使得开发团队不得不同时维护两套代码。
想要做到在不同平台之间共用代码,就不得不做一件事情,那就是代码的架构分层。嵌入式软件的架构分层可以很好地解决软件和硬件的耦合问题,在应用层和设备层之间引入一个驱动抽象层,使得应用层和设备层可以单独变化,对于应用层而言,有稳定驱动抽象层,在不同的设备之间就可以快速迁移,不同设备只需要提供相应的板级支持包,也就是BSP。对于Linux驱动开发而言,使用设备树和linux驱动的子系统,对于MCU驱动开发而言,需要底软来开发完成相应的驱动开发。总而言之,更加不同的开发平台,实现应用层所需要的驱动接口,这就是架构分层的意义。当然于此,两台平台的兼容还需要做到系统无关性。
架构分层的关键是分离应用层和设备层,同时将应用层的硬件操作进行抽象化,实现标准化接口,也就是说驱动抽象层的归属权是属于应用层,不同的平台,需要来适配这一抽象层,实现这样的接口。通过接口,应用层可以隔离变化,同时也和设备层解耦,应用层和设备层各自演进。
在进行分层的同时,也可以更加项目实际情况进一步细分,比如设备层再分硬件抽象层和实现层,当然这是为了应对同质化的硬件平台,不同的处理方案,比如stm32f4和stm32f7的平台,就可以采用这种方式将BSP的稳定部分进一步抽象,将变化的部分近一步隔离。
抽象是有着相当的代价的,最大问题应该属于项目层次复杂性,本来应用层可以直接访问设备层,分层后,可能会隔着多层才会最终调用到设备。这对项目管理来说是个相当大的成本。总而言之,抽象的前提是基于变化,若软件失去了变化,那么抽象也则失去了基础。根据项目的复杂层度,来选择相应的抽象层级,越复杂越需要多层抽象。
开发模式
面向对象的开发理念,十分适合做架构分层,或者说,面向对象本身就是一种架构分层理念,类的存在实现了封装,继承和多态的特性自然地隔离不同层次,抽象类的存在实现了接口隔离。面向对象和架构分层的理念可以说十分契合。当然除此之外,面向对象还有着大量成熟的设计模式可以使用,有着SOLID设计原则,来帮助开发人员检验自己的架构是否良好。
当然在嵌入式领域更为常用的面向过程的开发方式,同样也可以实现架构分层。或者说,架构分层并依赖开发的模式和理念,只要抽象层是稳定标准的接口,就能够实现抽象层的作用,以分离应用层和设备层。当然在架构分层领域面向过程还有有相当的缺陷的,这就是封装,由于继承和多态的存在,使得面向对象对于类型的扩展及其便利,面向过曾则要麻烦的多。不过面向过程对于方法的扩展较为便利,面向对象则不然。由于封装问题,面向过程开发的项目,往往兼容性可移植性都要差很多,要做好这一点,也比面向对象开发也更为困难。所以面向过程也有其独特的风格,也是目前嵌入式领域最为常用的使用方式。
面临问题
从我个人而言,我会觉得面向对象在大多数场景相较于面向过程优势更加明显。但是实际开发过程中,问题往往不在于那种技术更有优势,而是开发团队能够使用哪种技术。在我们项目上,由于改版之初,我曾提出以面向对象的方式来设计整个项目的软件架构,但是项目领导考虑到整个团队,仅有两三个人可使用面向对象来进行开发,还是未采用面向对象设计整个项目。其实我在看来仅使用面向过程,往往造成原来的弊端,若要同样实现面向对象的效果,其要求更高,对开发人员技术要求也高。于此,不禁让人想起Rober C.Martin在《The Clean Coder》中所言
软件行业中项我们这样的一批人必须要面对这样一个事实,即指引下一代软件开发人员成熟起来的重任无法寄希望于大学教育,建立一种包含学徒期、实习期和长期指引的机制已是迫在眉睫。
与时俱进
软件开发不断向前发展,我们作为从业人员,怎么可以固步自封,需要不断学习才能在日新月异的时代中不被时代所抛弃。当看到C23标准的发布,想到我们团队还在使用C11的标准,在C23标准中看到许多特性与C++的特性相似,不禁让人感慨C活成了C++的样子。我曾试过使用C++开发STM32,通过屏蔽C++的异常机制和RTTI机制,使得C++开发的bin文件并未显著增加,反而可以使用一些泛型、面向对象特性和STL,还有智能指针,C和C++的兼容性也非常不错,相互调用都较为容易,但我从未想过在项目团队中推广,因为我知道,让一群写C的人去写C++,无疑是不现实的。同样的道理也在RUST上,我对RUST也相当好奇,0成本抽象让我想一探究竟,所以最近也在研究RUST方面的东西。这些更加前沿的东西,不能实际运用到实际的开发工作中,我感到甚为可惜。不知什么时候我们实际的开发工作才能走到时代的前沿,总有人会先行一步,希望走在前方的人,能够带领整个行业走向更远的未来。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。