嵌入式linux的中断函数实现和分析(一)
来源:互联网 发布:asp商城源码 编辑:程序博客网 时间:2024/06/06 02:09
分析linux中断中常用的两个中断函数:
Disable_irq(int irq)
Enable_irq(int irq)
第一步:
●对于关中断
跟踪代码到arch/arm/kernel/irq.c
void disable_irq(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
disable_irq_nosync(irq);
if (desc->action)
synchronize_irq(irq);
}
Irqdesc结构体中有一个irqchip的结构体,这个结构体中有mask,unmask等函数,这些函数是在arch/arm/mach-sep4020/irq.c中注册进去的,继续跟踪disable_irq_nosync(irq);
void disable_irq_nosync(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags); //获得自旋锁,并保存中断标志位
//仅仅是增加相应中断线的irqdesc结构中的disable_depth值,把自己从irq_pending链表中摘除,再等待现在正在执行的hangdler运行完毕。
考irqdesc的handle函数do_level_IRQ(),标记triggered,调用chip->ack()应答一下后,如果disable_depth不为0,说明该中断线已经disable,不做其他处理,但每次该中断线有中断触发,还是会应答一下,只是不做__do_irq()函数做的真正的工作,
desc->disable_depth++;
list_del_init(&desc->pend);
spin_unlock_irqrestore(&irq_controller_lock, flags); //释放自旋锁,并返回之前保存的中断位
}
disable_irq 不但会禁止给定的中断,而且也会等待当前正在执行的中断处理程序完成。另一方面,disable_irq_nosync 是立即返回的。这样,使用后者将会更快,但是可能会让你的驱动程序处于竞态下——这是百度搜索的结果。
但我们可以看到其实disable_irq也是使用的disable_irq_nosync的函数体,这里纳闷!
●对于开中断
void enable_irq(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags); //获得自旋锁,并保存中断标志位
if (unlikely(!desc->disable_depth)) {
printk("enable_irq(%u) unbalanced from %p/n", irq,
__builtin_return_address(0));
} else if (!--desc->disable_depth) {
desc->probing = 0;
desc->chip->unmask(irq);//实现了开中断
//如果中断正在等待处理,尝试重新运行它;我们不能直接从这里运行,因为caller可能在一个中断保护的区域
if (desc->pending && list_empty(&desc->pend)) {
desc->pending = 0;
if (!desc->chip->retrigger ||
desc->chip->retrigger(irq))
list_add(&desc->pend, &irq_pending);
}
}
spin_unlock_irqrestore(&irq_controller_lock, flags); //释放自旋锁,并返回之前保存的中断位
}
第二步:
●在arch/arm/mach-sep4020/irq.c中对irq进行初始化,其中有部分重要代码如下:
void __init sep4020_init_irq(void)
{
……
for(i = 0; i < NR_IRQS; i++)
{
set_irq_handler(i, do_level_IRQ); //先初始化所有的中断的处理函数为一个简单的,低级的handler
set_irq_chip(i, &sep4020_chip);//将我们所写的irqchip注册到Irqdesc结构体中的irqchip的chip,就是这一步实现了arch/arm/mach-sep4020/irq.c中的函数到系统函数的注册
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);//如果设置为IRQF_VALID,则表示此中断可用,设置为IRQF_PROBE,则表示此中断可探测,如果设置为IRQF_NOAUTOEN则表示不能自动enable此中断
}
}
通过这几个函数就能实现了中断的整个过程,分析完毕,呵呵。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/myleeming/archive/2008/10/20/3111526.aspx
- 嵌入式linux的中断函数实现和分析(一)
- 嵌入式linux的中断函数实现和分析
- LINUX系统中断处理结构及中断函数的实现
- Linux内核工作笔记——嵌入式网络设备驱动程序的阅读和分析(一)
- 嵌入式中断服务函数的编写要求
- 嵌入式中断服务函数的一些特点
- arm嵌入式-中断分析
- 嵌入式系统中设备控制函数实现的分析
- Linux中断处理体系结构分析(一)
- Linux中断处理体系结构分析(一)
- Linux中断处理体系结构分析(一)
- 超强的Linux中断分析
- linux 系统中断的分析
- 超强的Linux中断分析
- Linux的中断处理分析
- linux EHCI DRIVER之中断处理函数ehci_irq()分析(一)
- linux EHCI DRIVER之中断处理函数ehci_irq()分析(一)
- linux EHCI DRIVER之中断处理函数ehci_irq()分析(一)
- 读取GPS数据的两种方法 2Gpsapi
- 创建强类型DataSet --转自:小菜之智能客户端(2)
- 记录更新 条件来自本表另一记录
- Virtual PC/Windows CE Emulator”使Windows不稳定
- Remedy7.5学习笔记3
- 嵌入式linux的中断函数实现和分析(一)
- 深入浅出MFC笔记——第一章
- JAVA相关基础知识
- LM358 双运算放大器电路的典型应用
- Action配置方法
- 设计心得
- 加密的存储过程解密
- 如何选择棋牌游戏开发公司为合作商
- [J2ME]手机唯一标识