Linux 中断学习之小试牛刀篇(4)

a.int irq :中断号。
b.void *dev_id :与request_irq()的参数dev_id一致,可以根据这个设备id号得到相应设备的数据结构,进而得到相应设备的信息和相关数据。
c.返回值:中断程序的返回值是一个特殊类型 rqreturn_t。但是中断程序的返回值却只有两个值IRQ_NONE和IRQ_HANDLED。
IRQ_NONE:中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号。
IRQ_HANDLED:接收到了准确的中断信号,并且作了相应正确的处理。


一般 中断处理程序要做什么service,主要取决于产生的设备和该设备为什么要发送中断。

John哥说明:

1.当一个给定的中断处理程序正在执行时,这条中断线上的其它中断都会被屏蔽。but,所有其他中断线上的中断都是打开的。因此这些不同中断线上的其他中断都能被处理。

2.request_irq()函数可能会睡眠,所以,不能在中断上下文或其它不允许阻塞的代码中调用该函数。

4.在深入分析request_irq()函数之前,先来看几个重要的数据结构。


A.irqaction的数据结构(用irqaction结构体来描述一个具体的中断服务例程)


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};  
125 
 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};
 125
 

1>handler:指向具体的一个中断服务例程。

2>flags:表示中断标志位,对应于request_irq()函数中所传递的第三个参数,可取IRQF_DISABLED、IRQF_SAMPLE_RANDOM和IRQF_SHARED其中之一。

3>name:请求中断的设备名称,对应request_irq()函数中所传递的第四个参数

4>dev_id: 共享中断时有用。 对应于request_irq()函数中所传递的第五个参数,可取任意值,但必须唯一能够代表发出中断请求的设备,通常取描述该设备的结构体。

5>strct irqaction *next:指向irqaction描述符的下一个元素。用一条链表将共享同一条中断线上的中断服务例程链接起来。

6>irq:所申请的中断号

7>dir:指向proc/irq/NN/name entry

8>thread_fn:指向具体的一个线程化的中断。

9>thread:指向线程中断的指针。

10>thread_flags:线程中断的标志。


B.irq_desc的数据结构体

每个中断向量都有它自己的irq_desc 描述符。即用irq_desc来描述中断向量。所有的这些中断描述符组织在一起就形成了irq_desc irq_desc[NR_IRQS]数组

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;  
186        void                    *chip_data;  
187        struct irqaction        *action;        /* IRQ action list */ 
188        unsigned int            status;         /* IRQ status */ 
189  
190        unsigned int            depth;          /* nested irq disables */ 
191        unsigned int            wake_depth;     /* nested wake enables */ 
192        unsigned int            irq_count;      /* For detecting broken IRQs */ 
193        unsigned long           last_unhandled; /* Aging timer for unhandled count */ 
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} ____cacheline_internodealigned_in_smp;  
211  
212extern void arch_init_copy_chip_data(struct irq_desc *old_desc,  
213                                        struct irq_desc *desc, int node);  
214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);  
215  
216#ifndef CONFIG_SPARSE_IRQ  
217extern struct irq_desc irq_desc[NR_IRQS]; 
 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;
 186        void                    *chip_data;
 187        struct irqaction        *action;        /* IRQ action list */
 188        unsigned int            status;         /* IRQ status */
 189
 190        unsigned int            depth;          /* nested irq disables */
 191        unsigned int            wake_depth;     /* nested wake enables */
 192        unsigned int            irq_count;      /* For detecting broken IRQs */
 193        unsigned long           last_unhandled; /* Aging timer for unhandled count */
 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} ____cacheline_internodealigned_in_smp;
 211
 212extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
 213                                        struct irq_desc *desc, int node);
 214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
 215
 216#ifndef CONFIG_SPARSE_IRQ
 217extern struct irq_desc irq_desc[NR_IRQS];  

1>irq:表示这个描述符所对应的中断号。

2>handle_irq:指向该IRQ线的公共服务程序(即该IRQ所对应的中断处理程序。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwszfw.html