原文网址: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独占而发生系统崩溃.

【转】中断处理函数中不用disable_irq而用disable_irq_nosync原因的更多相关文章

  1. 中断处理函数中不用disable_irq而用disable_irq_nosync原因【转】

    转自:http://blog.csdn.net/beyondioi/article/details/9201695 今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现在进入中断处 ...

  2. Realview MDK 中不用手动开中断的原因

    startup.s启动代码文件: ; Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR ...

  3. 裸板中中断异常处理,linux中断异常处理 ,linux系统中断处理的API,中断处理函数的要求,内核中登记底半部的方式

    1.linux系统中的中断处理  1.0裸板中中断异常是如何处理的?     以s5p6818+按键为例          1)按键中断的触发        中断源级配置            管脚功 ...

  4. Linux驱动实践:中断处理函数如何【发送信号】给应用层?

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  5. 函数中声明变量不用Var的情况

    我们都知道函数中声明变量不用Var时这个变量会成为全局变量,但是并不是函数一开始执行就会把它变为全局变量,必须执行到这条语句. 看一段代码 function f(){    alert(a);    ...

  6. ES6 箭头函数中的 this?你可能想多了(翻译)

    箭头函数=>无疑是ES6中最受关注的一个新特性了,通过它可以简写 function 函数表达式,你也可以在各种提及箭头函数的地方看到这样的观点——“=> 就是一个新的 function”. ...

  7. IOAPIC重定位中断处理函数思路整理

    因为小可并非硬件编程出身,汇编基础又比较差...所以刚开始理解利用IOAPIC重定位技术的时候相当困难. 何为IOAPIC? 首先,必须认识到它是一个硬件,可编程的硬件.我理解的它在整个流程中的作用如 ...

  8. javascript函数中的三个技巧【二】

    技巧二: [惰性载入函数] 因为浏览器之间的行为的差异,我们经常会在函数中包含了大量的if语句,以检查浏览器特性,解决不同浏览器的兼容问题,比如,我们最常见的为dom节点添加时间的函数 functio ...

  9. C++ 数组长度 以及 数组名作为参数传递给函数 以及 为什么不在子函数中求数组长度

    在看排序,首先是插入排序,思路理清后想用代码实现,然后问题来了: 如何求数组长度? 如果没记错,在Java中应该是有直接可用的方法的, Python中(序列)也有.len,在C/C++中,字符串倒是有 ...

随机推荐

  1. oracle管道输出

    通常我们会在oracle中用dbms_output输出调试信息,但dbms_output只能在调用过程完成才返回结果,不能实时输出的.这意味着通常我们经常要等几分钟或更长的时间才能看到调试信息,那怎么 ...

  2. Android Toast封装

    package com.whoop.mobile.trace.util; import android.content.Context; import android.content.res.Reso ...

  3. Mysql + keepalived 实现双主热备读写分离【转】

    Mysql + keepalived 实现双主热备读写分离 2013年6月16日frankwong发表评论阅读评论   架构图 系统:CentOS6.4_X86_64软件版本:Mysql-5.6.12 ...

  4. 关于BT下载的一点事儿

    之前一直对BT下载很的好奇,今天迅雷出现了一些问题,于是上网了解了一下BT下载的原理,果然还是有所收获的. 1.为什么BT下载用户越多下载,速度越快? 答:BT全名为BitTorrent. 在传统下载 ...

  5. 配置本地yum源的方法

    配置本地yum源的方法 1. 挂载光驱 如果是上传iso镜像到服务器上,则直接挂载iso镜像即可: #mount -o loop -t iso9660 /xxxx.iso /挂载目录 开机自动加载#v ...

  6. IIS配置

    IIS配置文档: 1.安装IIS.控制面板→程序→打开关闭Windows功能,Web管理服务和万维网服务都勾上. 2.部署网站:ASP.Net项目的发布:项目中点右键“发布”,选择“文件系统”,发布到 ...

  7. (转)C#读取文件路径

    //获取包含清单的已加载文件的路径或 UNC 位置. public static string sApplicationPath = Assembly.GetExecutingAssembly ( ) ...

  8. Html.Action、html.ActionLink与Url.Action的区别

    1.html.ActionLink返回的指向指定controller.指定action的超链接标签<a>标签.如果没有指定controller,则默认为本页面对应的Controller. ...

  9. c - 给分数分级别

    /* 题目: 学习成绩>=90 分的同学用 A 表示, 80-89 分之间的用 B 表示,70-79 分的用 C 表示, 60-69 分用 D表示,小于60分用E表示. 分析: 使用swith. ...

  10. Linux && vim 批量替换

    Linux批量文件的字符串替换 sed -i "s/oldstring/newstring/g" `grep oldstring -rl path` vim多行替换::1,2s/s ...