ARM WFI 不会休眠
ARM WFI won't sleep
我正在尝试在 Cortex-M4 上进入待机模式。正常行为是设备大约每 2 分钟唤醒一次,但在我最新的固件版本中,代码似乎 "randomly" 卡住了。
经过调查,似乎代码通过了 WFI
指令而没有进入待机状态(无待机 => 无复位 => 无限循环 => ... => 42)。
所以在阅读了很多不清楚的规范之后,我的理解是 WFI
如果有未决的中断可能不会进入睡眠状态。
- 你能确认最后一句话吗
- 如何确保在调用
WFI
之前清除所有挂起的中断?
导致处理器从 WFI 指令唤醒的三种情况:
- 发生非屏蔽中断且其优先级大于当前执行优先级(即取中断)
- 被 PRIMASK 屏蔽的中断变为挂起
- 一个调试入口请求。
如果在执行 WFI 指令时任何唤醒条件为真,则它实际上是一个 NOP(即您不进入睡眠状态)。
至于确保没有挂起的中断,这是您的代码必须做到的。通常这意味着确保中断源得到满足,这样它就不会断言其中断请求,然后清除必要的挂起位。您可以通过读取中断挂起寄存器来查看挂起的内容,但中断处理程序通常负责确保它们保持静止状态。
请注意,大多数系统必须在执行 WFI 之前或之后立即执行一些工作。例如,在决定使用 WFI 入睡之前,通常必须进行一项测试以确定是否还有任何额外的工作要做。然后在 PRIMASK 设置为 1 的关键部分完成该测试和 WFI 的执行(因此我们正在执行上面的选项 #2)。这将确保在测试和 WFI 之间没有中断,并且在唤醒后,如果有额外的操作(通常涉及时钟)需要完成,则没有中断。唤醒后,PRIMASK 被设置回 0(退出临界区),任何挂起的中断都会被接受。
此外,ARM 建议在 WFI 之前立即执行 DSB 指令,以确保在处理器进入睡眠状态之前完成所有数据操作。它可能并非在所有情况下都绝对必要,但以防万一情况发生变化而您忽略了它。
我正在尝试在 Cortex-M4 上进入待机模式。正常行为是设备大约每 2 分钟唤醒一次,但在我最新的固件版本中,代码似乎 "randomly" 卡住了。
经过调查,似乎代码通过了 WFI
指令而没有进入待机状态(无待机 => 无复位 => 无限循环 => ... => 42)。
所以在阅读了很多不清楚的规范之后,我的理解是 WFI
如果有未决的中断可能不会进入睡眠状态。
- 你能确认最后一句话吗
- 如何确保在调用
WFI
之前清除所有挂起的中断?
导致处理器从 WFI 指令唤醒的三种情况:
- 发生非屏蔽中断且其优先级大于当前执行优先级(即取中断)
- 被 PRIMASK 屏蔽的中断变为挂起
- 一个调试入口请求。
如果在执行 WFI 指令时任何唤醒条件为真,则它实际上是一个 NOP(即您不进入睡眠状态)。
至于确保没有挂起的中断,这是您的代码必须做到的。通常这意味着确保中断源得到满足,这样它就不会断言其中断请求,然后清除必要的挂起位。您可以通过读取中断挂起寄存器来查看挂起的内容,但中断处理程序通常负责确保它们保持静止状态。
请注意,大多数系统必须在执行 WFI 之前或之后立即执行一些工作。例如,在决定使用 WFI 入睡之前,通常必须进行一项测试以确定是否还有任何额外的工作要做。然后在 PRIMASK 设置为 1 的关键部分完成该测试和 WFI 的执行(因此我们正在执行上面的选项 #2)。这将确保在测试和 WFI 之间没有中断,并且在唤醒后,如果有额外的操作(通常涉及时钟)需要完成,则没有中断。唤醒后,PRIMASK 被设置回 0(退出临界区),任何挂起的中断都会被接受。
此外,ARM 建议在 WFI 之前立即执行 DSB 指令,以确保在处理器进入睡眠状态之前完成所有数据操作。它可能并非在所有情况下都绝对必要,但以防万一情况发生变化而您忽略了它。