`
womendu
  • 浏览: 1513433 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

标准linu休眠和唤醒机制分析(二)

阅读更多

三、pm_test属性文件读写

int pm_test_level = TEST_NONE;

static const char * const pm_tests[__TEST_AFTER_LAST] = {

[TEST_NONE] = "none",

[TEST_CORE] = "core",

[TEST_CPUS] = "processors",

[TEST_PLATFORM] = "platform",

[TEST_DEVICES] = "devices",

[TEST_FREEZER] = "freezer",

};

// core >> processors >> platform >> devices >> freezer 控制范围示意

cat pm_test的时候最终会调用函数pm_test_show(),在终端上打印出上面数组中的字符串,当前的模式用[]表示出来。

echo devices > pm_test的时候会最终调用到函数pm_test_store()中去,该函数中设置全局变量pm_test_level的值,可以是0-5,分别代表上none ~ freezer。该全局变量会在后面的suspendresume中被引用到。

memchr函数说明:

原型:extern void *memchr(void *buf, char ch, unsigned int count);

用法:#include <string.h>   

功能:从buf所指内存区域的前count个字节查找字符ch   

说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL

四、state属性文件

power_attr(state)宏定义了一个struct kobj_attribute结构体state_attr

static struct kobj_attribute state_attr = {

.attr = {

.name = __stringify(state),

.mode = 0644,

},

.show = state_show,

.store = state_store,

}

kobj_attribute结构体封装了struct attribute结构体,新建属性文件是依据struct attribute结构体。最终通过函数kobj_attr_showkobj_attr_store回调到实际的showstore函数(kobject.c)

state_show()函数主要是显示当前系统支持哪几种省电模式。

static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

{

char *s = buf;

#ifdef CONFIG_SUSPEND //def

int i;

for (i = 0; i < PM_SUSPEND_MAX; i++) {

if (pm_states[i] && valid_state(i))

s += sprintf(s,"%s ", pm_states[i]);

}

#endif

#ifdef CONFIG_HIBERNATION // undef, don't support STD mode

s += sprintf(s, "%s\n", "disk");

#else

if (s != buf)

/* convert the last space to a newline */

*(s-1) = '\n';

#endif

return (s - buf);

}

@ kernel/include/linux/suspend.h

#define PM_SUSPEND_ON ((__force suspend_state_t) 0)

#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)

#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)

#define PM_SUSPEND_DISK ((__force suspend_state_t) 4)

#define PM_SUSPEND_MAX ((__force suspend_state_t) 5)

@ kernel/kernel/power/suspend.c

const char *const pm_states[PM_SUSPEND_MAX] = {

#ifdef CONFIG_EARLYSUSPEND // android修改了标准linux的休眠唤醒机制,增加了eraly suspendlate resume机制,如果是android内核,则这个宏是需要定义的。

[PM_SUSPEND_ON] = "on",

#endif

[PM_SUSPEND_STANDBY] = "standby",

[PM_SUSPEND_MEM] = "mem",

};

该函数中值得注意的地方应该是valid_state(i),这个函数是用户配置的支持省电模式的验证函数,如果没有这个验证过程,cat时候打印出来的模式则是on standby mem,给上层用户的使用造成困扰。

那这个valid_state()函数在哪里定义的呢?一般定义于文件kernel/kernel/power/suspend.c

static struct platform_suspend_ops *suspend_ops;

void suspend_set_ops(struct platform_suspend_ops *ops) // 该函数调用见后面

{

mutex_lock(&pm_mutex);

suspend_ops = ops;

mutex_unlock(&pm_mutex);

}

bool valid_state(suspend_state_t state)

{

return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);

}

而实际平台的platform_suspend_ops结构体一般都是在文件arch/arm/mach-xxxx/pm.c中进行定义,对于mtk的平台是文件mtkpm.c,如下:

@ kernel/include/linux/suspend.h

struct platform_suspend_ops {

int (*valid)(suspend_state_t state);

int (*begin)(suspend_state_t state);

int (*prepare)(void);

int (*prepare_late)(void);

int (*enter)(suspend_state_t state);

void (*wake)(void);

void (*finish)(void);

void (*end)(void);

void (*recover)(void);

};

经过后面的代码分析,得出了如下结论:

休眠唤醒过程依次会执行的函数是:beginprepareprepare_lateenterwake finish end同颜色的函数执行了恰好相反的工作。休眠的时候代码执行是停留在函数enter中,wake之后也是从suspend的时候停留的地方继续运行。

至于recover函数貌似只有在pm_test处于devices的模式下,才会被调用到。

@ kernel/arch/arm/mach-mt6516/mtkpm.c

static struct platform_suspend_ops mtk_pm_ops = {

.valid = mtk_pm_state_valid,

.begin = mtk_pm_begin,

.prepare = mtk_pm_prepare,

.enter = mtk_pm_enter,

.finish = mtk_pm_finish,

.end = mtk_pm_end,

};

static int mtk_pm_state_valid(suspend_state_t pm_state)

{

return pm_state == PM_SUSPEND_MEM ;

}

void mtk_pm_init(void)

{

_Chip_PM_init();

/* Register and set suspend operation */

suspend_set_ops(&mtk_pm_ops);

}

而函数mtk_pm_init()是在函数mt6516_init_irq()中调用。可以看出该平台只支持mem的省电模式。

state_store()函数:

static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,

const char *buf, size_t n)

{

#ifdef CONFIG_SUSPEND // set

#ifdef CONFIG_EARLYSUSPEND //对标准linux而言,这个宏不存在

suspend_state_t state = PM_SUSPEND_ON;

#else

suspend_state_t state = PM_SUSPEND_STANDBY;

#endif

const char * const *s;

#endif

char *p;

int len;

int error = -EINVAL;

p = memchr(buf, '\n', n);

len = p ? p - buf : n;

/* First, check if we are requested to hibernate */

if (len == 4 && !strncmp(buf, "disk", len)) {

error = hibernate(); // 如果值是disk,那么进入STD模式,该模式暂不讨论

goto Exit;

}

#ifdef CONFIG_SUSPEND // def

for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {

if (*s && len == strlen(*s) && !strncmp(buf, *s, len))

break;

}

if (state < PM_SUSPEND_MAX && *s)

#ifdef CONFIG_EARLYSUSPEND

// androidlinux内核会定义该宏,首先进入eraly suspend模式

if (state == PM_SUSPEND_ON || valid_state(state)) {

error = 0;

request_suspend_state(state);

}

#else // 标准linux内核直接enter_state()函数

error = enter_state(state); // kernel/kernel/power/suspend.c

#endif

#endif

Exit:

return error ? error : n;

}

分享到:
评论

相关推荐

    Linu内核分析

    综上所述,《Linux内核分析》一书从Linux内核的历史背景、开发模式、结构特征、硬件基础、中断机制以及进程管理等方面,提供了深入浅出的讲解,对于想要深入了解Linux内核工作原理的读者来说,是一本不可多得的技术...

    特色平台前端linu移植项目可行性分析报告.pdf

    特色平台前端linu移植项目可行性分析报告.pdf

    嵌入式linu学习规划

    4. **文件处理**:掌握文件的打开、读写、关闭等操作,理解二进制文件和文本文件的区别。 **推荐教材**: - 《C语言程序设计》- 谭浩强 - 《C和指针》 - 《C专家编程》 **学习建议**: - 在真实环境中编写代码,...

    Linu系统安全配置标准V.pdf

    Linu系统安全配置标准V.pdf

    Linux内核QoS实现机制.doc

    Linux内核QoS(服务质量)实现机制是网络管理和优化的关键组成部分,它确保了不同类型的网络服务得到合理且优先级适中的资源分配。QoS的主要目标是通过控制带宽、延迟、丢包率和抖动来提升网络性能和用户体验。在...

    Linu系统安全配置标准.pdf

    这份"Linu系统安全配置标准.pdf"文档提供了一系列针对Linux服务器的安全加固技术要求,以增强系统的稳定性和防止未授权访问。以下是根据文档内容提炼出的关键知识点: 1. **补丁管理**: - **系统补丁**:建议定期...

    vstock61.zip_palm recognition_主成分分析_小波 人脸识别_小波 分析 人脸识别_模式识别 linu

    1. **掌纹识别(Palm Recognition)**:这是一种生物特征识别技术,通过分析和比较个人的掌纹特征来进行身份验证。掌纹具有独特的纹理、线形结构和细节,使其成为生物识别系统中的一个可靠选项。在实现时,通常需要...

    Linu系统配置DNS服务器

    ### Linu系统配置DNS服务器知识点详解 #### 一、实验环境 - **操作系统**: CentOS 6.4 - **DNS服务器软件**: BIND (Berkeley Internet Name Domain) #### 二、DNS服务器配置概述 DNS服务器(Domain Name System)...

    linu下cadence的patch包

    总的来说,这个"linu下cadence的patch包"是一个用于提升Linux环境下Cadence工具性能和稳定性的更新,对于那些依赖Cadence进行复杂电路设计的专业人士来说,定期检查和应用这些补丁是保持工作效率和数据安全的重要...

    支持qt和linu通信的qssh库

    支持qt和linu通信的qssh库

    《LINU系统及其编程》考试复习重点.docx

    解决方案:通过分析系统负载和进程状态,找出 CPU 使用率过高的原因。如果是由于高负载应用导致的,可以优化应用代码或增加服务器资源。 * 问题 2:内存泄漏 解决方案:通过内存检测工具找出内存泄漏的原因,并进行...

    linu学习资料

    "奔跑吧"可能代表了作者希望读者能积极主动地深入学习和理解Linux内核,而“基于Linux 4.x内核源代码问题分析”则表明该书将详细探讨Linux 4.x版本的内核源代码,帮助读者理解内核的工作原理和解决实际问题。...

    Linu编程GCC手册

    ### Linu编程GCC手册知识点概览 #### 一、GCC简介 GCC(GNU Compiler Collection)是一套由GNU项目开发的编译器集合,它支持多种编程语言,包括但不限于C、C++、Objective-C、Fortran、Ada、Go等。本手册主要介绍了...

    Windows客户端访问Linu服务器NFS.doc

    "Windows客户端访问Linu服务器NFS" 本文档主要讲解Windows客户端如何访问Linux服务器的NFS(Network File System),以解决异构环境中的文件共享问题。文中介绍了跨平台通讯工具SFU(Services For Unix),它能够...

    myself linu x(2)

    myself linu x(2)myself linu x(2)myself linu x(2)myself linu x(2)myself linu x(2)

    Linu0.01内核分析与操作系统设计4/4

    《Linux0.01内核分析与操作系统设计》介绍LINUX0.01的内核,0.01是拥有比较少的代码,对于初学者来说容易理解。(共4个文件,第1个文件扣分,其余不扣。4/4)

    linu 下安装 websphere 手册

    linu下安装websphere手册,一目了然

    linu字符设备开发.ppt

    linu字符设备开发

    linu 搭建ELK(es+kibana+logstash)安装包

    它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般

Global site tag (gtag.js) - Google Analytics