【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2606|回复: 1

android 休眠唤醒流程及定位唤醒问题总结

[复制链接]
发表于 2013-1-29 16:58:25 | 显示全部楼层 |阅读模式

就从earlysuspend.c中说起,在early suspend中执行完所有驱动的early suspend后会调用wake_unlock,在wake_unlock函数中,如果判断系统已经没有唤醒锁,则会调度休眠的工作队列,此时就会执行队列函数suspend。见定义:static DECLARE_WORK(suspend_work, suspend);suspend就是开始进行linux休眠的函数。调用关系如下:static void suspend(struct work_struct *work)
--> int pm_suspend(suspend_state_t state)
--> int enter_state(suspend_state_t state)

在此函数中要做一些准备工作:同步文件系统(sys_sync);分配控制台和冻结所有的进程(suspend_prepare)等;然后调用下面这个函数;

  1. int suspend_devices_and_enter(suspend_state_t state)
  2. {
  3.   int error;
  4.   gfp_t saved_mask;
  5.   /*判断休眠的操作函数集合指针是否被赋值,此指针会在对应的平台电源管理模块中被赋值
  6.   在s5pv210平台中是在plat-samsung/pm.c中*/
  7.   if (!suspend_ops)   
  8.   return -ENOSYS;
  9.   if (suspend_ops->begin) {
  10.    error = suspend_ops->begin(state);
  11.    if (error)
  12.     goto Close;
  13.   }
  14.   suspend_console();//suspend console subsystem,此时printk就不能打印信息,但还有其他方式可以进行打印
  15.   saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
  16.   suspend_test_start();
  17.   error = dpm_suspend_start(PMSG_SUSPEND);//在此函数里,会调到驱动注册的所有suspend函数,如果想知道suspend
  18.   顺序的话,可以在里面打印出来。
  19.   if (error) {
  20.    printk(KERN_ERR "PM: Some devices failed to suspend\n");
  21.    goto Recover_platform;
  22.   }
  23.   suspend_test_finish("suspend devices");
  24.   if (suspend_test(TEST_DEVICES))
  25.    goto Recover_platform;

  26. suspend_enter(state); //在此函数中会调用到系统的休眠功能,使系统进入sleep模式,而系统也就会停留在
  27.   休眠的地方,当唤醒的时候再继续往下执行。

  28. Resume_devices: //当系统被外部中断唤醒的时候,这里会被执行到
  29.   suspend_test_start();
  30.   dpm_resume_end(PMSG_RESUME);//此函数会执行resume流程,会调用驱动中注册的所有resume函数。
  31.   suspend_test_finish("resume devices");
  32.   set_gfp_allowed_mask(saved_mask);
  33.   resume_console();
  34.   Close:
  35.   if (suspend_ops->end)
  36.    suspend_ops->end();
  37.   return error;

  38. Recover_platform:
  39.   if (suspend_ops->recover)
  40.    suspend_ops->recover();
  41.   goto Resume_devices;
  42. }

  43. static struct platform_suspend_ops s3c_pm_ops = {
  44.   .enter  = s3c_pm_enter, //操作系统寄存器的接口,里面会使系统进入休眠/唤醒状态,在其中会保留系统的寄存器的值,设置好外部唤醒源。执行完s3c_cpu_save系统就进入了休眠模式。
  45.   当系统被唤醒时,再从s3c_cpu_save这个函数下面开始执行。
  46.   .prepare = s3c_pm_prepare,//为建立CRC校验做准备,分配存放CRC值的内存。
  47.   .finish  = s3c_pm_finish,
  48.   .valid  = suspend_valid_only_mem,
  49. };//这个是s5pv210中定义的平台的电源管理操作接口,suspend_ops会指向这个结构体变量的指针

  50. static int suspend_enter(suspend_state_t state)
  51. {
  52.   int error;

  53. if (suspend_ops->prepare) {
  54.    error = suspend_ops->prepare();
  55.    if (error)
  56.     return error;
  57.   }

  58. error = dpm_suspend_noirq(PMSG_SUSPEND);
  59.   if (error) {
  60.    printk(KERN_ERR "PM: Some devices failed to power down\n");
  61.    goto Platfrom_finish;
  62.   }

  63. if (suspend_ops->prepare_late) {
  64.    error = suspend_ops->prepare_late();
  65.    if (error)
  66.     goto Power_up_devices;
  67.   }

  68. if (suspend_test(TEST_PLATFORM))
  69.    goto Platform_wake;

  70. error = disable_nonboot_cpus();
  71.   if (error || suspend_test(TEST_CPUS))
  72.    goto Enable_cpus;

  73. arch_suspend_disable_irqs();
  74.   BUG_ON(!irqs_disabled());

  75. error = sysdev_suspend(PMSG_SUSPEND);
  76.   if (!error) {
  77.    if (!suspend_test(TEST_CORE))
  78.     error = suspend_ops->enter(state); //调用此函数进行休眠
  79.    sysdev_resume();
  80.   }

  81. arch_suspend_enable_irqs();
  82.   BUG_ON(irqs_disabled());

  83. Enable_cpus:
  84.   enable_nonboot_cpus();

  85. Platform_wake:
  86.   if (suspend_ops->wake)
  87.    suspend_ops->wake();

  88. Power_up_devices:
  89.   dpm_resume_noirq(PMSG_RESUME);

  90. Platfrom_finish:
  91.   if (suspend_ops->finish)
  92.    suspend_ops->finish();

  93. return error;
  94. }
复制代码
遇到唤醒/休眠不了的问题的定位方法:首先要让串口打印出来,打开内核调试选项,在s5pv210平台中;Kernel hacking  --->
         Kernel debugging
System Type  --->
        S3C2410 PM Suspend debug打开这两个选项后,就可以打印休眠/唤醒前后的所有信息。如果需要查看在哪个驱动唤醒/休眠出问题了,可以通过打印来定位。注:late_resume要等到android设置on到/sys/power/state才会被调用到。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-11-23 12:24

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表