欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux内核设计与实现——第七章 中断和中断处理

程序员文章站 2022-07-13 21:45:49
...

为什么要有中断机制?

计算机有很多的硬件设备,如硬盘、键盘、鼠标等,操作系统需要对这些硬件设备进行管理,然而处理器的速度和外围硬件设备的速度往往不在一个数量级上。如果内核让处理器向硬件发出一个请求,然后专门等待回应,性能会很差。内核应该在此期间处理其他事务,等到硬件真正完成请求的操作后再回头对它进行处理。因此,采用一种机制让硬件在需要的时候向内核发出信号

1 中断

中断本质就是一种特殊的电信号,由硬件发向处理器。内核随时可能因为新到来的中断被打断。

不同设备对应的中断不同,每个中断都通过唯一的一个数字标识。操作系统根据不同的中断提供不同的中断处理程序。这些中断值通常称为中断请求线(IRQ)。

异常

而谈到中断就会谈到异常,异常与中断的区别在于,异常在产生时必须考虑与处理器时钟同步(称为同步中断)。一般是处理器执行到由于编程失误而导致的错误指令(如除0),或者在执行期间出现特殊情况(如缺页)就会产生一个异常

2 中断处理程序

在响应特定中断时,内核会执行一个函数,即中断处理程序。中断处理程序通常和特定中断关联。

中断处理程序就是函数,但与其他内核函数的真正区别是,中断处理程序是被内核调用来响应中断的,而它们运行于中断上下文中,该上下文中的代码不可被阻塞。

中断处理程序随时可能执行,所以必须保证其能快速执行。

3 上半部与下半部的对比

中断处理程序运行速度和完成工作量之间的平衡使得将中断处理切为两部分:

  • 中断处理程序为上半部:接收到一个中断,立即执行,但只做有严格时限的工作。
  • 下半部:将能被允许稍后完成的工作推迟到下半部做。

4 注册中断处理程序

驱动程序通过 request_irp() 函数来注册一个中断处理程序,并且**给定的中断线以处理中断。

int request_irq(unsigned int irq, // 表示要分配的中断号
				irq_handler_t handler, // 指针指向处理这个中断的实际中断处理程序
				unsigned long flags, // 中断处理程序标志
								     // IRQF_DISABLED:禁止所有的其他中断
								     // IRQF_SAMPLE_RANDOM:这个设备产生的中断对内核熵池有贡献
								     // IRQF_TIMER:特别为系统定时器的中断处理准备
								     // IRQF_SHARED:可以在多个中断处理程序之间共享中断线。
				const char *name, // 与中断相关的设备的ASCII文本表示
				void *dev // 用于共享中断线
				)

request_irp() 成功执行返回0,否则错误即指定的中断处理程序不会被注册。

卸载驱动程序时需要注销相应的中断处理程序,并释放中断线

void free_irq(unsigned int irq, // 表示要释放的中断号
			  void *dev
			  )

如果中断线不是共享的,则删除处理程序的同时禁用此中断线;
如果中断线是共享的,则仅删除dev所对应的处理程序。