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

问题描述 投票:0回答:4

当使用依赖于 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 指令之前没有未完成的内存事务。”

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

freertos cortex-m
4个回答
3
投票

我相信ISB的目的是确保wfi指令“按顺序”执行,并且在它被唤醒之前没有任何指令被执行。也就是说,根据 ARM 文档,我认为这不是必需的。我怀疑这是腰带和牙套的方法。


0
投票

ISB 添加在 WFI 之后,因为程序员希望确保 WFI 应在 WFI 之后的任何指令之前执行。 ARM 还具有支持乱序执行的 A 级内核。如果我们通过删除无序核心上的 ISB 来运行上述代码,则 WFI 之后的指令可能会在 WFI 之前执行。


0
投票

ISB 指令将导致流水线在某个时刻被刷新,它的一个用例是强制指令执行的顺序,基于此,如果我们在 WFI 之后有一条指令,我们可能希望 WFI 在下一条指令之前真正执行特别是,对于支持乱序执行模型或超标量模型的更复杂的 Arm 处理器,我们可能会在 WFI 被获取并馈送到处理器管道后获得指令,这里的一种解决方法是使用 ISB 刷新管道,从而导致执行WFI会触发CPU进入睡眠模式,我们保证下一条指令不会被执行


-1
投票

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

来自 ARM cortex-M3 指南。

DSB 和 ISB 指令对于自修改代码非常重要。例如,如果一个程序 更改了自己的程序代码,下一条执行的指令应基于更新后的程序。 然而,由于处理器是流水线的,修改后的指令位置可能已经被 取来的。先使用DSB,然后使用ISB,可以确保修改后的程序代码被再次取出。 从架构上来说,ISB指令应该在更新CONTROL寄存器的值之后使用。在 Cortex-M3 处理器中,这不是严格要求的。但如果您想确保您的应用程序是可移植的,您应该确保在更新到 CONTROL 寄存器后使用 ISB 指令。

© www.soinside.com 2019 - 2024. All rights reserved.