Linux系统下简单实现一个Watchdog

定义

看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog/service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT清零,如果超过规定的时间不喂狗(一般在程序跑飞时),WDT定时超过,就会给出一个复位信号到MCU,使MCU复位。防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。

基本原理

看门狗是一种监控系统的运行状况的手段,通过软硬件结合的方式实现对系统运行状况的监控。稳定运行的软件会在执行完特定指令后进行喂狗,若在一定周期内看门狗没有收到来自软件的喂狗信号,则认为系统故障,会进入中断处理程序或强制系统复位。系统上电后根据不同的工作模式可以选择使能看门狗的时机,若看门狗被使能则计数器开始计数,如果在设定的时间内没有及时喂狗则会发生看门狗超时。

看门狗主要由寄存器、计数器和狗叫模块构成,通过寄存器对看门狗进行基本设置,计数器计算狗叫时间,狗叫模块决定看门狗超时后发出的中断或复位方式。

QOTOM Q300P自带硬件看门狗,由SuperIO芯片提供,这里简单实现一下看门狗的复位功能,只需要对看门狗的配置寄存器组和数据寄存器组进行操作。

WDTCTRL:Watch Dog Timer Control Register (Index=71h, Default=00h) 控制寄存器,主要是设置中断,这里不涉及

WDTCONF:Watch Dog Timer Configuration Register (Index=72h, Default=001s0000b) 配置寄存器

Bit6 or Bit4设置为1即可开启看门狗功能,这里使用Bit6脉冲信号

WDT

WDTVALLSB:Watch Dog Timer Time-out Value (LSB) Register (Index=73h, Default=38h) 低位数据寄存器

WDTVALMSB:Watch Dog Timer Time-out Value (MSB) Register (Index=74h, Default=00h) 高位数据寄存器

流程

进入IO配置——>选择逻辑设备——>设置看门狗配置寄存器——>设置看门狗数据寄存器(循环喂狗)

核心代码

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
27
28
29
30
31
32
33
34
/* IO Ports */
#define REG 0x2e
#define VAL 0x2f
/* Logical device Numbers LDN */
#define LDNREG 0x07
#define GPIOLND 0x07

//superio enter
outb(0x87, REG);
outb(0x01, REG);
outb(0x55, REG);
outb(0x55, REG);

//select logic device
outb(LDNREG, REG);
outb(GPIOLND, VAL);

//WDT Output through KRST (pulse) Enable
outb(0x72, REG);
outb(0xC0, VAL);

//WDT Timer-out Value (feed dog)
outb(0x73, REG);
outb(0x1e, VAL);//1e:30s
outb(0x74, REG);
outb(0x00, VAL);

//Close WDT
//outb(0x72, REG);
//outb(0x80, VAL);

//exit superio
outb(0x02, REG);
outb(0x02, VAL);

执行以上代码,如果在超时时间内没有进行喂狗,WDT将会自动产生一个复位信号,重启电脑

完整代码地址:https://github.com/huchanghui123/Watch-Dog-Linux

------ 本文结束------