转自:http://blog.csdn.net/lixiaojie1012/article/details/23788713

前边我们讨论分析了linux 内核的dpm实现,分析的目的在于学以致用;在好多实时操作系统中,并没有dpm这个框架,所以我们可以仿照linux的dpm框架,来实现我们自己的dpm,可以运用到需要dpm的系统中。

知识点:链表,回调函数,函数指针,互斥锁,锁中断

为便于描述,本文使用伪代码,仅个别地方具体实现;

1、首先,我们需要定义两个结构体类型,一个用于控制,一个用于各个模块注册;

(1)控制结构体

struct my_dpm{

list_head    dpm_list;

list_head    prepare_list;

list_head   early_list;

list_head    suspend_list;

list_head    late_list;

spinlock_t      lock_mutx;

}dpm_ctrl;

(2)各模块注册dpm使用的结构体

struct dpm_device{

char *device_name;

list_head     entry;

void *data;

int  (*prepare)(struct dpm_device *dev);

int  (*suspend_early)(struct dpm_device *dev);

int (*suspend)(struct dpm_device *dev);

int (*suspend_late)(struct dpm_device *dev);

int  (*resume_early)(struct dpm_device *dev);

int  (*resume)(struct dpm_device *dev);

int  (*resume_late)(struct dpm_device *dev);

int  (*complete)(struct dpm_device *dev);

};

2、OK,结构体我们已经定义完了,那么我们接下来需要初始化一下控制结构体的变量

int  my_dpm_init(void){

初始化五个链表;

初始化spin_lock锁;

return OK;

}

3、到此,我们自己的dpm已初始化完成,各个模块想要注册dpm,就差一个注册接口了,下面我们来实现注册接口

int dpm_register(struct dpm_device *device

获取互斥锁;

初始化设备结构体中的entry;

加入到dpm_list链表中;

释放互斥锁;

return OK;

}

4、这样,用户就可以调用dpm_register来注册dpm了;但是注册完后,得需要提供接口来供低功耗流程来调用啊,莫急,我们这就来实现供低功耗调用的接口,    dpm_suspend和dpm_resume

(1)dpm_suspend:主要回调各个模块注册的保存信息的回调函数,包括prepare、suspend_early、suspend、suspend_late

int dpm_suspend(void){

if(prepare())

return -1;

if(suspend_early())

return -1;

if(suspend())

return -1;

if(suspend_late())

return -1;

return 0;

}

(2)dpm_resume:主要用在唤醒阶段,按照优先级回调各个模块注册的恢复信息的回调函数,包括resume_early、resume、resume_late、complete

int dpm_resume(void)

{

if(resume_early())

return -1;

if(resume())

return -1;

if(resume_late())

return -1;

if(complete())

return -1;

return 0;

}

5、大家可以看到,上面两个接口中分别调用了4个函数,供8个函数,分别用在suspend阶段和resume阶段,接下来我们简单实现一下其中一个函数prepare

int prepare(void)

{

获取互斥锁;

遍历dpm_list链表,检查每个结点是否注册prepare回调函数,如果注册,则执行回调函数:ret=dev->prepare(dev),如果成功,则移入prepare_list,否则,执行恢复操作;

释放互斥锁;

}

其他的suspend_early()、suspend()、suspend_late()、resume()、resume_early()、resume_late()、complete()等具体函数实现基本大致相同,只不过所操作的链表不同罢了。

好了,我们的dpm框架实现完成了,简单吧,我们尝试注册一个吧:

int my_prepare(struct dpm_device *dev){}

int my_suspend dpm_device *dev){}

int my_resumet dpm_device *dev){}

int my_completedpm_device *dev){}

struct dpm_device test_device={

.device_name = "my_test_device";

.prepare = my_prepare;

.suspend = mysuspend;

.resume = my_resume;

.omplete = my_complete;

};

在合适的地方调用dpm_register(&test_device)即可,需要注意的是,dpm回调函数注册一定要配对:prepare--complete       suspend--resume        suspend_late--resume_early                suspend_late--resume_early

仿照linux dpm机制,实现自己的dpm【转】的更多相关文章

  1. Linux模块机制浅析

    Linux模块机制浅析   Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...

  2. android & Linux uevent机制

    Linux uevent机制 Uevent是内核通知android有状态变化的一种方法,比如USB线插入.拔出,电池电量变化等等.其本质是内核发送(可以通过socket)一个字符串,应用层(andro ...

  3. 利用linux信号机制调试段错误(Segment fault)

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

  4. Linux 内存机制详解宝典

    Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...

  5. Linux Namespaces机制——实现

    转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480573.html 由于Linux内核提供了PID,IPC,NS等多个Namespace ...

  6. Linux Namespaces机制

    转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480316.html Linux Namespaces机制提供一种资源隔离方案.PID,I ...

  7. Linux分页机制之概述--Linux内存管理(六)

    1 分页机制 在虚拟内存中,页表是个映射表的概念, 即从进程能理解的线性地址(linear address)映射到存储器上的物理地址(phisical address). 很显然,这个页表是需要常驻内 ...

  8. [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)

    Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...

  9. [转帖]Linux分页机制之概述--Linux内存管理(六)

    Linux分页机制之概述--Linux内存管理(六) 2016年09月01日 19:46:08 JeanCheng 阅读数:5491 标签: linuxkernel内存管理分页架构更多 个人分类: ┈ ...

随机推荐

  1. iOS进阶--将项目的编译速度提高5倍

    前言 作为开发团队的负责人,最近因为在快速迭代开发新功能,项目规模急速增长,单个端业务代码约23万行,私有库约6万行,第三方库代码约15万行,单个客户端的代码行数约60万.现在打包一次耗时需要11~1 ...

  2. 【bzoj2190】[SDOI2008]仪仗队 欧拉函数

    题目描述 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图 ...

  3. Codeforces Round #522 Div. 1 没打记

    开场被A劝退,写了得有50min于是不敢交了.unrated了喜闻乐见. A:瞎猜都能猜到如果要走到那条直线上,进入直线的点横坐标或纵坐标与起点相同,离开直线的点横坐标或纵坐标与终点相同,证明脑补一下 ...

  4. HDU3949:XOR——题解

    http://acm.hdu.edu.cn/showproblem.php?pid=3949 求n个数的异或和第k小. 参考:https://blog.sengxian.com/algorithms/ ...

  5. [学习笔记]min-max容斥

    [Learning]min-max容斥以及推广 min-max容斥 就是max(a,b)=min(a)+min(b)-min(a,b) max(a,b,c)=a+b+c-min(a,b)-min(a, ...

  6. [LOJ 6000]搭配飞行员

    link 其实就是一道二分图匹配板子,我们建立$S$,$T$为源点与汇点,然后分别将$S$连向所有正驾驶员,边权为$1$,然后将副驾驶员与$T$相连,边权为$1$,将数据中给出的$(a,b)$,将$a ...

  7. 使用Faster-Rcnn进行目标检测(实践篇)转载

    原 文链接:http://blog.csdn.net/gavin__zhou/article/details/52052915 原理 上一篇文章,已经说过了,大家可以参考一下,Faster-Rcnn进 ...

  8. TiXmlHandle的使用-简化tinyxml的代码

    借鉴于:http://www.cppblog.com/elva/archive/2008/04/24/47907.html 例如: <?xml version="1.0" s ...

  9. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  10. MySQL查看所有用户及拥有权限

    查看MYSQL数据库中所有用户 mysql> SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM m ...