首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux挂起/唤醒如何用于mach-omap2 2?

linux挂起/唤醒如何用于mach-omap2 2?
EN

Stack Overflow用户
提问于 2015-05-19 23:24:45
回答 1查看 295关注 0票数 1

我试图弄清楚mach-omap2是如何实现挂起/唤醒的,特别是在针对TI out 3530/‘m 3730的Linux2.6.37中。

下面是一些相关代码:

http://lxr.free-electrons.com/source/arch/arm/mach-omap2/pm34xx.c?v=2.6.37

代码语言:javascript
复制
static int omap3_pm_suspend(void)
{
    struct power_state *pwrst;
    int state, ret = 0;

    if (wakeup_timer_seconds || wakeup_timer_milliseconds)
        omap2_pm_wakeup_on_timer(wakeup_timer_seconds,
                     wakeup_timer_milliseconds);

    /* Read current next_pwrsts */
    list_for_each_entry(pwrst, &pwrst_list, node)
        pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
    /* Set ones wanted by suspend */
    list_for_each_entry(pwrst, &pwrst_list, node) {
        if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
            goto restore;
        if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
            goto restore;
    }

    omap_uart_prepare_suspend();
    omap3_intc_suspend();

    omap_sram_idle();

restore:
    /* Restore next_pwrsts */
    list_for_each_entry(pwrst, &pwrst_list, node) {
        state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
        if (state > pwrst->next_state) {
            printk(KERN_INFO "Powerdomain (%s) didn't enter "
                   "target state %d\n",
                   pwrst->pwrdm->name, pwrst->next_state);
            ret = -1;
        }
        omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
    }
    if (ret)
        printk(KERN_ERR "Could not enter target state in pm_suspend\n");
    else
        printk(KERN_INFO "Successfully put all powerdomains "
               "to target state\n");

    return ret;
}

我真的很难理解它是怎么工作的。

看起来,当挂起过程在omap_sram_idle();之后运行时,系统已经处于挂起模式,在这个函数的上下文中,所有东西都会冻结在那里。当它醒来时,它只是继续从restore:中恢复一切。这是正确的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-20 21:28:52

系统挂起发生在的中间 of omap_sram_idle()omap_sram_idle()的第二部分实际上是还原代码。更准确地说,实际睡眠是通过wfi ARM指令在omap34xx_cpu_suspend()汇编程序函数中完成的。详情请进一步阅读。

挂起路径

  • 看看闲置()函数的实现
  • 您可以看到(从注释中判断),系统进入休眠状态之前的最后一行是_omap_sram_idle()调用(这里)。
  • _omap_sram_idle()指向以前复制到SRAM暂停()汇编程序函数(因此它不会在关闭内存时丢失);请看下面的代码行:
代码语言:javascript
复制
1. [\_omap\_sram\_idle() assignment](http://lxr.linux.no/#linux+v2.6.37/arch/arm/mach-omap2/pm34xx.c#L998) (notice that first parameter that is passed to it is `omap34xx_cpu_suspend` function address)
2. [omap\_sram\_push()](http://lxr.linux.no/#linux+v2.6.37/arch/arm/plat-omap/sram.c#L247) implementation; pay attention to [memcpy() call](http://lxr.linux.no/#linux+v2.6.37/arch/arm/plat-omap/sram.c#L256): `omap_sram_ceil` is start address of SRAM memory, `start` is address of `omap34xx_cpu_suspend() function`
3. [omap34xx\_cpu\_suspend()](http://lxr.linux.no/#linux+v2.6.37/arch/arm/mach-omap2/sleep34xx.S#L187) implementation; it's the actual function being executed at [this line](http://lxr.linux.no/#linux+v2.6.37/arch/arm/mach-omap2/pm34xx.c#L446) (instead of `_omap_sram_idle()`). Take a look at comment above this function:

/* *强制OMAP进入空闲状态** omap34xx_suspend() -这段代码只对普通的idles执行WFI *。**注意:此代码在启动时被复制到内部SRAM中。当OMAP *醒来的时候,它会在睡觉的时候继续执行。*/

  • 实际睡眠发生在wfi (等待中断) ARM指令中(在omap34xx_cpu_suspend()函数中);处理器将休眠,只有当某些IRQ发生时它才会醒来。
  • omap34xx_cpu_suspend()中有两个地方可以执行wfi
    • 如果不需要上下文保存:这里
    • 如果需要上下文保存:这里

恢复路径

一旦出现了一些唤醒信号,CPU将在wfi指令之后继续执行指令(这首先使它进入睡眠状态)。因此,您的系统在omap34xx_cpu_suspend()汇编程序函数(从wait_sdrk_ok:标签开始)中醒来,然后返回到omap_sram_idle() (到行),然后返回到omap3_pm_suspend(),返回到restore:标签。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30337804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档