所有重要的软件都有错误。我不想称它们为“错误”,因为这会使它们与需要为自己的错误负责的开发人员分离。显然,设计良好的软件可能会更少,而现代嵌入式软件开发工具的应用可以将它们保持在最低限度。当然,具体的错误无法预测(否则它们可以被根除),但是可以识别某些类型的软件问题,并且有可能在问题变成灾难之前发现问题。
我会将此类软件问题分为两大类:
数据损坏
代码循环
由于大量嵌入式代码是用 C 编写的,这意味着开发人员很可能会使用指针。小心使用,指针是该语言的一个强大功能,但它们也是最常见的程序员错误来源之一。指针使用的问题很难静态识别,并且引入的错误可能会在代码执行时以微妙的方式表现出来。有些事情,比如取消引用空指针很容易检测到,因为它们通常会导致陷阱。只需要实现一个陷阱处理程序。其他的更难,因为指针最终可能指向任何地方——通常它会指向一个有效的地址,但不幸的是,它可能不是正确的地址。自测试代码对此几乎无能为力。然而,有两种特殊但非常常见的,
不应发生堆栈溢出,因为应仔细确定堆栈分配,并在调试阶段验证其使用情况。但是,很可能会忽略不寻常的情况或使用不易测试的构造(如递归函数)。一个简单的解决方案是在堆栈空间的任一端包含一个额外的词——“保护词”。这些预加载了特定值,由自检任务(可能在后台运行)监控。如果值更改,则违反了堆栈限制。应谨慎选择该值。奇数是最好的,因为它不代表大多数处理器的有效地址。也许是 0x55555555。只要该值“不太可能”——例如不是 0x00000001 或 0xffffffff——就有 40 亿比 1 的机会发生误报。
在某些语言中,存在用于在数组边界之外寻址的内置检测,但这会引入运行时开销,这可能是不受欢迎的。因此,这不是在 C 中实现的。此外,可以使用指针而不是运算符来访问数组元素,因此可能会规避任何检查。最好的方法是通过在数组末尾定位一个保护字并以与堆栈溢出检查相同的方式进行监视来检查缓冲区溢出类型的错误。
在这两种情况下,当保护字被破坏时,这表明即将发生故障。堆栈或数组可能只是一个字就溢出或不足,因此还没有造成真正的损害。定位错误访问的原因比调试可能发生的随机崩溃要容易得多。
代码永远不应陷入无限循环,但逻辑错误或未发生预期的外部事件可能会导致代码挂起。当代码在等待某事发生时,理想情况下应该有一个超时机制,这样代码就不会无限期地挂起。
在任何类型的多线程环境中——无论是 RTOS 还是带有 ISR 的主线代码——都可以实现“看门狗”机制。每个连续运行的任务(可能只是主线代码)都需要每隔一段时间与看门狗任务(可能是计时器 ISR)“签入”。如果发生超时,则需要采取措施。
那么,当检测到堆栈溢出、数组绑定违例或挂起任务时该怎么办呢?这取决于应用程序。可能只需要停止和重新启动单个任务,但可能需要更激烈的操作:停止系统、发出某种警报或简单地重置系统。选择取决于许多因素,但从广义上讲,目标是为了比崩溃的系统更好的东西。
订阅
审核编辑:郭婷
-
嵌入式
+关注
关注
5081文章
19073浏览量
304321 -
RTOS
+关注
关注
22文章
810浏览量
119531 -
代码
+关注
关注
30文章
4766浏览量
68458
发布评论请先 登录
相关推荐
评论