目 录
本文档概要记录了看门狗的设计背景、设计方案、运行流程、及应用方法等,让读者能够了解和使用看门狗
在嵌入式应用系统中,有效的应用程序必须稳定、可靠的长期运行其产品才能算是一个稳健的产品,但由于系统的种种未知原因导致程序不能正常运行出现跑飞、卡死等异常情况,在未能解决实质出错问题的时候看门狗可做临时复位操作来提高系统的可靠性。看门狗本身不是用来解决系统出现的问题,在调试过程中发现的故障应该要查改设计本身的错误。加入看门狗目的是对一些程序潜在错误和恶劣环境干扰等因素导致系统死机而在无人干预情况下自动恢复系统正常工作状态。看门狗也不能完全避免故障造成的损失,毕竟从发现故障到系统复位恢复正常这段时间内怠工。同时一些系统也需要复位前保护现场数据,重启后恢复现场数据,这可能也需要一笔软硬件的开销。
本设计针对mifi项目中出现ap_service概率性出现cpu为0%而导致mifi假死可用作恢复处理,提高系统的稳定性让mifi能正常使用。
1.3 定义与缩写
本文档中使用的术语如表1-1术语表所示。
表1-1 术语表
缩写、术语 | 解 释 |
WatchDog | 看门狗 |
SysMonitor | 系统监控 |
Timer | 定时器 |
Cpu | 处理器 |
Server | 服务端 |
Client | 客户端 |
《使用 watchdog 构建高可用性的 Linux 系统及应用》
本模块概要设计的参考资料如表1-2 参考资料表所示。
序号 | 文档名称 | 作者或资料来源 |
1 | 《Linux高级程序设计》 | Jon Masters&Richard Blum |
2 | 《linux网络编程》 | 宋敬彬、孙海滨 |
3 |
|
|
4 |
|
|
5 |
|
|
看门狗分可分为硬件看门狗和软件看门狗两种。
硬件看门狗的主体是一个定时电路,并由被监控CPU提供周期性“喂狗”信号,对定时器清零(俗称“清狗”)。CPU正常工作时,由于能定时“清狗”,看门狗内的定时器不会溢出。当CPU出现故障,则不能继续提供“清狗”信号,使得看门狗内定时器不断累加而溢出,从而触发一个复位信号对CPU进行复位,使CPU重新工作。
软件看门狗原理上一样,只是将硬件电路上的定时器用内部定时器代替。本设计使用软件看门狗方案。
实时地对mifi嵌入式系统中的ap_service进程进行监控,当发现ap_service异常(cpu为0%)时重启ap_service进程让其恢复正常。
Cpu:armv7 System:oelinux
由于项目中ap_service进程有自动重启功能如图1-1:
图1-1
项目中要求ap_service出现异常后只需要快速的恢复就好,需求特殊所以我们将看门狗超时处理设置为强行杀死ap_service进程后ap_service则会自重启来恢复来代替整个系统的重启开销。
根据特殊需求我们将看门狗设计成两个部分,一部分为WatchdogServer端,另一部分为WatchdogClient端,两端用回送地址127.0.0.1进行通信,server端独立于client端,client端植入ap_service进程中(ap_service启用sysmonitor监视线程)。
Ap_service和Watchdog之间的关系如图1-2
本设计的看门狗服务器端相当于一个独立的监控程序,所以其必须依赖一个稳定的linux嵌入式系统,否则一切归零,内部定时器也要稳定、可靠,本设计用的基于事件驱动的libevent第三方库,本地的socket通信也要稳定可靠。
看门狗server端,如图1-3
看门狗client端,如图1-4
序号 | 入口函数 | 输入参数 | 功能描述 |
1 | askey_libevent_init() | Null | 初始化libevent |
2 | askey_libevent_loop() | Null | 循环事件 |
3 | askey_libevent_exit() | Null | Libevent退出 |
4 | askey_libevent_add_timeout() | int sec 时间(s) event_callback_fn timeout_cb 回调函数 askey_timer_t_type_e type 触发类型 void *arg 参数 | 添加timer并注册回调函数 |
5 | askey_libevent_del_timeout() | int *ev_handle | 删除指定timer |
序号 | 名称 | 输入参数 | 功能描述 |
1 | wdg_main_sighandler_cb() | Signo 信号 | 信号处理函数 |
2 | askey_init_watchdog_server() | Null | 初始化看门狗server |
3 | askey_release_watchdog_service() | Null | 释放看门狗servsr |
序号 | 名称 | 输入参数 | 功能描述 |
1 | system_monitor_run () | Null | 运行系统监控 |
2 | create_thread () | pthread_t* thread_hdl askey_thread_callback callback 回调函数 void *arg 参数 | 创建PTHREAD_CREATE_JOINABLE属性的线程 |
3 | system_monitor_thr_cb() | Null | 系统监控回调函数 |
数据结构名 | wdg_server_info_t | 定义模块 | server | ||
功能简述 | 看门狗server基本信息结构体 | 类型 | 结构体 | ||
成员 | 成员名 | 类型 | 初始值 | 说明 | |
fd | int | 0 | 通信socket | ||
Is_thr_run | int | 0 | Watchdog server运行状态 | ||
Port | unsigned short | 0 | 端口 | ||
| Reserv | unsigned short | 0 |
| |
| Pid | pthread_t | 0 | 线程id | |
详细描述 | 记录watchdog server的信息状态 |
数据结构名 | wdg_cli_conn_inf_t | 定义模块 | server | ||
功能简述 | 看门狗client基本信息结构体 | 类型 | 结构体 | ||
成员 | 成员名 | 类型 | 初始值 | 说明 | |
fd | int | 0 | 通信socket | ||
pthread_run_stat | pthread_t | 0 | 线程id | ||
Timer | Int | 0 | 计时器 | ||
| timer_times | Int | 0 | 连接时间 | |
详细描述 | 记录watchdog client的信息状态 |
数据结构名 | ASKEY_CMD_MSG_TYPE_E | 定义模块 | server | ||
功能简述 | 通信命令 | 类型 | 枚举 | ||
成员 | 成员名 | 类型 | 初始值 | 说明 | |
ASKEY_CMD_WDG_KEEPLIVE_ASK | enum | 0x3001 | 心跳 | ||
ASKEY_CMD_SYS_INF_ASK | enum | 0x3002 | Client 信息 | ||
ASKEY_SYS_EXCEPTION | enum | 0x3003 | 异常 | ||
详细描述 | Server和client的通信命令 |
数据结构名 | cmr_msg_header | 定义模块 | server | ||
功能简述 | 通信基本包 | 类型 | 结构体 | ||
成员 | 成员名 | 类型 | 初始值 | 说明 | |
ASKEY_CMD_MSG_TYPE_E | enum | 0 | 通信命令 | ||
msg_len | Int | 0 | 额外数据长度 | ||
详细描述 | Server和client的基本通信包 |
数据结构名 | askey_sys_inf_t | 定义模块 | server | ||
功能简述 | Client sysinfo | 类型 | 结构体 | ||
成员 | 成员名 | 类型 | 初始值 | 说明 | |
pid | Int | 0 | Client进程号 | ||
proc_path | Char* | 0 | 运行路径 | ||
详细描述 | Client进程的基本信息 |
3 系统细节设计
调试由自己封装的宏函数作打印调试,如图1-5
/**系统timer检测时间5s**/
#define ASKEY_WDG_MONITOR_TIME (5)
/**读超时时间5s**/
#define WDG_CLIENT_READ_TIMEVAL(5)
/**客户端连接心跳时间1s**/
#defineWDG_CLIENT_KEEPLIVE_TIMEVAL (1)
/**客户端连接最大超时时间30s**/
#defineWDG_CLIENT_KEEPLIVE_MAX_TIMEOUT (30)
/**客户端最大连接数 2**/
#define ASKEY_WDG_MAX_CLIENT_NUM(2)
Watchdog servsr端timer为周期性触发每隔5s会做一次“喂狗”标志检测,若 “喂狗”标志为1则表示已喂狗,ap_service运行正常,timer进入下个周期;若 “喂狗”标志为0则表示超时未喂狗,ap_service运行异常须做重启操作。
watchdog客户端每3s发出一次喂狗操作,同时检测server端的回馈包
Watchdog servsr端判断client 30s未收到数据会判断超时会自动断开连接。
由于此设计是基于c/s模式,所以正确的启动顺序为:
启动askey_watchdog_server--->ap_service(watchdog_client)
Ap_service是概率性出现cpu为0%的情况,我们可以用kill –STOP命令模拟ap_servicecpu为0的情况
5.5.1具体方法
1、mifi系统植入watchdog之后,正常开机运行
2、连接好usb线,adb shell工具登录终端
3、发送命令:kill –STOP $(pgrep "ap_service")
(note:kill –STOP pid命令可以让ap_service停止,此时ap_service的system_monitor线程将不会进行“喂狗”操作,从而导致watchdog server timer检测出未进行喂狗操作“杀死”ap_service,之后ap_service重启之后连接watchdog server正常“喂狗”,系统正常恢复)
源代码可联系索要。