Aks*_*l D 3 c embedded state-machine misra safety-critical
我已经实现了一个复杂的状态机,具有许多状态转换,用于安全SIL 4系统.这个实现的后骨是使用函数指针完成的.当一切顺利航行时,V&V反对在SIL 4系统中使用功能指针.参考 - 规则9 NASA .Misra C 2004然而并没有说不能使用函数指针.
有没有其他方法可以在没有任何函数指针的情况下实现复杂的状态机?
首先,NASA的文件不是正典.首先询问强制您遵守NASA文件的法律/指令/标准/要求/文件.如果它没有在任何地方执行(这似乎很可能,即使在NASA本身),你没有义务遵循它,你可以解雇整个事情.
没有把废话当作无稽之谈,你可以在用安全标准打墙时使用通常的程序:解决方案总是要详细记录所述规则没有意义,并用他们自己的方法打击他们的脸. .
因此,不要放弃函数指针,而是通过下面描述的方法确保以安全的方式使用它们.
由于所有与安全相关的设计都归结为风险评估,因此您始终可以:
错误 - >原因 - >危险 - >安全措施
根据美国宇航局文件中给出的(差)理由,你可以证明安全措施"避免使用函数指针",例如:
执行了错误的代码 - >损坏的函数指针 - >失控代码/非法操作代码
堆栈溢出 - >函数指针递归 - >内存损坏
困惑的程序员 - >函数指针语法 - >非预期的程序功能
这完全是模糊的,也是一个值得怀疑的风险评估,但这正是NASA文件归结为的结果.
对于上述3种列出的危险,我建议使用以下安全措施代替"避免功能指针":
- 防御性编程和断言.
- 防御性编程和断言.教育程序员.
- 使用typedef.教育程序员.
防御性编程和断言
STATES_N或某些此类)sizeof(func_pointer_array)/sizeof(*func_pointer_array).STATE_MACHINE[i]();在哪里STATE_MACHINE,然后只需添加运行时检查i以确保它始终有效.const尽可能使用指针(指针本身是只读的).如果需要在运行时重新分配它们,请确保它们在调用它们之前指向有效的函数.上述类型的状态机是惯用且极其安全的,可能比代码中其他地方的普通函数调用更安全.您当然必须确保以安全合理的方式完成状态转换,但这不是涉及函数指针的事情.
避免递归
这主要是关于教育程序员不要使用它,函数指针或没有函数指针(似乎这会阻止丰田的bug).
既不难发现也不避免递归,因此半正式的代码审查手续应该足以阻止它.无论安全关键系统经验如何,没有经验丰富的嵌入式系统程序员都会批准包含递归的代码.
您可以/应该设置一个内部设计规则,声明所有与安全相关的代码必须由具有n年安全关键程序设计经验的资深C程序员审查和批准.
此外,您还应该使用静态分析器工具检查递归(即使它们无法通过函数指针检测递归).如果您的静态分析仪符合任何版本的MISRA-C,则包括此内容.
关于非预期的递归,使用上述防御性编程方法可以避免这种情况.
Confusig函数指针语法
C语言中的函数指针语法无疑是非常令人困惑的,只需看一下即可
int (*(*func)[5])(void);
Run Code Online (Sandbox Code Playgroud)
或者其他一些荒谬的例子.它可以通过始终强制执行typedeffor函数指针类型来解决.
(参考:Les Hatton,Safer C,p184"从安全相关的角度来看,简单的答案是它们永远不应该被允许在typedef机制之外.")
你可以通过两种不同的方式来定义它们,我更喜欢这样:
typedef int func_t (void);
func_t* fptr;
Run Code Online (Sandbox Code Playgroud)
因为这不会隐藏typedef背后的指针,这通常是不好的做法.但如果你觉得替代方案更舒服
typedef int (*func_t) (void);
func_t fptr;
Run Code Online (Sandbox Code Playgroud)
那也没关系.