一、syswatch组件介绍1 o% ~/ J$ C0 ]/ i
系统看守(syswatch)组件 主要功能是保障实时操作系统正常运行,防止系统死机 以及各种异常引起的线程阻塞,保障整个系统长期正常运行。系统看守具备以下几种行为模式:
* m! F: Z. Y7 q9 Z0 L1.系统崩溃或硬件异常导致系统失去调度时,执行 系统复位 恢复系统正常运行。- [$ H" a/ Y) G: r1 o$ ]
2.当有异常导致某些线程长时间阻塞时,可根据用户的配置实施 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 的方式恢复系统正常运行。
+ M3 g T6 V( X v1 Z二、工作原理简述# z0 C# L V' P1 C
系统看守(syswatch)组件 使用实时操作系统中允许的最高优先级作为看守线程的优先级,保障看守线程不会被阻塞,同时看守线程由看门狗提供看护,保障看守线程正常运行;系统看守通过 线程调度回调接口 监测线程的调度情况,当检测到有线程发生异常阻塞时,开始检测和确认具体哪个线程发生了异常阻塞,最后根据异常解决模式执行 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 清除异常,使系统恢复正常运行。; D4 b4 u. I2 q% s% e0 Z
& x; _+ g" [2 _8 ?3 y" d2 }; R! s
三、参数说明
5 t) Y( {# f6 |syswatch_config.h中:) _8 O7 H& v+ D) U$ } M
y% J) g; \! K5 f i! z% y1 z
! t% W0 h, F) t& ]
7 ]$ m# |7 y! @7 I( G
四、注意事项6 t, r+ C- @* F9 W
1.syswatch 依赖于看门狗设备而工作,使用本组件时请确认已注册了看门狗设备。
2 e. W6 t' f/ F, v( ^5 S# S2.syswatch 全权管理看门狗,请不要在其它线程中使用和操作看门狗。
7 u2 i3 D' x- v5 y; A3.syswatch 提供了3种异常解决模式,请根据实际需要配置适合的工作模式。% U+ F3 I4 Q" A5 y
4.syswatch_set_event_hook 提供用户安装事件回调函数,以便针对重要事件发生时进行一些必要处理,如系统复位前须对重要数据进行保存时,可设置回调函数完成相应处理,如不需要可不设置
! @5 I$ o* L6 \' d2 A/ o5.保证syswatch线程优先级最高 |- r! k& u) V! z
* m7 G+ O/ W; @/ S( o* c
四、移植过程$ @. {( V7 U; k4 I* U' _+ g1 [% J2 G
1.首先获取源码,下方工程链接下载后有,或者去rt_thread官网下载。# y! O* G" g- c* _
2.修改static int syswatch_wdt_startup(void)函数为:% l: S5 x5 L& `! D t6 _
# I( N( {2 Q5 P% j) T( {- static int syswatch_wdt_startup(void)
7 Q( H, E2 t: [0 H. ~1 R/ M+ c3 } - {8 {9 H$ ~! f0 m; t% ?5 t6 t
- // rt_uint32_t wdt_tmo = SYSWATCH_WDT_TIMEOUT;
/ D: g4 M: W! E. d - // rt_device_t wdt = rt_device_find(SYSWATCH_WDT_NAME);1 W7 F2 j7 z5 a3 u
- //
4 n' Q, {' ^. ~) f; y" z - // if (wdt == RT_NULL)
" {) Z/ G. S. Z4 K! y- O - // {( r+ E W5 w! Q" g6 |" N3 e
- // return -RT_ERROR;
' X) u% |8 E$ ^; e$ y - // }: }& n& p. O5 {# ~
- * R$ v* M- B2 k: _# H# ^' [
- // sw_data.wdt = wdt;. b) E, P- i. f
- // rt_device_init(wdt);
3 B/ r7 D+ Y$ C8 K - // rt_device_control(wdt, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &wdt_tmo);4 q7 p/ `$ P1 U9 q. N6 a, t; j
- // rt_device_control(wdt, RT_DEVICE_CTRL_WDT_START, RT_NULL);* N- ^: X1 S% F$ L' d5 r- `5 q5 t
- watch_dog_init(4,SYSWATCH_WDT_TIMEOUT*416);
* r9 g2 x4 ?4 A - return RT_EOK;
+ d, m* K! z0 J' n - }
复制代码
: S3 o* s+ F3 [# [. @1 y% J+ {2.修改static void syswatch_thread_entry(void *parameter)函数为:7 ]) j# y" @5 S! d0 J
# r! N8 r6 f& Z7 f! c- W- static void syswatch_thread_entry(void *parameter)
3 ?4 \* Y/ Q; \% P& ` Q6 s - {
C, Y2 Y, k1 V - if (syswatch_wdt_startup() != RT_EOK)
5 l0 c' h0 \' U6 J6 L4 y _) _, f - {
. g" W3 M' C: x" s& _! f - #ifdef SYSWATCH_PRINTF_INFO
. Z M% ^2 O1 e( y - rt_kprintf("watch dog startup fail");
3 F. K H6 v& V! ^3 ]' m; N - #endif$ a4 l4 F2 t' q" k: c' D& V$ \
- return;
8 i) _$ I7 n2 t5 L3 J9 h, K1 | - }
$ B) g; y2 U, Q( M - #ifdef SYSWATCH_PRINTF_INFO7 V/ T E8 U; B& @1 n
- rt_kprintf("system watch startup successfully");# q$ ?' A8 u/ J: _5 v* @) a/ `
- #endif& e' @4 J' Y4 a' U+ {
- + H1 u: Z) r X2 l" H" v4 N
- rt_slist_init(&(sw_data.wait_resume_slist));, a4 u5 C1 h ?" v! N
- rt_scheduler_sethook(syswatch_thread_switch_hook);6 f" z# ^6 _( v4 w& d' I8 F% J3 \0 W
& V* }" q3 F) ~' w- while(1)
. W5 x' }& l" ~ - {4 N9 ~ x( M; V& c6 \
- rt_thread_delay(RT_TICK_PER_SECOND);( B6 q1 \* a$ D- s0 d7 f% N
- // syswatch_wdt_feed();/ ]4 ~) ?: P7 ^! S7 U# O$ A
- syswatch_fsm();9 S/ m7 S+ \" Z/ A* J+ A4 q) F
- watch_dog_feed();0 O- j' F5 a& u9 r/ O
- }
. \! d6 @7 ~! F' ~) I/ I: \ - }
复制代码 & q9 K5 h6 j" x& i/ M- E/ c
! h' r* d8 e! r; r$ h. h7 y
* x6 Y+ s) Q5 h/ Q6 W
" C$ g: e- Q# D$ V9 q5 c
/ \, G4 @* _6 F2 n
|