详解linux 看门狗驱动编写
看门狗是linux驱动的一个重要环节。某些特殊的设备,有时候需要放在一些环境恶劣的地方,比如电信设备。但是,任何软件都不可能100%没有bug。如何保证软件在遇到严重bug、死机的时候也能正常运行呢,那么看门狗就是有效的一种方法。看门狗一般要求用户定时喂狗,如果一段时间没有喂狗的话,那么系统就会自动重启。今天,我们就来看看这个看门狗驱动怎么编写?
1、代码目录
drivers/watchdog
2、阅读目录下的Kconfig,可以找一个s3c模块macro
configHAVE_S3C2410_WATCHDOG bool help ThiswillincludewatchdogtimersupportforSamsungSoCs.If youwanttoincludewatchdogsupportforanymachine,kindly selectthisintherespectivemach-XXXX/Kconfigfile. configS3C2410_WATCHDOG tristate"S3C2410Watchdog" dependsonHAVE_S3C2410_WATCHDOG||COMPILE_TEST selectWATCHDOG_CORE selectMFD_SYSCONifARCH_EXYNOS help WatchdogtimerblockintheSamsungSoCs.Thiswillreboot thesystemwhenthetimerexpireswiththewatchdogenabled. Thedriverislimitedbythespeedofthesystem'sPCLK signal,sowithreasonablyfastsystems(PCLKaround50-66MHz) thenwatchdogintervalsofoverapproximately20secondsare unavailable. ThedrivercanbebuiltasamodulebychoosingM,andwill becalleds3c2410_wdt
3、S3C2410_WATCHDOG主要依赖WATCHDOG_CORE,可以继续跟踪Makefile
obj-$(CONFIG_S3C2410_WATCHDOG)+=s3c2410_wdt.o
4、macro只依赖一个s3c2410_wdt.c文件,继续查看
staticSIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops,s3c2410wdt_suspend, s3c2410wdt_resume); staticstructplatform_drivers3c2410wdt_driver={ .probe=s3c2410wdt_probe, .remove=s3c2410wdt_remove, .shutdown=s3c2410wdt_shutdown, .id_table=s3c2410_wdt_ids, .driver={ .name="s3c2410-wdt", .pm=&s3c2410wdt_pm_ops, .of_match_table=of_match_ptr(s3c2410_wdt_match), }, }; module_platform_driver(s3c2410wdt_driver);
5、确认driver为platform类型,继续在probe函数中查找有用的code
ret=watchdog_register_device(&wdt->wdt_device); if(ret){ dev_err(dev,"cannotregisterwatchdog(%d)\n",ret); gotoerr_cpufreq; }
6、网上继续查找,寻找到和watchdog有关的数据结构
staticconststructwatchdog_infos3c2410_wdt_ident={ .options=OPTIONS, .firmware_version=0, .identity="S3C2410Watchdog", }; staticconststructwatchdog_opss3c2410wdt_ops={ .owner=THIS_MODULE, .start=s3c2410wdt_start, .stop=s3c2410wdt_stop, .ping=s3c2410wdt_keepalive, .set_timeout=s3c2410wdt_set_heartbeat, .restart=s3c2410wdt_restart, }; staticconststructwatchdog_devices3c2410_wdd={ .info=&s3c2410_wdt_ident, .ops=&s3c2410wdt_ops, .timeout=S3C2410_WATCHDOG_DEFAULT_TIME, };
7、找到设备注册函数、函数结构基本就算结束了,当然有中断的话,也可以确认一下
ret=devm_request_irq(dev,wdt_irq->start,s3c2410wdt_irq,0, pdev->name,pdev); if(ret!=0){ dev_err(dev,"failedtoinstallirq(%d)\n",ret); gotoerr_cpufreq; }
8、有兴趣的话,可以找一个函数阅读一下。比如下面这个重启函数,可以和spec对比者来看
staticints3c2410wdt_restart(structwatchdog_device*wdd,unsignedlongaction, void*data) { structs3c2410_wdt*wdt=watchdog_get_drvdata(wdd); void__iomem*wdt_base=wdt->reg_base; /*disablewatchdog,tobesafe*/ writel(0,wdt_base+S3C2410_WTCON); /*putinitialvaluesintocountanddata*/ writel(0x80,wdt_base+S3C2410_WTCNT); writel(0x80,wdt_base+S3C2410_WTDAT); /*setthewatchdogtogoandreset...*/ writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16| S3C2410_WTCON_RSTEN|S3C2410_WTCON_PRESCALE(0x20), wdt_base+S3C2410_WTCON); /*waitforresettoassert...*/ mdelay(500); return0; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。