详解linux 看门狗驱动编写
<p>看门狗是linux驱动的一个重要环节。某些特殊的设备,有时候需要放在一些环境恶劣的地方,比如电信设备。但是,任何软件都不可能100%没有bug。如何保证软件在遇到严重bug、死机的时候也能正常运行呢,那么看门狗就是有效的一种方法。看门狗一般要求用户定时喂狗,如果一段时间没有喂狗的话,那么系统就会自动重启。今天,我们就来看看这个看门狗驱动怎么编写?</p>
<p>
1、代码目录</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_776754">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">drivers/watchdog</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
2、阅读目录下的Kconfig,可以找一个s3c模块macro</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_32570">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">config HAVE_S3C2410_WATCHDOG </code>
</div>
<div class="line number2 index1 alt1">
<code class="plain spaces"> </code><code class="plain plain">bool </code>
</div>
<div class="line number3 index2 alt2">
<code class="plain spaces"> </code><code class="plain plain">help </code>
</div>
<div class="line number4 index3 alt1">
<code class="plain spaces"> </code><code class="plain plain">This will include watchdog timer support for Samsung SoCs. If </code>
</div>
<div class="line number5 index4 alt2">
<code class="plain spaces"> </code><code class="plain plain">you want to include watchdog support for any machine, kindly </code>
</div>
<div class="line number6 index5 alt1">
<code class="plain spaces"> </code><code class="plain plain">select this in the respective mach-XXXX/Kconfig file. </code>
</div>
<div class="line number7 index6 alt2">
<code class="plain spaces"> </code>
</div>
<div class="line number8 index7 alt1">
<code class="plain plain">config S3C2410_WATCHDOG </code>
</div>
<div class="line number9 index8 alt2">
<code class="plain spaces"> </code><code class="plain plain">tristate "S3C2410 Watchdog" </code>
</div>
<div class="line number10 index9 alt1">
<code class="plain spaces"> </code><code class="plain plain">depends on HAVE_S3C2410_WATCHDOG || COMPILE_TEST </code>
</div>
<div class="line number11 index10 alt2">
<code class="plain spaces"> </code><code class="plain plain">select WATCHDOG_CORE </code>
</div>
<div class="line number12 index11 alt1">
<code class="plain spaces"> </code><code class="plain plain">select MFD_SYSCON if ARCH_EXYNOS </code>
</div>
<div class="line number13 index12 alt2">
<code class="plain spaces"> </code><code class="plain plain">help </code>
</div>
<div class="line number14 index13 alt1">
<code class="plain spaces"> </code><code class="plain plain">Watchdog timer block in the Samsung SoCs. This will reboot </code>
</div>
<div class="line number15 index14 alt2">
<code class="plain spaces"> </code><code class="plain plain">the system when the timer expires with the watchdog enabled. </code>
</div>
<div class="line number16 index15 alt1">
<code class="plain spaces"> </code>
</div>
<div class="line number17 index16 alt2">
<code class="plain spaces"> </code><code class="plain plain">The driver is limited by the speed of the system's PCLK </code>
</div>
<div class="line number18 index17 alt1">
<code class="plain spaces"> </code><code class="plain plain">signal, so with reasonably fast systems (PCLK around 50-66MHz) </code>
</div>
<div class="line number19 index18 alt2">
<code class="plain spaces"> </code><code class="plain plain">then watchdog intervals of over approximately 20seconds are </code>
</div>
<div class="line number20 index19 alt1">
<code class="plain spaces"> </code><code class="plain plain">unavailable. </code>
</div>
<div class="line number21 index20 alt2">
<code class="plain spaces"> </code>
</div>
<div class="line number22 index21 alt1">
<code class="plain spaces"> </code><code class="plain plain">The driver can be built as a module by choosing M, and will </code>
</div>
<div class="line number23 index22 alt2">
<code class="plain spaces"> </code><code class="plain plain">be called s3c2410_wdt </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
3、S3C2410_WATCHDOG主要依赖WATCHDOG_CORE,可以继续跟踪Makefile</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_270351">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
4、macro只依赖一个s3c2410_wdt.c文件,继续查看</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_960929">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">static</code> <code class="cpp plain">SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend, </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">s3c2410wdt_resume); </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp keyword bold">static</code> <code class="cpp keyword bold">struct</code> <code class="cpp plain">platform_driver s3c2410wdt_driver = { </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.probe = s3c2410wdt_probe, </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.</code><code class="cpp functions bold">remove</code> <code class="cpp plain">= s3c2410wdt_remove, </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.shutdown = s3c2410wdt_shutdown, </code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.id_table = s3c2410_wdt_ids, </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.driver = { </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.name = </code><code class="cpp string">"s3c2410-wdt"</code><code class="cpp plain">, </code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.pm = &s3c2410wdt_pm_ops, </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.of_match_table = of_match_ptr(s3c2410_wdt_match), </code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">}, </code>
</div>
<div class="line number14 index13 alt1">
<code class="cpp plain">}; </code>
</div>
<div class="line number15 index14 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number16 index15 alt1">
<code class="cpp plain">module_platform_driver(s3c2410wdt_driver);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
5、确认driver为platform类型,继续在probe函数中查找有用的code</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_836115">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">ret = watchdog_register_device(&wdt->wdt_device); </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp keyword bold">if</code> <code class="cpp plain">(ret) { </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">dev_err(dev, </code><code class="cpp string">"cannot register watchdog (%d)\n"</code><code class="cpp plain">, ret); </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">goto</code> <code class="cpp plain">err_cpufreq; </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp plain">} </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
6、网上继续查找,寻找到和watchdog有关的数据结构</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_382336">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">static</code> <code class="cpp keyword bold">const</code> <code class="cpp keyword bold">struct</code> <code class="cpp plain">watchdog_info s3c2410_wdt_ident = { </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.options = OPTIONS, </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.firmware_version = 0, </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.identity = </code><code class="cpp string">"S3C2410 Watchdog"</code><code class="cpp plain">, </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp plain">}; </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp spaces"> </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp keyword bold">static</code> <code class="cpp keyword bold">const</code> <code class="cpp keyword bold">struct</code> <code class="cpp plain">watchdog_ops s3c2410wdt_ops = { </code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.owner = THIS_MODULE, </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.start = s3c2410wdt_start, </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.stop = s3c2410wdt_stop, </code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.ping = s3c2410wdt_keepalive, </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.set_timeout = s3c2410wdt_set_heartbeat, </code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.restart = s3c2410wdt_restart, </code>
</div>
<div class="line number14 index13 alt1">
<code class="cpp plain">}; </code>
</div>
<div class="line number15 index14 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number16 index15 alt1">
<code class="cpp keyword bold">static</code> <code class="cpp keyword bold">const</code> <code class="cpp keyword bold">struct</code> <code class="cpp plain">watchdog_device s3c2410_wdd = { </code>
</div>
<div class="line number17 index16 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.info = &s3c2410_wdt_ident, </code>
</div>
<div class="line number18 index17 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.ops = &s3c2410wdt_ops, </code>
</div>
<div class="line number19 index18 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.timeout = S3C2410_WATCHDOG_DEFAULT_TIME, </code>
</div>
<div class="line number20 index19 alt1">
<code class="cpp plain">}; </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
7、找到设备注册函数、函数结构基本就算结束了,当然有中断的话,也可以确认一下</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_513065">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">ret = devm_request_irq(dev, wdt_irq->start, s3c2410wdt_irq, 0, </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">pdev->name, pdev); </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp keyword bold">if</code> <code class="cpp plain">(ret != 0) { </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">dev_err(dev, </code><code class="cpp string">"failed to install irq (%d)\n"</code><code class="cpp plain">, ret); </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">goto</code> <code class="cpp plain">err_cpufreq; </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp plain">} </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
8、有兴趣的话,可以找一个函数阅读一下。比如下面这个重启函数,可以和spec对比者来看</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_746253">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">static</code> <code class="cpp color1 bold">int</code> <code class="cpp plain">s3c2410wdt_restart(</code><code class="cpp keyword bold">struct</code> <code class="cpp plain">watchdog_device *wdd, unsigned </code><code class="cpp color1 bold">long</code> <code class="cpp plain">action, </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">void</code> <code class="cpp plain">*data) </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp plain">{ </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">void</code> <code class="cpp plain">__iomem *wdt_base = wdt->reg_base; </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp spaces"> </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp spaces"> </code><code class="cpp comments">/* disable watchdog, to be safe */</code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">writel(0, wdt_base + S3C2410_WTCON); </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp comments">/* put initial values into count and data */</code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">writel(0x80, wdt_base + S3C2410_WTCNT); </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">writel(0x80, wdt_base + S3C2410_WTDAT); </code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number14 index13 alt1">
<code class="cpp spaces"> </code><code class="cpp comments">/* set the watchdog to go and reset... */</code>
</div>
<div class="line number15 index14 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 | </code>
</div>
<div class="line number16 index15 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20), </code>
</div>
<div class="line number17 index16 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">wdt_base + S3C2410_WTCON); </code>
</div>
<div class="line number18 index17 alt1">
<code class="cpp spaces"> </code>
</div>
<div class="line number19 index18 alt2">
<code class="cpp spaces"> </code><code class="cpp comments">/* wait for reset to assert... */</code>
</div>
<div class="line number20 index19 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">mdelay(500); </code>
</div>
<div class="line number21 index20 alt2">
<code class="cpp spaces"> </code>
</div>
<div class="line number22 index21 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0; </code>
</div>
<div class="line number23 index22 alt2">
<code class="cpp plain">} </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。</p>
<p>
原文链接:https://blog.csdn.net/feixiaoxing/article/details/79874642</p>
頁:
[1]