底层驱动书写的基本规则

1 对每个硬件对象编写独立的驱动程序

每个对象对应一个头文件和源文件,如果对象是外部对象,则要在头文件用宏定义对象接在哪个脚上,头文件只声明供外部调用的功能函数,也就是说,其他人只要看头文件函数声明就知道如何使用此对象而无需去看源文件去阅读代码。一般函数的命名规则是:对象功能,比如初始化 Charger,函数名可以为 ChargerInit。
如果一个函数只供对象功能函数内部调用,则此函数在源文件里面声明和实现,不出现在头文件里,并声明为 static 函数,因为声明为 static 的函数只能供定义此函数的源文件使用,其他源文件看不到此函数。如果一个全局变量只供某模块使用,则可以把此全局变量定义为 static,这样此变量只能在定义它的源文件中使用,其他源文件看不到此变量,所以不会产生命名冲突。

2 封装要完整、封装之间不能交叉

模块函数就实现此模块要实现的功能,模块内部之间不能相互调用,如果要调用则交给高端来处理,比如在 Flash 子程序里面不能调用串口,当然测试 Flash 子程序的时候例外,当测试完毕时,必须把调用串口子程序代码删除,此时 Flash 子程序可以通过返回值告诉高端,让高端根据返回值来决定是否调用串口子程序。

3 返回值问题

如果只返回一个基本类型的返回值,则用返回值返回此值也可,如果返回一个复杂类型的返回值,比如一个 struct 结构体,则用返回值返回的话要进行复制,开销很大,此时用传址方式返回,如果返回的值很多,可以把这些值定义在一个 struct 里面,通过指针形式返回。

4 函数编写

函数第一要命名合理,一看函数名就知道此函数的功能、操作的对象。函数的层次最好不要多于 5 级,一个是效率降低,再一个阅读性也变差,对每个函数注释清楚,所有的函数代码编写方式有一个统一的风格,注意对齐。函数中的堆栈变量使用前一定要赋初值,再一个嵌入式的 RAM 一般比较少,注意不要堆栈溢出。尽量用效率高的方式编码,比如乘除可以用移位来实现。如果编写的程序在 16 位控制器上运行,函数整型参数和局部整型变量要用 16 位,因为如果用 8 位的整型变量,系统要做多余的工作来防止 8 位溢出之类的事情,不仅不节省空间,还会降低效率,通过反汇编对比可以看出此现象。

5. 调用驱动程序

一般会在两个地方调用驱动程序,一个是轮巡调用的函数,一个是中断处理函数,可能有多个源文件包含相同的头文件。设计头文件的时候要避免重复定义问题,方法是:以定义 CHARGER模块为例,头文件如下编写:

#ifndef _CHARGER_H
#define _CHARGER_H
/*函数声明*/
#endif

猜你喜欢

转载自blog.csdn.net/weixin_43704402/article/details/114664347
今日推荐