仿照linux dpm机制,实现自己的dpm【转】
转自: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【转】的更多相关文章
- Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- android & Linux uevent机制
Linux uevent机制 Uevent是内核通知android有状态变化的一种方法,比如USB线插入.拔出,电池电量变化等等.其本质是内核发送(可以通过socket)一个字符串,应用层(andro ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- Linux 内存机制详解宝典
Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...
- Linux Namespaces机制——实现
转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480573.html 由于Linux内核提供了PID,IPC,NS等多个Namespace ...
- Linux Namespaces机制
转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480316.html Linux Namespaces机制提供一种资源隔离方案.PID,I ...
- Linux分页机制之概述--Linux内存管理(六)
1 分页机制 在虚拟内存中,页表是个映射表的概念, 即从进程能理解的线性地址(linear address)映射到存储器上的物理地址(phisical address). 很显然,这个页表是需要常驻内 ...
- [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)
Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...
- [转帖]Linux分页机制之概述--Linux内存管理(六)
Linux分页机制之概述--Linux内存管理(六) 2016年09月01日 19:46:08 JeanCheng 阅读数:5491 标签: linuxkernel内存管理分页架构更多 个人分类: ┈ ...
随机推荐
- BZOJ 1055 玩具取名(区间DP)
很显然的区间DP,定义dp[i][j][k], 如果dp[i][j][k]=1表示字符串[i,j]可以组成k字符. # include <cstdio> # include <cst ...
- OI入门
学习顺序: 1.高精度计算: 高精度计算(一) 高精度计算练习1 高精度计算(二) 高精度计算练习2 2.递推 3.递归 递归算法 递归练习 4.搜索与回溯 搜索与回溯算法(一) 搜索与回溯练习(一) ...
- CF757G Can Bash Save the Day?
CF757G Can Bash Save the Day? #include<bits/stdc++.h> #define RG register #define IL inline #d ...
- [BZOJ4036] [HAOI2015]按位或
传送门:https://lydsy.com/JudgeOnline/problem.php?id=4036 Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数 ...
- Android 字母导航条实现
在Activity中进行功能的实现,需要用到第三方jar包:pinyin4j.jar,此jar包用于将汉字转换为汉语拼音. 首先,设置右侧边栏索引列表(A-Z),并且设置列表点击,Touch事件,点击 ...
- BZOJ4503 两个串 【fft】
题目链接 BZOJ4503 题解 水水题. 和残缺的字符串那题几乎是一样的 同样转化为多项式 同样TLE 同样要手写一下复数才A #include<algorithm> #include& ...
- javascript push 和 concat 的区别
array.push(item1,item2,item3...) array.concat(item1,item2,item3...) 1. push和concat的元素都既可以是普通元素(任意类型) ...
- mysql语句进阶
1.null mysql> create table worker(id int not null,name varchar(8) not null,pass varchar(20) not n ...
- python 多线程实现
多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...
- UVA:11183:Teen Girl Squad (有向图的最小生成树)
Teen Girl Squad Description: You are part of a group of n teenage girls armed with cellphones. You h ...