为什么在 Cortex-M FreeRTOS 中的 WFI 之后需要 ISB?

Why is an ISB needed after WFI in Cortex-M FreeRTOS?

在使用依赖于 WFI 指令的 tickless idle 功能时,我在 FreeRTOS 的 Cortex-M 端口中看到以下行

__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );

https://github.com/cjlano/freertos/blob/V9.0.0/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c#L530

我看到根据 ARM Cortex-M 内存屏障指令编程指南文档:"A DSB should be used to ensure that there are no outstanding memory transactions prior to executing the WFI or WFE instruction."

但是我很好奇为什么这里需要ISB?也许这可以确保从 WFI 唤醒芯片的中断在可能位于管道中的任何进一步指令之前立即执行?这是我最好的猜测,但想听听任何其他想法或确认。

ISB 指令刷新管道并确保所有 在执行新指令之前完成先前的指令。

来自 ARM cortex-M3 指南。

The DSB and ISB instructions can be important for self-modifying code. For example, if a program changes its own program code, the next executed instruction should be based on the updated program. However, since the processor is pipelined, the modified instruction location might have already been fetched. Using DSB and then ISB can ensure that the modified program code is fetched again. Architecturally, the ISB instruction should be used after updating the value of the CONTROL register. In the Cortex-M3 processor, this is not strictly required. But if you want to make sure your application is portable, you should ensure an ISB instruction is used after updating to CONTROL register.

我相信ISB的意图是确保wfi指令被执行"in order"并且在它被唤醒之前不会执行它之后的指令。也就是说,根据 ARM 文档,我认为它不是必需的。我怀疑这是腰带和牙套的方法。

ISB 被添加到 WFI 之后,因为程序员希望确保 WFI 应该在 WFI 之后的任何指令之前执行。 ARM 也有支持乱序执行的 A-Class 核心。如果我们 运行 通过删除乱序内核上的 ISB 来编写上面的代码,那么 WFI 之后的指令可能会在 WFI 之前执行。