Q1。中断会再次从中断控制器引发到核心吗?
当然,它会被重新筹集。这是电平触发中断的一个属性。中断控制器中没有状态。很难判断中断是被重新提出还是持续存在。特别是,中断可能已经服务了很短的时间,GIC 不会看到高-低-高转换来区分新中断源和现有中断源之间的区别。
Q2。如果(e)之后core直接做(g),会不会再次从Interrupt Controller向core提出中断
这似乎与上述问题相同。可能存在一个电平触发设备,在该设备服务该设备时,中断线为高电平。例如,中断可能是FIFO not empty。如果FIFO有两个入口,第一次读取可能不会清除中断。
请参阅Wikipedia 上的级别触发中断。 维修此设备后...... 您必须始终使用电平触发中断服务设备。中断控制器 (GIC) 不知道外设是如何工作的。将假设放入控制器将限制其使用。
现在在这种情况下如何中断嵌套工作。
目前尚不清楚什么是嵌套。例如,对于上面的FIFO示例,您可以读取设备的条目数或读取并在每次读取后检查中断状态。当读取清除中断时,可以重新启用中断源。
单独的 IRQ 源的嵌套是标准的。在步骤f中,IRQ 服务例程必须为设备服务,直到电平未被驱动。可以读取 0x300-0x304 处的irqActive位以确定 IRQ 服务是否完成。然后电平触发的 ISR 返回。如果它在任何时候被抢占,控制器将检测到新的电平源,或者 ISR 将继续为外设提供服务。
- 设备升线通知 GIC。
- GIC 向 ARM 内核发送信号并跳转到向量。
- Vector读取GIC中断ACK并跳转到ISR。
- 级别例程禁用级别 IRQ并重新启用中断。
- 电平例程服务设备直到irqActive低。(可在此处抢占其他 ISR)。
- 屏蔽中断,重新启用电平源,并返回给调用者。
如果在最后一步(或之前)发生了额外的服务项目,则会有一个背靠背级别的中断。这种情况很少发生,因为多个中断源必须在同一时间段内发生。这是典型的中断嵌套。整个系统会更忙,但延迟会更好。
第3.2.1 节优先级下降和中断去激活有以下步骤来禁用电平中断,
- 读取 IAR - 活动中断的初始读取。
- 写EOIR-从优先级中删除它;允许嵌套较低优先级。
- 写 DIR - 说它已经结束(或服务)。
当确定实际设备已被服务时,中断被重新启用。如果您希望只允许更高优先级的中断,则写入EOIR
将延迟到 ISR 结束;较高优先级的中断自然会抢占级别中断。
编辑:
现在这里可能有两种情况。
A. 核心屏蔽 GIC 上的特定中断,但在设备上不执行任何操作来清除设备上的中断。核心启用其中断
如果中断被屏蔽,则不会重新断言。
B. Core 设置 GICC_EOImode =1,并将中断 id 写入 EOIR。核心启用其中断
写入EOIR将从active+pending转换为 just active,并且中断将重新触发(如果您所做的只是“B”)。
在中断嵌套中,Linux 自然做了第一部分。当有两个活动 ISR(右侧)时,这是一个可选配置;在“IRQ-k”期间,必须重新启用中断。这样做需要更多的堆栈,您将不得不修改库存的 Linux afaik。
Edit2: 这GICC_CTRL.EOImode =1
令人困惑。这将服务的中断与优先级下降部分分开。如果您有一个关键部分和非关键部分的中断,您可以将这些阶段分开。在关键部分之后写入EOIR以降低优先级。然后DIR寄存器说中断服务完成了。我总是会离开GICC_CTRL.EOImode=0
,因为我认为这没有必要。手册文档是从中断控制器的角度编写的,而不是从使用它的 CPU 的角度编写的(因此是程序员的心理模型);deactivated 表示当前的IRQ线,而不是一般的中断。