看门狗驱动程序

来源:互联网 发布:如何评价新东方 知乎 编辑:程序博客网 时间:2024/05/01 19:58

1. 看门狗的框架介绍

看门狗是以misc设备的模式注册到设备中的,没有像其它设备那样复杂

struct miscdevice  {int minor;                  //此设备号const char *name;           //混杂设备名字const struct file_operations *fops;                 //设备的操作函数struct list_head list;                             //指向下一个混杂设备struct device *parent;                             //指向父设备struct device *this_device;                        //指向当前设备结构体const char *nodename; mode_t mode;};static const struct file_operations s3c2410wdt_fops = {.owner= THIS_MODULE,.llseek= no_llseek,.write= s3c2410wdt_write,.unlocked_ioctl= s3c2410wdt_ioctl,.open= s3c2410wdt_open,.release= s3c2410wdt_release,};static struct miscdevice s3c2410wdt_miscdev = {.minor= WATCHDOG_MINOR,.name= "watchdog",.fops= &s3c2410wdt_fops,};
2. 看门狗的初始化

直接看s3c2410wdt_probe

static int __devinit s3c2410wdt_probe(struct platform_device *pdev){struct device *dev;unsigned int wtcon;int started = 0;int ret;int size;DBG("%s: probe=%p\n", __func__, pdev);dev = &pdev->dev;wdt_dev = &pdev->dev;/* get the memory region for the watchdog timer */wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (wdt_mem == NULL) {dev_err(dev, "no memory resource specified\n");return -ENOENT;}size = resource_size(wdt_mem);if (!request_mem_region(wdt_mem->start, size, pdev->name)) {dev_err(dev, "failed to get memory region\n");return -EBUSY;}wdt_base = ioremap(wdt_mem->start, size);if (wdt_base == NULL) {dev_err(dev, "failed to ioremap() region\n");ret = -EINVAL;goto err_req;}DBG("probe: mapped wdt_base=%p\n", wdt_base);wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);if (wdt_irq == NULL) {dev_err(dev, "no irq resource specified\n");ret = -ENOENT;goto err_map;}ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);if (ret != 0) {dev_err(dev, "failed to install irq (%d)\n", ret);goto err_map;}wdt_clock = clk_get(&pdev->dev, "watchdog");if (IS_ERR(wdt_clock)) {dev_err(dev, "failed to find watchdog clock source\n");ret = PTR_ERR(wdt_clock);goto err_irq;}clk_enable(wdt_clock);if (s3c2410wdt_cpufreq_register() < 0) {printk(KERN_ERR PFX "failed to register cpufreq\n");goto err_clk;}/* see if we can actually set the requested timer margin, and if * not, try the default value */if (s3c2410wdt_set_heartbeat(tmr_margin)) {                        //设置看门狗的复位时间started = s3c2410wdt_set_heartbeat(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);if (started == 0)dev_info(dev,   "tmr_margin value out of range, default %d used\n",       CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);elsedev_info(dev, "default timer value is out of range, ""cannot start\n");}ret = misc_register(&s3c2410wdt_miscdev);                 //注册混杂设备if (ret) {dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",WATCHDOG_MINOR, ret);goto err_cpufreq;}if (tmr_atboot && started == 0) {                             //开机时就立即启动看门狗定时器dev_info(dev, "starting watchdog timer\n");s3c2410wdt_start();} else if (!tmr_atboot) {/* if we're not enabling the watchdog, then ensure it is * disabled if it has been left running from the bootloader * or other source */s3c2410wdt_stop();}/* print out a statement of readiness */wtcon = readl(wdt_base + S3C2410_WTCON);dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", (wtcon & S3C2410_WTCON_ENABLE) ?  "" : "in", (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", (wtcon & S3C2410_WTCON_INTEN) ? "" : "en");return 0; err_cpufreq:s3c2410wdt_cpufreq_deregister(); err_clk:clk_disable(wdt_clock);clk_put(wdt_clock); err_irq:free_irq(wdt_irq->start, pdev); err_map:iounmap(wdt_base); err_req:release_mem_region(wdt_mem->start, size);wdt_mem = NULL;return ret;}
3. 看门狗的操作函数集

s3c2410wdt_open主要是调用s3c2410wdt_start启动看门狗

s3c2410wdt_release,如果允许关闭,就调用s3c2410wdt_stop关闭看门狗。如果不允许关闭,则调用s3c2410wdt_keepalive,使看门狗成为活动状态。

s3c2410wdt_write,该函数主要用来设置allow_close变量为允许关闭状态。

s3c2410wdt_irq,该中断处理函数的主要功能是喂狗操作,使看门狗重新开始计数。


0 0
原创粉丝点击