tag 标签: 可靠性设计规范

相关博文
  • 热度 16
    2011-11-16 15:45
    3804 次阅读|
    7 个评论
    声明如下: 1、最近频繁出差和几个项目的攻关,实在未能抽出时间写文章贡献,愧对大家,正努力改进中; 2、嵌入式软件可靠性之于系统的重要性,如女主人之于家庭的重要性,须谨慎对待之。若欲做好,可研究下军工嵌入式软件设计规范、汽车控制电子MISRA设计规范、医疗电子报警和可使用性设计规范、GJB5000军工软件能力成熟度模型四个方面的内容。如下文章是MISRA的原版翻译稿,先供参考。后续相关不少内容持续写作中...... 开发环境 规则 1.1 所有代码应该遵循ISO 9899:1990 C语言编程规范,该规范根据如下标准修订: ISO/IEC 9899/COR1:1995, ISO/IEC 9899/AMD1:1995, 和 ISO/IEC 9899/COR2: 1996 规则 1.2 不应该依赖于没有定义或不明确的行为. 规则 1.3只有当目标代码的语言/编译器/汇编器符合统一定义的接口标准的时候,才能使用多个编译器或多种语言。 规则 1.4应该检查编译器/链接器,确保外部标识符能够支持31个区分大小写有效字符。 规则 1.5浮点实现应该遵守定义的浮点标准 语言扩展 规则 2.1汇编语句应该被封装并且隔离。 规则 2.2源代码只能使用C风格的注释。 规则 2.3字符串 /* 不应该在注释中出现。 规则 2.4代码段不应该被注释掉。 文档化 规则 3.1所有使用已定义实现行为的地方都应该文档化。 规则 3.2所使用的字符集和相应的编码应该文档化。 规则 3.3在所选编译器中实现的整除运算,应该具有确定性,并记录下来予以考虑。 规则 3.4所有使用的 #pragma 命令都应该文档化并做出解释。 规则 3.5如果被依赖,应该对已定义实现的行为和位域封装在文档中进行记录。 规则 3.6所有产品代码中使用的库都应该与遵守本文的规定,并经过适当的验证。 字符集 规则 4.1只能够使用在ISO C标准中定义的换码符。 规则 4.2不允许使用三元符。 标识符 规则 5.1标识符(内部或外部)不应该依赖于超过31个字符表示的意义 规则 5.2内部标识符不应该与外部标示符重名,否则应隐藏该标识符。 规则 5.3 一个typedef的名称应该具有唯一的标识符。 规则 5.4标签名应该具有唯一的标识符。 规则 5.5静态存储的对象或函数的标识符不应该被重用。 规则 5.6一个命名空间中的标识符不能与其它命名空间中的标识符重名,结构和联合体成员的名称除外。 规则 5.7不应该重用标识符名称。 数据类型 规则 6.1 (普通)Char类型只能用来存储使用字符 规则 6.2 Signed和unsigned char只能用于存储和使用数值。 规则 6.3 应使用显示大小和符号的typedef来代替基本数据类型。 规则 6.4 位域只能用于所定义的 unsigned int 或 signed int 类型。 规则 6.5 signed int的位域至少为2个位长度 常量 规则 7.1 不应使用八进制常数(0除外)或八进制转义字符。 声明和定义 规则 8.1 函数应有原型声明,且该原型应在函数定义和调用处出现。 规则 8.2任何时候定义或声明的对象或函数应显示说明其类型。 规则 8.3每个函数中输入和返回参数的定义和声明的类型应该一致。 规则 8.4多次声明的对象或函数,其类型应相互兼容。 规则 8.5头文件中不应出现对象或函数的定义。 规则 8.6函数应定义在文件范围内。 规则 8.7仅在单个函数内访问的对象应定义在块范围内。 规则 8.8一个外部对象或函数应该在一个并且只有一个文件中声明。 规则 8.9具有外部链接的标识符应有唯一的外部定义。 规则 8.10文件范围内函数或对象的所有声明和定义应该具有内部链接,否则应具有外部链接。 规则 8.11静态存储类关键字应在有内部链接的对象和函数的定义和声明中使用。 规则 8.12声明为外部链接的数组,应显示说明其大小或在初始化时清楚的定义. 初始化 规则 9.1 所有自动变量应该使用前应该赋值。 规则 9.2括号应该用于指示和匹配非零初始化的数组和结构体的结构。 规则 9.3在枚举列表中,除非同时显式初始化所有成员,不应使用'='构造单独对第一个之外的个别成员显式初始化。 算术类型转换 规则 10.1 以下情况下,整型表达式中不允许出现隐式数据类型转换: a)整型操作数不是被扩充为更多位数的同符号整数; b)表达式是复杂表达式; c)表达式不是常数表达式,且是函数的参数; d)表达式不是常数表达式,且是函数的返回表达式。 规则 10.2以下情况下,浮点数表达式中不允许出现隐式数据类型转换: a)浮点型操作数不是被扩充为更多位数的同符号浮点数; b)表达式是复杂表达式; c)表达式是函数的参数; d)表达式是函数的返回表达式。 规则 10.3复杂的整型变量转化为窄整型变量时必须按照如下的方式使用强制转换。 规则 10.4复杂浮点类型的变量可以转换成窄浮点类型变量。 规则 10.5当位操作符~和移位操作符(或)的操作对象为unsigned char或者unsigned short类型时,其运算结果必须先显式转换为对应的数据类型。 规则 10.6所有无符号常数应加 “U”后缀。 指针类型转换 规则 11.1 指向函数的指针不能转化为除整型以外的其它任何类型。 规则 11.2指向对象的指针只能转换为整型,或者指向同类型对象的其他指针,或者是void类型。 规则 11.3指针和整型类型之间不应该做类型转换. 规则 11.4不同数据类型指针之间不应该做类型转换. 规则 11.5对指针进行类型转换时不允许将限定词const和volatile删除。 表达式 规则 12.1表达式中有限制的依赖应建立在C语言的优先级规则之上。 规则 12.2表达式的结果在标准允许的任何顺序的计算情况下都应该是一样的。 规则 12.3 sizeof操作符不能用在包含副作用的表达式上。 规则 12.4逻辑操作符 或 || 的右侧操作数不应带有副作用。 规则 12.5逻辑操作符 或 || 的操作数应作为主要表达式。 规则 12.6逻辑操作符(, || , !) 的操作对数应该是有效布尔型。有效布尔型表达式不应该与除逻辑操作符(, || ,!)之外的其他的操作符一起运算。 规则 12.7位操作符的操作数的潜在数据类型不应为有符号数。 规则 12.8移位操作时,操作符右侧的操作数的数值应大于于0,且小于左侧操作潜在数据类型的位长度。 规则 12.9一元负号操作符不应在潜在无符号数据类型的表达式中出现。 规则 12.10不应使用逗号操作符。 规则 12.11赋值表达式中使用无符号整形操作数时不应导致循环溢出。 规则 12.12不得使用任何形式的潜在位来表示浮点。 规则 12.13位操作符的操作数的潜在数据类型不应为有符号数。 控制语句表达式 规则 13.1在返回布尔值的表达式中不应使用赋值操作符。 规则 13.2判断一个值是否为0 应该是显式的,除非该操作数是一个布尔值。 规则 13.3不允许对浮点数进行相等或者不相等的比较,即使是非直接的比较也是不允许的。 规则 13.4浮点变量不应作为循环计数器使用。 规则 13.5只有与循环控制相关的表达式才会出现在for语句中。 规则 13.6在一个循环中用于迭代计算的数字变量不得在循环体内修改变量值。 规则 13.7布尔表达式的值必须是可以改变的。 控制流 规则 14.1不应有不可达代码。 规则 14.2非空语句应产生副作用,或者使控制流改变。 规则 14.3一行中如果有空语句,那么该行只能有这条空语句,不能有别的语句,并且在这条空语句前不能有注释,注释必须在其后,用空格隔开。 规则 14.4不应使用goto语句。 规则 14.5不应使用continue 语句。 规则 14.6循环体中最多只能出现一个break 语句用于结束循环。 规则 14.7函数只应有一个出口,这个出口必须在函数末尾。 规则 14.8 switch , while, do… while 和for 语句的主体应是复合语句,即使该主体只包含一条语句。 规则 14.9 if 结构后面应是一个复合语句(即用大括号包含) ,else 后面必须是一个复合语句(即用大括号包含) 或者另一个if 语句。 规则 14.10 if …else if 结构应由一个else子句结束。(未完待续) MISRA:2004 嵌入式软件可靠性设计规范(2)
  • 热度 15
    2011-11-16 15:45
    2692 次阅读|
    5 个评论
    (续前节) MISRA:2004 嵌入式软件可靠性设计规范(1) Switch 语句 规则 15.0 Switch表达式中的case和default的语句必须在声明或者定义之后。 规则 15.1 witch 语句的主体必须是复合语句(即用大括号包含)。 规则 15.2 何一个非空的case语句或者default语句最后必须有break。 规则 15.3 switch表达式中的最后一个语句必须为default。 规则 15.4一个switch 表达式的取值不能为一个布尔值。 规则 15.5 每一个switch表达式至少应该有一个case。 函数 规则 16.1 不要使用参量数目是变化的函数。 规则 16.2函数不能进行直接或间接的递归调用。 规则 16.3在函数原型声明时全部给出所有参数的标识符。 规则 16.4一个函数声明和定义中使用的标识符应该完全一致。 规则 16.5无参函数声明时必须使用void类型。 规则 16.6传递给一个函数的参数个数应当同函数原型相匹配。 规则 16.7函数原型中的指针参数若不允许修改其指向的目标则必须声明为const指针。 规则 16.8non-void类型函数的所有出口路径都应该有显性的return语句表达式。 规则 16.9函数标识的使用必须采用前面带或者是带参数列表(可能为空)的方式。 规则 16.10函数返回的错误信息必须经过验证。 指针和数组 规则 17.1 只有指向数组的指针才允许进行算术运算。 规则 17.2只有指向同一个数组的两个指针才允许相减。 规则 17.3只有指向同一个数组的两个指针才允许用, =, , =等关系运算符进行比较。 规则 17.4只允许用数组索引做指针运算。 规则 17.5不要用2级以上指针。 规则 17.6动态分配对象的地址不允许在本对象消亡后传给另外一个对象。 结构和联合体 规则 18.1所有结构体和联合体的定义必须保证完整性。 规则 18.2结构体和联合体的定义不能嵌套。 规则 18.3存储过某种数据类型之后的内存区不要再做它用。 规则 18.4不允许使用联合体。 预处理指令 规则 19.1一个文件中的#include语句应该在其他预处理器指令或注释之前。 规则 19.2 #include指令中的头文件名称不能包含非标准的字符。 规则 19.3 #include指令后必须跟着一个文件名或者“文件名” 。 规则 19.4 宏只能应用在如下场合:大括号括起来的初始化语句,常量,小括号括起来的表达式,类型限定关键词,存储类型限定词,或者一个do-while-zero的结构语句。 规则 19.5不能在语句块里定义宏。 规则 19.6禁止使用#undef。 规则 19.7应优先考虑使用函数而非宏函数。 规则 19.8宏函数在没有参数的情况下不得被调用。 规则 19.9预处理指令不得作为宏函数参数。 规则 19.10在宏函数定义中,每一个参数及整体都应该加上小括号,除非是在#或##运算符中。 规则 19.11在预处理指令中,所有的宏定义名称在使用前必须先定义,除非是在#ifde  #ifndef预处理指令和defined()运算符中。 规则 19.12在单一的宏定义中,最多只能出现一次#和##预处理操作符。 规则 19.13 #和##预处理操作不可以使用。 规则 19.14两种标准方式定义的预处理操作符只可以使用其中的一种方式。 规则 19.15应该避免头文件的内容被包含两次。 规则 19.16每一条预处理指令在语法上都必须是有意义的,即使这条预处理指令可能不会执行。 规则 19.17所有的#else, #elif 和 #endif预处理指令应该包含在与之相对的#if 或 #ifdef预处理指令相关的相同文件中。 标准库 规则 20.1标准库中的保留标识符,宏和函数不能定义,重定义,和取消定义。 规则 20.2不应重用标准库中宏、对象和函数的名字。 规则 20.3必须检查传递给库函数的数值的有效性。 规则 20.4动态堆内存分配不能使用,不能使用:malloc、calloc、free、realloc。 规则 20.5不得使用错误指示符errno。 规则 20.6不得使用库函数 stddef . h 中的宏offsetof。 规则 20.7不应使用setjmp宏以及longjmp函数。 规则 20.8不得使用信号处理函数。 规则 20.9在产品代码中不应使用输入/输出库。 规则 20.10不得使用标准库中的库函数atof 、atoi 和atol 。 规则 20.11不得使用标准库中的库函数abort 、exit、getenv和system。 规则 20.12不得使用标准库中的时间处理函数。 运行时失效 规则 21.1 通过使用以下手段确保把运行时故障最小化: a) 静态分析工具/技术; b) 动态分析工具/技术; c) 编写明确的代码避免运行时错误;