简单谈谈Linux内核定时器
<p>软件意义上的定时器最终依赖硬件定时器来实现, 内核在时钟中断发生后检测各定时器是否到期 , 到期后的定时器处理函数将作为软中断在底半部执行 。实质上,时钟中断处理程序会 换起TIMER_SOFTIRQ软中断 ,运行当前处理器上到期的所有定时器。</p>
<p>
总结起来还是软中断的流程</p>
<p>
a.注册软中断处理函数</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_793841">
<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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp comments">/*/linux/kernel.timer.c*/</code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp keyword bold">void</code> <code class="cpp plain">__init init_timers(</code><code class="cpp keyword bold">void</code><code class="cpp plain">)</code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">-->open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
b.添加timer_list到某个链表</p>
<p>
<code>void add_timer (struct timer_list *timer);</code></p>
<p>
c.触发软中断处理函数</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_644044">
<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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">void</code> <code class="cpp plain">irq_exit(</code><code class="cpp keyword bold">void</code><code class="cpp plain">)</code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">-->tick_nohz_stop_sched_tick();</code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">-->raise_softirq_irqoff(TIMER_SOFTIRQ);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
d.调用软中断处理函数</p>
<p>
static void run_timer_softirq(struct softirq_action *h)<br>
-->__run_timers(base);<br>
-->遍历执行时间到达的timer_list中的定时器处理函数<br>
在Linux设备驱动编程中,可以利用Linux内核中提供的一组函数和数据结构来完成定时触发工作或者完成某种周期性的事务。这组函数和数据结构使得驱动程序师在多数情况下不用关心具体的软件定时器究竟对应着怎样的内核和硬件行为。</p>
<p>
1) 一个timer_list 结构体的实例对应一个定时器,其定义如下:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_813820">
<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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">struct</code> <code class="cpp plain">timer_list {</code>
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
<code class="cpp plain"> </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">list_head entry, </code><code class="cpp comments">/*定时器列表*/</code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp plain"> unsigned </code><code class="cpp color1 bold">long</code> <code class="cpp plain">expires, </code><code class="cpp comments">/*定时器到期时间*/</code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp plain"> </code><code class="cpp keyword bold">void</code> <code class="cpp plain">(*function) (unsigned </code><code class="cpp color1 bold">long</code><code class="cpp plain">), </code><code class="cpp comments">/*定时器处理函数*/</code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp plain"> unsigned </code><code class="cpp color1 bold">long</code> <code class="cpp plain">data,</code><code class="cpp comments">/*作为参数被传入定时器处理函数*/</code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp plain"> </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">timer_base_s *base,</code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp plain"> ...</code>
</div>
<div class="line number9 index8 alt2">
</div>
<div class="line number10 index9 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>
实例化 struct timer_list my_timer;</p>
<p>
2) 初始化定时器</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_193958">
<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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">void</code> <code class="cpp plain">init_timer (</code><code class="cpp keyword bold">struct</code> <code class="cpp plain">timer_list *timer);</code>
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
<code class="cpp plain">TIMER_INITIALIZER (_function, _expires, _data)</code>
</div>
<div class="line number4 index3 alt1">
</div>
<div class="line number5 index4 alt2">
<code class="cpp plain">DEFINE_TIMER (_name, _function, _expires, _data)</code>
</div>
<div class="line number6 index5 alt1">
</div>
<div class="line number7 index6 alt2">
<code class="cpp plain">setup_timer ();</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) 增加定时器</p>
<p>
<code>void add_timer (struct timer_list *timer);</code></p>
<p>
4) 删除定时器</p>
<p>
<code>int del_timer (struct timer_list *timer);</code></p>
<p>
5) 修改定时器的expire</p>
<p>
<code>int mod_timer (struct timer_list *timer, unsigned long expires);</code></p>
<p>
<code>原文链接:http://www.linuxidc.com/Linux/2017-10/147463.htm</code></p>
頁:
[1]