• 十四、【watchdog】看门狗


                       6818看门狗定时器框图

      由上图可知PCLK经过8bit分频器分频然后再经过最高1/128的分频就是看门狗定时器的时钟频率,8bit最大分频系数为255,t_watchdog=200M/(255+1)/128=6103HZ.所以最小频率为6103HZ.

    如果我们想要实现10s不喂狗就产生复位信号的功能,那WTCNT(计数器)的值设定为10*6103=61030 ,十六进制为0xEE66.当在10s内不喂狗,当WTCNT减到0(即10s后)产生复位信号,系统复位。

    1、代码编写

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/cdev.h>
    #include <linux/fs.h>
    #include <linux/types.h>
    #include <linux/device.h>
    #include <linux/ioport.h>
    #include <linux/io.h>
    #include <linux/uaccess.h>
    #include <linux/gpio.h>
    #include <cfg_type.h>
    #include <linux/ioctl.h>
    #include <linux/miscdevice.h>
    #include <linux/delay.h>
    
    #include <mach/platform.h>
    #include <mach/devices.h>
    #include <mach/soc.h>
    #include <linux/clk.h>
    //提供三个命令字,启动、停止、喂狗
    #define  WDT_START _IO('W', 0)
    #define  WDT_STOP   _IO('W', 1)
    #define  WDT_FEED   _IO('W', 2)
    
    //IO内存的静态映射
    #define WTREG(x) ((x) + IO_ADDRESS(PHY_BASEADDR_WDT))
    
    #define WTCON      		WTREG(0x00)
    #define WTDAT     		WTREG(0x04)
    #define WTCNT      		WTREG(0x08)
    #define WTCLRINT   		WTREG(0x0C)
    
    static long wdt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    {
    
    	switch(cmd)
    	{
    		case WDT_START:
    			writel(( readl(WTCON)|(1<<5)|(1<<2)|(1<<0) ),WTCON);
    		break;
    		case WDT_STOP:
    			writel(( readl(WTCON)&(~((1<<5)|(1<<2)|(1<<0))) ),WTCON);
    		break;
    		case WDT_FEED:
    			writel(0xEE66,WTCNT);
    		break;
    		default:
    			return -ENOIOCTLCMD;
    	}
    
    	return 0;
    }
    	
    //定义文件操作集合结构体
    static struct file_operations  wdt_misc_fops = 
    {
    	//.open = wdt_open,//操作集合中没有提供.open和.release
    	//.release = wdt_close,//使用系统默认的,其它操作函数没有默认
    	.unlocked_ioctl = wdt_ioctl,
    };
    
    
    static struct miscdevice wdt_misc= //定义杂项字符设备
    {
    	.minor = MISC_DYNAMIC_MINOR,//让内核动态分配次设备号
    	.name = "wdt_misc",//设备名,也是设备文件名
    	.fops = &wdt_misc_fops,
    };
    
    
    //入口函数
    static int  __init wdt_init (void)
    {
    	int ret;
    	printk("<1>""wdt_init\n");
    
    	//注册杂项设备
    	ret = misc_register(&wdt_misc);
    	if(ret < 0)
    	{
    		printk(KERN_ALERT"misc_register fail\n");
    		goto misc_register_err;
    	}
    	printk("<1>""misc_register OK\n");
    
    
    	//复位WDT
    	nxp_soc_peri_reset_set(RESET_ID_WDT);
    	nxp_soc_peri_reset_set(RESET_ID_WDT_POR);
    	
    	//通过虚拟地址设置寄存器
    	writel( 0, WTCON);//
    	
    	writel( ( readl(WTCON)|(3<<3) ), WTCON);//再分频参数 11b = 128
    	writel( ( (readl(WTCON) & (~(0xff<<8))) | (255<<8)  ), WTCON);//预分频参数255
    	writel( 0xEE66, WTDAT);//10S对应的计数值
    	writel( 0xEE66, WTCNT);//10S对应的计数值
    	writel( 0, WTCLRINT);
    	printk("<1>""wdt_init OK\n");
    
    	return 0;
    
    
    misc_register_err:
    	return ret;
    
    
    }
    
    //出口函数
    static void __exit wdt_exit(void)
    {
    
    	printk(KERN_ALERT"wdt_exit\n");
    
    	//注销杂项设备
    	misc_deregister(&wdt_misc);
    }
    
    
    module_init(wdt_init);
    module_exit(wdt_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("XLG");
    MODULE_DESCRIPTION("first chardev drv");  

    main.c

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdio.h>
    #include <sys/ioctl.h>
    
    #define  WDT_START _IO('W', 0)
    #define  WDT_STOP   _IO('W', 1)
    #define  WDT_FEED   _IO('W', 2)
    
    
    int main(void)
    {
    	int digtal = 0;
    	int ret,i;
    	int fd = open("/dev/wdt_misc",O_RDWR);
    	if(fd < 0)
    	{
    		perror("open failed");
    		return -1;
    	}
    
    	ret = ioctl(fd,WDT_START);
    	if(ret < 0)
    	{
    		perror("ioctl failed");
    		return ret;
    	}
    	
    	i = 0;
    	
    	while(1)
    	{
    		
    		sleep(8);
    		printf("%d seconds\n",++i*8);
    		ioctl(fd,WDT_FEED);   //喂狗
    	}
       ioctl(fd,WDT_STOP);   
    	close(fd);
    	
    	return 0;
    
    }
    

      

      

  • 相关阅读:
    iozone的三大神器之一fileop
    nginx反向代理配置相对路径
    自建yum源解决Ceph搭建过程中从官网取包慢的问题
    SourceInsight 4重启之后文件变只读无法编辑
    Android应用启动时Activity被创建两次
    mfscli的使用方法(解决mfscgi响应慢的问题)
    漫谈moosefs中cgi各项的意义
    Linux stress CPU的测试方法
    磁盘测试工具FIO工具安装和使用方法
    iperf测试工具
  • 原文地址:https://www.cnblogs.com/yuanqiangfei/p/15733241.html
Copyright © 2020-2023  润新知