S3C2440驱动篇—看门狗驱动分析
时间:11-19
来源:互联网
点击:
定时器中断里面不断的在“喂狗”。后来想想,这里还必须要“喂狗”一次,因为当上面我们判断到写入的数据是"V"时,看门狗定时器的当前操作状态马上被设置为关闭,再当驱动去调用看门狗设备驱动的关闭接口函数时,看门狗定时器中断被禁止,无法再实现“喂狗”,所以这里要手动“喂狗”一次,否则定时器溢出系统被复位*/s3c2410wdt_keepalive();}return len;}#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)/*用于支持看门狗IO控制中获取看门狗信息的命令WDIOC_GETSUPPORT,下面的宏和看门狗信息结构体定义在include/linux/watchdog.h中*/static const struct watchdog_info s3c2410_wdt_ident = {.options = OPTIONS,.firmware_version = 0,.identity = "S3C2410 Watchdog",};static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd,unsigned long arg){void __user *argp = (void __user *)arg;int __user *p = argp;int new_margin;/*以下对看门狗定时器IO控制的命令定义在watchdog.h中*/switch (cmd) {case WDIOC_GETSUPPORT:/*获取看门狗的支持信息,wdt_ident定义在上面*/return copy_to_user(argp, &s3c2410_wdt_ident,sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;case WDIOC_GETSTATUS:case WDIOC_GETBOOTSTATUS:return put_user(0, p);case WDIOC_KEEPALIVE:s3c2410wdt_keepalive();return 0;case WDIOC_SETTIMEOUT:if (get_user(new_margin, p))return -EFAULT;if (s3c2410wdt_set_heartbeat(new_margin))return -EINVAL;s3c2410wdt_keepalive();return put_user(tmr_margin, p);case WDIOC_GETTIMEOUT:return put_user(tmr_margin, p);default:return -ENOTTY;}}/* kernel interface */static const struct file_operations s3c2410wdt_fops = {.owner = THIS_MODULE,.llseek = no_llseek, /*定义为不可定位,即屏蔽seek操作,no_llseek定义在fs.h中*/.write = s3c2410wdt_write,.unlocked_ioctl = s3c2410wdt_ioctl,.open = s3c2410wdt_open,.release = s3c2410wdt_release,};static struct miscdevice s3c2410wdt_miscdev = {.minor = WATCHDOG_MINOR, //位于include/linux/miscdevic.h中.name = "watchdog",.fops = &s3c2410wdt_fops,};/* interrupt handler code */static irqreturn_t s3c2410wdt_irq(int irqno, void *param){dev_info(wdt_dev, "watchdog timer expired (irq)\n");s3c2410wdt_keepalive();return IRQ_HANDLED;}/* device interface */static int __devinit s3c2410wdt_probe(struct platform_device *pdev){struct resource *res; /*定义一个资源,用来保存获取的watchdog的IO资源*/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 */res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (res == NULL) {/*dev_err定义在device.h中,在platform_device.h中已经引用,所以这里就不需再引用*/dev_err(dev, "no memory resource specified\n");return -ENOENT;}size = (res->end - res->start) + 1;/*申请watchdog的IO端口资源所占用的IO内存,request_mem_region定义在ioport.h中*/wdt_mem = request_mem_region(res->start, size, pdev->name);if (wdt_mem == NULL) {dev_err(dev, "failed to get memory region\n");ret = -ENOENT;goto err_req;}wdt_base = ioremap(res->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;}/*定义在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/wdt_clock = clk_get(&pdev->dev, "watchdog");if (IS_ERR(wdt_clock)) {dev_err(dev, "failed to find watchdog clock sourc
S3C2440看门狗驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)