linux内核中断和定时器

中断(IRQ)和计时器(timer)
----------------------------


中断(IRQ)和计时器(timer)是不是内核的标准工作组件呢?当然是的。为什么不将其
和内核的其他组件放在一起来讨论呢?因为我觉得中断和计时器比起其他的组件更特殊。

首先,这两者都是比较偏向于内核的底层,更直接的与硬件接触,也就是说他们更依赖于
CPU,比如CPU周围通过总线交互的一些外设(键盘,鼠标...)都是通过硬中断实现的。
其次,内核的其他组件基本上都要依赖于这两个组件,比如像进程管理,驱动程序开发等
等这样的内核组件都依赖这两个组件。


中断(IRQ)
-----------


两种类型的中断:硬件中断和软中断。

硬件中断(hardware interrupt):由系统自身和与之连接的外设自动产生。他们用于支
持更高效地实现设备驱动程序,也用于引起处理器自身对异常或错误的关注,这些是需要
与内核代码进行交互的。
与内核的其他部分相比,用于处理中断和系统调用相关部分的代码中,汇编和C代码交织
在一起,以解决C语言无法独立处理的一些微妙问题。在内核的中断部分中,高层代码和
底层的硬件交互代码,已经尽可能有效而干净地分隔开了。

软中断(SoftIRQ):用于有效实现内核中的延期操作。
内核中经常需要一些机制,将某些活动延迟到未来的某个时间执行,或将活动置于某个队
列(tasklet)上,在时间充裕时进行后续处理。


在linux中有一个用于中断和IRQ的通用框架,linux所支持的各种平台只负责在最低层次
上与硬件交互。所有其他功能都由通用代码提供。

硬件中断不能由处理器外部的外设直接产生,而必须借助于一个称为中断控制器的标准组
件来请求。中断外部设备会有电路连接到用于中断控制器发送中断请求的组件。中断控制
器就是一个控制电路,好了,这里涉及了电路设计的问题,不打算深入电路设计的内部,
如果你有兴趣的话,可以看看关于通用计算机体系设计,如CPU,内存,总线,外设,尤
其像CPU的设计里面的控制电路不胜枚举,扯远了。

中断处理的过程:中断现行程序,转到中断服务程序处执行,回到被中断的程序继续执行。


                  |CPU收到中断信号
正在运行的程序    v
------------------>                    ------------------------>
                  |                   ^   中断服务程序执行结束
              +-------+               |   返回继续执行元程序
              |  中断 |           +----------+
              +-------+           |  中断返回|
                  |               +----------+
                  v                   |
                  -------------------->
                   CPU中断正在执行的程序
                   转到执行中断服务程序


这些中断处理过程中涉及了CPU中的寄存器操作,这些操作只能由汇编语言来完成了。

       中断                             +-----------------------------+
        |                                   |有必要                       |
        v                                  |进行调度?--- --->调度        |
+-----------------+                         |   |                         |
|   切换到内核栈  |                         |   v                         |
|       |         |     +-------------+     |  信号------>将信号投递到进程|
|       v        |---->| 中断处理程序|---->|   |                         |
|   保存寄存器    |     +-------------+     |   v                         |
+-----------------+                         |恢复寄存器                   |
                                            |   |                         |
                                            |   v                         |
                                            |激活用户栈                   |
                                            +-----------------------------+
             中断的处理过程

在软中断的基础之上,实现了tasklet和工作队列机制,这两种机制是内核对可延迟中断
处理的支持。

他们的特点为:
tasklet在软中断之上实现。
在同一个CPU上软中断/tasklet不嵌套。
tasklet是并行可执行,同类tasklet不能并发。
软中断由内核静态分配,tasklet可以在运行时分配和初始化。
软中断/tasklet不能睡眠,阻塞,工作队列以内核线程身份运行。

可延迟函数上可以执行4种操作:
初始化:定义一个新的可延迟函数,通常在内核初始化时进行。
激活:设置可延迟函数在下一轮处理中执行。
屏蔽:有选择的屏蔽一个可延迟函数,这样即使被激活也不会被运行。
执行:在特定的时间执行可延迟函数。

有了软中断之上的tasklet和工作队列机制的更高抽象,这样便可以面向内核的其它组件,
例如:进程的调度,时钟,网络,驱动程序(网络及驱动的中断和硬件中断相比他们在更
高抽象层次)。


内核时间
--------
为什么需要一个内核时间?因为在程序协调(如进程调度,中断等等)时,需要有一个度
量的单位,这就是时间。内核通过他来测量时间以及不同时间点的时差。

jiffies是一个合适的时间坐标。名为jiffies_64和jiffies(分别是64位和32位)的全局
变量,会按恒定的时间间隔递增。每种计算机体系结构都提供了一些执行周期性操作的手
段,通常的形式是定时器中断。

jiffies递增的频率同体系结构有关,取决于内核中一个主要的常数HZ。该常数的值通常
介于100和1000中间。

基于jiffies的计时相对粒度较粗,在底层硬件能力允许的前提下,内核可使用高分辨率
的定时器提供额外的计时手段,能偶以纳秒级的精确度和分辨率来计量时间。

计时的周期是可以动态改变的。在没有或无需频繁的周期性操作的情况下,周期性地产生
定时器中断是没有意义的,这会阻止处理器降低耗电进入睡眠状态。动态改变计时周期对
于供电受限的系统是很有用的,例如笔记本电脑和嵌入式系统。
内核对自身的各种任务使用定时器,例如在设备驱动程序与相关的硬件通信时,使用的协
议通常带有按时间先后定义的次序。TCP实现中,就使用了很多定时器来指定等待的超时
时间。

linux中有高分辨率定时器和低分辨率定时器,由于以前linux使用的是低分辨率定时器,
随着时间的推移,嵌入式设备为了省电以及多媒体为了提高精确的帧,linux才实现了高
分辨率,为了兼容以前的程序,低分辨率也实现了,只不过是在高分辨率定时器的基础之
上实现的。

构成时间子系统的各个组件的概览:

                                                     +--------+
                                                      |定时器轮|
                                                     +--------+
                                                        ^
                                                         |
+------+    +--------+      +--------------+     +--------------+
|时钟源|    |时钟事件|<---->|高分辨率定时器|---->|低分辨率定时器|
+------+----+--------+      +--------------+     +--------------+
|通用时间和时钟事件层|        |          |
+--------------------+         v          v
  ^             ^      +--------+ +---------------------+
   |              |        |进程统计| |jiffies和全局时钟信号|
   v             v      +--------+ +---------------------+
+--------------------+     per-CPU        全系统
|  体系结构相关代码  |
+--------------------+
  ^            ^
   |              |
   v             v
+--------------------+
 |    硬件时钟芯片    |
+--------------------+

时钟源抽象为所有硬件时钟芯片提供了一个通用接口。就是该接口允许读取时钟芯片提供
的运行计数器的当前值。

时钟事件是周期性事件的基础。

周期性时间---->高分辨率定时器----->低分辨率定时器

高分辨率定时器承担了两个重要的任务:
1)处理全局jiffies计数器。该值周期性地增长,他表示了一种简单的时间基准。
2)进行各进程统计。这也包括了对经典的低分辨率定时器的处理,这种定时器可以关联
到任意进程。


==============================================================================

你可能感兴趣的:(linux内核,定时器,中断)