You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:30:23