嵌入式软件工程师在编写 C 语言应用程序的时候,经常会遇到程序运行时跑飞的情况,程序运行时产生错误,多半是程序员在编写代码时,没有预判好发生错误的地方,并且没有设计好合适的错误处理机制。
在嵌入式C语言编程中,错误处理机制是确保系统稳定性和可靠性的关键部分,能确保系统在已知的风险和错误条件下正常运行。
以下分享一些常用的错误处理方法:
1、断言 (Assertions)
断言用于在开发阶段捕获程序中的逻辑错误。通过 assert 宏,可以在条件不满足时终止程序并输出错误信息,这有助于在开发阶段及早发现问题。
强烈建议使用断言机制对函数传参的参数合法性进行判断,很多芯片的SDK包的函数传参都采用了有效的断言机制,以防止参数不合法带来不必要的麻烦。
2、错误码 (Error Codes)
通过返回错误码来指示函数执行的结果。调用者可以根据错误码采取相应的措施,这是一种灵活且适用于多种应用场景的错误处理方式。
对于有返回值的函数接口调用,错误码包含了非常丰富的调试信息,当某个函数接口调用异常时,通常先根据错误码进行有效分析。
3、中断服务程序 (Interrupt Service Routines, ISR)
在嵌入式系统中,中断是处理异常情况的常用方法。ISR用于处理硬件中断,并确保系统在异常情况下仍能进入中断服务程序进行相应处理。
通常是CPU运行程序时,内部硬件或总线出现错误而触发中断,对于MCU应用可以使用 cm_backtrace 组件进行栈回溯排查,以发现错误发生的地方。
4、看门狗定时器 (Watchdog Timer)
看门狗定时器用于检测和恢复系统故障,通常可以使用CPU的内部看门狗,或使用外部看门狗芯片,系统在正常运行时需要定期重置看门狗定时器。
如果某些错误原因,导致程序逻辑不能及时重置定时器(俗称:喂狗),看门狗就会触发系统软复位或外部RST引脚复位,这有助于防止系统因软件错误而陷入死循环。
5、日志记录 (Logging)
在应用软件运行时,如果产品上面有容量较大的非易失性存储器,可以把运行时的错误日志记录到存储器里面。
记录程序运行时的错误日志,这种方式有助于出错时的调试和维护,开发人员不用时刻在机器旁边进行程序运行监视,存储的错误日志还可以通过串口或调试接口输出,这对于出现错误后的分析和问题解决非常重要。
6、错误传递
C 语言通常使用返回值来标志函数是否执行成功,调用者通过检查返回值以判断函数执行情况。此外,也可以通过全局状态标志或局部跳转(goto)来处理错误。
对于goto语句需要谨慎使用,在局部函数内某个环节运行出错,使用goto语句可以直接跳转到错误处理节点,但大范围使用goto跳转,可能会破坏代码的运行结构与完整性。
不同的错误处理机制,有对应不同的业务应用场景和系统要求,建议 C 语言程序开发者根据具体情况进行具体分析,没有一概而论完美的方法。
但为了提升嵌入式系统整体的稳定性和可靠性,在嵌入式 C 语言程序里面引入合适的错误处理机制,是非常值得且有必要的。