linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(⼀)linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(⼀)
1. Based on linux
2.6.32,  only for mem(SDR)
2. 有兴趣请先参考阅读:电源管理⽅案APM和ACPI⽐较.doclinux下的sleep函数
Linux系统的休眠与唤醒简介.doc
3. 本⽂先研究标准linux的休眠与唤醒,android对这部分的增改在另⼀篇⽂章中讨论
4. 基于⼿上的⼀个项⽬来讨论,这⾥只讨论共性的地⽅
虽然linux⽀持三种省电模式:standby、suspend to ram、suspend to disk,但是在使⽤电池供
电的⼿持设备上,⼏乎所有的⽅案都只⽀持STR模式(也有同时⽀持standby模式的),因为STD
模式需要有交换分区的⽀持,但是像⼿机类的嵌⼊式设备,他们普遍使⽤nand来存储数据和代
码,⽽且其上使⽤的⽂件系统yaffs⼀般都没有划分交换分区,所以⼿机类设备上的linux都没有
⽀持STD省电模式。
⼀、项⽬power相关的配置
⽬前我⼿上的项⽬的linux电源管理⽅案配置如下,.config⽂件的截图,当然也可以通过make
menuconfig使⽤图形化来配置:
#
# CPU Power Management
#
# CONFIG_CPU_IDLE is not set
#
# Power management options
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_HAS_WAKELOCK=y
CONFIG_HAS_EARLYSUSPEND=y
CONFIG_WAKELOCK=y
CONFIG_WAKELOCK_STAT=y
CONFIG_USER_WAKELOCK=y
CONFIG_EARLYSUSPEND=y
# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
# CONFIG_CONSOLE_EARLYSUSPEND is not set
CONFIG_FB_EARLYSUSPEND=y
# CONFIG_APM_EMULATION is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
上⾯的配置对应下图中的下半部分图形化配置。。。,看来是直接在Kconfig⽂件中删除了配置STD模式的选项。
使⽤上⾯的配置编译出来的系统,跑起来之后,进⼊sys⽬录可以看到相关的接⼝:
# pwd
/sys/power
# ls
state  wake_lock  wake_unlock  wait_for_fb_sleep  wait_for_fb_wake
# cat state
mem
如果配置了宏CONFIG_PM_DEBUG,那么在power⽬录下会多出⼀个pm_test⽂件,cat
pm_test后,列出的测试选项有:[none] core processors platform devices freezer。关于这个test模式的使⽤,可以参考kernel⽂档:/kernel/documentation/ 这个⽂档我也有详细的阅读和分析。
⼆、sys/power和相关属性⽂件创建
系统bootup时候在sys下新建power和相关属性⽂件,相关源码位置:
kernel/kernel/power/main.c
static int __init pm_init(void)
{
int error = pm_start_workqueue();// CONFIG_PM_RUNTIME not set, so this fun is null
if (error)
return error;
power_kobj = kobject_create_and_add("power", NULL);
// 建⽴power对应的kobject和sysfs_dirent对象,同时建⽴联系:kobject.sd =
//  &sysfs_dirent, sysfs_dirent.s_dir->kobj = &kobject。
if (!power_kobj)
return -ENOMEM;
return sysfs_create_group(power_kobj, &attr_group);
// 建⽴⼀组属性⽂件,可以在power下建⽴⼀个⼦⽬录来存放这些属性⽂件,    // 不过需要在结构体attr_group中指定name,否则直接将这些属性⽂件放在    //  power_kobj对应的⽬录下。
}
core_initcall(pm_init);  // 看的出来,该函数是很早就被调⽤,initcall等级为1
static struct attribute_group attr_group = {
.attrs = g,
};
struct attribute_group {
const char            *name;
mode_t                (*is_visible)(struct kobject *,
struct attribute *, int);
struct attribute      **attrs;
};
// 属性⽂件都是以最基本得属性结构struct attribute来建⽴的
static struct attribute * g[] = {
&state_attr.attr,
#ifdef CONFIG_PM_TRACE  // not set
&pm_trace_attr.attr,
#endif
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG)    // not set        &pm_test_attr.attr,
#endif
#ifdef CONFIG_USER_WAKELOCK      // set
&wake_lock_attr.attr,
&wake_unlock_attr.attr,
#endif
NULL,
};
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM_DEBUG
power_attr(pm_test);
#endif
#endif
power_attr(state);
#ifdef CONFIG_PM_TRACE
power_attr(pm_trace);
#endif
#ifdef CONFIG_USER_WAKELOCK
power_attr(wake_lock);
power_attr(wake_unlock);
#endif
#define power_attr(_name) /
static struct kobj_attribute  _name##_attr = { /
.attr = {                      /
.
name = __stringify(_name),      /
.mode = 0644,                    /
},                                /
.show    = _name##_show,              /
.store      = _name##_store,        /
}
// ⽽这些被封装过的属性结构体,将来会使⽤kobject的ktype.sysfs_ops->show(store)这两个通⽤函数通过container_of()宏到实际的属性结构体中的show和store函数来调⽤。
关于更多sysfs的内容,请查看其他关于这部分内容的详细解析⽂档。
分类: ARM嵌⼊式底层及内核驱动

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。