电平触发中断处理和中断嵌套 [英] Level Triggered Interrupt handling and nested interrupts

查看:313
本文介绍了电平触发中断处理和中断嵌套的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[如GIC v2中的更新问题有3个寄存器ACK,EOIR,DIR]

这是我需要别人来澄清和状态,下面的顺序是正确的最基本的问题。

在下面的牌坊,

  [核心] ----- [中断控制器] --level触发 -  [设备]


     
  • 一个。设备引发的级别,并通知中断控制器

  •  
  • 乙。中断控制器触发中断的核心。 (假设核心的中断使能)

  •  
  • ℃。假设中断控制器GIC(用于ARM),它有3个寄存器

  •    

            
    1. - 中断停用(GICC_DIR)

    2.       
    3. - 中断ACK(返回IRQ号),(GICC_IAR)

    4.       
    5. - 完中断寄存器(GICC_EOIR)

    6.    

     

注:在GICv2实施,GICC_CTLR.EOImode设置为1分离的优先下降,中断停用操作。

参考:3中断处理和优先级(ARM IHI 0048B.b ID072613)


现在这就需要确认点,


        
  • Ð。直到核心犯规ACK中断拿到IRQ,中断仍然悬而未决,设备中断线路中断控制器级别高

  •     
  • 电子。核心禁用其中断。核心ACK是否得到IRQ,从设备的中断线路没有变化。

现在可以有此两种情况。


  • 系统。核心口罩上GIC特殊的中断,但确实这将清除设备的中断在设备上什么都没有。核心使得它的中断

  • 乙。核心设置GICC_EOImode = 1,并写入中断id来EOIR。核心使得它的中断

基于(A)

或(B)


  

Q1。将中断从中断控制器再次提高核心?


现在怎么会<一个href=\"http://syszux.com/book/kernel/Understanding.the.Linux.Kernel%283rd%20Edition%29/images/understandlk_0403.jpg\"相对=nofollow>中断嵌套工作在这种情况下?


解决方案

  

Q1。将在中断从中断控制器再次提高核心?


当然,它会被重新升高。这是中断引发的水平的特性。没有的状态的中断控制器。它必须或者告诉难度如果中断已被重新提出,如果它仍然存在。尤其,中断可能已经服务于一个非常小的时间和GIC不会看到高 - 低 - 高的过渡告诉一个新的和现有的中断源之间的差别。


  

Q2。如果之后(五)核心直接支持(克),将中断从中断控制器再次提高核心


这似乎等同于上面的问题。有可能是电平触发装置,其中的保养的设备离开断线高。例如,一个中断可能会 FIFO不为空。如果在 FIFO 有两个项目,第一个读取可能无法清除中断。

请参阅电平触发中断在Wikipedia 的。的维修该设备后... 的。你必须始终以服务的电平触发的中断设备。中断控制器(GIC)不知道如何外围设备的工作。在控制器把假设将限制它的使用。


  

现在怎么会打断这种情况下筑巢的工作。


目前还不清楚是什么筑巢。例如用在 FIFO 上面的例子中,可以读出设备条目的数量或读取和检查的中断状态的每次读取后。当的阅读的清除中断,它是好的重新anble中断源。

单独的IRQ源嵌套是标准配置。在步骤˚F,IRQ服务程序必须直至水平不驱动的服务设备。该 irqActive 在0x300-0x304可进行读出,以确定是否IRQ服务结束。然后,电平触发ISR的回报。如果它是$ P $任意点p抢占,控制器将检测一个新的水平源或ISR将继续提供服务的周


  • 设备引发行通知GIC。

  • GIC信号ARM内核,并跳转到矢量。

  • 矢量读取GIC中断ACK,并跳转到ISR。

  • 等级例行禁用的级别IRQ 的和重新允许中断。

  • 等级常规服务设备,直到的 irqActive 的低。 (可以在此处pre-抢先到其他的ISR)。

  • 屏蔽中断,重新启用的级别的源代码,并返回到调用者。

如果在上一步中(或之前)的附加服务项目情况,会有一个背到后面的水平中断。这将是在频繁的多个中断源将具有在同一时间段期间发生。这是典型的中断嵌套的的。整个系统将是繁忙,但延迟会更好。

部分的 3.2.1优先级降和中断停用的有以下几个步骤来禁用级中断,


  1. 阅读IAR - 活动中断的初始读

  2. 写EOIR - 从拖放到的优先级的;让低优先级的嵌套。

  3. 写DIR - 说它的结束的(或服务)

当已确定的实际设备对已被提供服务,重新启用中断。如果你希望只允许较高优先级的中断,那么写 EOIR 将被推迟,直到ISR结束;高优先级的中断将自然pre抢先级中断。

编辑:


  

现在可以有此两种情况。


  
  

一个。核心口罩上GIC特殊的中断,但确实这将清除设备的中断在设备上什么都没有。核心使得它的中断


如果中断被屏蔽,也不会重新断言


  

乙。核心设置GICC_EOImode = 1,并写入中断id来EOIR。核心使得它的中断


编写的 EOIR 的将过渡的主动+挂起的只是有效的和中断将重烧(如果你正在做的是'B ')

在<一个href=\"http://syszux.com/book/kernel/Understanding.the.Linux.Kernel%283rd%20Edition%29/images/understandlk_0403.jpg\"相对=nofollow>中断嵌套,Linux的自然做图片的第一部分。当有两个活动的ISR(右侧),这是一个可选配置; IRQ-K'期间,必须重新启用中断。它需要更多的堆栈要做到这一点,你将不得不修改标准Linux AFAIK。

EDIT2: GICC_CTRL.EOImode = 1 是混乱的。这种分离的中断服务的距离的优先级降的部分。如果你有一个临界部分和非关键的中断,可以单独的相。写的 EOIR 的关键部分之后放弃的优先级。随后的 DIR 的寄存器说,中断服务结束。我将永远离开 GICC_CTRL.EOImode = 0 ,因为我不认为这是需要做的。手动文档从中断控制器,而不是CPU的角度使用它(并因此程序员的心智模型)写的;停用表示当前的 IRQ 的线不是一般的中断。

[Updated question as GIC v2 has 3 registers ACK, EOIR, DIR]

This is the most basic question which I need someone else to clarify and state that the sequence below is correct.

In the following arch,

  [Core] ----- [ Interrupt Controller ] --Level Triggered -- [Device]

  • a. Device Raises the Level and informs the Interrupt Controller
  • b. Interrupt controller triggers core of an interrupt. (Assuming core's interrupts enabled)
  • c. Assuming the Interrupt controller is GIC (used with ARM) and it has 3 registers
    1. - Interrupt Deactivate (GICC_DIR)
    2. - Interrupt ACK (which returns the IRQ number), (GICC_IAR)
    3. - End Of Interrupt Register (GICC_EOIR)

Note: On a GICv2 implementation, setting GICC_CTLR.EOImode to 1 separates the priority drop and interrupt deactivation operations.
Ref: 3 Interrupt Handling and Prioritization (ARM IHI 0048B.b ID072613)

Now the points which need confirmation,

  • d. Till the Core doesnt ACK the interrupt to get the IRQ, the interrupt remains pending and device interrupt line to Interrupt controller level high
  • e. Core disables its interrupts. Core Does ACK get IRQ, no change in interrupt line from device.

Now there can be two cases here.

  • A. Core masks the particular interrupt on GIC, but does nothing on the device which will clear the interrupt on device. Core enables its interrupts
  • B. Core sets GICC_EOImode =1, and writes interrupt id to EOIR. Core enables its interrupts

Based on (A) or (B)

Q1. Would the interrupt be raised again from Interrupt Controller to Core?

Now how would interrupt nesting work in this case?

解决方案

Q1. Would the interrupt be raised again from Interrupt Controller to Core?

Of course, it will be re-raised. This is a property of the level triggered interrupt. There is no state in the interrupt controller. It would have difficulty to tell if the interrupt has been re-raised or if it persisted. Especially, the interrupt may have been serviced for a very small time and the GIC would not see the high-low-high transition to tell the difference between a new and an existing interrupt source.

Q2. If after (e) core directly does (g), will the interrupt be raised again from Interrupt Controller to core

This seems identical to the above question. There maybe a level triggered device where servicing the device leaves the interrupt line high. For example, an interrupt might be FIFO not empty. If the FIFO has two entries, the first read may not clear the interrupt.

See level triggered interrupts at Wikipedia. After servicing this device.... You must always service the device with level triggered interrupts. The interrupt controller (GIC) has no idea how a peripheral works. Putting assumptions in the controller will limit its use.

Now how would interrupt nesting work in this case.

It is not clear what is nesting. For instance with the FIFO example above, you can read the device for the number of entries or read and check the interrupt status after each read. When a read clears the interrupt, it is fine to re-anble the interrupt source.

Nesting of separate IRQ sources is standard. At step f, the IRQ service routine must service the device until the level is not driven. The irqActive bits at 0x300-0x304 can be read to determine if the IRQ service is finished. Then the level triggered ISR returns. If it is pre-empted at any point, the controller will detect an new level source, or the ISR will continue servicing the peripheral.

  • Device raises line informs GIC.
  • GIC signals ARM core and jumps to vector.
  • Vector reads GIC interrupt ACK and jumps to ISR.
  • Level routine disables the level IRQ and re-enables interrupts.
  • Level routine services device until irqActive low. (may pre-empt to other ISRs here).
  • Mask interrupts, re-enable level source, and return to caller.

If in the last step (or just before) an additional service item happens, there will be a back-to-back level interrupt. This will be in-frequent as multiple interrupt sources will have to happen during the same time period. This is typical of interrupt nesting. The overall system will be busier, but latency will be better.

Section 3.2.1 Priority drop and interrupt deactivation has the following steps to disable the level interrupt,

  1. read IAR - initial read of active interrupt.
  2. write EOIR - drop it from the priority; allow nesting of lower priority.
  3. write DIR - say it has ended (or serviced).

When the actual device has been determined to have been serviced, the interrupt is re-enabled. If you wish to allow only higher priority interrupts, then the write to EOIR would be delayed until the end of the ISR; the higher priority interrupts will naturally pre-empt the level interrupt.

Edit:

Now there can be two cases here.

A. Core masks the particular interrupt on GIC, but does nothing on the device which will clear the interrupt on device. Core enables its interrupts

If the interrupt is masked, it will not re-assert.

B. Core sets GICC_EOImode =1, and writes interrupt id to EOIR. Core enables its interrupts

Writing the EOIR will transition from active+pending to just active and the interrupt will refire (if all you are doing is 'B').

In interrupt nesting, Linux naturally does the first part of the picture. When there are two active ISR (right side), this is an optional configuration; during 'IRQ-k', interrupts must be re-enabled. It takes more stack to do this and you will have to modify the stock Linux afaik.

Edit2: The GICC_CTRL.EOImode =1 is confusing. This separates the interrupt serviced from the priority drop portion. If you have an interrupt with a critical portion and a non-critical, you can separate the phases. Write to EOIR after the critical portion to drop the priority. Then the DIR register says that the interrupt service is finished. I would always leave GICC_CTRL.EOImode=0 as I don't think this is needed. The manual documentation is written from the perspective of the interrupt controller and not a CPU using it (and hence a programmer's mental model); deactivated means the current IRQ line and not the interrupt in general.

这篇关于电平触发中断处理和中断嵌套的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆