嵌入式开发人员可用的最强大的错误压缩工具之一是断言宏。尽管断言很强大,但却很少看到它被实现,并且在使用它的情况下,实现要么有缺陷,要么不正确。以下七个技巧不仅有助于阐明何时何地使用断言,而且还有助于阐明如何开始正确使用它。
技巧1 – 记住断言的定义
断言对于许多开发人员来说是一个令人困惑的话题,因为他们很容易以一种并非设计用于的方式使用断言。 关于断言的最清晰定义是:“断言是程序中特定点的布尔表达式,除非程序中存在错误,否则它将为真。”
检查上述断言定义的开发人员应注意三个关键点:
断言将表达式评估为真或假
断言是对代码中特定点的系统状态的假设
断言正在验证系统假设,如果不正确,则表明代码中存在错误
技巧2 – 使assert来验证函数的前置条件
断言在按合同设计的环境中工作得很好,其中嵌入式开发人员已经明确定义了函数的先决条件。 断言可用于检查函数的输入是否满足前提条件。以下代码片段为例:

函数的状态输入应属于定义的系统状态。如果 State 在有效状态之外,那不是错误而是bug!断言可用于验证状态有效的假设,如下图所示:

如果状态不小于最大值,则断言表达式将被评估为假,然后程序执行将停止。 停止程序执行使开发人员可以很容易地立即看到代码出错的地方,而不是等很久以后。
技巧3 – 使用断言来验证函数的后置条件
断言还可用于验证有关按合同设计环境中函数输出的假设。例如,如果先前定义的System_StateSet 函数返回 SystemState 变量,开发人员会期望它也在预期范围内。可以使用断言来监视错误,如下图所示:

检查上面的代码,嵌入式开发人员可能会觉得这些检查毫无价值。刚刚设置的 SystemState怎么会大于 SYSTEM_STATE_MAX?答案是它不应该是这样,这就是为什么如果它确实发生了变化,可能是通过中断或并行线程,断言将立即标记错误。
技巧4 – 不要使用断言进行错误处理
在记住断言的定义后,开发人员应该牢记断言是用于检测错误而不是用于错误处理。错误处理是旨在响应不正确的用户输入和意外事件序列的软件。错误预计会在系统中发生,但仅仅因为输入无效并不意味着代码中存在错误。错误处理应与错误搜寻分开。不正确使用断言的一个典型例子是在尝试打开文件进行读取时检查文件指针。图4显示了一个示例。

读者可以清楚地看到,尝试打开文件的结果取决于文件系统和用户数据的状态,与代码中的错误完全无关。而不是断言,嵌入式开发人员应该编写一个错误处理程序,如果文件不存在,它会创建它,它将一些默认的可用数据用于进一步发生在代码中的操作。
技巧5 – 断言用于开发而非生产
断言宏的初衷是在开发期间启用它,然后在生产中禁用它。启用和禁用断言是使用宏 NDEBUG 完成的。正确实现的断言在禁用时应该对嵌入式系统几乎没有影响。问题是,如果在开启它们的情况下执行测试,应该这样做以捕获任何错误,现在关闭它们会导致交付的产品处于与测试状态不同的状态。
技巧6 – 不要让断言产生副作用
assert 的默认实现将允许嵌入式开发人员将可执行代码作为布尔表达式的一部分包含在内。例如,状态变量可以作为传递给 assert 的表达式的一部分来实现。如果传递给 assert 的表达式有副作用,即它改变了嵌入式系统的状态,禁用断言将改变系统的行为。开发人员应确保他们的表达式没有副作用,因为他们可能会在系统中添加睡眠时间错误,该错误只会唤醒生产代码。

对于代码库中应该存在多少断言,每个开发人员都有自己的看法。可以商定的一个数字是代码库中断言的百分比应该大于零。断言为开发人员提供了一种在代码库中出现错误时发现错误的好方法。调试是开发嵌入式系统最大的浪费时间和令人沮丧的组件之一。无论开发人员的人数是1%、3%还是5%,都可以利用断言来发挥自己的优势,让开发嵌入式软件变得更加愉快。如果有的话,我们知道有 0% 不是正确的解决方案!
技巧8 – 使用断言作为可执行代码注释
断言会产生很好的评论!一个写得很好的表达式可以准确地告诉开发人员他们在代码中的给定点应该期望什么。开发人员应该构建他们的断言,以便更清楚地了解系统中正在发生的事情,这反过来将有助于减少错误。
结论
断言是一个了不起的工具,被太多的嵌入式开发人员忽略了。本文探讨的 7 个技巧只是如何正确使用断言的冰山一角。你可以采取的下一步是在测试台上设置并开始使用断言,并研究它们在真实嵌入式系统中的工作方式。
发表评论 取消回复