当使用依赖于WFI指令的无空闲空闲功能时,我在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内存屏障指令编程指南文档:"应该使用DSB来确保在执行WFI或WFE指令之前没有未完成的内存事务。&#34 ;
但我很好奇为什么ISB在这里是必要的?也许这可以确保从WFI唤醒芯片的中断在可能位于管道中的任何进一步指令之前立即执行?这是我最好的猜测,但希望听到任何其他想法或确认。
答案 0 :(得分:1)
我认为ISB的目的是确保执行wfi指令"顺序"它被执行后没有任何指令,直到它被唤醒。也就是说,根据ARM文档,我认为不需要它。我怀疑这是腰带和牙套的方法。
答案 1 :(得分:0)
在WFI之后添加了ISB,因为程序员希望确保WFI应该在WFI之后的任何指令之前执行。 ARM还具有支持乱序执行的A级内核。如果我们通过删除乱序内核上的ISB来运行上述代码,则WFI之后的指令可能会在WFI之前执行。
答案 2 :(得分:-1)
ISB指令刷新管道并确保全部 在执行新指令之前,先前的说明已完成。
来自ARM cortex-M3指南。
DSB和ISB指令对于自修改代码非常重要。例如,如果一个程序 更改自己的程序代码,下一个执行的指令应该基于更新的程序。 但是,由于处理器是流水线的,因此修改后的指令位置可能已经过 牵强。使用DSB然后ISB可以确保再次获取修改的程序代码。 在架构上,应在更新CONTROL寄存器的值后使用ISB指令。在Cortex-M3处理器中,这不是严格要求的。但是如果你想确保你的应用程序是可移植的,你应该确保在更新到CONTROL寄存器后使用ISB指令。