linux中断三个数据结构

以一个IRQ中断为例子。

内核启动-------调用start_kernel()函数------调用setup_arch(&command_line)函数-----------调用early_trap_init()函数,实现异常向量表,异常处理代码的搬运
如果产生IRQ中断---------PC指向搬运后的异常向量表的vector_irq + stubs_offset地址 -------跳到搬运后的vector_irq地址-----调用函数asm_do_IRQ函数------调用generic_handle_irq(irq)函数,该函数里的handle_irq(irq, desc)作用就是irq中断号条用irq_desc数组中对应的handle_irq-------判断irq对应的中断是不是以组为形式是的话,是的话调用相应的函数判断是那个中断产生-----判断中断什么类型------若是电平触发,调用函数handle_level_irq,若是边沿触发调用函数handle_edge_irq---------条用action链表上用户定义的中断处理函数。


struct irq_desc {

unsigned intirq;                                         //中断号

irq_flow_handler_t handle_irq;               //当前中断入口地址
struct irq_chip *chip;                            //与硬件有关的操作函数模型
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction *action; /* IRQ action list */            //用户注册的中断处理函数会通过该变量组成链表
unsigned int status; /* IRQ status */


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;
unsigned long last_unhandled; /* Aging timer for unhandled count */
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_t pending_mask;
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
const char *name;                                 //中断的名称

} ____cacheline_internodealigned_in_smp;


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);
int (*retrigger)(unsigned int irq);
int (*set_type)(unsigned int irq, unsigned int flow_type);
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;
};



struct irqaction {
irq_handler_t handler;                       //
unsigned long flags;                       //中断标志
cpumask_t mask;
const char *name;
void *dev_id;                                       //用户传给handler的参数,也可以区分共享中断
struct irqaction *next;
int irq;
struct proc_dir_entry *dir;
};


你可能感兴趣的:(数据结构,linux,struct,vector,action,nested)