我对裸机编程非常陌生,以前从未接触过中断,但我一直在学习 RISC-V FE310-G002 SOC 驱动的开发板。
我一直在阅读有关 RISC-V WFI(等待中断)指令和手册的信息,听起来您不能依靠它来真正使内核休眠。相反,它只是建议系统可以暂停执行,并且应该将指令视为更像 NOP。但是,这对我来说似乎毫无用处。考虑以下 ASM 程序片段:
wfi_loop:
WFI
J wfi_loop
由于不能依赖 WFI,因此必须这样做。但是,在来自中断处理程序的 MRET 之后,您仍然会被困在循环中。因此,您必须以全局变量为条件,该变量的值在中断处理程序中更新。这似乎非常混乱。
此外,如果您的实现确实遵守 WFI 指令并且在 WFI 指令执行之前触发了中断,则整个内核将停止,直到触发其他中断,因为它将在 WFI 指令之前返回。
当没有工作要做时,该指令的唯一正确用法似乎是在内核调度程序中。但即便如此,我认为您永远不会希望从中断处理程序返回到此类代码,而是从头开始重新启动调度程序算法。但这也是一个问题,因为您将不得不以某种方式回滚堆栈等......
我一直在脑子里转来转去,似乎无法找到安全的使用方法。也许,如果您以原子方式使用 CSRRS 启用中断,然后立即像这样调用 WFI:
CSRRSI zero, mie, 0x80
wfi_loop:
WFI
J wfi_loop
NOP
NOP
然后确保在从中断处理程序调用 MRET 之前将 mepc 寄存器增加 8 个字节。在返回之前,还必须在中断处理程序内部的 mie 寄存器中再次禁用中断。这种解决方案只有在 WFI、J 和 NOP 都被编码为 4 字节指令时才是安全的,无论是否使用压缩指令。它还取决于程序计数器在被 CSRRSI 指令启用后,在可能触发中断之前到达 WFI 指令。然后,这将允许在代码中的安全位置触发中断,并以中断等待它的循环的方式返回。
我想我只是想了解我可以从硬件中得到什么行为,因此,如何正确调用中断并从中断返回并使用 WFI 指令?