mini6410实现 看门狗移植

来源:互联网 发布:时光知味 编辑:程序博客网 时间:2024/06/05 20:10

看门狗是嵌入式系统中最常见的功能之一,一旦启动了看门狗,它就无法停止了,

只有不停的去喂它,否则系统就会复位重启。Reboot和“看门狗”是完全不同的功能,“看门狗”属于“冷”启
动,它不会逐项关闭各个应用和服务,而是直接复位重启。

S3C2440芯片本身就带有看门狗,最新的内
核中已经包含了它的驱动,现在我们就在应用程序中启动它。

写在移植前的:

   看门狗在嵌入式系统开发中占据重要的地位,管理系统的工作状态。在这里本人muge0913在参考别人的基础上,实现了mini6410看门狗的移植。本文章仅供技术交流请勿商用,转载请标明地址:

http://blog.csdn.net/muge0913/article/details/7063001

   在mini6410中看门狗驱动文件为linux2.6.38/drivers/watchdog/s3c2410_wdt.c

   在mini6410中linux系统默认看门狗是不开机启动,但是我们可以向/dev/watchdog写入数据来启动或关闭看门狗。

如:echo 0 >/dev/watchdog

   echo这个命令启动的作用是先打开文件,再写入内容,然后关闭。也就是open->write->release。

运行效果:

一段时间后系统会自动重启。

如果执行:

  echo 0 >/dev/watchdog

  echo V >/dev/watchdog

系统侧不会重启。

原因分析:

open函数:

[cpp] view plaincopyprint?
  1. static int s3c2410wdt_open(struct inode *inode, struct file *file)  
  2. {  
  3.     if (test_and_set_bit(0, &open_lock))  
  4.         return -EBUSY;  
  5.   
  6.     if (nowayout)  
  7.         __module_get(THIS_MODULE);  
  8.   
  9.     expect_close = 0;  
  10.   
  11.     /* start the timer */  
  12.     s3c2410wdt_start();  
  13.     return nonseekable_open(inode, file);  
  14. }  

release函数:

[cpp] view plaincopyprint?
  1. static int s3c2410wdt_release(struct inode *inode, struct file *file)  
  2. {  
  3.     /* 
  4.      *  Shut off the timer. 
  5.      *  Lock it in if it's a module and we set nowayout 
  6.      */  
  7.   
  8.     if (expect_close == 42)  
  9.         s3c2410wdt_stop();  
  10.     else {  
  11.         dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");  
  12.         s3c2410wdt_keepalive();  
  13.     }  
  14.     expect_close = 0;  
  15.     clear_bit(0, &open_lock);  
  16.     return 0;  
  17. }  

write函数:

[cpp] view plaincopyprint?
  1. static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,  
  2.                 size_t len, loff_t *ppos)  
  3. {  
  4.     /* 
  5.      *  Refresh the timer. 
  6.      */  
  7.     if (len) {  
  8.         if (!nowayout) {  
  9.             size_t i;  
  10.   
  11.             /* In case it was set long ago */  
  12.             expect_close = 0;  
  13.   
  14.             for (i = 0; i != len; i++) {  
  15.                 char c;  
  16.   
  17.                 if (get_user(c, data + i))  
  18.                     return -EFAULT;  
  19.                 if (c == 'V')  
  20.                     expect_close = 42;  
  21.             }  
  22.         }  
  23.         s3c2410wdt_keepalive();  
  24.     }  
  25.     return len;  
  26. }  

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

 

 

看门狗在mini6410上的移植过程:

首先配置:make menuconfig


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

[cpp] view plaincopyprint?
  1. #define CONFIG_S3C2410_WATCHDOG_ATBOOT      (1)  
  2. #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME    (15)  

注:

[cpp] view plaincopyprint?
  1. #define CONFIG_S3C2410_WATCHDOG_ATBOOT      (0)//系统启动时不开启看门狗  
  2. #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME    (15)//复位时间  

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

[cpp] view plaincopyprint?
  1. #include <stdio.h>    
  2. #include <unistd.h>    
  3. #include <sys/stat.h>    
  4. #include <sys/types.h>    
  5. #include <fcntl.h>    
  6. #include <stdlib.h>    
  7. #include <errno.h>    
  8. #include <linux/watchdog.h>    
  9.     
  10. int main(int argc, char **argv){    
  11.     int fd;    
  12.     fd = open("/dev/watchdog",O_RDONLY);    
  13.     if(fd < 0){    
  14.         perror("/dev/watchdog");    
  15.         return -1;    
  16.     }    
  17.     for(;;){    
  18.         ioctl(fd, WDIOC_KEEPALIVE);    
  19.         sleep(3);    
  20.     }    
  21.     close(fd);    
  22.     return 0;    
  23. }  

编译:

[cpp] view plaincopyprint?
  1. arm-linux-gcc wdt.c -o wdt  

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

[cpp] view plaincopyprint?
  1. #! /bin/sh  
  2.   
  3. PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:  
  4. runlevel=S  
  5. prevlevel=N  
  6. umask 022  
  7. export PATH runlevel prevlevel  
  8.   
  9. #  
  10. #   Trap CTRL-C &c only in this shell so we can interrupt subprocesses.  
  11. #  
  12. trap ":" INT QUIT TSTP  
  13. /bin/hostname FriendlyARM  
  14.   
  15. [ -e /proc/1 ]    || /bin/mount -n -t proc  none /proc  
  16. [ -e /sys/class ] || /bin/mount -n -t sysfs none /sys  
  17. [ -e /dev/tty ]   || /bin/mount    -t ramfs none /dev  
  18. /bin/mount -n -t usbfs none /proc/bus/usb  
  19.   
  20. echo /sbin/mdev > /proc/sys/kernel/hotplug  
  21. /sbin/mdev -s  
  22. /bin/hotplug  
  23. # mounting file system specified in /etc/fstab  
  24. mkdir -p /dev/pts  
  25. mkdir -p /dev/shm  
  26. /bin/mount -n -t devpts none /dev/pts -o mode=0622  
  27. /bin/mount -n -t tmpfs tmpfs /dev/shm  
  28. /bin/mount -n -t ramfs none /tmp  
  29. /bin/mount -n -t ramfs none /var  
  30. mkdir -p /var/empty  
  31. mkdir -p /var/log  
  32. mkdir -p /var/lock  
  33. mkdir -p /var/run  
  34. mkdir -p /var/tmp  
  35.   
  36. /sbin/hwclock -s  
  37.   
  38. syslogd  
  39. /etc/rc.d/init.d/netd start  
  40. echo "                        " > /dev/tty1  
  41. echo "Starting networking..." > /dev/tty1  
  42. sleep 1  
  43. /etc/rc.d/init.d/httpd start  
  44. echo "                        " > /dev/tty1  
  45. echo "Starting web server..." > /dev/tty1  
  46. sleep 1  
  47. /etc/rc.d/init.d/leds start  
  48. echo "                        " > /dev/tty1  
  49. echo "Starting leds service..." > /dev/tty1  
  50. echo "                        "  
  51. sleep 1  
  52.   
  53. echo "                        " > /dev/tty1  
  54. /etc/rc.d/init.d/alsaconf start  
  55. echo "Loading sound card config..." > /dev/tty1  
  56. echo "                        "  
  57.   
  58. /sbin/ifconfig lo 127.0.0.1  
  59. /etc/init.d/ifconfig-eth0  
  60.   
  61. /sbin/wdt&  
  62.   
  63. /bin/qtopia &  
  64. echo "                                  " > /dev/tty1  
  65. echo "Starting Qtopia, please waiting..." > /dev/tty1  

查看进程已经运行

0 0
原创粉丝点击