启动android2.3后,进入cd sys/power目录,然后输入echo mem >state,按理应该打印相关睡眠信息,然后进入睡眠。
但是现在是遇到的一系列问题:
1、输入echo mem >state,并无反应,输入echo on >state 会显示wakeup相关信息,
检查代码,即kernel/kernel/power/main.c中state_store()函数,
通过插桩打印信息发现是由于valid_state(state)导致的,跟踪此函数,
bool valid_state(suspend_state_t state)
{
/*
* All states need lowlevel support and need to be valid to the lowlevel
* implementation, no valid callback implies that none are valid.
*/
return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
}
里面suspend_ops的注册是通过如下函数实现
void suspend_set_ops(struct platform_suspend_ops *ops)
{
mutex_lock(&pm_mutex);
suspend_ops = ops;
mutex_unlock(&pm_mutex);
}
此函数是在arch/arm/plat-samsung/pm.c中如下
int __init s3c_pm_init(void)
{
printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
suspend_set_ops(&s3c_pm_ops);
return 0;
}
但是发现此函数最后就是上面那个函数,启动内核打印信息里也没有
“S3C Power Management, Copyright 2004 Simtec Electronics”,说明此函数并没有被加载,
于是在pm.c最后添加如下语句,arch_initcall(s3c_pm_init);这样启动信息里就有以上打印信息了。
2、在睡眠所经过的重要函数里全部插桩,发现,睡眠时停在了wake_unlock(),
在kernel/kernel/power/wakelock.c里has_wake_lock_locked里添加打印信息如下
static long has_wake_lock_locked(int type)
{
struct wake_lock *lock, *n;
long max_timeout = 0;
BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
list_for_each_entry_safe(lock, n, &active_wake_locks[type], link) {
if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
long timeout = lock->expires - jiffies;
if (timeout <= 0)
expire_wake_lock(lock);
else if (timeout > max_timeout)
max_timeout = timeout;
} else
{
printk("lockname = %s,lockflag = ox%x\n",lock->name,lock->flags); //添加的部分
return -1;
}
}
return max_timeout;
}
此函数的作用,检查活跃锁链表中是否还有类型为type的锁,在睡眠时type为WAKE_LOCK_SUSPEND,
此函数返回0,表示没有该类型的锁被持有,返回值大于0,表示有该类型的延时锁被持有,等到时候后会自动释放该锁,
此返回值为离解锁的时间。返回-1,表示有该类型的非延时锁被持有,不能进入睡眠。插入此打印信息后发现,
名叫radio-interface的非延时锁被持有,此锁是与电话功能有关的锁,但是6410开发板没有打电话功能,因此可以在
android/system/core/rootdir/init.rc和android/vendor/forlinux/OK6410/init.rc中屏蔽掉rild相关内容。如下
#servic ril-daemon /systembin/rild
# socket rild stream 660 root radio
# socket rild-debug stream 660 radio system
# user root
# group radio cache inet misc audio sdcard rw
解决了持有锁不能进一步睡眠的问题,睡眠程序继续执行调度wake_unlock里的工作队列
queue_work(suspend_work_queue, &suspend_work),并执行处理函数suspend()进而执行
如下函数:pm_suspend、enter_state。
3 、终端出现打印信息stop_drawing_early_suspend: timeout waiting for userspace to stop drawing,检查发现时由于配置的问题,应该配置
以及这些配置
编译之后烧写内核 输入命令echo mem >state,屏幕黑屏,echo on >state 屏幕亮