嵌入式linux的中断函数实现和分析
来源:互联网 发布:万达电商 玩数据百家 编辑:程序博客网 时间:2024/05/18 01:33
分析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此中断
}
}
通过这几个函数就能实现了中断的整个过程,分析完毕,呵呵。
ps:这些都是基于sep4020的linux2.6.16实现的,可能有了基于sep4020的linux源代码更方便看懂,如果有兴趣,可以留下电子邮箱,我会把相应的patch发到邮箱里。
- 嵌入式linux的中断函数实现和分析
- 嵌入式linux的中断函数实现和分析(一)
- LINUX系统中断处理结构及中断函数的实现
- 嵌入式中断服务函数的编写要求
- 嵌入式中断服务函数的一些特点
- arm嵌入式-中断分析
- 嵌入式系统中设备控制函数实现的分析
- 超强的Linux中断分析
- linux 系统中断的分析
- 超强的Linux中断分析
- Linux的中断处理分析
- linux内核分析笔记---中断实现
- 《Linux操作系统分析》之分析精简的Linux的内核中断和时间片轮询
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】深入剖析Linux中断机制之三--Linux对异常和中断的处理
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】深入剖析Linux中断机制之三--Linux对异常和中断的处理
- 嵌入式Linux的技术分析
- linux内核分析笔记----中断和中断处理程序
- linux内核分析笔记----中断和中断处理程序
- DES-JAVA
- 将一个图片以二进制值的形式存入Xml文档中
- velocity模板引擎简介
- 信息化管理中细节决定成败
- 用vimdiff查看cvs管理下的不同版本
- 嵌入式linux的中断函数实现和分析
- 设计 Microsoft SQL Server 2005 基础结构
- 残疾人太不容易了
- 什么是A记录?什么是别名记录(CNAME)?什么是MX记录?什么是NS记录?
- 我的C语言快速排序方法
- Windows 文件系统操作之一[前言]
- Windows 文件系统操作之二[概述]
- 删除表内的重复数据
- 韩国男子纵火砍死6人 受害者多为中国女性