嵌入式系统编程规范
李红志
程序的可读性、可扩展性、可复用性、易维护性、
语法是代码的入门,算法是代码的灵魂。
第1章编程常见错误
1.1、语法错误
1、错用函数数据类型,比如abs(x),x可能为16bit的值,如果为16bit的值,给出32bit的值就会出错。
2、内存越界访问
内存越界访问有两种:一种是读越界,即读了不属于自己的数据,如果所读的内存地址是无效的,程度立刻就崩溃了。如果所读内存地址是有效的,在读的时候不会出问题,但由于读到的数据是随机的,它会产生不可预料的后果。另外一种是写越界,又叫缓冲区溢出,所写入的数据对别人来说是随机的,它也会产生不可预料的后果。
3、结构的成员顺序变化引发的错误
在初始化一个结构时,老手可能很少像新手那样老老实实的,一个成员一个成员的为结构初始化,而是采用快捷方式,如:
Struct s{int l;char*p;};int main(int argc,char*argv[]){struct s s1={4,"abcd"};return0;}
以上这种方式是非常危险的,原因在于你对结构的内存布局作了假设。如果这个结构是第三方提供的,他很可能调整结构中成员的相对位置。而这样的调整往往不会在文档中说明,你自然很少去关注。如果调整的两个成员具有相同数据类型,编译时不会有任何警告,而程序的逻辑可能相距十万八千里了。
4、栈溢出。
我们在前面关于堆栈的一节讲过,在PC上,普通线程的栈空间也有十几M,通常够用了,定义大一点的临时变量不会有什么问题。
而在一些嵌入式中,线程的栈空间可能只5K大小,甚至小到只有256个字节。在这样的平台中,栈溢出是最常用的错误之一。
1.2、编译错误
1.3、链接错误
第2章编程知识
关键字valotile的作用是告诉编译器,不要把变量优化到寄存器里。
第3章编程规范
1.1整体结构
1、必须包含的两个文件:
“#include"std_inc.h"”
“#include"std_defs.h"”
2、一个完整的project需要有程序说明文档
3、需要有变量宏定义函数说明文档,包含变量规则命名。
4、需要有程序流程图
5、需要有硬件测试报告
6、需要有程序修改记录
7、要有软件时间控制分析
1.2编程规范
1、定义宏定义按照功能模块来区分;
2、枚举型定义当宏定义来处理;
3、程序和数据要分开;
4、格式上要对齐;
5、空行要规范;
6、中断中调用的变量,一定要分析在计算过程中别的地方赋值是不是有非本身意义的赋值;
7、变量的意义要清晰;
8、程序要分层设计;
9、
1.3注释规范
1、变量和宏定义都要在定义的时候注释一下,作用是什么,单位,放大倍数。
2、用“#”标记需要问别人、需要改进的地方。
3、用“$”标记如果硬件改变需要进行变化的地方。
4、用“//XX”。
5、每个函数上面都要写注释;
6、程序段内不要太多的注释,多的话影响程序的可读性;
1.4变量命名
最容易上手的编程语言
1、变量名用小写
2、宏定义用大写
1.5不建议使用全局变量的原因:
(1)全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元;
(2)它使函数的通用性降低了,因为函数在执行时依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件中的变量同名时,就会出现问题,降低了程序的可靠性和通用性。在程序设计中,在划分模块时就要求模块的“内聚性”强、与其他模块的“耦合性”弱。即模块的功能要单一(不要把许多互不相干的功能放到一个模块中),与其他模块的相互影响要尽量少,而使用全局变量是不符合这个原则的。一般要求把C程序中的函数做成一个封闭体,除了可以通过“实参——形参”的渠道与外界发生联系外,没有其他渠道。这样的程序移植性好,可读性强。
(3)使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此要限制使用全局变量。
(4)如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。
说明:使用全局变量的作用是增加了函数间的数据联系的渠道。由于函数的调用只能带回一个返回值,因此有时可以利用全局变量增加与函数联系的渠道,从而到到一个以上的返回值。
第4章2011-4-22:程序的矩阵化设计思想
适用于嵌入式软件设计,无操作系统,软件结构较复杂的情况。
1.6定义
最小时延原则:软件设计过程中,在不影响其他性能的情况下,应该让数据的产生过程和使用过程之间的时延最小。需控变量:软件运行过程中,需要控制计算顺序的全局变量。
非需控变量:软件运行过程中,不需要控制计算顺序的全局变量,比如从总线引发的中断中获取的信号。
优化矩阵:在设计函数执行顺序时,用于记录函数和函数输出变量的矩阵。
1.7软件结构的矩阵化
程序上的分层设计。层与层之间有接口。矩阵化设计。全局变量的作用范围要有设定,不能从上到下
都是一种变量。分层设计后,才比较容易处理指令冲突的问题,因为指令被执行之前会有对几种指令进行判断的操作。模块化是矩阵化设计的基础,模块作为矩阵的cell,同一个层面的作为一个row,程序执行一次,就是从顶层到底层一次,只不过每次可能走的trace不同。这个trace就是程序真正运行了哪些模块。
程序应该是从模块化、发展到分层、再到矩阵。
环境识别、驾驶意图识别、干预退出预估、
1.8函数执行顺序的矩阵化
适用情况:系统信号较多,全局变量较多,在一个控制周期内,相互之间有计算先后要求。同一层次的函数较多。全局变量只在一个函数中被赋值,在多处被调用。
全局变量分为需控变量和非需控变量。
该方法是对某一层的函数进行执行顺序的设计
1.对每一个函数进行编号;
2.建立需控变量集:将每一个函数的输入全局变量和输出全局变量中的需控变量放进需控变量集。
3.对需控变量集中的每个元素编号;
4.建立每个函数的输入需控变量集和输出需控变量集,变量集用需控变量集中元素编号表示;
5.逐个将函数添加至优化矩阵,每添加一个函数,调整优化矩阵,直到所有函数添加完成。得到每个函数的
可存放域。
6.根据最小时延原则,调整每个函数到最优位置。
7.输出可行的函数序列。
第5章编程经验
1.9程序设计思想
控制时序的设计思想:
程序分层的设计思想:
程序的矩阵式设计思想;
变量的集中处理思想;
变量自衰减的处理思想;
估算变量的自衰减。估算变量时,由于只有满足估算条件才能进行估算,而估算条件不是持续成立的,所以只能在某些点进行估算。没有进行计算的地方,该变量就要随时间衰减,并且要给出一个health指标,表明这个被估算值的可信度。
干预退出预估的处理思想;
1.10【2010-12-5】
1、能从CAN上获取的信号要从CAN上获取,比如发动机转速、发动机输出转矩、加速踏板位置(不知道还有用没了)、节气门开度(不知道还有用没了)、传动比(或者说档位)。
2、我觉得用115200,10ms传出100个byte没什么问题。这样的话,B+S的采集主要作用就在于同步一下压力,方向盘、横摆等信号用更高的频率采集,确认一下单片机的处理是否达到精度。
3、变量命名的规范化。全局变量中的temp,写成s32temp1,局部变量的temp,写成temp1s32.感觉不怎么好,但是总要区别一下的。
4、abs(x);的函数原型是int abs(int x)
5、尽量避免一个变量在不同程序段被幅值;
6、中断中用到的量,要小心在程序外会不会有非本身含义的短时间赋值;
7、一段代码尽量不要超过100行;
8、全局附着比局部复杂要复杂;
9、任何一段代码,要做到能用1句话描述;
10、

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。