WFI(Wait For Interrupt)指令是ARM中的一个Hint 指令,内核执行hint指令的时候不需要依赖额外的处理操作。WFI指令可以让CPU进入standby 模式,即低功耗模式,此时内核会暂停其他活动,一直等待中断事件的发生,检测到中断发生后,WFI指令执行完成,CPU退出standby模式。
本文将从ARM hint指令、WFI的用途以及WFI的唤醒事件等三个角度解释WFI指令。
目录
HINT 指令可以合法地被视为 NOP指令,但它们可以具有特定于实现的效果,常见的HINT指令有:
ARM 汇编语言中包含可用于让core进入低功耗状态(low-power state)的指令:WFI或WFE。ARM架构将这些指令定义为hint指令,这意味着core在执行它们时不需要采取任何特定操作。然而,在 Cortex-A 处理器系列中,这些指令的实现方式是关闭几乎所有内核部分的时钟。这意味着内核的功耗显着降低,仅消耗静态漏电流,没有动态功耗。
WFI指令的主要目的就是使core进入standby模式,直到中断或者类似中断的事件发送,才退出,core继续工作。
在待机模式下,core保持上电状态,但其大部分时钟停止或者进入时钟门限。这意味着core的绝大部分都处于static state,唯一消耗的功率是用于寻找中断唤醒条件的泄漏电流和少量逻辑时钟。
使用 WFI(等待中断)或 WFE(等待事件)指令可以进入此模式。 ARM 建议在 WFI 或 WFE 之前使用数据同步屏障 (Data Synchronization Barrier ,DSB) 指令,以确保待处理的内存事务在更改状态之前完成。
core进入待机状态后,会停止执行,直到检测到唤醒事件。唤醒条件取决于进入指令。对于 WFI,需要中断事件或外部调试请求来唤醒core。对于 WFE,存在许多指定的事件,包括cluster中执行 SEV 指令的另一个core。
WFI 指令广泛用于电池供电的系统。例如,手机可以每秒多次将core置于待机模式,同时等待用户按下按钮才唤醒core,从而可以节省功耗。
WFE 类似于 WFI。core暂停执行,直到发生事件。这可以是列出的事件条件之一,也可以是cluster中另一个core发出的事件信号。其他core可以通过执行 SEV 指令来发出事件信号。 SEV 向所有core发送一个事件信号。还可以对generic timer通用定时器进行编程,以触发将core从 WFE 唤醒的周期性事件。
总而言之,WFI 指令可以提示hint core在接收到中断或类似的exception之前无需执行任何操作,具体来说有两部分:
WFI可以使core进入待机状态,而将core从待机状态中唤醒,则需要中断事件或者类似中断事件的exception(debug事件):
- Timer(10); // 假设这是个timer,10秒后将发起中断,中断handler在其他地方定义
- WFI(); //如果处理器没有接收到中断,WFI指令将没有完成,一直处于休眠状态,下一条printf也不会被执行
- printf("中断发生,WFI检测到中断");
正常情况下是可以看到打印的,但是,在timer和WFI之间加入一个耗时事件: - Timer(10); // 10秒后将发起中断
- WasteTime(20); // 执行这个函数需要20秒
- WFI(); //从中断发生,到处理完成中断用不了10秒,执行到WFI时,中断已经消失了,所以CPU会一直处于休眠状态,下面的printf也不会被执行
- printf("中断发生,WFI检测到中断");