全部博文(46)
分类: LINUX
2010-08-30 14:51:02
中断:
在响应中的时候,内核会执行一个函数,这个函数叫做中断处理程序,handler()
在
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *,struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
函数参数说明
unsigned int irq:所要注册的中断号
irqreturn_t (*handler)(int, void *, struct pt_regs *):中断服务程序的入口地址。
unsigned long flags:与中断管理有关的位掩码选项,有三组值:
1. SA_INTERRUPT :快速中断处理程序,当使用它的是后处理器上所有的其他中断都被禁用。
2. SA_SHIRQ :该中断是在设备之间可共享的
3. SA_SAMPLE_RANDOM :这个位表示产生的中断能够有贡献给 /dev/random
和 /dev/urandom 使用的加密池.(此处不理解)
const char *dev_name:设备描述,表示那一个设备在使用这个中断。
void *dev_id:用作共享中断线的指针. 它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区(来标识哪个设备在中断) 。这个参数在真正的驱动程序中一般是指向设备数据结构的指针.在调用中断处理程序的时候它就会传递给中断处理程序的void *dev_id。如果中断没有被共享, dev_id 可以设置为 NULL, 但是使用这个项指向设备结构不管如何是个好主意. 我们将在"实现一个处理"一节中看到 dev_id 的一个实际应用。我家之言:void *dev_id可以做为注册中断时的一个参数传给中断处理函数,而且在释放中断的时候要用到这个参数来唯一确定释放那个中断号。
中断处理函数的返回值:中断程序的返回值是一个特殊类型—irqreturn_t。但是中断程序的返回值却只有两个—IRQ_NONE和IRQ_HANDLED。
irqreturn.h中定义了这两个返回值。
/**
* enum irqreturn
* @IRQ_NONE interrupt was not from this device
* @IRQ_HANDLED interrupt was handled by this device
* @IRQ_WAKE_THREAD handler requests to wake the handler thread
*/
enum irqreturn {
IRQ_NONE, //0
IRQ_HANDLED, //1
IRQ_WAKE_THREAD, //2,枚举类型里的分隔符为豆号
};
//对枚举类型变量只能使用2类运算:赋值运算与关系运算
typedef enum irqreturn irqreturn_t;
#define IRQ_RETVAL(x) ((x) != IRQ_NONE)
在使用中断中要注意的事项之我说:中断运行在中断上下文中,所以中断不可以睡眠,中断处理程序并不具有自己的栈空间。上、下两部分的划分在中断里不是必需的,如果中断处理用时比较长,则要用到“底半部”机制。常用的底半部机制有tasklets、工作队列和软中断。中断的上半部接收到一个中断,它就立刻开始执行,但只有严格时限的工作,能够被允许稍后的工作会推迟到下部去,下半部分,会在中断处理程序返回时立即执行,软中断一般用在系统的定时器中,使用较少。Tasklets的底层实现也是使用了软件中断,仍然运行在中断上下文中,不允许睡眠,一般在调用后会马上执行,工作队列则运行在进程上下文中,它靠内核线程来实现的,所有更宽松的执行时间,可以休眠,被中断等。
在宋宝华书《Linux设备驱动程序开发详解》p193有关于tasklets与工作队列的模板。
chinaunix网友2010-08-30 21:39:42
Download More than 1000 free IT eBooks: http://free-ebooks.appspot.com