微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Linux中断机制之中断的初始化

ARM Linux中断机制之中断的初始化

时间:11-10 来源:互联网 点击:
一,认识几个重要结构体:

1.中断描述符

对于每一条中断线都由一个irq_desc结构来描述。

//在include/linux/irq.h中

struct irq_desc {
unsigned intirq;//中断号
struct timer_rand_state *timer_rand_state;
unsigned int *kstat_irqs;
#ifdef CONFIG_INTR_REMAP
struct irq_2_iommu *irq_2_iommu;
#endif

/*

在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()
完成的

*/
irq_flow_handler_thandle_irq;//上层中断处理函数,
struct irq_chip*chip;//底层硬件操作
struct msi_desc*msi_desc;
void*handler_data;//附加参数,用于handle_irq
void*chip_data;//平台相关附加参数,用于chip
struct irqaction*action;/* IRQ action list*///中断服务例程链表
unsigned intstatus;/* IRQ status *///中断当前的状态

//中断关闭打开层数调用一次disable_irq( ) ,depth加1;调用一次enable_irq( )该值减1,

//如果depth等于0就开启这条中断线,如果depth大于0就关闭中断线。

unsigned intdepth;
unsigned intwake_depth;////* 唤醒次数 */
unsigned intirq_count;/* 发生的中断次数 */
unsigned longlast_unhandled;/* Aging timer for unhandled count */
unsigned intirqs_unhandled;
spinlock_tlock;
#ifdef CONFIG_SMP
cpumask_var_taffinity;
unsigned intcpu;
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_var_tpending_mask;
#endif
#endif
atomic_tthreads_active;
wait_queue_head_t wait_for_threads;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry*dir;///proc/irq/ 入口
#endif
const char*name;///proc/interrupts 中显示的中断名称
} ____cacheline_internodealigned_in_smp;

/*在kernel/irq/handle.c中有个全局irq_desc数组,描述了系统中所有的中断线:

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 = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
}
};

NR_IRQS为最大中断数对于s3c2410芯片,在文件arch/arm/mach-s3c2410/include/mach/irqs.h中定义如下:

#ifdef CONFIG_CPU_S3C2443
#define NR_IRQS (IRQ_S3C2443_AC97+1)
#else
#define NR_IRQS (IRQ_S3C2440_AC97+1)//每一个中断源都对应一个irq_desc结构体。
#endif

*/

2. 中断硬件操作函数集

//在include/linux/irq.h中定义

//该结构体中各函数在文件linux/arch/arm/plat-s3c24xx/irq.c中实现

struct irq_chip {
const char*name;//用于 /proc/interrupts
unsigned int(*startup)(unsigned int irq);//默认为 enable 如果为NULL
void(*shutdown)(unsigned int irq);//默认为 disable 如果为NULL
void(*enable)(unsigned int irq);//允许中断,默认为 unmask 如果为NULL
void(*disable)(unsigned int irq);//禁止中断,默认为 mask如果为 NULL

void(*ack)(unsigned int irq);//响应一个中断,清除中断标志
void(*mask)(unsigned int irq);//mask 一个中断源,通常是关闭中断
void(*mask_ack)(unsigned int irq);//响应并 mask 中断源
void(*unmask)(unsigned int irq);//unmask 中断源
void(*eoi)(unsigned int irq);

void(*end)(unsigned int irq);
void(*set_affinity)(unsigned int irq,
const struct cpumask *dest);
int(*retrigger)(unsigned int irq);
int(*set_type)(unsigned int irq, unsigned int flow_type);//设置中断触发方式 IRQ_TYPE_LEVEL
int(*set_wake)(unsigned int irq, unsigned int on);

/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void(*release)(unsigned int irq, void *dev_id);
#endif
/*
* For compatibility, ->typename is copied into ->name.
* Will disappear.
*/
const char*typename;
};

3.中断处理例程描述符

//在include/linux/interrupt.h中

struct irqaction {
irq_handler_t handler;/* 具体的中断处理程序 */
unsigned long flags;//用一组标志描述中断线与 I/O 设备之间的关系。
cpumask_t mask;
const char *name;/* 名称,会显示在/proc/interreupts中 */
void *dev_id;/* 设备ID,用于区分共享一条中断线的多个处理程序 ,以便从共享中断线的诸多中断处理程序中删除指定的那一个*/
struct irqaction *next;/* 指向下一个irq_action结构 */
int irq;/* 中断通道号 */
struct proc_dir_entry *dir; /* procfs目录 */
irq_handler_t thread_fn;
struct task_struct *thread;
unsigned long thread_flags;
};

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top