ARMv7 Cortex-A7双核+RTOS环境下WFI指令未正常工作求助
ARMv7 Cortex-A7双核RTOS空闲任务WFI指令失效问题
基于ARMv7 Cortex-A7双核平台搭配RTOS开发,尝试在空闲任务中使用WFI指令降低功耗,厂商已确认硬件支持WFI/WFE。RTOS空闲任务代码如下:
.type cpu_intrpt_save, #function cpu_intrpt_save: MRS R0, CPSR CPSID I DSB BX LR
void idle_task(void *arg) { uint8_t cpu_num; /* avoid warning */ (void)arg; cpu_num = cpu_cur_get(); while (TRUE) { // ... 其他空闲任务处理逻辑 cpsr = cpu_intrpt_save(); next_tick = get_first_timer_timeout(); adjust_tick_timer(next_tick); __asm__ volatile ("wfi":::"memory", "cc"); cpu_intrpt_restore(cpsr); /// adjust_tick_timer(normal_tick_rate); } }
问题现象
执行流程为:获取下一个定时器事件的触发tick → 调整tick定时器(类无tick内核实现) → 调用WFI进入待机等待中断。但实际运行时WFI未使CPU进入等待模式,循环持续运行,导致tick定时器无法触发中断。移除WFI前后的中断禁用/启用操作后问题依旧。
裸机验证结果
编写裸机代码测试WFI功能:
int main(int argc, char** argv) { const int count = 5; int result = 0; __asm__ volatile ("wfi":::"memory", "cc"); for (int i = 1; i < count; i++) { result = result + i; // <<<< Set breakpoint here } done: // We should rather use 'WFI' here. goto done; }
在WFI指令后设置断点,自由运行时断点未触发,直到手动触发中断才进入循环,说明裸机环境下WFI指令工作正常。
排查方向
- 中断掩码与使能检查:确认
cpu_intrpt_save仅关闭IRQ,FIQ未被意外屏蔽;同时检查调整后的tick定时器中断是否已正确使能,中断控制器中对应中断的掩码位是否清除。 - 指令同步屏障:在WFI指令前添加
ISB指令,确保调整定时器的硬件操作已完成同步,避免WFI执行时定时器未准备好触发中断:__asm__ volatile ("dsb\n\tisb\n\twfi":::"memory", "cc"); - 编译优化验证:查看编译后的汇编输出,确认WFI指令未被编译器优化移除;必要时添加
-O0编译选项临时关闭优化测试。 - 多核干扰排查:确认空闲任务是否绑定到指定核心,检查另一核心是否在频繁触发全局中断,导致当前核心WFI被立即唤醒;同时验证多核间的中断路由配置是否正确。
- 定时器状态确认:调用
adjust_tick_timer后,读取定时器硬件寄存器,确认比较值、使能位等配置是否符合预期,排除定时器未正确设置的问题。
内容的提问来源于stack exchange,提问作者wangt13
相关产品推荐
相关产品推荐

