Linux的中断服务程序

1.几个重要的数据结构:

///////////////////////////////////////////////
1.struct irq_desc; 表示一个中断号

31struct irq_desc;
32typedef void (*irq_flow_handler_t)(unsigned int irq,
33                             struct irq_desc *desc);

175struct irq_desc {
176        unsigned int            irq; //中断号
177        struct timer_rand_state *timer_rand_state;
178        unsigned int            *kstat_irqs;
179#ifdef CONFIG_INTR_REMAP
180        struct irq_2_iommu      *irq_2_iommu;
181#endif
182        irq_flow_handler_t      handle_irq; //该中断号对应的公共处理程序
183        struct irq_chip         *chip; //中断控制器
184        struct msi_desc         *msi_desc;
185        void                    *handler_data; //handle_irq公共处理程序的参数
186        void                    *chip_data; 
187        struct irqaction        *action; //该中断线上已经注册的中断处理程序链表
188        unsigned int            status; //中断线此时的状态
189
190        unsigned int            depth;
191        unsigned int            wake_depth;
192        unsigned int            irq_count;
193        unsigned long           last_unhandled;
194        unsigned int            irqs_unhandled;
195        raw_spinlock_t          lock;
196#ifdef CONFIG_SMP
197        cpumask_var_t           affinity;
198        const struct cpumask    *affinity_hint;
199        unsigned int            node;
200#ifdef CONFIG_GENERIC_PENDING_IRQ
201        cpumask_var_t           pending_mask;
202#endif
203#endif
204        atomic_t                threads_active;
205        wait_queue_head_t       wait_for_threads;
206#ifdef CONFIG_PROC_FS
207        struct proc_dir_entry   *dir;
208#endif
209        const char              *name; //中断线的名字
210}

<全部中断号组成一个中断号数组>
216#ifndef CONFIG_SPARSE_IRQ
217extern struct irq_desc irq_desc[NR_IRQS];
218#endif

///////////////////////////////////////////
2.struct irqaction; 表示一个中断处理程序

98typedef irqreturn_t (*irq_handler_t)(int, void *);

113struct irqaction {
114        irq_handler_t handler; //中断处理程序
115        unsigned long flags;   //中断发生时的一些标志
116        const char *name; //中断程序名字
117        void *dev_id;  //设备标志
118        struct irqaction *next; //该中断线上的下一个中断处理程序
119        int irq;  //中断号
120        struct proc_dir_entry *dir;
121        irq_handler_t thread_fn;
122        struct task_struct *thread;
123        unsigned long thread_flags;
124};

///////////////////////////////////////
3.struct irq_chip; 表示一个中断控制器

111struct irq_chip {
112        const char      *name; //中断控制器的名字
113        unsigned int    (*startup)(unsigned int irq); //启动某条中断线
114        void            (*shutdown)(unsigned int irq); //关闭某条中断线
115        void            (*enable)(unsigned int irq); //允许某条中断线中断
116        void            (*disable)(unsigned int irq); //禁止某条中断线中断
117
118        void            (*ack)(unsigned int irq);
119        void            (*mask)(unsigned int irq);
120        void            (*mask_ack)(unsigned int irq);
121        void            (*unmask)(unsigned int irq);
122        void            (*eoi)(unsigned int irq);
123
124        void            (*end)(unsigned int irq);
125        int             (*set_affinity)(unsigned int irq,
126                                        const struct cpumask *dest);
127        int             (*retrigger)(unsigned int irq);
128        int             (*set_type)(unsigned int irq, unsigned int flow_type);
129        int             (*set_wake)(unsigned int irq, unsigned int on);
130
131        void            (*bus_lock)(unsigned int irq);
132        void            (*bus_sync_unlock)(unsigned int irq);
133
134        /* Currently used only by UML, might disappear one day.*/
135#ifdef CONFIG_IRQ_RELEASE_METHOD
136        void            (*release)(unsigned int irq, void *dev_id);
137#endif
138        /*
139         * For compatibility, ->typename is copied into ->name.
140         * Will disappear.
141         */
142        const char      *typename;
143};

2.上述三个结构的关系:

这里写图片描述

3.中断发生时的执行过程:

这里写图片描述

1.键盘产生一个中断,通过中断线把信号(中断号)发给中断控制器

2.中断控制器把该中断号发给处理器,处理器停止当前工作

3.处理器调用common_interrup这个公共的中断处理程序,保存当前执行进程的环境,大概就是一些寄存器值,都保存到该进程的堆栈中

4.处理器调用do_IRQ()函数,该函数会调用struct irq_desc结构中的属于该中断线的公共处理程序,即 handle_irq字段指向的函数

5.handle_irq指向的函数最终会调用上述图片中所示的hand_IRQ_event函数,该函数会依次调用属于该中断线上的处理程序,即依次调用struct irq_desc结构中的action字段指向的属于该中断线上的中断处理程序链表上的处理程序
6.中断处理程序执行完后,调用上述图片中的ret_from_intr()函数,该函数返回到中断之前的现场环境

本文引述自 http://edsionte.com/techblog/archives/1618

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值