欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > linux驱动学习(十一)之看门狗

linux驱动学习(十一)之看门狗

2024/11/18 20:18:44 来源:https://blog.csdn.net/ckg3824278/article/details/139632660  浏览:    关键词:linux驱动学习(十一)之看门狗

需要板子一起学习的可以这里购买(含资料):点击跳转

一、看门狗定时器功能

1、产生复位信号:当系统受到由于噪声或者干扰而造成系统死机,看门狗产生一个复位信号。

2、普通定时器:16bits定时器,产生周期性的中断信号

二、看门狗系统框图

设置计数值以每隔10S就会产生一个复位信号:

第一分频值:PCLK/256 ---> 255+1 ---->781250
第二次分频值:128 ----> 781250/128 -->6103
计数值:6103 * 10 ---> 61030 不能大于 65536(0-65535) 16bits

三、看门狗定时器相关的寄存器

1、WTCON(控制寄存器)

2、WTDAT(数据寄存器)

3、WTCNT(计数寄存器)

4、WTCLRINT(清中断寄存器)

四、编程

#define WDT_START  _IO('W',0)
#define WDT_KEEPALIVE  _IO('W',1)
#define WDT_STOP  _IO('W',2)static struct resource *gec6818_wdt_res = NULL;
static void __iomem *wdt_va_base = NULL; 
static void __iomem *wdt_va_con = NULL;//WDTCON  0XC0019000
static void __iomem *wdt_va_dat = NULL; //WDTDAT 0XC0019004
static void __iomem *wdt_va_cnt = NULL; //WDTCNT 0XC0019008
static void __iomem *wdt_va_clrint = NULL; //WTCLRINT 0XC001900C
static struct clk	*wdt_clock;
static unsigned long wdt_freq;long gec6818_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long args)
{printk("gec6818_wdt_ioctl\n");switch(cmd){case WDT_START:printk("WDT_START\n");*(unsigned int*)wdt_va_con = (255<<8) | (3<<3) | (1<<2) | (1<<0);  //[15:8] [4:3] [2] [0]*(unsigned int*)wdt_va_con |= (1<<5); //开启看门狗功能break;case WDT_KEEPALIVE:*(unsigned int*)wdt_va_cnt = 0XEE66;break;case WDT_STOP:*(unsigned int*)wdt_va_cnt = 0;break;	default:return -ENOIOCTLCMD;/* No ioctl command */break;}return 0;
}//[2]
static struct file_operations gec6818_wdt_ops = {.owner = THIS_MODULE,.open = gec6818_wdt_open,.unlocked_ioctl = gec6818_wdt_ioctl,.release = gec6818_wdt_release,//当应用程序调用close时,执行驱动程序中的接口函数
};//[1] 定义混杂设备
static struct miscdevice wdt_misc = {.name = "wdt_drv",  //设备文件的名字.fops = &gec6818_wdt_ops,.minor = MISC_DYNAMIC_MINOR, //设置次设备号,MISC_DYNAMIC_MINOR --- 表示由系统动态分配一个次设备号
};
static int __init gec6818wdt_init(void) //执行insmod执行一次
{int ret;// char temp;printk("gec6818wdt_init\n");//[3] 注册混杂设备ret = misc_register(&wdt_misc);if(ret < 0){printk("misc_register error\n");ret = -EBUSY;goto misc_register_error;}//申请物理内存区gec6818_wdt_res = request_mem_region(0XC0019000,0x1000,"WDTC_MEM");if(gec6818_wdt_res == NULL){printk("request_mem_region error\n");ret = -EBUSY;goto request_mem_region_error;}//动态映射wdt_va_base = ioremap(0XC0019000,0x1000);if(wdt_va_base == NULL){printk("ioremap error\n");ret = -EFAULT;goto ioremap_error;}wdt_va_con = wdt_va_base + 0x00;wdt_va_dat = wdt_va_base + 0x04;wdt_va_cnt = wdt_va_base + 0x08;wdt_va_clrint = wdt_va_base + 0x0C;/***************给程序设置时钟源*********************/wdt_clock = clk_get(NULL, "pclk");if (IS_ERR(wdt_clock)) {ret = PTR_ERR(wdt_clock);goto err_map;}clk_enable(wdt_clock);wdt_freq = clk_get_rate(wdt_clock);printk("wdt_freq = %luHz\n",wdt_freq);nxp_soc_peri_reset_set(RESET_ID_WDT);nxp_soc_peri_reset_set(RESET_ID_WDT_POR);/**********************************************///给对应寄存器进行初始化*(unsigned int*)wdt_va_con = 0; //默认看门狗关闭*(unsigned int*)wdt_va_dat = 0XEE66;//61030 ---> *(unsigned int*)wdt_va_cnt = 0XEE66;*(unsigned int*)wdt_va_clrint = 0;return 0;err_map:ioremap_error:release_mem_region(0XC0019000,0x1000);gec6818_wdt_res = NULL;request_mem_region_error:misc_deregister(&wdt_misc);misc_register_error:return ret;	
}

觉得有帮助的话,打赏一下呗。。

           

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com