嵌入式裸机架构的探索与回归

本文作者因项目开发中遇到的问题,探索嵌入式裸机架构。介绍了架构1.0、2.0、3.0版本,指出裸机架构中回调函数作用不大,回归前后台系统开发原则。强调做好分层、头文件和全局变量管理,还分享了实战心得,如APP模块化、资源声明、低耦合等。

为什么会想着探索下嵌入式裸机的架构呢?是因为最近写了一个项目,项目开发接近尾声时,发现了一些问题:

1、项目中,驱动层和应用层掺杂在一起,虽然大部分是应用层调用驱动层,但是也存在驱动层调用业务层的情况,这导致了层次间的耦合;

2、应用程序全都放在了一个app.c文件夹里,代码高达1万行,实在是过于庞大,我想着将代码拆分下,发现实在是太困难,牵一发动全身;

3、全局变量满天飞,代码量大了之后,自己都晕了,虽然写了注释,但是想想,如果注释没写清楚,那么时间久了,自己回来看都不知道是啥~~~~~~;

那么,如何在后续项目中有所改进呢?

架构1.0

关于程序的架构和规范化,要做到:

层次分明,模块化,高內聚低耦合,风格规范易懂。

自顶向下设计,自底向上开发,花一两天来设计,设计好之后再开发。

层次分明

根据需求,有各种各样的功能要实现,但是因为嵌入式不仅涉及到软件,还会涉及到硬件,所以,需要分层,思维才能更清晰,更有利于后期的开发和维护。

根据我自己的开发经验,先说下我的最初裸机分层习惯。

将整体的架构设计分成3层,再多层次对于裸机感觉没什么必要了。

模版示例:

APP存放业务层代码;

DRIVER存放硬件驱动层代码;

SYSPERIPHERALS存放系统外设代码;

FWLIB存放固件库;

CORE存放一些板级核心代码;

OBJ存放keil的输出文件;

MIDDLEWARE存放中间件;

RESOURCE存放一些资源比如字库等;

USER存放工程;

UTILITIES存放其他内容;

除了一些固定的文件,在开发时分为系统外设、驱动层,再加上一个业务层。

系统外设层主要是对用到的各种片上外设进行初始化,之前经常跟驱动层写到一起,但时间久了就发现二者其实是不同的层次,写到一起容易混乱。

理想情况下,系统外设层向驱动层提供接口,驱动层向业务层提供接口。

系统外设层的各个硬件口,最后都用宏定义给重命名,如果要移植,就只用该硬件口就行,而不用去动驱动层,比如,如果就用GPIOA去开发,那么如果换了板子,就要改驱动层的书写,但是如果重命名,就只用改系统外设层的头文件即可。

另外,对于业务层来说,不推荐将所有的功能都放在同一个文件中,虽然比较方便,但是这会导致文件特别大,不利于后续开发和维护。最好按照功能模块进行开发,然后有一些各模块共用的功能,可以抽离出来,单独一个文件。通常,拆一个总的入口文件,再按大模块拆一拆,然后就是共用的部分。按模块其实是同级拆分,将共用功能分离出来,其实是上下层次的拆分,不过,也没啥必要再分不同目录来放了。

上面实例中,其实拆的太多了,就多了文件跟文件之间的纠缠,后续也很难理清。

前期一定就要做好设计和规划,不要试图想着先开发,后续再修改,惨痛的教训告诉你,修改比重新开发更让人烦躁,很费时间,分分钟有牵一发动全身的风险。

总之就是,越往上层,就应当越抽象。

层数越多,越复杂。

请合理平衡。

关于系统外设和驱动层的初始化,如果系统外设是和具体的驱动关联的,就可以放在驱动里,如果不能跟具体的驱动关联,就直接在系统外设层定义初始化接口即可,比如定时器。

另外,注意编码规范,如果太随意,越往后代码量越大就越难开发。就按照常规推荐的那些编码规范来写就行了,也不必特立独行。

关于变量还有头文件中的宏定义,有共用的,有专用的,专用的肯定是放在自己的c中,共用的可以放在common中,该static的就static。关于程序中的全局变量,建议如果超过3个,就用结构体封装起来,函数最好也是用函数指针结构体封装起来(借鉴硬件家园的风格)。区分仅自己使用和需要共享使用的情况,然后决定是用static限定或者加入到相应结构体中。

模块化就比较好理解,各个模块单独开发,最好可以实现独立编译。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值