嵌入式软件架构的设计

嵌入式软件架构的设计

大多数嵌入式程序员学习编程,都是从开发板的附带例程开始。之后工作也会继续参考那些例程,很多编程习惯、方式也会受之影响。

其实开发板式的编程方式与工作中实际需求的并不完全一致。

开发板的通常卖给初学者,注重“即插即用”,兼容各种模块,讲究功能的全面而不讲究性能、效率、成本、功耗等。很多时候为了兼容各种型号IC或者显示屏之类,程序累赘,逻辑混乱。开发板的程序往往是一个人完成,不需要讲究多人合作,这也影响了其编程方式。

实际工作中,开发一款产品,需要讲究成本(物料,开发,加工),稳定性,功耗(比如电池产品)。通常,由于项目开始的时候,往往没有明确的需求,或者在确认需求后却由于种种原因多次更改需求,为了更好的开发,编程方式更侧重于程序的移植性(需求变化可能导致更改MCU等),可读性(换人还能快速接手),稳健性。

当一个项目变得复杂,代码量很大时,往往需要一个良好的软件架构。否则很容易造成程序逻辑混乱,顾此失彼,移植困难,灵活性差。

一、分层

对软件进行分层,容易实现高内聚低耦合。

分层的原则有:1单向逐层调用;2针对接口编程;3依赖倒置;4封装变化。

分层数目,太多会导致产生不必要的开销,太少又会导致系统分离不够,结构不合理。

下图为安卓系统的软件层次体系

二、三层架构

回顾一下,软件开发流程一般为分为下面若干阶段:需求分析,概要设计,详细设计,编码,测试,交付验收,维护。

这里必须明白一点,包含单片机开发的项目一般都不会是纯粹的软件项目,甚至单片机软件本身都不一定是项目最重要的一部分。此类项目一般还会包括机械结构设计,平面设计,交互设计等等。

一个项目的生命周期,一般由四个主要阶段构成:概念阶段,定义阶段、开发阶段和结束阶段。

嵌入式软件工程师,通常会在定义阶段开始参与,协助主管做项目可行性分析。立项之后,再作需求分析。然而问题往往出现在这里:需求不明确,或者需求随意更改。这里不要说什么职责,责任范围,问责之类,毕竟理论是一回事,实际又是一回事。比如老板空降一个特别需求,主管也只能往下扔,你倒是敢向老板问责?

所以,为了更好地完成任务,一个灵活而合适的软件架构,是非常必须的。

一般使用单片机(比如STM32)开发的项目,分层数目为3比较合适。从下到上,分别为硬件驱动层(底层)、模块功能层(中间层)、业务逻辑层(顶层)。

硬件驱动层:包括MCU片内资源驱动代码与外部各类IC的底层驱动代码,MCU片内驱动代码与IC驱动代码最好也能各自保持独立。向上提供API接口。

模块功能层:隔离顶层与底层,实现与提供顶层所需的API接口。

业务逻辑层:具体业务逻辑代码,也可以说是应用层。

构建工程文件时,为各层建立单独文件夹,而MCU库,操作系统代码,文件系统代码,USB库,GUI系统代码等等独立部件也要单独设立文件夹。这有利于需要时方便地更换或者删除、添加。

在编程时,要遵循上面的几个分层原则。分层有时会导致性能下降,对性能要求高的关键地方,可灵活运用函数指针,内联,甚至函数别名减少开销。

假设,一个项目原本只需要显示静态图片,后来需求更改,还需要播放视频。之后选择修改方案:更换MCU,使用更大外置存储器。

那么,1.底层,我们只需要将原来的MCU相关代码与存储器IC驱动替换掉。2.中间层,添加视频播放相关API函数。

这样原来的代码大多还能复用,节省不少时间。

假如需求不变,只是更换一些功能IC(比如考虑成本,或者断货,或者新出的更好IC),甚至只需要更换硬件驱动层相关 IC文件即可。

三、举例

下面以一个实际项目为例做参考。

某项目用到显示屏显示网络数据。以显示模块为例,解析3层架构的运用。假设显示屏驱动为st7789,MCU采用FSMC方式st7789,定时器pwm控制背光。

下面只是说明显示模块部分。

1.硬件驱动层(底层):两个c文件以及对应头文件:单片机内部资源驱动文件mcu_bsp_drv.c,st7789驱动文件lcd_drv.c 。

mcu_bsp_drv.c,包括所有的各个功能模块所需要的MCU资源的初始化驱动代码,并且每个模块只用一个函数并且以_mcu_init结尾。这类函数一般只用一次,不要怕又臭又长,但必须要有详细的注释说明。显示模块初始化函数命名为lcd_mcu_init();

lcd_drv.c,这实际上是st7789的驱动文件,为什么不命名为st7789.c呢?因为如果更换了驱动IC,也不需要修改中间层的头文件包含代码。对于显示模块,一般需要提供一下接口:初始化函数,画点函数,单色方块填充函数,数据填充函数,显示打开关闭函数,背光控制函数。命名方式为lcd_drv_xxx()。这些函数在lcd_drv.h中声明,为中间层显式提供API;

2.模块功能层(中间层):lcd_api.c以及对应头文件

中间层实现显示相关函数:初始化函数,背光控制函数,各种几何图形(直线,圆,方框等)绘制函数,各种控件(窗口,按钮等)绘制函数,假如使用了第三方GUI系统,这些就不需要自己实现了。

3.业务逻辑层(顶层):这一层与具体业务有关,也是程序员最花时间与精力的一部分。如果业务复杂,还可以细化分层。

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页