如何建立一个通用软件架构以满足嵌入式产品的快速迭代需求
最近几年连续开发几款智能仪器的嵌入式产品。因为是相近的产品类型,只是控制器和一些具体功能电路
有些差异。考虑到软件研发人力有限,同时又要把过往的成熟产品的一些处理经验方法把它IP化,形成自己独有的算法处理体系。因此,建立起一个通用的软件架构,尽量做到与底层硬件的弱耦合,这样可以更快的构建产品原型。尤其是在产品早期,很多想法不一定成熟,或者产品使用一个阶段之后,可能需要添加修改一些功能,这个时候,通用的软件架构因为其硬件的无关性,就能帮助我们快速实现想要的功能,完成快速迭代。
CSL,chipsupport layer,又称之为register drivers,这一部分对控制器底层要非常了解。比如,主频设置,时钟源选择,复位方式,片内外设如UART、IIC、ADC、PWM、GPIO等的时钟选择,使能设置等等。
BSP,boardsupport packet,板级支持包,包括一部分外设驱动。这里主要是实现某一个明确的功能,比如如何实现WDC,如何输出PWM,怎样通过ADC读取一次转换数据等。
CSL和BSP这两层,基本上控制器厂商都会有源代码支持。这里主要是要求硬件工程师或驱动工程师对芯片本身比较了解,一般工作量不会太大。
再往上走,就是与产品应用有关的硬件抽象层HAL,hardware abstract layer。硬件抽象层的主要作用在于,屏蔽掉底层不同的BSP、CSL调用接口,向上层应用提供尽可能统一的调用接口,使应用工程师专注于产品功能的实现。一般地,相近的产品,其功能调用接口都大同小异。同一家公司,同一个研发团队,应尽可能定义一个自己的统一风格的HAL,并随着后续产品的研发,逐渐充实、完善这套HAL。通常,所谓的HAL调用接口,可定义成如下方式
Hal_LED_AlarmOn(void);
Hal_LED_ServiceOff(void);
把这些看似简单的接口从一开始就定义清晰,久而久之,就形成了自己产品代码编写风格。既方便后续阅读维护,也方便新来工程师的尽快上手。
中间件层
MDL, middleware layer, 主要是一些与产品应用相关的如算法实现,数据滤波,私有协议栈,也包括自有特色的如图形交互界面,交互控制台,以及如类似XML
配置参数解析在内的服务型设施等。
HAL和MDL构成了相近产品或一家公司嵌入产品的核心IP,往往需要多年的产品积累和技术沉淀,以软件IP方式巩固产品特色。HAL和MDL向下兼容了不同的硬件,向上则为应用程序开发提供统一的API以及功能组件。
最后是应用层,这部分是与产品功能、性能紧密相关的代码,实现组合逻辑调用、输入输出控制、交互配置等功能。
现在的软件开发过程,往往都是果断开始,快速搭建和迭代更新。对于嵌入式软件,基本上都要求具有bootloader引导功能,一方面可基于私有协议实现在线升级,可保证一定的安全性,另一方面为快速迭代更新提供技术保障。以笔者的项目为例,同时提供ISP/IAP功能,为产品生产阶段和量产发布阶段的迭代更新提供完整的技术保障方案。
最后,附上自己在程序开发过程中,遵从上述原则所进行的源代码文件的工程管理例子。