首先贴上测试应用程序,如下:
#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
typedef unsigned int __u32;
typedef unsigned char __u8;
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 */
};
#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)
int main(void)
{
int fd, retval;
unsigned int val = 1;
fd = open ("/dev/watchdog0", O_RDWR);
if (fd<0) {
printf("open /dev/watchdog0 faild!!!\n");
return ;
}
val = 8;
retval = ioctl(fd, WDIOC_SETTIMEOUT, &val);
if (retval < 0) {
printf("ioctl WDIOC_GETTIMEOUT failed\n");
return ;
}
retval = ioctl(fd, WDIOC_GETTIMEOUT, &val);
if (retval < 0) {
printf("ioctl WDIOC_GETTIMEOUT failed\n");
return ;
}
printf("WDIOC_GETTIMEOUT val1 = %d\n", val);
while(1)
{
printf("ping watchdog\n");
write(fd, &val, 4);
sleep(1);
}
close(fd);
return 0;
}
测试的过程中发现, watchdog超时后,console无法输入, 整个系统感觉卡死一样,没有按照预期出现系统复位, 也就是watchdog的功能是没有实现的。
看到板子上PA3的跳冒是连着的,也就是PA3是低电平, 根据PWRON寄存器的描述, watchdog上电后是关闭的。 于是拔掉PA3跳冒,使得PA3为高电平, 重新测试后发现系统经过一定时间就会reset。 但是另一个问题是linux启动到console需要一定时间,系统在还没有进入console的时候就已经watchdog timeout从而reset了, 在nuc970wdt_probe函数中打印watchdog的两个寄存器,居然有值如下:
probe REG_WDT_CR=782
probe REG_WDT_CTALT=0
猜测是uboot中启动了watchdog。
正确的做法是在uboot中关闭watchdog, 这里偷懒直接在nuc970wdt_probe
函数末尾调用了nuc970wdt_stop(&nuc970_wdd);
这样经过测试系统能够正常进入console, 同时运行测试程序也能测出watchdog功能正常,