7年经验总结,C语言嵌入式系统_编程规范_编程思想
- 格式:docx
- 大小:25.39 KB
- 文档页数:7
嵌入式系统编程规范李红志程序的可读性、可扩展性、可复用性、易维护性、语法是代码的入门,算法是代码的灵魂。
第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"}; return 0; }以上这种方式是非常危险的,原因在于你对结构的内存布局作了假设。
如果这个结构是第三方提供的,他很可能调整结构中成员的相对位置。
而这样的调整往往不会在文档中说明,你自然很少去关注。
如果调整的两个成员具有相同数据类型,编译时不会有任何警告,而程序的逻辑可能相距十万八千里了。
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、【2011-7-4】代码变成各种意义明确的节的优点:1、高可靠性:每段很小,就更容易做到确认代码不会出问题,更能确认该段指令是千锤百炼的,绝对可靠的;2、可维护性强:由于每段很小,很容易看懂,调试及修改都更方便;3、可扩展性强:如果某一种计算有问题了,只用替换或修改某一小段,而不用到处找需要改哪些地方;4、可复用性强:对某些小段,可能多个地方都可以用到,不用在不同的地方写很多次;5、结构清晰:每一小段意义明确,程序结构、层次、调用关系、数据流等都更清晰;6、可读性强:由于结构清晰,增加了可读性,另外结构清晰了,就容易写清楚注释,也增加了可读性;7、函数无条件执行的优点:1、结构更清晰:不用考虑是否执行了;2、数据流更清晰:一个新的计算量由哪些变量得到,传递关系更清晰;3、函数的模块化更好:能让函数无条件执行,表示该函数具有更高的独立性,也就是模块更完整,与其他代码的耦合程度更低,迁移更方便;4、程序清晰之后,程序结构简单,从而增加可靠性;5、集中处理的优点:(集中处理是只,如果一个变量的计算,在不同条件下,算法不同,那么把条件汇总到一起,在一段代码处处理这个变量)1、结构清晰:一个变量的计算只出现在一个位置;2、分散处理会造成同一个值在一次运算周期重复计算,后面的计算结果覆盖前面的计算结果,从而难以控制数据流;3、【2011-7-5】1、ESP方式的减压和泄压:开关控制方式下,两者没什么区别;2、ABS方式的减压:减压速率和ESP减压方式差别很大;远小于ESP泄压速率,近似1/2关系;3、Bosch 8.1的HCU,保压时有个大约90Hz的噪声,和王伟玮讨论了一下,基本上可以理解为那就是当时电机转动频率;【2011-7-6】1、在举升机上,两前轮确实会有转速差,并且转速差可能越来越大;2、阀的端口,烧程序时的状态确认;没有高电平的;3、粗略来讲,泄压速率正比于轮缸压力?4、轮缸制动液净进入量和轮缸压力什么关系?在常用的范围内,大概是正比关系;5、制动轮缸制动液液量增大了,谁变形了?制动盘、摩擦块、制动钳,还有谁?那个变形大?是不是制动钳>摩擦块>制动盘(最大也就0.1mm),6、主动增压时,进油速率基本恒定。
HCU中的柱塞泵效率大概50%,好点儿能到60%;轮缸压力大,效率可能稍微高一点儿;轮缸压力大,电机转速稍微低一点儿。
7、【2011-7-8】1、大型的复杂的程序,用面向对象编程效率要高得多;单就变量的private和public设定而言,就会减少很多变量赋值的误操作,相当于自动添加了一种自检验机制;其他还有很多优点。
2、应该把每个函数都做一个更新记录。
这种更新记录怎么能做到比较容易看到上次的状态呢?难道只能把不同状态都记录下来看的时候再对比?3、【2011-7-9】1、轴距和FMVSS126的A值之间的关系,基本上只轴距减小10%,A值减小3%(尊驰在CarSim中的仿真结果)。