handle_level_irq 与handle_edge_irq 的区别【转】

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 转自:http://blog.csdn.net/xavierxiao/article/details/6087277 版权声明:本文为博主原创文章,未经博主允许不得转载。 Linux 里, handle_level_irq  *    Level type interrupts a...

转自:http://blog.csdn.net/xavierxiao/article/details/6087277

Linux 里,

handle_level_irq

 *    Level type interrupts are active as long as the hardware line has
 *    the active level. This may require to mask the interrupt and unmask
 *    it after the associated handler has acknowledged the device, so the
 *    interrupt line is back to inactive.

     当中断线电平达到激活电平,中断一直会被激活。 所以需要刚进中断处理函数就要屏蔽掉中断,

等handler 处理完后再打开中断(unmask)

 

 Pesudo code

[c-sharp] view plain copy
  1. handle_level_irq()  
  2. {  
  3.   mask( irq );  
  4.   ack( irq );  
  5.   status |=IRQ_INPROGRESS;  
  6.   handle_IRQ_event();   
  7.   status &=~IRQ_INPROGRESS;   
  8.   unmask( irq );  
  9. }  

      由于irq在整个处理过程中都被屏蔽,所以需要handle_level_irq里的action要尽量简短

 

handle_edge_irq

 *    Interrupt occures on the falling and/or rising edge of a hardware
 *    signal. The occurence is latched into the irq controller hardware
 *    and must be acked in order to be reenabled. After the ack another
 *    interrupt can happen on the same source even before the first one
 *    is handled by the assosiacted event handler. If this happens it
 *    might be necessary to disable (mask) the interrupt depending on the
 *    controller hardware. This requires to reenable the interrupt inside
 *    of the loop which handles the interrupts which have arrived while
 *    the handler was running. If all pending interrupts are handled, the
 *    loop is left.

    中断发生在上升沿/下降沿, 它会被中断控制器锁存起来,需要ack 后才能重新使能。 Ack 后新的

中断可以在前一个中断正在被处理时产生,如果这种情况发生,则需要屏蔽中断。同时,需要用一个loop

来处理中断处理过程中又有中断产生的情况,在这个loop中重新把中断屏蔽打开。 如果所有pending的

中断都处理完了,loop就可以离开。

Pesudo code

[c-sharp] view plain copy
  1. handle_edge_irq()  
  2. {  
  3.    if( status & IRQ_INPROGRESS ) {  
  4.       status |= (IRQ_PENDING | IRQ_MASKED);  
  5.       mask();  
  6.       ack();  
  7.       return;  
  8.    }  
  9.      
  10.    ack();  
  11.    status |= IRQ_INPROGRESS;  
  12.    do{  
  13.        if( status & (IRQ_PENDING | IRQ_MASKED ) )  
  14.          umask();  
  15.        handle_IRQ_event();  
  16.    }while( status & IRQ_PENDING );   
  17.      
  18.    status &= ~IRQ_INPROGRESS;  
  19. }  

 

中断触发方式的比较

http://blog.21ic.com/user1/2662/archives/2007/37347.html

    沿触发: 这是很最常见的触发方式,我们可以用数字电路的方法来解释它的特性。沿触发应该应触发器来描述:  输入引脚(当作触发器的CLK) ----> 触发器------> 中断控制器 ,当输入引脚的相应的沿到来时,就会将触发器置1,并触发中断,触发器会一直保持电平1除非在ISR中用一条语句清0,否则会不断的触发中断,这也就是每 次触发中断都要清0的原因。当有高优先级的中断运行后退出时,处理器检测到触发器的值为1,所以依然会进入中断服务程序。
    电平触发: 有的时候,边沿触发很容易产生毛刺并导致误中断,这时候就要使用电平触发,电平触发是持续触发,可以用数字电路的缓冲器来描述
     输入引脚 ----> 缓冲器 ----> 中断控制器  , 缓冲器的作用就是对信号整形,并增加驱动能力,缓冲器输出的数据和输入的数据相同,可以看出输入引脚的电平直接放映到输出引脚,以高电平触发为例,只要输 入引脚的电平为高就立即触发中断,当ISR退出时如果电平依然为高则会再次触发中断,这也就是持续触发的来由,所以采用电平触发时必须保证电平的持续时间 不能太长,在ISR中可能需要适当的延时操作保证退出时电平为低,或者读出电平值,电平变低时才退出。 在带用 OS的系统中,很多关键的数据或者代码区(临界区)都需要关闭中断,那么它对中断有什么影响呢?  电平触发如果电平的持续时间比较短,很可能在关闭中断后再开中断之前电平已经变低,结果开中断后中断就没有触发,结果是这次中断被漏掉了,所以在带OS的 系统中一定不能关闭中断太久,在允许中断嵌套的情况下必须保证高优先级的中断执行时间不能超过电平的持续时间。 综合考虑,电平触发的持续时间不能太短也不能太长,在自己的系统中要仔细地考虑好中断地持续时间。
      另外,开关中断也是很讲究的,在我的开发中我就发现一种“ISR优先级翻转现象”,比如我有三个ISR,按照优先级的高低次序一次是 ISR0   ISR1  ISR2,我在ISR3 关闭ISR0的中断(因为共享数据需要互斥),可知ISR3 运行时ISR0不能得到响应,然而ISR1的优先级高于ISR2,所以在支持嵌套的情况下ISR1会打断ISR2的执行,显然这时即使ISR0中断到来也 不会得到响应,这也就是我遇到的ISR优先级翻转问题,当然这可能是我编写程序的风格不好,但是分析起来也是很有趣的,类似于任务的优先级翻转。

 

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
2月前
|
NoSQL Go 容器
Available flags for AddressSanitizer
Available flags for AddressSanitizer
|
6月前
|
机器学习/深度学习 并行计算 PyTorch
【已解决】RuntimeError: CUDA error: device-side assert triggeredCUDA kernel errors might be asynchronous
【已解决】RuntimeError: CUDA error: device-side assert triggeredCUDA kernel errors might be asynchronous
|
6月前
|
消息中间件
Handle 的sendMessageDelayed
Handle 的sendMessageDelayed
39 0
error: static assertion failed: Signal and slot arguments are not compatible.
error: static assertion failed: Signal and slot arguments are not compatible.
error: static assertion failed: Signal and slot arguments are not compatible.
|
网络安全 Windows
解决adb报错“failed to create fdevent interrupt socketpair: Invalid argument“问题
解决adb报错“failed to create fdevent interrupt socketpair: Invalid argument“问题
344 0
解决adb报错“failed to create fdevent interrupt socketpair: Invalid argument“问题
Unable to handle kernel NULL pointer dereference at virtual address 00000000问题的解决
今天在编译好内核模块后,安装内核模块memdev.ko的时候,出现了Unable to handle kernel NULL pointer dereference at virtual address 00000000等如图所示的问题:     在百度和google找了很多答案,明显就是跟指针有关系。
3194 0