ARM WFI 不会休眠

Jul*_*ien 0 arm interrupt cortex-m

我正在尝试在 Cortex-M4 上进入待机模式。正常的行为是设备大约每 2 分钟唤醒一次,但在我最新的固件版本中,代码似乎是“随机”卡住的。

经过调查,代码似乎WFI在没有进入待机状态的情况下传递了指令(无待机 => 无重置 => 无限循环 => ... => 42)。

因此,在阅读了许多不清楚的规范之后,我的理解是,WFI如果存在待处理的中断,则可能不会进入睡眠状态。

  1. 你能确认最后一句话吗
  2. 如何确保在调用之前清除所有挂起的中断WFI

and*_*ngo 5

三种情况会导致处理器从 WFI 指令中唤醒:

  1. 发生非屏蔽中断且其优先级大于当前执行优先级(即采取中断)
  2. 被 PRIMASK 屏蔽的中断变为待处理状态
  3. 调试条目请求。

如果执行 WFI 指令时任何唤醒条件为真,则它实际上是 NOP(即不进入睡眠状态)。

至于确保没有待处理的中断,这是您的代码必须执行的操作。通常这意味着确保满足中断源,以便它不会断言其中断请求,然后清除必要的挂起位。您可以通过读取中断挂起寄存器来查看挂起的内容,但中断处理程序通常负责确保它们使事物保持静止状态。

请注意,大多数系统必须在执行 WFI 之前或之后立即执行一些工作。例如,在决定使用 WFI 入睡之前,通常必须进行一项测试来确定是否需要做任何额外的工作。然后,该测试和 WFI 的执行在 PRIMASK 设置为 1 的关键部分完成(因此我们正在执行上面的选项 #2)。这将确保测试和 WFI 之间不会出现中断,并且在唤醒后,如果需要完成其他操作(通常涉及时钟),则不会出现中断。唤醒后,PRIMASK 被设置回 0(退出临界区),并且任何挂起的中断都会被处理。

此外,ARM 建议在 WFI 之前立即执行 DSB 指令,以确保在处理器进入睡眠状态之前完成所有数据操作。可能并非在所有情况下都绝对有必要,但将其放入以防万一情况发生变化并且您忽略了它。