设为首页 加入收藏

TOP

Linux 中断学习之小试牛刀篇(十)
2014-11-24 07:26:15 来源: 作者: 【 】 浏览:19
Tags:Linux 中断 习之 小试牛刀
3 if (retval)
1094 kfree(action);
1095
1096#ifdef CONFIG_DEBUG_SHIRQ
1097 if (!retval && (irqflags & IRQF_SHARED)) {
1098 /*
1099 * It's a shared IRQ -- the driver ought to be prepared for it
1100 * to happen immediately, so let's make sure....
1101 * We disable the irq to make sure that a 'real' IRQ doesn't
1102 * run in parallel with our fake.
1103 */
1104 unsigned long flags;
1105
1106 disable_irq(irq);
1107 local_irq_save(flags);
1108
1109 handler(irq, dev_id);
1110
1111 local_irq_restore(flags);
1112 enable_irq(irq);
1113 }
1114#endif
1115 return retval;
1116}


程序的第一行和第二行分别定义了:


(1) struct irqaction *action;


(2)2struct irq_desc *desc;


两个指针action和desc,它们分别指向了结构体irqaction和 irq_desc。


(3) if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;


作用是:判断中断标志位,如果是共享中断的话就必须要有一个唯一的dev_id,否则返回一个错误。


(4) desc = irq_to_desc(irq);


irq_to_desc(irq):根据中断号irq在 irq_desc[NR_IRQS]数组中 返回一个具体的irq_desc。即根据irq找到它的中断处理程序。


(5) if (!desc)


return -EINVAL;


当返回一个空值时返回一个错误。说明申请中断号失败。


(6)if (desc->status & IRQ_NOREQUEST)
return -EINVAL;


判断中断线的状态,若为IRQ_NOREQUEST时( IRQ_NOREQUEST表示 IRQ 不能被申请)


(7) if (!handler) {
if (!thread_fn)
return -EINVAL;
handler = irq_default_primary_handler;
}


判断中断服务例程是否为空,如果handler为空,则判断线程中断服务例程,若线程中断服务例程也为空,则返回一个错误值。否则中断服务例程指向: rq_default_primary_handler。


(8)


1079 action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
1080 if (!action)
1081 return -ENOMEM;
1082
1083 action->handler = handler;
1084 action->thread_fn = thread_fn;
1085 action->flags = irqflags;
1086 action->name = devname;
1087 action->dev_id = dev_id;


从1079~1087:根据requst_irq()函数中传递的参数生成一个irqaction.


1097 if (!retval && (irqflags & IRQF_SHARED)) {
1098 /*
1099 * It's a shared IRQ -- the driver ought to be prepared for it
1100 * to happen immediately, so let's make sure....
1101 * We disable the irq to make sure that a 'real' IRQ doesn't
1102 * run in parallel with our fake.
1103 */
1104 unsigned long flags;
1105
1106 disable_irq(irq);
1107 local_irq_save(flags);
1108
1109 handler(irq, dev_id);
1110
1111 local_irq_restore(flags);
1112 enable_irq(irq);
1113 }


1097~1113:如果为共享中断的话,在执行中断服务例程之前,要先把这条中断线上的中断屏蔽,让后在执行,执行完之后打开中断。


6.有注册中断服务函数,那必然有相应的释放中断函数。


可以调用void free_irq(unsigned int irq, void *dev_id)来释放我们申请的中断线。


函数形参:


1>unsigned int riq:表示申请的中断号与request_irq()函数中的第一个形参对应。


2>void *dev_id:与request_irq()函数中的最后一个形参含义和用法相同,在此不再说明。


函数功能:


如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断线本省只有在删除了最后一个处理程序时才会被禁止。


切记:This function must not be called from interrupt context


freee_irq()函数不能在中断上下文中被调用。


3>深入分析下free_irq()函数内部是如何实现的


993void free_irq(unsigned int irq, void *dev_id)
994{
995 struct irq_desc *desc = irq_to_desc(irq);
996
997 if (!desc)
998

首页 上一页 7 8 9 10 下一页 尾页 10/10/10
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux 中断学习之前言篇 中断之原.. 下一篇Linux之Git工具的使用

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)