Answers:
嵌入式代码验证非常棘手,尤其是在处理诸如PIC之类的资源有限的部件时。由于部件的内存限制以及在这类设备上进行的“实时”编程,您常常没有在测试用例中编写代码的奢侈方法。
这是我的一些准则:
如果没有规范,则写一个规范:如果您不按照规范进行编码,请记录您的代码应该是什么,有效输入是什么,预期输出是什么,每个例程应该花多长时间,可以和不能得到什么?崩溃等-操作理论,流程图,没有什么总比没有好。
注释您的代码:仅仅因为某些东西对您而言是显而易见的,并不意味着它对其他人而言是显而易见的(或正确的)。注释和代码的可维护性都必须使用纯语言注释。
防御性代码:不要只包含普通输入的代码。处理缺失的输入,超出范围的输入,数学上的溢出等-代码设计覆盖的角落越多,部署代码时的自由度就越小。
使用静态分析工具:可能会令人困惑,例如在代码中可以找到PC-lint之类的错误工具。将干净的静态分析运行作为认真测试的一个良好起点。
同行评审是必不可少的:您的代码应干净整洁并有充分的文档记录,以使独立的各方可以对其进行有效地审查。在门口检查自己的自我,认真考虑提出的任何批评或建议。
测试是必不可少的:您应该自己进行验证,并对代码进行独立验证。其他人可能以您无法想象的方式破坏您的代码。测试您可以想到的每个有效条件和每个无效条件。使用PRNG并输入垃圾数据。尽一切可能破坏事物,然后修复并重试。如果幸运的话,您将能够在调试模式下运行代码,并查看寄存器和变量-如果不行,则需要提高技巧并切换LED /数字信号以了解自己的状态设备。做任何必要的以获得您需要的反馈。
深入了解:不要害怕看C编译器生成的机器代码。您可能会(会吗?)找到漂亮的C代码爆炸成数十个(甚至不是数百个)操作的地方,应该安全的地方(因为它只有一行代码,对吗?)执行多个中断所需的时间很长。已解雇条件并使其无效。如果某些事情变得非常低效,请对其进行重构,然后重试。
用于在PC上创建可靠软件的大多数相同技术也适用于嵌入式开发。将您的算法与特定于硬件的代码分开,并使用单元测试,模拟,静态分析和诸如Valgrind之类的工具分别进行测试,这很有帮助。这样,只有经过硬件测试的代码要少得多。
我不会放弃C。虽然像Ada这样的语言可以提供一些小的保证,但很容易陷入陷阱,以为该语言的承诺要比实际的多。
MISRA-C对于提高通用代码质量并最大程度地减少错误确实非常有用。只要确保您已阅读并理解每条规则,它们中的大多数都是好方法,但是其中一些没有任何意义。
这里是警告。MISRA文档假定读者是具有C语言广泛知识的人。如果您的团队中没有这样的资深C专家,而是决定使用静态分析器,然后盲目地遵循每一个给出的警告,则很可能会导致代码质量降低,因为这可能会降低可读性并偶然引入错误。我已经看到这种情况发生了很多次,将代码转换为MISRA合规性并不是一件容易的事。
可能有两种版本的MISRA-C文档。MISRA-C:2004仍然是当前的嵌入式行业实际标准。或支持C99标准的新MISRA-C:2012。如果您以前从未使用过MISRA-C,我建议您实施后者。
但是请注意,工具供应商通常会在说自己进行MISRA检查时引用MISRA-C:2004(有时甚至会参考过时的MISRA-C:1998版本)。据我所知,MISRA-C:2012的工具支持仍然有限。我认为到目前为止,只有一些静态分析器实现了它:Klocwork,LDRA,PRQA和Polyspace。可能更多,但您肯定需要检查其支持的MISRA版本。
在做出决定之前,您当然可以先阅读MISRA文件并查看其中的内容。可以从misra.org上以10英镑的价格购买它,与ISO标准的价格相比,这是相当实惠的。
对于此问题的完整答案,我不考虑“代码可靠性”的思想,而是考虑“设计可靠性”,因为代码只是设计的最终表达。
因此,从需求开始,编写并检查这些需求。如果您没有需求文档,请指向随机的代码行,然后问自己“为什么需要该行?” 最终,对任何一行代码的需求都应该可以追溯到需求,即使它很简单/显而易见,例如“如果输入介于12-36VDC之间,则电源将输出5VDC。” 考虑这一点的一种方法是,如果该行代码无法追溯到需求,那么您怎么知道它是正确的代码,或者根本不需要它?
接下来,验证您的设计。如果它完全在代码中(例如,在注释中)也可以,但是这使得很难知道代码是否在执行真正的意思。例如,代码中的一行可能显示output = 3 * setpoint / (4 - (current * 5));
为current == 4/5
:是否输入有效的输入,可能会导致崩溃?在这种情况下应采取什么措施防止被零除?您是完全避免该操作还是降低输出?在设计文档中有关于如何处理此类极端情况的一般注释,可以更轻松地在更高级别上验证设计。因此,现在代码检查变得更加容易,因为这是检查代码是否正确实现了该设计的问题。
与此同时,代码检查还应检查IDE不能捕获的常见错误(您正在使用IDE,对吗?),例如,当您表示'=='时,例如'=',缺少会改变'if'含义的花括号。 '语句,不应在的分号等。
在撰写本文时,我很难在一个帖子中总结多年的软件质量培训/经验。我为医疗设备编写了代码,以上内容是我们处理该方法的极为简化的摘要。