/************************************************************************************
*本文为个人学习记录,如有错误,欢迎指正。
* https://blog.csdn.net/fridayll/article/details/51854126
* https://www.cnblogs.com/edver/p/7260696.html
* https://www.linuxidc.com/Linux/2017-08/146264.htm
* https://www.cnblogs.com/amanlikethis/p/6941666.html?utm_source=itdadao&utm_medium=referral
* https://www.cnblogs.com/chen-farsight/p/6155503.html
************************************************************************************/
中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时中断的程序。Linux中通常分为外部中断(又叫硬件中断)和内部中断(又叫异常)。
2. Linux内核中断机制的初始化
2.1 相关数据结构
linux内核将所有的中断统一编号,使用一个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着一个中断源,记录了中断的入口处理函数(不是用户注册的处理函数)、中断标记,并提供了中断的底层硬件访问函数(中断清除、屏蔽、使能)。另外,通过这个结构体数组项成员action,能够找到用户注册的中断处理函数。
(1)irq_desc[NR_IRQS]数组
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { [0 ... NR_IRQS-1] = { .status = IRQ_DISABLED, .chip = &no_irq_chip, .handle_irq = handle_bad_irq, .depth = 1, .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock), } };
(2)struct irq_desc
Linux内核中使用struct irq_desc来描述一个中断源。Linux内核中将CPU的所有中断进行编号,具体编号定义在/kernel/arch/arm/mach-s5pv210/include/mach/irqs.h。
struct irq_desc { unsigned int irq; /*中断号*/ 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;