Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux挂起/唤醒如何为mach-omap2工作?_Linux_Linux Kernel_Arm_Omap - Fatal编程技术网

linux挂起/唤醒如何为mach-omap2工作?

linux挂起/唤醒如何为mach-omap2工作?,linux,linux-kernel,arm,omap,Linux,Linux Kernel,Arm,Omap,我正在试图弄清楚如何为mach-omap2实现挂起/唤醒,特别是在针对TI OMAP3530/DM3730的Linux 2.6.37中 以下是一些相关代码: 静态int omap3\u pm\u挂起(无效) { 结构电源状态*pwrst; int状态,ret=0; if(唤醒计时器秒数唤醒计时器毫秒数) omap2\u pm\u唤醒定时器开启(唤醒定时器秒, 唤醒计时器(毫秒); /*读取当前下一个\u PWRST*/ 每个条目的列表(pwrst和pwrst列表,节点) pwrst->save

我正在试图弄清楚如何为
mach-omap2
实现挂起/唤醒,特别是在针对TI OMAP3530/DM3730的Linux 2.6.37中

以下是一些相关代码:

静态int omap3\u pm\u挂起(无效)
{
结构电源状态*pwrst;
int状态,ret=0;
if(唤醒计时器秒数唤醒计时器毫秒数)
omap2\u pm\u唤醒定时器开启(唤醒定时器秒,
唤醒计时器(毫秒);
/*读取当前下一个\u PWRST*/
每个条目的列表(pwrst和pwrst列表,节点)
pwrst->saved_state=pwrdm_read_next_pwrst(pwrst->pwrdm);
/*设置挂起所需的*/
每个条目的列表(pwrst和pwrst列表,节点){
如果(omap_设置_pwrdm_状态(pwrst->pwrdm,pwrst->next_状态))
去恢复;
如果(pwrdm\u清除\u所有\u上一个\u pwrst(pwrst->pwrdm))
去恢复;
}
omap_uart_prepare_suspend();
omap3_intc_suspend();
omap_sram_idle();
恢复:
/*恢复下一个\u PWRST*/
每个条目的列表(pwrst和pwrst列表,节点){
状态=pwrdm_read_prev_pwrst(pwrst->pwrdm);
如果(状态>pwrst->next_状态){
printk(内核信息“Powerdomain(%s)未输入”
“目标状态%d\n”,
pwrst->pwrdm->name,pwrst->next_state);
ret=-1;
}
omap_设置_pwrdm_状态(pwrst->pwrdm,pwrst->saved_状态);
}
如果(ret)
printk(KERN_ERR“无法在pm_suspend中进入目标状态\n”);
其他的
printk(KERN_INFO“成功放置所有powerdomains”
“到目标状态\n”);
返回ret;
}
我真的很难理解它是如何工作的


看起来,当挂起过程在
omap_sram_idle()之后运行时,系统已经处于挂起模式,在该函数的上下文中,所有内容都冻结在那里。当它醒来时,它只是从
还原:
继续并还原所有内容。这是正确的吗

系统挂起发生在
omap\u sram\u idle()
的中间位置。
omap\u sram\u idle()
的第二部分实际上是恢复代码。更准确地说,实际睡眠是通过
omap34xx\u cpu\u suspend()
汇编程序函数中的
wfi
ARM指令完成的。请进一步阅读以了解详细信息

挂起路径
  • 看看函数实现
  • 您可以看到(从注释判断),系统进入睡眠前的最后一行是
    \u omap\u sram\u idle()
    call()
  • \u omap\u sram\u idle()
    指向先前复制到的汇编程序函数(因此在RAM断电期间不会丢失);请看下面几行代码:

  • (请注意,传递给它的第一个参数是
    omap34xx\u cpu\u suspend
    函数地址)
  • 实施;请注意:
    omap\u sram\u ceil
    是sram内存的起始地址,
    start
    omap34xx\u cpu\u suspend()函数的地址
  • 实施;它是在执行的实际函数(而不是
    \u omap\u sram\u idle()
    )。查看此函数上方的注释:

    /*
    *强制OMAP进入空闲状态
    *
    *omap34xx_suspend()-这段代码只执行WFI
    *对于正常怠速。
    *
    *注意:此代码在引导时被复制到内部SRAM。当OMAP
    *醒来时,它会在进入睡眠状态时继续执行。
    */
    
  • 实际休眠发生在(等待中断)ARM指令中(在
    omap34xx\u cpu\u suspend()函数中);处理器将处于休眠状态,只有在出现IRQ时才会唤醒

  • 当可以执行wfi时,
    omap34xx\u cpu\u suspend()
    中有两个位置:
    • 如果不需要进行上下文保存:
    • 如果需要进行上下文保存:
还原路径
一旦出现某种唤醒信号,CPU将继续在
wfi
指令之后执行指令(这些指令首先将其置于睡眠状态)。因此,您的系统在
omap34xx\u cpu\u suspend()
汇编程序函数中唤醒(从
wait\u sdrk\u ok:
label开始),然后返回到
omap\u sram\u idle()
(到line),然后返回到
omap3\u pm\u suspend()
,恢复到
label。

回答得好!在以后的linux版本中,这个实现是否随着时间的推移而改变了?不,不是真的。您可以在内核4.0源代码中导航相同的代码。我看不出2.6有什么大区别。如果您尝试查看上次对此文件做了多少承诺(
git log-arch/arm/mach-omap2/pm34xx.c
),您将看到自2.6以来,pm_挂起代码基本上没有变化。下面是一些相关问题,以及。操作系统代码需要将东西置于一种特殊模式,以便
wfi
指令进入深度睡眠。这可能相当复杂,因为DDR在挂起时无法运行代码(而且它通常是一个大的当前用户)。所以,在这个答案中有omap的细节,但是这些概念适用于所有Linux ARM CPU。嗨,我只是想检查一下,是否有可能停止暂停一个特殊模块/设备,比如基于Jacinto的主板上的SGX模块?@Milan你的意思是,暂停CPU,但保持一些IP核心运行?也许可以通过修改其驱动程序代码来实现,但我看不出它在没有CPU运行的情况下(在
wfi
指令中)有什么帮助。有关详细信息,请参阅。你想解决的问题是什么?