基于linux构建无人值守系统(看门狗)
2012-11-15 19:02
375 查看
菜鸟心得,高手路过。。。
在各种嵌入式设备soc中基本都提供了看门狗,在很长一段时间里我对看门狗的理解就是“关掉它,不然它会找麻烦”。但是当某种需求存在的时候,它又是必不可少的,比如你的产品是一个类似路由器的服务设备,可能在阳台的某刻角落一丢就是好几年,虽然孤独听起来让人伤感,可是如果在孤独中死去,那就会给客户带来更大的烦恼。所以我们应该去了解它
讲解中使用的环境主要基于linux系统,设备是arm s3c6410
首先对模块进行初始化
module_init(modinit);
module_exit(modexit);
从平台中通过文件名"s3c2410-wdt"找出设备,回调wdt_probe
当然你的确定arch/arm/mach-s3c64xx/mach-s3c6410的static struct platform_device *smdk6410_devices[] __initdata中找到&s3c_device_wdt,,如果没有,看看arch/arm/plat-samsung/中有没有dev-wdt.c文件搞到里面的platform_device对象,添加到__initdata中
在各种嵌入式设备soc中基本都提供了看门狗,在很长一段时间里我对看门狗的理解就是“关掉它,不然它会找麻烦”。但是当某种需求存在的时候,它又是必不可少的,比如你的产品是一个类似路由器的服务设备,可能在阳台的某刻角落一丢就是好几年,虽然孤独听起来让人伤感,可是如果在孤独中死去,那就会给客户带来更大的烦恼。所以我们应该去了解它
讲解中使用的环境主要基于linux系统,设备是arm s3c6410
#include <linux/io.h> #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/clk.h> static int wdt_probe(struct platform_device * dev); static int wdt_remove(struct platform_device * dev); struct wdt_driver { struct platform_driver pdrv; unsigned long phys_regs; unsigned long phys_regs_len; struct timer_list timer; int irq; void * regs; }; static struct wdt_driver wdtdrv = { .pdrv = { .probe = wdt_probe, .remove = wdt_remove, .driver = { .name = "s3c2410-wdt", .owner = THIS_MODULE, }, }, }; irqreturn_t wdt_irq(int irq,void * data) { struct wdt_driver * wdtdrv = data; iowrite32(1,wdtdrv->regs+0xc); printk("wdt_irq\n"); return IRQ_HANDLED; } void wdt_timeout(unsigned long data) {//喂狗 struct wdt_driver * wdtdrv = (void *)data; //printk("wdt_timeout\n"); iowrite32(3764,wdtdrv->regs+8); mod_timer(&wdtdrv->timer,jiffies+HZ/2); } //pclk 66500000 static int wdt_init(struct wdt_driver * wdtdrv) { iowrite32(3764,wdtdrv->regs+4); iowrite32(3764,wdtdrv->regs+8); //狗中断 //iowrite32(0x80<<8|0x1<<5|0x1<<2|0x3<<3,wdtdrv->regs); //狗reset iowrite32(0x80<<8|0x1<<5|0x3<<3|1,wdtdrv->regs); printk("WTCON=%x\n",ioread32(wdtdrv->regs)); printk("WTDAT=%x\n",ioread32(wdtdrv->regs+4)); printk("WTCNT=%x\n",ioread32(wdtdrv->regs+8)); //启动喂狗定时器 setup_timer(&wdtdrv->timer, wdt_timeout,(unsigned long)wdtdrv); mod_timer(&wdtdrv->timer,jiffies+HZ/2); //狗超时中断 // if(!request_irq(wdtdrv->irq,wdt_irq,IRQF_TRIGGER_FALLING,"wdt",wdtdrv)) // goto err_timer; return 0; } static int wdt_destroy(struct wdt_driver * wdtdrv) { //狗timer停止运行 iowrite32(0x80<<8|0<<5|0x3<<3|1,wdtdrv->regs); //启动喂狗定时器 del_timer(&wdtdrv->timer); //狗超时中断 //free_irq(wdtdrv->irq,(unsigned long)wdtdrv); return 0; } static int wdt_probe(struct platform_device * dev) { struct wdt_driver * wdtdrv; struct resource * res; printk("wdt_probe:%s\n",dev->name); wdtdrv = container_of(container_of(dev->dev.driver,struct platform_driver,driver),struct wdt_driver,pdrv); //获取控制器寄存器地址 res = platform_get_resource(dev,IORESOURCE_MEM,0); if(!res) goto err_out; wdtdrv->phys_regs = res->start; wdtdrv->phys_regs_len = res->end-res->start; wdtdrv->regs = ioremap(wdtdrv->phys_regs,wdtdrv->phys_regs_len); if(!wdtdrv->regs) goto err_out; if(!request_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len,dev_name(&dev->dev))) goto err_ioremap; //获取中断 wdtdrv->irq = platform_get_irq(dev,0); if(wdtdrv->irq<0) goto err_request_mem; printk("irq=%d\n",wdtdrv->irq); wdt_init(wdtdrv); return 0; err_request_mem: release_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len); err_ioremap: iounmap(wdtdrv->regs); err_out: return -1; } static int wdt_remove(struct platform_device * dev) { struct wdt_driver * wdtdrv; printk("wdt_remove:%s\n",dev->name); wdtdrv = container_of(container_of(dev->dev.driver,struct platform_driver,driver),struct wdt_driver,pdrv); wdt_destroy(wdtdrv); release_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len); iounmap(wdtdrv->regs); return 0; } static int modinit(void) { printk("mod init\n"); platform_driver_register(&wdtdrv.pdrv); return 0; } static void modexit(void) { platform_driver_unregister(&wdtdrv.pdrv); printk("mod exit\n"); } module_init(modinit); module_exit(modexit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("dragon101788");
首先对模块进行初始化
module_init(modinit);
module_exit(modexit);
从平台中通过文件名"s3c2410-wdt"找出设备,回调wdt_probe
当然你的确定arch/arm/mach-s3c64xx/mach-s3c6410的static struct platform_device *smdk6410_devices[] __initdata中找到&s3c_device_wdt,,如果没有,看看arch/arm/plat-samsung/中有没有dev-wdt.c文件搞到里面的platform_device对象,添加到__initdata中
相关文章推荐
- 基于 SquashFS 构建 Linux 可读写文件系统
- 基于 SquashFS 构建 Linux 可读写文件系统
- 无人值守自动安装linux系统
- 基于Linux的嵌入式文件系统构建与设计
- 基于busybox构建最小linux Docker镜像系统
- 基于 SquashFS 构建 Linux 可读写文件系统
- 无人值守网络安装Linux系统
- 基于AT91SAM9G20构建嵌入式Linux系统
- 基于AT91SAM9G20构建嵌入式Linux系统
- pxe无人值守linux系统安装
- 基于 SquashFS 构建 Linux 可读写文件系统
- 基于 SquashFS 构建 Linux 可读写文件系统
- 无人值守自动化安装linux系统
- Linux学习日志day1——无人值守系统安装DHCP+TFTP+PXE+Kickstar 推荐
- 基于 SquashFS 构建 Linux 可读写文件系统
- 无人值守网络安装Linux系统—pxe
- 基于LINUX系统来构建DNS服务
- 用EP9315构建基于嵌入式Linux的NAS系统平台
- 基于S3C2410的嵌入式Linux系统构建
- 使用 Ansible 在树莓派上构建一个基于 Linux 的高性能计算系统 | Linux 中国