原文网址:http://blog.csdn.net/skyflying2012/article/details/8265869
今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现在进入中断处理后内核就挂掉了,于是研究了一下才发现disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回. 在中断处理程序中应该使用disable_irq_nosync来关闭中断
先看一下disable_irq_nosync,内核代码中是这样解释的:
/** * disable_irq_nosync - disable an irq without waiting * @irq: Interrupt to disable * * Disable the selected interrupt line. Disablesand Enables are * nested. * Unlike disable_irq(),this function doesnot ensure existing * instances of the IRQ handler have completed before returning. * * This function may be called from IRQ context. */ void disable_irq_nosync(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags;
if (!desc) return;
chip_bus_lock(irq, desc); spin_lock_irqsave(&desc->lock, flags); __disable_irq(desc, irq, false); spin_unlock_irqrestore(&desc->lock, flags); chip_bus_sync_unlock(irq, desc); }
|
关闭中断后程序返回, 如果在中断处理程序中, 那么会继续将中断处理程序执行完.
/** * disable_irq - disable an irq and wait for completion * @irq: Interrupt to disable * * Disable the selected interrupt line. Enables and Disables are * nested. * This function waits for any pending IRQ handlers for this interrupt * to complete before returning. If you use this function while * holding a resource the IRQ handler may need you will deadlock. * * This function may be called - with care - from IRQ context. */ void disable_irq(unsignedint irq) { struct irq_desc *desc = irq_desc + irq; if (irq>= NR_IRQS) return; disable_irq_nosync(irq); if (desc->action) synchronize_irq(irq); }
|
关闭中断并等待中断处理完后返回.从代码中可以看到, disable_irq先是调用了disable_irq_nosync, 然后检测desc->action是否为1. 在中断处理程序中, action是置1的, 所以进入synchronize_irq函数中.
/** * synchronize_irq - wait for pending IRQ handlers (on other CPUs) * @irq: interrupt number to wait for * * This function waits for any pending IRQ handlers for this interrupt * to complete before returning. If you use this function while * holding a resource the IRQ handler may need you will deadlock. * * This function may be called - with care - from IRQ context. */ void synchronize_irq(unsignedint irq) { struct irq_desc *desc= irq_to_desc(irq); unsigned int status; if (!desc) return; do { unsigned long flags; /* * Wait until we're out of the critical section. This might * give the wrong answer due to the lack of memory barriers. */ while (desc->status& IRQ_INPROGRESS) cpu_relax(); /* Ok, that indicated we're done: double-check carefully. */ spin_lock_irqsave(&desc->lock, flags); status = desc->status; spin_unlock_irqrestore(&desc->lock, flags); /* Oops, that failed? */ } while (status & IRQ_INPROGRESS); /* * We made sure that no hardirq handler is running. Now verify * that no threaded handlers are active. */ wait_event(desc->wait_for_threads,!atomic_read(&desc->threads_active)); }
|
注释中说明该函数是在等待中断处理程序的结束, 这也是disable_irq与disable_irq_nosync不同的主要所在. 但是在中断处理函数中调用会发生什么情况呢? 进入中断处理函数前IRQ_INPROGRESS会被__setup_irq设置, 所以程序会一直陷在while循环中, 而此时内核以经被独占, 这就导致系统死掉.
总结:
由于在disable_irq中会调用synchronize_irq函数等待中断返回, 所以在中断处理程序中不能使用disable_irq, 否则会导致cpu被synchronize_irq独占而发生系统崩溃.
最新文章
- [转]Java使用commons-dbcp2.0
- UVA 10474 大理石在哪 lower_bound
- 语音直播是否真能让国内网红向“Creator”转变?
- MySql 分页
- python表达式
- “通过jumpserver远程登录linux服务器,rz上传文件速度过慢”问题的解决
- 关于php的一些小知识
- 解决li在ie,firefox中行高不一致问题
- hdu 1113 Word Amalgamation
- tomcat配置文件server.xml具体解释
- Oracle表空间扩展
- Python进阶(面向对象编程基础)(二)
- 关于ActionBar的向下兼容
- Swift - 类初始化和反初始化方法(init与deinit)
- socket通信实例
- win7系统盘扩容后不识别修复方法
- navicate连接不上阿里云mysql
- ORACLE跨数据库查询的方法
- 树莓派apt-get The value '\stable' is invalid for APT 错误
- ESAPI学习笔记
热门文章
- iOS 设备和外部配件的通讯
- SKPhysicsContact类
- android插件化-获取apkplug框架已安装插件-03
- 泛泰A870刷4.4专用英文版非触摸CWM Recovery 6.0.4.8(三版通刷)
- C语言判断文件是否存在
- mysql 修复表和优化表
- 【c#】Form调用百度地图api攻略及常见问题
- javascript內容向上不間斷滾動
- Chapter 4. Using the Gradle Command-Line 使用gradle命令行
- Centos6 安装vnc