Linux应用开发 ——看门狗编程

IMX6ULL上的看门狗

ls /dev/watchdog*
/dev/watchdog  /dev/watchdog0

<linux/watchdog.h> : watch的ioctl命令

#define	WATCHDOG_IOCTL_BASE	'W'

#define	WDIOC_GETSUPPORT	_IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define	WDIOC_GETSTATUS		_IOR(WATCHDOG_IOCTL_BASE, 1, int)
#define	WDIOC_GETBOOTSTATUS	_IOR(WATCHDOG_IOCTL_BASE, 2, int)
#define	WDIOC_GETTEMP		_IOR(WATCHDOG_IOCTL_BASE, 3, int)
#define	WDIOC_SETOPTIONS	_IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define	WDIOC_KEEPALIVE		_IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define	WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define	WDIOC_SETPRETIMEOUT	_IOWR(WATCHDOG_IOCTL_BASE, 8, int)
#define	WDIOC_GETPRETIMEOUT	_IOR(WATCHDOG_IOCTL_BASE, 9, int)
#define	WDIOC_GETTIMELEFT	_IOR(WATCHDOG_IOCTL_BASE, 10, int)

#define	WDIOS_DISABLECARD	0x0001	/* Turn off the watchdog timer */
#define	WDIOS_ENABLECARD	0x0002	/* Turn on the watchdog timer */
#define	WDIOS_TEMPPANIC		0x0004	/* Kernel panic on temperature trip */

常用指令:

ioctl指令
WDIOC_GETSUPPORT获取看门狗支持哪些功能
WDIOC_SETOPTIONS用于开启或关闭看门狗
WDIOC_KEEPALIVE喂狗操作
WDIOC_SETTIMEOUT设置看门狗超时时间
WDIOC_GETTIMEOUT获取看门狗超时时间

WDIOC_GETSUPPORT 通过struct watchdog_info获取看够支持的功能。

struct watchdog_info {
	__u32 options;		/* Options the card/driver supports */
	__u32 firmware_version;	/* Firmware version of the card */
	__u8  identity[32];	/* Identity of the board */
};
  • options,记录看够支持的功能或选项
  • firmware_version,设备版本号
  • identity,描述性的字符串

options字段主要是以下值的位或:

#define	WDIOF_UNKNOWN		-1	/* Unknown flag error */
#define	WDIOS_UNKNOWN		-1	/* Unknown status error */

#define	WDIOF_OVERHEAT		0x0001	/* Reset due to CPU overheat */
#define	WDIOF_FANFAULT		0x0002	/* Fan failed */
#define	WDIOF_EXTERN1		0x0004	/* External relay 1 */
#define	WDIOF_EXTERN2		0x0008	/* External relay 2 */
#define	WDIOF_POWERUNDER	0x0010	/* Power bad/power fault */
#define	WDIOF_CARDRESET		0x0020	/* Card previously reset the CPU */
#define	WDIOF_POWEROVER		0x0040	/* Power over voltage */
#define	WDIOF_SETTIMEOUT	0x0080  /* Set timeout (in seconds) */
#define	WDIOF_MAGICCLOSE	0x0100	/* Supports magic close char */
#define	WDIOF_PRETIMEOUT	0x0200  /* Pretimeout (in seconds), get/set */
#define	WDIOF_ALARMONLY		0x0400	/* Watchdog triggers a management or
					   other external alarm not a reboot */
#define	WDIOF_KEEPALIVEPING	0x8000	/* Keep alive ping reply */

看门狗编程

编程步骤:

  1. open看门狗设备节点,打开狗看门狗会立即运行
  2. WDIOC_SETOPTIONS,关闭看门狗
  3. WDIOC_SETTIMEOUT ,设置看门狗超时时间
  4. WDIOC_KEEPALIVE,喂狗

wdg.h :

#ifndef __WDG_H__
#define __WDG_H__

enum {
    WDG_OFF = 0,
    WDG_ON,
};
typedef unsigned char wdg_on_off_t;

/*
 * @brief : 打开看门狗  
 */
int wdg_open(const char *devname);

/*
 * @brief : 开启or停止看门狗
 */
int wdg_on_off(int fd, wdg_on_off_t on_off);

/*
 * @brief : 设置看门狗超时时间
 * @param : timeout 超时时间,单位s(秒)
 */
int wdg_set_timeout(int fd, int timeout);

/*
 * @brief : 喂狗
 */
int wdg_feed(int fd);

#endif /* __WDG_H__ */

wdg.c :

#include "wdg.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <linux/watchdog.h>

/*
 * @brief : 打开看门狗  
 */
int wdg_open(const char *devname)
{
    return open(devname, O_RDWR);
}

/*
 * @brief : 开启or停止看门狗
 */
int wdg_on_off(int fd, wdg_on_off_t on_off)
{
    int op = WDIOS_ENABLECARD;

    if (on_off == WDG_OFF)
        op = WDIOS_DISABLECARD;

    ioctl(fd, WDIOC_SETOPTIONS, &op);
}

/*
 * @brief : 设置看门狗超时时间
 * @param : timeout 超时时间,单位s(秒)
 */
int wdg_set_timeout(int fd, int timeout)
{
    return ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
}

/*
 * @brief : 喂狗
 */
int wdg_feed(int fd)
{
    return ioctl(fd, WDIOC_KEEPALIVE, NULL);
}

wdg_sample:

#include "stdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <stdint.h>
#include <sys/select.h>

#include "wdg.h"

#define    WDOG_DEV      "/dev/watchdog0" 

void sleep_ms(unsigned int ms)
{
    struct timeval delay;
	delay.tv_sec = 0;
	delay.tv_usec = ms * 1000; 
	select(0, NULL, NULL, NULL, &delay);
}

int main(int argc, char **argv)
{
    int fd;
    
    fd = wdg_open(WDOG_DEV);
    if (fd < 0) 
    {
        printf("Open watchdog err\r\n");
        return -1;
    }

    wdg_on_off(fd, WDG_OFF);

    wdg_set_timeout(fd, 2);

    wdg_on_off(fd, WDG_ON);

    int cnt = 0;
    while (1)
    {
        printf("--------> %d\r\n", cnt);
        wdg_feed(fd);
        if (++cnt < 20)
        {
            sleep_ms(500);
        }
        else
        {
            while (1)
            {
                sleep_ms(5000);
            }
        }
    }

    return 0;
}

测试:

debian@npi:~/nfs_root$ sudo ./wdg_sample
--------> 0
--------> 1
--------> 2
--------> 3
--------> 4
--------> 5
--------> 6
--------> 7
--------> 8
--------> 9
--------> 10
--------> 11
--------> 12
--------> 13
--------> 14
--------> 15
--------> 16
--------> 17
--------> 18
--------> 19


U-Boot 2020.10-g4f79a1a2 (Apr 08 2021 - 09:59:52 +0800)

CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 52C
Reset cause: WDOG
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK

看够uboot信息可以知道系统重启了

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
看门(Watchdog)是一种硬件定时器,用于监视系统是否正常运行。如果系统正常运行,那么看门会在设定的时间间隔内被定期喂;如果系统出现异常,看门就会在时间间隔到达后触发中断或复位操作,以恢复系统的正常运行。 在Mini2440上,看门的控制寄存器位于WTDAT、WTCON和WTCNT中。其中,WTDAT用于设置看门的计数器初始值,WTCON用于配置看门的工作模式和计数器时钟源,WTCNT则是看门的计数器。 下面是一个简单的示例代码,用于启动看门并设置其定时时间为5秒钟: ```c #include "s3c2440_soc.h" void delay(int count) { while(count--); } int main() { /* 设置看门定时时间为5秒钟 */ WTCON = (0x1 << 5) | (0x3 << 3) | (0x1 << 0); /* 启动看门 */ WTCNT = 0x10000; while(1) { /* 喂 */ WTCNT = 0x10000; delay(100000); /* 业务处理 */ // ... } return 0; } ``` 在上述代码中,我们首先设置了看门的定时时间为5秒钟。然后在主循环中,我们每隔一段时间就喂一次,以保证看门不会触发中断或复位操作。同时,我们还可以在喂的时间间隔内进行业务处理。 需要注意的是,在实际应用中,我们通常不会像上述代码一样简单地启动一个看门并喂。实际上,我们需要在系统正常运行时定期喂,以确保看门不会触发中断或复位操作;同时,我们还需要在系统出现异常时及时处理异常并复位系统,以防止系统陷入死循环或其他错误状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欲盖弥彰1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值