watch-dog-test

hi3521 watch dog


更新記錄

item note
20150916 第一版

目錄


HI3520D WatchDog

載入watch dog ko

  • insmod ./wdt.ko default_margin=5
    • 將產生每5秒hidog_feed

kernel介面如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define HIDOG_EXIT    	0
#define HIDOG_SELFCLR 1
#define HIDOG_EXTCLR 2

volatile static unsigned int hidog_state = 0;

static struct file_operations hidog_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = hidog_write,
.unlocked_ioctl = hidog_ioctl,
.open = hidog_open,
.release = hidog_release,
};

測試watch dog

  • wdt-test
    • 開啟/dev/watchdog,此時hidog_state會由HIDOG_SELFCLR切為HIDOG_EXTCLR
    • 產生watchdog time out reboot
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <fcntl.h>
int main(void)
{
int wtd_fd;
wtd_fd=open("/dev/watchdog",O_RDWR);

if(wtd_fd<=0)
{
printf("type 0:wtd WDIOC_GETSUPPORT\n");
}
while(1) sleep(10);
}

watchdog kernel 產生程序

  • 當測試程式有while(1)時
    • 開啟/dev/watchdog產生 kernel/open (即hidog_open)
    • 此時hidog_state由HIDOG_SELFCLR改變為HIDOG_EXTCLR,將不會再產生hidog_feed
    • 等到timeout時間到reboot
1
2
3
4
hidog_keepalive entry, hidog_state:1
hidog_open 00 entry, ret:0, hidog_state:1
hidog_open 11 entry, ret:0, hidog_state:2
hidog_deamon entry, hidog_state:2
  • 當測試程式無while(1)時
    • 在關閉/dev/watchdog產生 kernel/release (即hidog_release)
    • 將hidog_state由HIDOG_EXTCLR改變為HIDOG_SELFCLR,將會再次自動產生hidog_feed
1
2
3
4
5
6
hidog_keepalive entry, hidog_state:1
hidog_open 00 entry, ret:0, hidog_state:1
hidog_open 11 entry, ret:0, hidog_state:2
hidog_release 00 entry, hidog_state:2,cur_margin:5
hidog_release 11 entry, hidog_state:1
hidog_deamon entry, hidog_state:1

使用echo

  • 當採用echo ‘V’,將nowayout設定為1(即不能rmmod wdt.ko)
1
2
3
4
5
6
7
8
9
10
11
 # echo a > /dev/watchdog 
hidog_keepalive entry, hidog_state:1
hidog_open 00 entry, ret:0, hidog_state:1
hidog_open 11 entry, ret:0, hidog_state:2
hidog_write 00 entry, len:2,hidog_state:2
hidog_keepalive entry, hidog_state:2
hidog_write 11 entry, len:2,hidog_state:2
hidog_release 00 entry, hidog_state:2,cur_margin:5
hidog_release 11 entry, hidog_state:1
hidog_deamon entry, hidog_state:1
# hidog_deamon entry, hidog_state:1

hidog_write程式內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static ssize_t hidog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
/*
* * Refresh the timer.
* */

printk("hidog_write 00 entry, len:%d,hidog_state:%d\n",len,hidog_state);
if(len) {
size_t i;

nowayout = 0;

for (i = 0; i != len; i++) {
char c;

if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
nowayout = 1;
}
hidog_keepalive();
}

printk("hidog_write 11 entry, len:%d,hidog_state:%d\n",len,hidog_state);
return len;
}

使用busybox watchdog

  • insmod ./wdt-dd.ko default_margin=5 nodeamon=1
    • 設定載入時不要自帶feed deamon
    • watchdog -t 5 /dev/watchdog
    • 由busybox的watchdog去feed
    • 此時會產生watchdog processs,若將此process刪除將會於60S後產生timeout
1
2
3
4
1166 root      3180 S    -sh
1193 root 3044 S watchdog -t 5 /dev/watchdog
1194 root 3180 S -sh
1195 root 3180 R ps
  • busybox watchdog feed會產生write訊息,就會產生hidog_keepalive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# watchdog -t 5 /dev/watchdog 
hidog_keepalive entry, hidog_state:1
# hidog_open 00 entry, ret:0, hidog_state:1
hidog_open 11 entry, ret:0, hidog_state:2
hidog_ioctl entry, cmd:-2147199228
hidog_ioctl entry, cmd:-1073457402
hidog_keepalive entry, hidog_state:2
hidog_write 00 entry, len:1,hidog_state:2
hidog_keepalive entry, hidog_state:2
hidog_write 11 entry, len:1,hidog_state:2
hidog_write 00 entry, len:1,hidog_state:2
hidog_keepalive entry, hidog_state:2
hidog_write 11 entry, len:1,hidog_state:2
hidog_write 00 entry, len:1,hidog_state:2
hidog_keepalive entry, hidog_state:2
hidog_write 11 entry, len:1,hidog_state:2

#
#
# hidog_write 00 entry, len:1,hidog_state:2
hidog_keepalive entry, hidog_state:2
hidog_write 11 entry, len:1,hidog_state:2

busybox 程式如下

1
2
3
4
5
6
7
8
9
10
int watchdog_main(int argc, char **argv)
...
while (1) {
/*
* Make sure we clear the counter before sleeping,
* as the counter value is undefined at this point -- PFM
*/
write(3, "", 1); /* write zero byte */
usleep(stimer_duration * 1000L);
}

watchdog 測試方式

  • 帶起watchdog之後,手動刪除watchdog(killall watchdog),再5秒後將會產生硬体動啟
1
2
insmod ./wdt-dd.ko default_margin=5 nodeamon=1
watchdog -t 4 -T 5 /dev/watchdog

其它說明

1
2
3
4
5
6
7
8
9
10
11
12
BusyBox v1.16.1 (2013-07-17 17:28:26 CST) multi-call binary.

Usage: watchdog [-t N[ms]] [-T N[ms]] [-F] DEV

Periodically write to watchdog device DEV

Options:
-T N Reboot after N seconds if not reset (default 60)
-t N Reset every N seconds (default 30)
-F Run in foreground

Use 500ms to specify period in milliseconds