第12课第4.1节 字符设备驱动程序之中断方式的按键驱动_Linux异常处理结构.wmv
----中断也是种异常
从模糊的概念来说中断和异常在判断的机制上都是一样的,即内核是通过中断向量号来识别的,cpu将中断向量号做为中断描述表的索引,相应的表项中包含了中断处理程序或者异常处理程序的地址,以此来处理中断或者异常。
中断:中断从对象上可以分为硬件中断和软件中断,而硬件中断(IRQ)分为短类型和长类型,短类型即在短时间内需要被机器响应处理,而长类型需要较长时间,在此期间内可能发生其他中断,中断从程序上分为上半部(tophalf)和下半部(bottom half)<暂时放下>
中断相关头文件:irq.h
中断相关函数:1.Struct irq_desc(中断请求队列)
2.Struct irqacton(服务列表结构)
3.int request_irq(请求中断)
4.void free_irq(释放中断)
队列——休眠——等待
1.int request_irq
对于编程来说,中断最核心的函数就是int request_irq,这个请求中断函数的完整定义是:
int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
- unsigned int irq:表示要申请的硬件中断号(硬件中断号:一个标号,让CPU能够判断是哪个硬件设备呼叫了她)
- irq_handler_t handler:(*handler)(unsigned int , struct irqdesc *, struct pt_regs *),先看这个函数的定义:void (*handler)(unsigned int irq, struct irqdesc *dev_id, struct pt_regs *); // 定义该种指针函数irq_handler_t返回值为void,参数为unsigned int, struct irqdesc *, struct pt_regs *,如下附上一个关于对typedef比较认同的解读方法:

(*handler)(unsigned int irq, struct irqdesc *dev_id, struct pt_regs *),因此我们知道在这里我们选择两个参数进行传递(irq,dev_id),第三个是空
- unsigned long irqflags:决定中断处理的特性(例程给出的是:IRQT_BOTHEDGE,意义未知)
- const char *devname:设备名
- void *dev_id:设备id(例程:&pins_desc[0],对应的是S3C2410_GPF0 = S3C2410_GPIONO(S3C2410_GPIO_BANKF, 0) = S3C2410_GPIONO(bank,offset) = (bank) + (offset) = 32*5 + 0 = 160,是S3C2410_GPF0对应的编好的设备号?参考其他管脚发现都有如下定义)
将该函数写入驱动open函数中,当驱动载入时会初始化我们需要的中断信息:设备名、中断号(架构设定好了IO)、设备id(架构设定好了IO)、中断处理函数、中断函数类型。
总而言之,request_irq函数主要做了以下工作:
1.使用参数构造一个irqection结构,然后调用setup_irq函数将它链入链表中
2.设置irq_desc[irq]结构中成员,让他们指向一些默认函数
3.中断触发方式被设定好
4.中断已经使能
2.中断处理函数
首先需要明确几个概念:用户空间、内核空间、硬件
用户空间:用户可操作
内核空间:计算机处理(驱动所在)
硬件:最外层
中断处理过程大致可以描述为以下过程:
1.中断向量调用总入口函数asm_do_IRQ,传入中断号irq
2.根据中断号调用handle_irq处理(不同中断类型处理函数的入口不一样)
3.处理完后逐个调用在链表中注册的待处理函数
(待补充)在中断处理函数中涉及一些队列方面知识之后补充

浙公网安备 33010602011771号