ARM+LINUX移植攻略(十九)Linux驱动移植之看门狗

努力成为linux kernel hacker的人李万鹏原创作品,为梦而战。转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/06/06/6527969.aspx

默认看门狗是不开机启动的,我们可以向/dev/watchdog写入数据来启动关闭看门狗。使用echo命令,经过我的测试,这个命令启动的作用是先打开那个文件,再写入内容,然后关闭。也就是open->write->release。

echo 0 > /dev/watchdog

此时打印出:

过了几秒后系统复位。

如果这样:

echo 0 > /dev/watchdog echo V > /dev/watchdog

则系统不会复位。

为什么这样呢,下面看看源码是怎样实现的,open函数:

static int s3c2410wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &open_lock)) return -EBUSY; printk("fuck open\n"); if (nowayout) __module_get(THIS_MODULE); allow_close = CLOSE_STATE_NOT; /* start the timer */ s3c2410wdt_start(); return nonseekable_open(inode, file); }

write函数:

static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* * Refresh the timer. */ if (len) { if (!nowayout) { size_t i; /* In case it was set long ago */ allow_close = CLOSE_STATE_NOT; for (i = 0; i != len; i++) { char c; if (get_user(c, data + i)) return -EFAULT; if (c == 'V') allow_close = CLOSE_STATE_ALLOW; } } s3c2410wdt_keepalive(); } return len; }

release函数:

static int s3c2410wdt_release(struct inode *inode, struct file *file) { /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ printk("fuck release\n"); if (allow_close == CLOSE_STATE_ALLOW) s3c2410wdt_stop(); else { dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); s3c2410wdt_keepalive(); } allow_close = CLOSE_STATE_NOT; clear_bit(0, &open_lock); return 0; }

看门狗只能被一个进程打开,打开函数中先判断了一下,然后启动了看门狗;再看write函数,写入的如果是V则允许关闭看门狗,如果不是V仅仅喂狗一次;最后是release函数,如果允许关闭则关闭看门狗,如果不允许关闭,打印"Unexpected close, not stopping watchdog",喂狗一次。此时看门狗并没有关闭,所以系统会复位的,如果输入V则看门狗被关闭,这样系统就不复位了。

下面让看门狗开机启动:

查看启动信息:

首先make menuconfig进行配置:

在drivers/watchdog/s3c2410_wdt.c中进行修改:

#define CONFIG_S3C2410_WATCHDOG_ATBOOT (1) #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (20)

设置成系统启动就启动看门狗,并且看门狗到期时间为20s。这样系统复位后每20s系统就会复位一次,所以我们在用户空间进行喂狗,驱动中的那个中断函数是当看门狗作为定时器时用的,所以没有实现喂狗,所以只能在用户程序中喂狗,下面是源码:

#include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <linux/watchdog.h> int main(int argc, char **argv){ int fd; fd = open("/dev/watchdog",O_RDONLY); if(fd < 0){ perror("/dev/watchdog"); return -1; } for(;;){ ioctl(fd, WDIOC_KEEPALIVE); sleep(3); } close(fd); return 0; }

然后:

arm-linux-gcc watchdog.c -o wdt

把wdt拷贝到root-2.6.30.4/sbin/下,并修改root-2.6.30.4/etc/init.d/rcS文件,添加wdt&这么一句,让系统启动后这个应用程序在后台运行:

#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel # Mount virtual filesystem /bin/mount -t proc procfs /proc /bin/mount -n -t sysfs sysfs /sys /bin/mount -n -t usbfs usbfs /proc/bus/usb /bin/mount -t ramfs ramfs /dev # Make dir /bin/mkdir -p /dev/pts /bin/mkdir -p /dev/shm /bin/mkdir -p /var/log /bin/mount -n -t devpts none /dev/pts -o mode=0622 /bin/mount -n -t tmpfs tmpfs /dev/shm # Make device node echo /sbin/mdev > /proc/sys/kernel/hotplug /sbin/mdev -s /bin/hostname -F /etc/sysconfig/HOSTNAME wdt&

然后重新制作文件系统:

mkyaffs2image root-2.6.30.4 root-2.6.30.4.bin

此时由于用户程序在不断喂狗所以系统不复位了。再次查看启动信息:

分析看门狗源码s3c2410_wdt.c其中的中断处理函数是定时器中断处理函数。如果关闭复位功能,使能定时器功能,则中断处理函数中的喂狗也就是让定时器重新定时罢了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值