一、syswatch组件介绍
' e1 N. }# ~# {9 U 系统看守(syswatch)组件 主要功能是保障实时操作系统正常运行,防止系统死机 以及各种异常引起的线程阻塞,保障整个系统长期正常运行。系统看守具备以下几种行为模式:( N N, K& [9 Q+ {' H7 U
1.系统崩溃或硬件异常导致系统失去调度时,执行 系统复位 恢复系统正常运行。- K# T8 f( N _, W1 B( U
2.当有异常导致某些线程长时间阻塞时,可根据用户的配置实施 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 的方式恢复系统正常运行。
6 b& Y' o: m9 |' l! U: V0 v二、工作原理简述
% {: p$ o; c, H$ b 系统看守(syswatch)组件 使用实时操作系统中允许的最高优先级作为看守线程的优先级,保障看守线程不会被阻塞,同时看守线程由看门狗提供看护,保障看守线程正常运行;系统看守通过 线程调度回调接口 监测线程的调度情况,当检测到有线程发生异常阻塞时,开始检测和确认具体哪个线程发生了异常阻塞,最后根据异常解决模式执行 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 清除异常,使系统恢复正常运行。( O' V+ o% o/ I0 B2 K4 p' I8 J
* A8 k* H* `; v& |, y8 I三、参数说明8 ?$ W& l* }5 H
syswatch_config.h中:
/ P; `0 `6 C. P J x6 P, ~" f' h; h. W% U$ n/ Z9 h" p( \
0 E; z! R+ V$ h( K- x' M& }1 v, _2 T4 \1 w; D/ X
四、注意事项
: k% M0 T3 ?1 z+ d1.syswatch 依赖于看门狗设备而工作,使用本组件时请确认已注册了看门狗设备。 \& a5 \$ D6 W5 h7 V% H
2.syswatch 全权管理看门狗,请不要在其它线程中使用和操作看门狗。
! Y; u/ S9 ~" L) L% }3.syswatch 提供了3种异常解决模式,请根据实际需要配置适合的工作模式。
* F. V% T4 c8 |! X' D1 d4.syswatch_set_event_hook 提供用户安装事件回调函数,以便针对重要事件发生时进行一些必要处理,如系统复位前须对重要数据进行保存时,可设置回调函数完成相应处理,如不需要可不设置" t$ r6 e, i/ C
5.保证syswatch线程优先级最高
/ U( ^3 \8 v4 L6 r7 _+ l' y8 N0 @" z! ]7 l( F
四、移植过程, D; k; H6 ~4 t3 V2 N% B f/ k& }
1.首先获取源码,下方工程链接下载后有,或者去rt_thread官网下载。
3 E8 j4 D. \; M) L2.修改static int syswatch_wdt_startup(void)函数为:' K* g' u7 h$ Z8 [
9 y0 p1 o6 m4 T$ A9 B* ?& L5 p) q
- static int syswatch_wdt_startup(void): Y; n9 m( l* ?' A" c
- {
! q4 U4 `) T: Y" x - // rt_uint32_t wdt_tmo = SYSWATCH_WDT_TIMEOUT;, C* i0 `! w* _" E
- // rt_device_t wdt = rt_device_find(SYSWATCH_WDT_NAME);" G9 j' |+ \2 }6 N- \* W
- // F& _! V+ C% \0 B6 C* ^
- // if (wdt == RT_NULL)
# a9 f) R: A( E j- ?9 }# E - // {
$ T" y. @4 J3 Y9 w5 k1 k. r - // return -RT_ERROR;% W1 T2 g' U* a- @, p+ p% h
- // }( T$ L9 \, X+ I! r+ a
5 H$ ~) J' M8 R1 e# k1 g: _- // sw_data.wdt = wdt;; Q# q( T8 N+ Z c, g
- // rt_device_init(wdt);$ N" u% J5 q* g7 j; k2 _; H2 m9 g
- // rt_device_control(wdt, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &wdt_tmo);, Y6 a1 R5 x. w% b5 k- {
- // rt_device_control(wdt, RT_DEVICE_CTRL_WDT_START, RT_NULL);
9 F7 K4 h8 n! }2 U, v: ` - watch_dog_init(4,SYSWATCH_WDT_TIMEOUT*416);
: K, o S7 [! P f - return RT_EOK;
. @* w; E4 q, q4 t% G1 P# ~6 N - }
复制代码
8 U, ]; [/ a* n) u7 _( U2.修改static void syswatch_thread_entry(void *parameter)函数为:
# I' u' }* Y% T2 _: M/ _- N0 z, @ s
- static void syswatch_thread_entry(void *parameter)( v: ?' j# d v1 @- }
- {
2 s$ E5 A& g6 F& L9 z4 \ - if (syswatch_wdt_startup() != RT_EOK)
) \' F7 }( M- G* ] - {
, o9 I- ?- ?, c+ }/ a- c - #ifdef SYSWATCH_PRINTF_INFO
0 b$ [0 R0 l* w! x8 e4 P - rt_kprintf("watch dog startup fail");
0 U2 [" c/ u O5 { - #endif) W0 X3 r- ~( _" |
- return;- I7 I+ V5 @$ q/ k7 z
- }
. m7 p" h0 u' s- O. z3 N - #ifdef SYSWATCH_PRINTF_INFO
6 D& @2 _' L) o& o2 g - rt_kprintf("system watch startup successfully");# U- C( ^0 _+ e
- #endif
7 @5 i& F( v/ M$ S" w' g
: N9 b7 o6 _; V$ J9 e0 @+ I: a- rt_slist_init(&(sw_data.wait_resume_slist));
' {2 T) }8 y, x - rt_scheduler_sethook(syswatch_thread_switch_hook);& F7 X( L! u P* G& B8 c# g: D$ r
- ! A; @0 ?, }4 e
- while(1)7 d9 J* l0 F) M- u( Q9 ~
- {+ N& q# U) e! C: M+ D, }9 h! Z+ n
- rt_thread_delay(RT_TICK_PER_SECOND);' ^. ?' j i8 G# ~$ _& G
- // syswatch_wdt_feed();
- Q' _" n( F% `7 z# N - syswatch_fsm();! y& o. z7 q8 ] n$ K
- watch_dog_feed();4 h8 r3 d" E7 c i* {4 W
- }
2 { F+ T7 ?; S' V - }
复制代码
# u& Q- d$ [$ j/ h- z$ \
, ^4 I! K: ]! ^/ C! p0 a+ F" Z! W( I/ ^2 ^. Q7 o" m# [1 z
$ V9 @5 \# i. {& M3 p7 a* k; W8 o2 v4 P! U
|