我有这样的代码希望可以在wfi上停止cpu:
__asm volatile ( "MSR DAIFSET, #15" );
__asm volatile ( "DSB SY" );
__asm volatile ( "ISB SY" );
__asm volatile ("wfi");
print("never get here\n");
问题是我总是收到“永不到达这里”的日志,为什么会发生这种情况? irq发生了,我可以猜到是拱形计时器PPI。但是不应该禁用它吗?
平台是el3中的cortex-a53。
我将代码更改为:
__asm volatile ( "MSR DAIFSET, #15" );
__asm volatile ( "DSB SY" );
__asm volatile ( "ISB SY" );
while (1) {
__asm volatile ("wfe");
print("never get here\n");
}
我无休止的“永不到达这里”,唤醒事件的源头是什么?
答案 0 :(得分:2)
wfi
不能以您认为的方式工作。参见ARMv8 Reference Manual,第D1.17.2节:
D1.17.2等待中断
[...]
该体系结构允许PE出于任何原因退出低功耗状态,但是要求它必须在收到任何架构的WFI唤醒事件后必须退出低功耗状态。----------注意----------
由于该体系结构允许PE出于任何原因而退出低功耗状态,因此允许PE将WFI视为NOP,但这不建议用于最低功耗操作。
----------------------------[...]
WFI唤醒事件
以下是WFI唤醒事件:
- PE接收到的任何物理SError中断,IRQ中断或FIQ中断,无论相应的PSTATE的值如何。{A,I,F}屏蔽位。
- [...]
----------注意----------
- WFI唤醒事件永远不会被EDSCR.INTdis禁用,也永远不会被PSTATE屏蔽。{A,I,F}屏蔽位。如果被禁用或屏蔽的中断调用唤醒功能,则不会接受该中断。
- [...]
----------------------------
因此您的中断屏蔽效果很好,只是wfi
对此并不在意,而只是一个nop
即可。
与此相反,wfe
似乎被设计为强制进入低功耗状态,并且确实采用了中断屏蔽。我只浏览了一下,所以可能有一些警告,但请参阅手册中的G1.18.1节。