linux驱动之中断处理过程C程序部分
Posted 上善若水,止于至善
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux驱动之中断处理过程C程序部分相关的知识,希望对你有一定的参考价值。
当发生中断之后,linux系统在汇编阶段经过一系列跳转,最终跳转到asm_do_irq()函数,开始C程序阶段的处理。在汇编阶段,程序已经计算出发生中断的中断号irq,这个关键参数最终传递给asm_do_irq()。linux驱动中断处理C程序部分,主要涉及linux中断系统数据结构的初始化和C程序的具体执行跳转。
一、中断处理数据结构
linux内核将所有的中断统一编号,使用一个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着一个中断源(可能是一个中断,也可能是一组中断),记录了中断的入口处理函数(不是用户注册的处理函数)、中断标记,并提供了中断的底层硬件访问函数(中断清除、屏蔽、使能)。另外,通过这个结构体数组项成员action,能够找到用户注册的中断处理函数。结构体irq_desc的数据类型在include/linux/irq.h中定义,内容如下:
struct irq_desc { irq_flow_handler_t handle_irq; /* 当前中断的处理函数入口 */ struct irq_chip *chip; /* 低层的硬件访问 */ struct msi_desc *msi_desc; void *handler_data; void *chip_data; struct irqaction *action; /* 用户提供的中断处理函数链表 */ unsigned int status; /* IRQ状态 */ unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ unsigned int irq_count; /* For detecting broken IRQs */ unsigned int irqs_unhandled; spinlock_t lock; const char *name; /* 中断名称 */ } ____cacheline_internodealigned_in_smp;
irq_desc成员变量handle_irq是这个或这组中断的入口处理函数,成员变量chip结构体包含了这个中断的清除、屏蔽或者使能等底层函数,结构体类型irq_chip的定义也在include/linux/irq.h中,内容如下:
struct irq_chip { const char *name; unsigned int (*startup)(unsigned int irq); void (*shutdown)(unsigned int irq); void (*enable)(unsigned int irq); void (*disable)(unsigned int irq); void (*ack)(unsigned int irq); void (*mask)(unsigned int irq); void (*mask_ack)(unsigned int irq); void (*unmask)(unsigned int irq); const char *typename; };
irq_desc成员变量action记录了用户注册的中断处理函数、中断标志等等内容,其类型irqaction类型定义在include/linux/interrupt.h中,内容如下:
struct irqaction { irq_handler_t handler; /* 用户注册的中断处理函数 */ unsigned long flags; /* 中断标志,是否共享中断,电平触发还是边沿触发等 */ cpumask_t mask; /* 用于SMP */ const char *name; /* 用户注册的中断名字,/proc/interrupts */ void *dev_id; /* 用户传递给handler的参数,还可以用来区分共享中断 */ struct irqaction *next; /* 指向下一个irqaciton结构体指针 */ int irq; /* 中断号 */ struct proc_dir_entry *dir; };
用户注册的每个中断处理函数对应一个irqaciton结构体,一个中断源可以有多个处理函数(共享终端),它们的irqaciton结构体可以构成一个单项链表,irq_desc[irqn].action则是表头。irq_desc[NR_IRQS]结构体数组的构成情况如下图所示:
以上是关于linux驱动之中断处理过程C程序部分的主要内容,如果未能解决你的问题,请参考以下文章