【问题标题】:Why is an ISB needed after WFI in Cortex-M FreeRTOS?为什么在 Cortex-M FreeRTOS 中的 WFI 之后需要 ISB?
【发布时间】:2017-10-30 19:00:07
【问题描述】:

在使用依赖于 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


    【解决方案1】:

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

    【讨论】:

    • 这也可能是一种解决方法,例如针对特定核心实现中的管道错误。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      ISB 指令刷新流水线并确保所有 之前的指令在执行新指令之前完成。

      来自 ARM cortex-M3 指南。

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

      【讨论】:

      • 您引用的文档仅提到了自修改代码,这不适用于 FreeRTOS,而 CONTROL 寄存器也不适用于 FreeRTOS。所以你的回答没有解释 ISB 与 WFI 的关系。
      猜你喜欢
      • 2017-06-07
      • 2016-04-15
      • 2014-06-11
      • 2017-03-16
      • 1970-01-01
      • 2014-06-25
      • 2016-07-13
      • 2017-05-22
      • 1970-01-01
      相关资源
      最近更新 更多