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

android 休眠唤醒流程及定位唤醒问题总结
android2.3.1 kernel:2.6.35
就从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)等;
然后调用下面这个函数;
--> int suspend_devices_and_enter(suspend_state_t state)
{
 int error;
 gfp_t saved_mask;
 /*判断休眠的操作函数集合指针是否被赋值,此指针会在对应的平台电源管理模块中被赋值
 在s5pv210平台中是在plat-samsung/pm.c中*/
 if (!suspend_ops)  
  return -ENOSYS;
 if (suspend_ops->begin) {
  error = suspend_ops->begin(state);
  if (error)
   goto Close;
 }
 suspend_console();//suspend console subsystem,此时printk就不能打印信息,但还有其他方式可以进行打印
 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
 suspend_test_start();
 error = dpm_suspend_start(PMSG_SUSPEND);//在此函数里,会调到驱动注册的所有suspend函数,如果想知道suspend
 顺序的话,可以在里面打印出来。
 if (error) {
  printk(KERN_ERR "PM: Some devices failed to suspend\n");
  goto Recover_platform;
 }
 suspend_test_finish("suspend devices");
 if (suspend_test(TEST_DEVICES))
  goto Recover_platform;

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

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

 Recover_platform:
 if (suspend_ops->recover)
  suspend_ops->recover();
 goto Resume_devices;
}

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

static int suspend_enter(suspend_state_t state)
{
 int error;

 if (suspend_ops->prepare) {
  error = suspend_ops->prepare();
  if (error)
   return error;
 }

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

 if (suspend_ops->prepare_late) {
  error = suspend_ops->prepare_late();
  if (error)
   goto Power_up_devices;
 }

 if (suspend_test(TEST_PLATFORM))
  goto Platform_wake;

 error = disable_nonboot_cpus();
 if (error || suspend_test(TEST_CPUS))
  goto Enable_cpus;

 arch_suspend_disable_irqs();
 BUG_ON(!irqs_disabled());

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

 arch_suspend_enable_irqs();
 BUG_ON(irqs_disabled());

 Enable_cpus:
 enable_nonboot_cpus();

 Platform_wake:
 if (suspend_ops->wake)
  suspend_ops->wake();

 Power_up_devices:
 dpm_resume_noirq(PMSG_RESUME);

 Platfrom_finish:
 if (suspend_ops->finish)
  suspend_ops->finish();

 return error;
}

遇到唤醒/休眠不了的问题的定位方法:
首先要让串口打印出来,打开内核调试选项,在s5pv210平台中;
Kernel hacking  --->
         Kernel debugging
System Type  --->
        S3C2410 PM Suspend debug
打开这两个选项后,就可以打印休眠/唤醒前后的所有信息。
如果需要查看在哪个驱动唤醒/休眠出问题了,可以通过打印来定位。
注:late_resume要等到android设置on到/sys/power/state才会被调用到。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值