ARM-Linux驱动--Watch Dog Timer(看门狗)驱动分析
时间:11-20
来源:互联网
点击:
- //获取IO端口资源,这里IORESOURCE_MEM和平台设备中资源的定义一致
- res=platform_get_resource(pdev,IORESOURCE_MEM,0);
- if(res==NULL){
- dev_err(dev,"nomemoryresourcespecified\n");
- return-ENOENT;
- }
- size=(res->end-res->start)+1;
- //申请内存空间
- wdt_mem=request_mem_region(res->start,size,pdev->name);
- if(wdt_mem==NULL){
- dev_err(dev,"failedtogetmemoryregion\n");
- ret=-ENOENT;
- gotoerr_req;
- }
- //地址映射,wdt_base为基地址
- wdt_base=ioremap(res->start,size);
- if(wdt_base==NULL){
- dev_err(dev,"failedtoioremap()region\n");
- ret=-EINVAL;
- gotoerr_req;
- }
- DBG("probe:mappedwdt_base=%p\n",wdt_base);
- //从平台设备中获取中断号
- wdt_irq=platform_get_resource(pdev,IORESOURCE_IRQ,0);
- if(wdt_irq==NULL){
- dev_err(dev,"noirqresourcespecified\n");
- ret=-ENOENT;
- gotoerr_map;
- }
- //注册中断,中断处理函数s3c2410wdt_irq()
- ret=request_irq(wdt_irq->start,s3c2410wdt_irq,0,pdev->name,pdev);
- if(ret!=0){
- dev_err(dev,"failedtoinstallirq(%d)\n",ret);
- gotoerr_map;
- }
- //获取系统时钟
- wdt_clock=clk_get(&pdev->dev,"watchdog");
- if(IS_ERR(wdt_clock)){
- dev_err(dev,"failedtofindwatchdogclocksource\n");
- ret=PTR_ERR(wdt_clock);
- gotoerr_irq;
- }
- //使能时钟
- clk_enable(wdt_clock);
- /*seeifwecanactuallysettherequestedtimermargin,andif
- *not,trythedefaultvalue*/
- if(s3c2410wdt_set_heartbeat(tmr_margin))
- {//这里第一次设置计时周期为tmr_margin,如果设置不成功,则重新设置为默认值
- started=s3c2410wdt_set_heartbeat(
- CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
- if(started==0)
- dev_info(dev,
- "tmr_marginvalueoutofrange,default%dused\n",
- CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
- else
- dev_info(dev,"defaulttimervalueisoutofrange,cannotstart\n");
- }
- //注册设备
- ret=misc_register(&s3c2410wdt_miscdev);
- if(ret)
- {
- dev_err(dev,"cannotregistermiscdevonminor=%d(%d)\n",
- WATCHDOG_MINOR,ret);
- gotoerr_clk;
- }
- if(tmr_atboot&&started==0)
- {
- dev_info(dev,"startingwatchdogtimer\n");
- s3c2410wdt_start();//启动看门狗
- }
- elseif(!tmr_atboot)
- {
- /*ifwerenotenablingthewatchdog,thenensureitis
- *disabledifithasbeenleftrunningfromthebootloader
- *orothersource*/
- s3c2410wdt_stop();
- }
- /*printoutastatementofreadiness*/
- 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");
- //设置GPB10端口为输出端口,用于点亮LED10
- s3c2410_gpio_cfgpin(S3C2410_GPB10,S3C2410_GPB10_OUTP);
- return0;
- //出错跳转表,异常处理
- 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_resource(wdt_mem);
- kfree(wdt_mem);
- returnret;
- }
- //设备移除函数,释放资源和映射
- staticints3c2410wdt_remove(structplatform_device*dev)
- {
- release_resource(wdt_mem);
- kfree(wdt_mem);
- wdt_mem=NULL;
- free_irq(wdt_irq->start,dev);
- wdt_irq=NULL;
- clk_disable(wdt_clock);
- clk_put(wdt_clock);
- wdt_clock=NULL;
- iounmap(wdt_base);
- misc_deregister(&s3c2410wdt_miscdev);
- return0;
- }
- //关闭看门狗
- staticvoids3c2410wdt_shutdown(structplatform_device*dev)
- {
- s3c2410wdt_stop();
- }
- //定义平台设备驱动
- staticstructplatform_drivers3c2410wdt_driver={
- .probe=s3c2410wdt_probe,
- .remove=s3c2410wdt_remove,
- .shutdown=s3c2410wdt_shutdown,
- .driver={
- .owner=THIS_MODULE,
- .name="s3c2410-wdt",//该名称参照内核源码中该资源的名称,两者必须一致
- },
- };
- staticcharbanner[]__initdata=
- KERN_INFO"S3C2410WatchdogTimer,(c)2004SimtecElectronics\n";
- //驱动安装时执行
- staticint__initwatchdog_init(void)
- {
- printk(banner);
- returnplatform_driver_register(&s3c2410wdt_driver);//注册设备
- }
- //驱动移除是执行
- staticvoid__exitwatchdog_exit(void)
- {
- platform_driver_unregister(&s3c2410wdt_driver);//移除设备
- }
- module_init(watchdog_init);
- module_exit(watchdog_exit);
- MODULE_AUTHOR("YanMing");
- MODULE_DESCRIPTION("S3C2410WatchdogDeviceDriver");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
设置默认不是重启机器,而是执行中断函数,当不喂狗,计数器减到0,点亮LED,然后喂狗,重新计数。
ARMLinux驱动看门 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)