版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2009-10-27 嵌入式在线 收藏 | 打印 在嵌入式系统的软件设计中,“汇编语言+C语言”早已成为理所当然的经典组合。的确,对于硬件配置来说,汇编语言清晰明了;对于上层设计来说,C语言紧凑高效。这样的搭配能够满足大多数传统嵌入式系统应用的需要。随着技术水平的提高,今天的嵌入式系统也比过去更加深入到人们的日常生活中,大到汽车、飞机、火箭,小到手机、打印机、闹钟、手表,都可以找到嵌入式系统的踪影。然而,这看似一成不变的情况,也在悄然转变。随着网络、多媒体等技术的出现、发展与普及,对嵌入式系统应用有了新的要求,也给了其他高级语言,特别是C+语言以机会。 由此带来的在语言使用中的安全问题,目前虽
2、然还未凸显,但根据以往的经验来看,终将成为限制行业发展的新瓶颈。已有的C+语言国际标准虽然庞大细致,但作为一个“语言标准”,只能是尽力做得面面俱到,其目标在于构造一个语句合法性的权威依据,以约束人们对于C+的使用。但它并不是针对应用而写的规范,对于可能遇到的安全性问题也无法进行特别深入的探讨,更加没有安全方面的实践经验支撑。一个针对安全方面的、被国际所认可的使用规范,无疑是C+语言在嵌入式系统中得到广泛应用的坚实基础与助推剂。1 C+在嵌入式应用中的机遇与挑战C+作为一门高级语言,人们在提及它时,总难免会谈到C语言。直至今天,很多人对于C+语言的认识依然是“C语言的超集”。这是因为C+的起源与
3、C语言有着千丝万缕的联系。1978年,美国贝尔实验室的Dennis Ritchie和BrianKernighan在BCPL以及其简化版本B语言的基础之上开发了C语言,并合作出版了The C Programming Lan-guage。C语言迅速得到了大家的认可,并广为流传。1989年,ANSI推出了第一个C语言的标准X3159-1989,并被ISO采纳,随之发布。ISOIEC 9899-1990。早在C语言标准发布之前,贝尔实验室的Bjarne Stroustrup就致力于在C语言里增加类、函数类型检查以及其他的一些优秀特征,于1980年发布“C with Classes”。经过持续的努力,他
4、最终完成了对C语言的改造,由此创生出一门新语言C+,并出版了The C+ ProgrammingLanguage一书。由于它带来了持续的影响,ISO于1998年发布ISOIEC 14882:1998;几乎同一时间,ANSI也发布了类似标准,这标志着C+作为一门独立语言的标准化得到了官方的认可。统计数据表明,日常生活中一个美国人平均占用8个微控制器,这些都离不开嵌入式系统的应用。然而嵌入式系统软件技术似乎落后于当前的软件发展形势,近年来才逐渐由汇编语言过渡到面向过程的C语言。但对于面向对象语言的应用还很有限。这一方面是由于嵌入式开发人员多年来应付有限资源的经验而养成的保守态度,另一方面也是由于长
5、久以来,嵌入式系统应用设计中,人们要花费许多精力在底层硬件的驱动上,功能实现也主要局限在实时操作系统和相关支撑软件的层次,并不涉及过多的应用软件开发。这种在严苛条件下追求效率与实时性的任务,其他的高级语言并没有特别的优势。最近几年,嵌入式系统领域又有了新的发展。首先,随着手机、PDA等消费性电子产品的飞速增长,嵌入式系统的市场规模在迅速扩大,同时越来越多的智能嵌入式应用场合需要互联网的支持,这要求嵌入式系统的软件具有更好的应用性和更高的复杂性;其次,随着芯片等相关领域的技术进步,嵌入式系统工程师们不再需要时时刻刻去考虑资源是否够用了。当面向对象的高级语言参与到嵌入式系统设计中去不再遥不可及时,
6、语言的效率则成为突出的问题。根据Thinking in C+一书的总结,C+与C的效率差别往往在5,这使得C+在新一轮的嵌入式应用发展浪潮中占得先机。值得注意的是,尽管自1998年发布最初的C+标准ISOIEC 14882:1998以来,每5年都会对此标准进行一次更新,但是由于C+语言过于复杂,以及它经历了长年的演变,直到2004年,没有任何一款编译器完全支持ISO C+。这对于时常要面对各种严苛条件的嵌入式系统应用工程师们来说,是难以忍受的。同时,即使是符合ISO C+标准的语句或者格式,对于实际的应用场合来说,也存在着重大隐患,而不应当被直接采用。因此,人们迫切需要一个正式的基于安全角度考
7、虑的C+语言使用规范。2 关于MISRAMISRA(the Motor Industry Software Reliability As-sociation),即汽车工业软件可靠性协会,于1994年在英国成立,以“协助汽车工业提供安全、可靠的软件”为使命,期望通过“规范指南”的形式来约束人们在汽车电子以及其他嵌入式系统开发领域或涉及安全与可靠性的领域中对于程序语言的使用。由于这些“规范指南”都是从大量工程实践中总结的第一手经验,因而具有极高的指导意义。 经过4年准备,它在1998年发布了一个针对汽车工业的Guidelines for the Use of the C Langtlage in
8、VehicleBased Software,简称“MISRA C:1998,针对那些满足C语言标准,却存在安全隐患的语言使用习惯,提出了127条规则。由于它很好地解决了C语言国际标准的冗繁性,以及其中对于安全性考虑的不足性,从而得到了广泛的好评。MISRA-C不仅成为众多汽车厂商推崇的行业标准,其影响力更是远远超出了汽车工业,得到铁路、航空航天、国防、医疗等众多领域的认可,成为“最佳实践”解决方案。2004年,MISRA对于已有的规则进行改编与扩充,推出了“MISRA C 2004”,首次将该规范指南的对象从汽车工业推广到所有具有安全性要求的系统应用中去,包含了强制规则121条,推荐规则20条
9、,并删除了15条旧规则,共计含有141条规则。时至今日,MISRA组织不仅是汽车工业软件规范的权威,其制定的规范指南更得到了嵌入式系统应用领域的广泛认可。考虑到近年来,C+语言在嵌入式系统中的应用越来越多,2005年MISRA C+委员会成立,并于2008年推出针对C+语言的MISRA C+:2008Guidelines for the USe of the C+ language in critical sys-tems,以下简称“MISRA C+:2008”。有兴趣的读者可以联系相关网站:http:wwwmisra-cppcom,购买详细的文档。MISRA C+:2008同样从推出之日起,
10、就得到了业内外广泛关注。例如:LDRA软件公司一直跟踪着MIS-RA C+:2008的制定进展,在MISRA C+:2008发布时同步宣称已经完成了对工具套件产品的相应改进,使其符合MISRA C+:2008标准。(LDRA的Testbed产品曾成功用于“神舟”飞船项目的软件测试)3 MISRA C+概述作为规范指南,MISRA C+:2008基于ISOIEC 14882:2003的C+语言国际标准,以规则(rule)的形式,给出了相关的建议。它的规则又细分为以下3种类型:强制型(required),必须符合、允许例外;推荐型(advisory),推荐符合;不容讨论型(document),必须
11、符合、不许例外。MISRA C+:2008中共给出了20个大类的规则(编号并不连续),细分为228条。详细情况如表1所列。文档中所有规则的书写格式如下:每条规则之后都有详细的解释,并给出了一些具体的程序语句作为例子。下面分别针对上述3种规则类别,进行举例说明。规则0-1-1(强制)工程中不允许包含无法触及的代码上述例子里,条件判断中的赋值语句和return语句之后的自增语句都是在任何条件下都无法触及的死代码,不允许这样使用。 规则0-1-2 (强制) 工程中不允许含有永远不会被执行的路径enum ecRED,BLUE,GREEN)col;if(col=GREEN) 不符合规则,条件永远为真Wi
12、ll always get,hereelse代码永远不会到达这里由于枚举类型有默认的初始赋值0,1,2,故col永远GREEN。上述例子中,含有任何条件下都不会被执行的路径,不允许这样使用。规则5-2-10(推荐) 自增(+)自减(-)运算符不应与表达式中其他运算符混合使用诸如下面的例程将导致理解上的混淆以及结果的不确定,在程序设计时应尽可能避免。u8a=+u8b+u8c-; 不符合规则规则0-4-2 (不容讨论) 对于浮点运算(floating-point)算法的使用,必须给出记录安全的使用浮点算法需要具有较高的数字分析技能和对编译器及硬件对象的深入了解。因此在使用浮点算法时,必须先进行分析
13、:是否必须使用它、采取的方法是否可行、过程是否得到了正确的执行,并将上述结果做出记录。规则16-6-1 (不容讨论) 所有的库函数代码必须符合MISRA C+上述这些例子只是为了让大家对MISRA C+:2008的3种规则有一定的认识,我们会结合相关内容,在接下来的几篇文章中进一步讨论学习。不难发现,许多违反了MISRA C+:2008中规则的例程都是符合C+语言标准的,但出于安全性考虑,应当被禁止或者谨慎使用。通览之后,往往会发现自己平时从未注意的一些编程习惯,都已经被严令禁止。它们有些是明显有碍安全性的,有些则相对隐蔽。 然而MISRA的号召力是不容小觑的。以嵌入式实时操作系统COS-II
14、为例,其252版本虽然已经于2000年通过了美国航空管理局(FAA)的安全认证,但2003年COS-II的作者就根据MISRA C:1998规范又对源码作了相应的修改,并发布了262的新版本,宣称其源代码99符合MISRA C:1998的要求。4 安全性问题对于安全性,MISRA给出以下5种可能的安全问题来源:开发人员的错误、开发人员对于语言的误解、编译器没有按照开发人员的预期工作、编译器本身含有错误、运行错误。这些错误的来源与实际使用的是何种计算机语言没有关系,可以说比较全面地包含了嵌入式系统开发以及其他相关的软件设计中可能导致安全问题的所有渠道。作为C+这样一门面向对象的高级语言(由于其与
15、C的渊源,严格地说,C+是具有某些面向对象特征的过程语言),通过类、函数参数类型检查、模版、异常处理以及派生、继承、多态等手段,使得其在保有高效率的同时,实现了强大的功能,并带来了自顶向下的模块化程序设计理念。但编程灵活度的提高,也令其代码复杂而易错。与C语言相比,它所面对的安全问题将更为隐蔽,更加难以发现。但就对数据的封装而言,C+远远优于C,只要参照合理的规范指南,进行项目的开发,就可以通过充分发挥C+灵活的特点,应用到更多更广的工程领域。5 行业展望标准与规范从来没有如眼下这般备受重视过。一个权威的标准或规范,不仅将成为相关领域的“金科玉律”,更是行业动向的风向标。可以说正是由于MISR
16、A-C的存在,使得在高级语言种类繁多的今天,C语言的地位依然无可替代。此次MISRA携着在C语言上的巨大成功,选择了C+语言进行新的规范化尝试,不仅因为C+语言的群众基础深厚,更是表明了嵌入式系统领域内大多数专家的观点:如果说未来能有一门语言取代目前C语言在嵌入式系统应用中的地位的话,也只能是C+语言。一名成功的嵌入式系统工程师,必须是对行业动向极为敏感的,也只有这样,才能在知识爆炸的今天紧跟时代潮流。从使用C语言到使用C+语言是一个巨大的跨越,决不仅仅像使用“增强的C”那么简单,需要从现在就开始学习。而从学习之初就养成的良好的语言使用习惯,将决定将来进阶的速度与可能性。MISRA C+:20
17、08无疑是培养这样良好习惯的最佳手册MISRA-C:2004静态分析 2008-02-20 13:57 阅读78评论0 字号: 大大 中中 小小 MISRA(The Motor Industry Software Reliability Association 汽车工业软件可靠性协会)MISRA是汽车工业C语言编程指导,是目前公认的最优秀的嵌入式C语言的编码规范,在航空/航天、汽车、医疗、船舶、电信等对软件安全性要求比较高的行业得到了广泛的应用。在1998年版的基础上,MISRA组织最新发布了MISRA-C:2004MISRA-C:2004包括141条规则,其中121条是强制(Required
18、)遵守的,20条是建议(Advisory)遵守的。MISRA官方网站:.ukMISRA规则的详细内容需要购买,印刷版本价格$76,电子版本(PDF)价格10.全部141条规则的中英文对照如下,请参考。在以后的日子里,我还会陆续写一些文章,来介绍某些规则的必要性。1 1.1 所有代码必须符合ISO 9899:1990标准(C 编程语言标准)。All code shall conform to ISO 9899:1990 Programming languages - C;1.2 软件不可依靠未定义或未指明的行为。(未指明的行为会产生不可靠性)No reliance sh
19、all be placed on undefined or unspecified behaviour; 1.3 只有当目标代码的一般定义界面标准和语言/编译器/汇编器相一致的时候才能使用多种编译器和/或多种语言。Multiple compilers and/or languages shall only be used if there is a common defined interface standard for object code to which the language/compilers/assemblers conform; 1.4 编译器、连接器和标识符不能支持超过3
20、1个字符的有效性。The compiler/linker/Identifiers (internal and external) shall not rely on significance of more than 31 characters.; 1.5 浮点执行应该符合明确的浮点标准。Floating point implementations should comply with a defined floating point standard;2 2.1 应该封装并隔离汇编语言。Assembly language shall be encapsulated and isolated;
21、2.2 在源代码中应该只使用/* . */的注释风格。Source code shall only use /* . */ style comments;2.3 在注释中不可以使用/*。The character sequence /* shall not be used within a comment;2.4 不可以注释掉部分代码。Sections of code should not be commented out;32.1 必须记录所有与使用执行定义程序有关的行为。All usage of implementation-defined behaviour shall be docum
22、ented;2.2 必须记录字符集与其编码。The character set and the corresponding encoding shall be documented;2.3 应该确定、记录并考虑选定编译器中的整数除法。The implementation of integer division in the chosen compiler should be determined, documented and taken into account.;2.4 必须记录并解译所有#pragma指示的使用。All uses of the #pragma directive shal
23、l be documented and explained.;2.5 如果代码使用位域,则必须纪录位段的执行定义行为与位段的组装。The implementation-defined behaviour and packing of bitfields shall be documented if being relied upon;2.6 所有执行代码使用的程序库必须符合本文件的规定,并必须经过适当的确认。All libraries used in production code shall be written to comply with the provisions of this d
24、ocument, and shall have been subject to appropriate validation.;4 4.1 只可使用国际标准化组织(ISO) C语言标准定义的转义-序列。Only those escape sequences which are defined in the ISO C standard shall be used.;3.2 不可使用三符组(?x)。Trigraphs shall not be used.; 5 5.1 内外标识符不能支持超过31个字符的有效性。Identifiers (internal and external) shall n
25、ot rely on the significance of more than 31 characters; 5.2 内层范围标识符不可与外层范围标识符同名,否则会屏蔽那个标识符。Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier.;5.3 Typedef的名字必须使用唯一的标识符。A typedef name shall be a unique identifier.;5.4一个标记符只
26、能用于唯一的标识符。A tag name shall be a unique identifier;5.5 不应该重用带有静态存储的对象或函数标识符。No object or function identifier with static storage duration should be reused;5.6 一个名字空间的标识符不可以与别的名字空间的标识符同名,结构体和联合体的成员名除外。No identifier in one name space should have the same spelling as an identifier in another name space,
27、 with the exception of structure and union member names;5.7 标识符名字不可以重用。No identifier name should be reused;66.1 “char”型的变量只能用于字符值的存储和使用。The type char shall be used only for storage and use of character values;6.2 有符号和无符号的“char”型变量只能用于数值的存储和使用。Signed and unsigned char type shall be used only for the
28、storage and use of numeric values;6.3 基本类型应该用指示大小和有无符号的typedef来代替。Typedefs that indicate size and signedness should be used in place of the basic types;6.4 位域只能被定义为无符号整型或有符号整型。Bit fields shall only be defined to be of type unsigned int or signed int.;6.5 使用有符号整型的位域的大小必须至少是2位。Bit fields of type signe
29、d int shall be at least 2 bits long.;7 7.1 不要使用“零”以外的八进制常量与八进制的转义序列(octal escape sequence)。Octal constants (other than zero) and octal escape sequences shall not be used.;8 8.1 函数必须有原型声明,原型对于函数的定义和调用必须是可见的。Functions shall have prototype declarations and the prototype shall be visible at both the fun
30、ction definition and call.;8.2 当声明或定义对象或函数的时候,必须明确规定它的类型。Whenever an object or function is declared or defined, its type shall be explicitly stated;8.3 对于每个函数的参数来说,声明和定义中给出的类型必须一致,返回类型也必须一致。For each function parameter the type given in the declaration and definition shall be identical, and the retur
31、n types shall also be identical.; 8.4 如果对象或函数被生命多次,类型必须是兼容的。If objects or functions are declared more than once their types shall be compatible.;8.5 在头文件中不能有对象或函数的声明。There shall be no definitions of objects or functions in a header file;8.6 函数必须在文件范围内声明。Functions shall always be declared at file sco
32、pe.;8.7 如果对象只在单个函数中被访问,那么它们必须在程序块中定义。Objects shall be defined at block scope if they are only accessed from within a single function;8.8 外部对象或外部函数只可以在一个文件中定义, 并且只能在一个文件中定义。An external object or function shall be declared in one file and only one file;8.9 有外部链接的标识符必须只有一个外部定义。An identifier with extern
33、al linkage shall have exactly one external definition.;8.10 所有文件范围的对象或函数声明都必须有内部链接,除非必需外部链接。All declarations and definitions of objects or functions at file scope shall have internal linkage unless external linkage is required;8.11 在有内部链接的对象和函数的定义和声明中必须使用静态存储类说明符。The static storage class specifier s
34、hall be used in definitions and declarations of objects and functions that have internal linkage;8.12 当声明一个有外部链接的数组时,必须通过初始化明确规定或隐式定义它的大小。When an array is declared with external linkage, its size shall be stated explicitly or defined implicitly by initialisation;99.1 所有自动变量在使用前必须配值。All automatic var
35、iables shall have been assigned a value before being used.;9.2 在结构体与数组非零的初始化中,必须使用花括号来指示和匹配结构。Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.;9.3 在枚举表中,不可以用=结构来明确初始化除第一个成员以外的其他成员,除非所有条目都被明确初始化。In an enumerator list, the = construct shall not be used to explicitly initialise members other than the first, unless all items are explicitly initialised.; 10 10.1 整数类型表达式的值不可以被隐式地转换为别的基本类型。The value of an expression of integer type shall not be implicitly converted to a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 交通安全行驶承诺函(8篇)
- 床上洗头护理的经济学分析
- 法制手抄报图片
- 护理不良事件的持续改进计划
- 春日里的趣事记叙文(12篇)
- 个人行为自律承诺责任书(4篇)
- 2024-2025学年度护士资格证考前冲刺练习(各地真题)附答案详解
- 2025 八年级地理下册南方地区山地生态系统的稳定性维持课件
- 业务合规运营诚信承诺书(5篇)
- 个人健身自律承诺书(5篇)
- GJB9001C-2017国军标标准培训讲义
- 人教版数学一年级下册第一单元《十几减9》真题同步测试3(含解析)
- 校园网网络工程分析需求报告
- 《杀死一只知更鸟》读书分享PPT
- 级自制书119本13黑今天穿什么
- Premiere 认证题库(整理版)
- 01厨房组织人员管理篇
- 考研考博-英语-华东理工大学考试押题卷含答案详解1
- 胆囊切除术 胆总管切开取石术
- 灭火器消防栓检查维护记录表
- 儿童炎症性肠病
评论
0/150
提交评论