2024年3月24日发(作者:穰曼岚)
ARM Linux中断机制分析
ARM Linux中断机制分析
作者:张俊岭
EMAIL: sprite_zjl@; jlzhang@
QQ: 251450387
日期:2009-8-15
说明:本文档基于AT91SAM9260EK板
1 数据结构
中断机制的核心数据结构是irq_desc,它完整地描述了一条中断线(或称为“中断通道” )。
irq_desc结构在include/linux/irq.h中定义:
typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
struct irq_desc *desc);
struct irq_desc {
irq_flow_handler_t handle_irq;
/* 高层次的中断事件处理函数 */
struct irq_chip *chip; /* 低层次的硬件操作 */
struct msi_desc *msi_desc; /* MSI 描述符?? */
void *handler_data; /* chip方法使用的数据*/
void *chip_data; /* chip私有数据 */
struct irqaction *action; /* 行为链表(action list) */
unsigned int status; /* 状态 */
unsigned int depth; /* 关中断次数 */
unsigned int wake_depth; /* 唤醒次数 */
unsigned int irq_count; /* 发生的中断次数 */
unsigned int irqs_unhandled;
spinlock_t lock; /* 自旋锁 */
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
cpumask_t pending_mask;
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir; /* 在proc文件系统中的目录 */
#endif
const char *name; /* 名称 */
} ____cacheline_aligned;
在kernel/irq/handle.c中有个全局irq_desc数组,描述了系统中所有的中断线:
第 1 页 共 15 页
ARM Linux中断机制分析
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
#ifdef CONFIG_SMP
.affinity = CPU_MASK_ALL
#endif
}
};
数组共有NR_IRQS个元素,每个元素对应一条中断线。其中NR_IRQS是系统中的中断线的数
量,对于AT91SAM9260EK板,这个值为32。
下面来看irq_desc结构中的重要数据成员。
首先是handle_irq,这是个函数指针,指向的是一个高层次的中断事件处理函数,定义了
处理中断事件的一种策略。
在kernel/irq/chip.c中实现了5个函数:handle_simple_irq(),handle_level_irq(),
handle_edge_irq(),handle_fasteoi_irq()以及handle_percpu_irq()。handle_irq指针可
以指向这5个函数中的一个,选择一种中断事件处理策略,这是通过函数set_irq_handler()
完成的。
接下来是chip,这是个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); /* 取消屏蔽中断 */
void (*eoi)(unsigned int irq); /* 中断结束 */
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest);
/* 重新触发中断 */
第 2 页 共 15 页
2024年3月24日发(作者:穰曼岚)
ARM Linux中断机制分析
ARM Linux中断机制分析
作者:张俊岭
EMAIL: sprite_zjl@; jlzhang@
QQ: 251450387
日期:2009-8-15
说明:本文档基于AT91SAM9260EK板
1 数据结构
中断机制的核心数据结构是irq_desc,它完整地描述了一条中断线(或称为“中断通道” )。
irq_desc结构在include/linux/irq.h中定义:
typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
struct irq_desc *desc);
struct irq_desc {
irq_flow_handler_t handle_irq;
/* 高层次的中断事件处理函数 */
struct irq_chip *chip; /* 低层次的硬件操作 */
struct msi_desc *msi_desc; /* MSI 描述符?? */
void *handler_data; /* chip方法使用的数据*/
void *chip_data; /* chip私有数据 */
struct irqaction *action; /* 行为链表(action list) */
unsigned int status; /* 状态 */
unsigned int depth; /* 关中断次数 */
unsigned int wake_depth; /* 唤醒次数 */
unsigned int irq_count; /* 发生的中断次数 */
unsigned int irqs_unhandled;
spinlock_t lock; /* 自旋锁 */
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
cpumask_t pending_mask;
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir; /* 在proc文件系统中的目录 */
#endif
const char *name; /* 名称 */
} ____cacheline_aligned;
在kernel/irq/handle.c中有个全局irq_desc数组,描述了系统中所有的中断线:
第 1 页 共 15 页
ARM Linux中断机制分析
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
#ifdef CONFIG_SMP
.affinity = CPU_MASK_ALL
#endif
}
};
数组共有NR_IRQS个元素,每个元素对应一条中断线。其中NR_IRQS是系统中的中断线的数
量,对于AT91SAM9260EK板,这个值为32。
下面来看irq_desc结构中的重要数据成员。
首先是handle_irq,这是个函数指针,指向的是一个高层次的中断事件处理函数,定义了
处理中断事件的一种策略。
在kernel/irq/chip.c中实现了5个函数:handle_simple_irq(),handle_level_irq(),
handle_edge_irq(),handle_fasteoi_irq()以及handle_percpu_irq()。handle_irq指针可
以指向这5个函数中的一个,选择一种中断事件处理策略,这是通过函数set_irq_handler()
完成的。
接下来是chip,这是个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); /* 取消屏蔽中断 */
void (*eoi)(unsigned int irq); /* 中断结束 */
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest);
/* 重新触发中断 */
第 2 页 共 15 页