我是老温,一名热爱学习的嵌入式工程师
+ L: y6 t X9 |- j关注我,一起变得更加优秀!) }* W0 N' i7 P# R/ {
嵌入式软件工程师在编写 C 语言应用程序的时候,经常会遇到程序运行时跑飞的情况,程序运行时产生错误,多半是程序员在编写代码时,没有预判好发生错误的地方,并且没有设计好合适的错误处理机制。
* l6 l% Q9 q. E; b i5 F& H在嵌入式C语言编程中,错误处理机制是确保系统稳定性和可靠性的关键部分,能确保系统在已知的风险和错误条件下正常运行。
l% J# P% ]9 R7 D" R以下分享一些常用的错误处理方法:7 E/ ^- x9 C- h- F* ?1 }
1、断言 (Assertions)
8 J7 k. ?# |, I断言用于在开发阶段捕获程序中的逻辑错误。通过 assert 宏,可以在条件不满足时终止程序并输出错误信息,这有助于在开发阶段及早发现问题。9 w0 q o- d- Y1 ^: K
强烈建议使用断言机制对函数传参的参数合法性进行判断,很多芯片的SDK包的函数传参都采用了有效的断言机制,以防止参数不合法带来不必要的麻烦。+ H2 x4 c- [% w! y
i0o3osqr4ge6408255906.png
8 F7 ? b( J2 X. n6 W1 c2、错误码 (Error Codes)/ H3 R* f2 F4 ~4 a7 [4 A. |
通过返回错误码来指示函数执行的结果。调用者可以根据错误码采取相应的措施,这是一种灵活且适用于多种应用场景的错误处理方式。( y. n3 P% D) W A+ Y% t
对于有返回值的函数接口调用,错误码包含了非常丰富的调试信息,当某个函数接口调用异常时,通常先根据错误码进行有效分析。3 H9 T: T% \7 G& T
fuvhjjjbp5t6408256006.png
! x* I0 D+ b9 s4 E5 c' G3、中断服务程序 (Interrupt Service Routines, ISR)6 i6 g* @+ U; J3 e" e+ |
在嵌入式系统中,中断是处理异常情况的常用方法。ISR用于处理硬件中断,并确保系统在异常情况下仍能进入中断服务程序进行相应处理。
( ]* @5 C' X; r. F9 R! r通常是CPU运行程序时,内部硬件或总线出现错误而触发中断,对于MCU应用可以使用 cm_backtrace 组件进行栈回溯排查,以发现错误发生的地方。! k3 ~# a6 _( V. X4 N; L, z
zcpsk15dsqm6408256106.png
L2 L% M0 ]# @. X
4、看门狗定时器 (Watchdog Timer): v! t& {( T7 B
看门狗定时器用于检测和恢复系统故障,通常可以使用CPU的内部看门狗,或使用外部看门狗芯片,系统在正常运行时需要定期重置看门狗定时器。
( r0 y0 ^$ R1 C+ Z- L, T. {如果某些错误原因,导致程序逻辑不能及时重置定时器(俗称:喂狗),看门狗就会触发系统软复位或外部RST引脚复位,这有助于防止系统因软件错误而陷入死循环。
/ ]/ y7 }. ]& W; W1 n+ g
z0dknst4rml6408256206.png
g4 @' f( d. G( S, H. S
) |) J9 p2 ?# t7 Q& m
msxebyerfbk6408256306.png
& d( O; | I7 j, u
5、日志记录 (Logging). K& o0 R9 X7 b
在应用软件运行时,如果产品上面有容量较大的非易失性存储器,可以把运行时的错误日志记录到存储器里面。
- Y, n1 V) h' ]* G4 {记录程序运行时的错误日志,这种方式有助于出错时的调试和维护,开发人员不用时刻在机器旁边进行程序运行监视,存储的错误日志还可以通过串口或调试接口输出,这对于出现错误后的分析和问题解决非常重要。( h; W# _; f( I+ f% e' P+ P
sjjqvifpmci6408256406.png
- E, Z5 K( i6 _# I) A
6、错误传递
V y+ e; m9 ]C 语言通常使用返回值来标志函数是否执行成功,调用者通过检查返回值以判断函数执行情况。此外,也可以通过全局状态标志或局部跳转(goto)来处理错误。) G N% W, p- y) q$ m& M% \, r
对于goto语句需要谨慎使用,在局部函数内某个环节运行出错,使用goto语句可以直接跳转到错误处理节点,但大范围使用goto跳转,可能会破坏代码的运行结构与完整性。
8 R7 P. ?( O/ l# @3 ~. r" F+ e( |8 D( z M5 V" v
ljygacmdjg46408256507.png
7 h5 l" G7 I% b* F( t1 W
不同的错误处理机制,有对应不同的业务应用场景和系统要求,建议 C 语言程序开发者根据具体情况进行具体分析,没有一概而论完美的方法。0 A6 T$ o m- k2 @6 u
但为了提升嵌入式系统整体的稳定性和可靠性,在嵌入式 C 语言程序里面引入合适的错误处理机制,是非常值得且有必要的。
8 h- o2 f1 p) b
, F7 D4 d# v7 x3 o$ k, g' S6 j
eejwfys2zzk6408256607.png
! U* {, u d! v3 ]0 e# k8 Y
, y( `! @) O5 x/ I: v5 n
/ H7 z0 ^! {3 S-END-
6 @/ @- R* `" ]9 n7 s" O往期推荐:点击图片即可跳转阅读- r; Y4 w c3 x, Y3 N( a; s) _2 r& w
: e L. P6 D- W4 m; z/ [" j 5 ?) e$ T4 S( s' Q7 ~
$ f ^$ j; t, X. \
! h9 S' V$ ^. s
1 l/ } D; S: N% c6 u
4kmx1fut2zg6408256707.jpg
4 c9 \7 l$ Z G' y# M6 g , w% j/ X5 h7 G, @0 j1 g6 s
有哪些不推荐使用的嵌入式 C 语言语法特性?9 f8 n$ x0 V$ i" z& `5 @6 s" Z
& O- [0 _. @! i F
! t, m/ g( G+ c* ` D
( |" _4 O* X" a8 k3 r0 G
- s0 D) l& [9 ]$ i
yoici31rnup6408256807.jpg
/ |% m9 @9 h% k- F; i v( G; Z( K/ U9 J5 q G
今年快过完了,明年准备进厂搞嵌入式工控,提前了解各方行业信息!0 r1 q5 e$ E) t9 n% r
; T! U* W. m1 ?* r; O- W2 U
4 n3 f4 J1 s7 ~5 q; g% W1 C# w
; ~4 e) @1 ]/ A9 v5 v# k2 z; A( l
ijnaykh4uoc6408256907.jpg
) I* S& w8 p/ w" r4 y/ s- w( s- t . u4 c% u, {! \( O A
基于全志T113-i平台,嵌入式Linux 快速启动,5.2秒成功进入应用界面!
! I7 z! E8 E7 h) O ! Q6 U) I+ M- E( d, x
& B7 }& H9 Q3 O4 Z, N0 u
" v/ y2 V6 V# P& k% Q 我是老温,一名热爱学习的嵌入式工程师3 s$ l+ l. z1 j9 I' s- Q
关注我,一起变得更加优秀! |