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

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

问题描述

[更新问题,因为 GIC v2 有 3 个寄存器 ACK、EOIR、DIR]

这是最基本的问题,我需要别人来澄清并说明以下顺序是正确的.

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

在下面的拱门中,

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

  • 设备提升电平并通知中断控制器
  • B.中断控制器触发中断的核心.(假设内核的中断已启用)
  • C.假设中断控制器是 GIC(与 ARM 一起使用)并且它有 3 个寄存器
    1. - 中断停用 (GICC_DIR)
    2. - 中断 ACK(返回 IRQ 编号),(GICC_IAR)
    3. - 中断寄存器结束 (GICC_EOIR)

    注意:在 GICv2 实现中,将 GICC_CTLR.EOImode 设置为 1 将优先级删除和中断停用操作分开.
    参考:3 中断处理和优先级 (ARM IHI 0048B.b ID072613)

    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)

    现在需要确认的点,

    • d.直到内核没有确认中断以获得 IRQ,中断保持挂起并且设备中断线到中断控制器级别高
    • e.核心禁用其中断.核心 ACK 是否获得 IRQ,设备的中断线没有变化.

    现在可能有两种情况.

    • A.核心屏蔽 GIC 上的特定中断,但不会在设备上执行任何操作来清除设备上的中断.核心启用其中断
    • B.Core 设置 GICC_EOImode =1,并将中断 id 写入 EOIR.核心启用其中断

    基于(A)或(B)

    第一季度.是否会再次从中断控制器向内核提出中断?

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

    现在如何 中断嵌套在这种情况下工作吗?

    Now how would interrupt nesting work in this case?

    推荐答案

    Q1. 是否会再次从中断控制器向内核提出中断?

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

    当然,它会被重新加注.这是电平触发中断的属性.中断控制器中没有状态.很难判断中断是重新引发还是持续存在.特别是,中断可能已经被服务了很短的时间,GIC 不会看到高-低-高转换来区分新的和现有的中断源.

    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.如果在(e)核直接做(g)之后,中断是否会再次从中断控制器向核提出

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

    这似乎与上述问题相同.可能有一个电平触发设备,其中服务设备将中断线保持为高电平.例如,中断可能是FIFO 非空.如果FIFO有两个入口,第一次读取可能不会清除中断.

    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.

    请参阅维基百科的级别触发中断.维修此设备后....您必须始终使用级别触发中断来服务设备.中断控制器 (GIC) 不知道外设是如何工作的.将假设置于控制器中会限制其使用.

    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.

    不清楚什么是嵌套.例如上面的FIFO示例,您可以读取设备的条目数或在每次读取后读取并检查中断状态.当清除中断后,重新启动中断源就可以了.

    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.

    独立 IRQ 源的嵌套是标准的.在步骤f,IRQ 服务例程必须为设备提供服务,直到电平没有被驱动.irqActive 可以读取 0x300-0x304 处的位来确定 IRQ 服务是否完成.然后触发 ISR 的电平返回.如果它在任何时候被抢占,控制器将检测到一个新的电平源,或者 ISR 将继续为外设提供服务.

    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.

    • 设备提升线通知 GIC.
    • GIC 向 ARM 内核发送信号并跳转到向量.
    • Vector 读取 GIC 中断 ACK 并跳转到 ISR.
    • 级别例程禁用级别 IRQ 并重新启用中断.
    • 将常规服务设备调至 irqActive 低电平.(可能会抢占此处的其他 ISR).
    • 屏蔽中断,重新启用级别源,并返回给调用者.
    • 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.

    3.2.1 Priority drop and interrupt deactivation部分有以下步骤来禁用电平中断,

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

    1. 读取 IAR - 活动中断的初始读取.
    2. 写 EOIR - 从优先级中删除它;允许嵌套较低优先级.
    3. 写 DIR - 说它已经结束(或服务).
    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).

    当确定已为实际设备提供服务时,将重新启用中断.如果您希望只允许更高优先级的中断,那么写入 EOIR 将被延迟到 ISR 结束;更高优先级的中断自然会抢占级别中断.

    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.

    现在这里可能有两种情况.

    Now there can be two cases here.

    A.核心屏蔽 GIC 上的特定中断,但不会在设备上执行任何操作来清除设备上的中断.核心启用其中断

    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 设置 GICC_EOImode =1,并将中断 id 写入 EOIR.核心启用其中断

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

    写入 EOIR 将从 active+pending 转换为 active 并且中断将重新触发(如果您所做的只是'B').

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

    中断嵌套,Linux 自然做了图的第一部分.当有两个活动的ISR(右侧)时,这是一个可选配置;在IRQ-k"期间,必须重新启用中断.要做到这一点需要更多的堆栈,你将不得不修改股票 Linux afaik.

    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: GICC_CTRL.EOImode =1 令人困惑.这将中断服务优先级下降部分分开.如果您有一个包含关键部分和非关键部分的中断,您可以将这些阶段分开.在关键部分之后写入 EOIR 以降低优先级.然后 DIR 寄存器表示中断服务完成.我总是会离开 GICC_CTRL.EOImode=0 因为我认为不需要这样做.手册文档是从中断控制器的角度编写的,而不是从使用它的 CPU 的角度编写的(因此是程序员的心智模型);停用意味着当前的 IRQ 行,而不是一般的中断.

    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天全站免登陆