zoukankan      html  css  js  c++  java
  • linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)

    1. Based on linux2.6.32,  only for mem(SDR)

    2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc

    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/power/Basic-pm-debugging.txt

    这个文档我也有详细的阅读和分析。

    二、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的内容,请查看其他关于这部分内容的详细解析文档。

  • 相关阅读:
    AD转化器分类及特点和选用
    采样频率 、采样率
    RGBA alpha 透明度混合算法
    SDRAM中数据掩码的作用
    Allegro---层叠结构设置
    PCB主线布线规范—高速线之DDR2
    Allegro 反射仿真--拓扑结构的提取提取及波形分析
    Allegro 反射仿真--仿真设置
    Allegro 反射仿真--IBIS模型转化
    SigXplorer设置延时及Local_Global
  • 原文地址:https://www.cnblogs.com/0822vaj/p/3935856.html
Copyright © 2011-2022 走看看