一、概念
1、外设的处理速度一般慢于CPU。
2、CPU不能一直等待外部事件。
所以设备必须有一种方法来通知CPU它的工作进度,这种方法就是中断。
二、中断实现
在Linux驱动程序中,为设备实现一个中断包含两个步骤:
1、向内核注册中断
2、实现中断处理函数
三、中断处理子系统
1、根据中断号找到正确的中断处理代码。
2、
Linux
定义名字为
irq_desc
的中断例程描述符表
:(include/
linux
/
irq.h
),该表struct irqdesc 结构组成。
struct irqdescirq_desc[NR_IRQS];//NR_IRQS表示中断源的数目
irq_desc
结构体中的成员
action
指向该中断号对应的
irqaction
结构体链表。
irqaction
结构体定义如下:
struct irqaction {
irq_handler_t handler;
unsigned long flags;
void *dev_id;
void __percpu *percpu_dev_id;
struct irqaction *next;
int irq;
irq_handler_t thread_fn;
struct task_struct *thread;
unsigned long thread_flags;
unsigned long thread_mask;
const char *name;
struct proc_dir_entry *dir;
} ____cacheline_internodealigned_in_smp;
irq_handler_t handler;
unsigned long flags;
void *dev_id;
void __percpu *percpu_dev_id;
struct irqaction *next;
int irq;
irq_handler_t thread_fn;
struct task_struct *thread;
unsigned long thread_flags;
unsigned long thread_mask;
const char *name;
struct proc_dir_entry *dir;
} ____cacheline_internodealigned_in_smp;
3、
4、共享中断
将不同的设备挂到同一个中断信号线上。Linux对共享的支持主要是为PCI设备服务。共享中断也是通过request_irq函数来注册的。
共享中断的处理程序中,不能使用disable_irq(unsigned int irq);
如果使用了这个函数,共享中断信号线的其它设备将同样无法使用中断,也就无法正常工作。
5、中断处理程序
中断处理程序是在中断上下文中运行的,它的行为受到某些限制:
1)不能向用户空间发送或接受数据。
2)不能使用可能引起阻塞的函数。
3)不能使用可能引起调度的函数。
6、Linux中断底半部机制
两个半部的理念:
解决既要中断执行快,又要做的事情多的矛盾。
下半部机制
软中断
tasklet
工作队列
Linux软中断机制
软中断是利用硬件中断的概念,用软件方式进行模拟,实现宏观上的异步执行效果。
硬中断是外部设备对CPU的中断
,
软中断通常是硬中断服务程序对内核的中断。
驱动程序延缓执行机制
Tasklet
和下半部处理
workqueue
和下半部处理
内核定时器
总结:
工作队列的使用方法和
tasklet
非常相似
tasklet
运行于中断上下文,
工作队列运行于进程上下文,
tasklet
处理函数中不能睡眠,而工作队列处理函数中允许睡眠 。