在好多實時操作系統(tǒng)中,并沒有dpm這個框架,所以我們可以仿照linux的dpm框架,來實現(xiàn)我們自己的dpm,可以運用到需要dpm的系統(tǒng)中。
為便于描述,本文使用偽代碼,僅個別地方具體實現(xiàn);
1、首先,我們需要定義兩個結(jié)構(gòu)體類型,一個用于控制,一個用于各個模塊注冊;
(1)控制結(jié)構(gòu)體
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使用的結(jié)構(gòu)體
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,結(jié)構(gòu)體我們已經(jīng)定義完了,那么我們接下來需要初始化一下控制結(jié)構(gòu)體的變量
int? my_dpm_init(void){
初始化五個鏈表;
初始化spin_lock鎖;
return OK;
}
3、到此,我們自己的dpm已初始化完成,各個模塊想要注冊dpm,就差一個注冊接口了,下面我們來實現(xiàn)注冊接口
int dpm_register(struct dpm_device *device
獲取互斥鎖;
初始化設(shè)備結(jié)構(gòu)體中的entry;
加入到dpm_list鏈表中;
釋放互斥鎖;
return OK;
}
4、這樣,用戶就可以調(diào)用dpm_register來注冊dpm了;但是注冊完后,得需要提供接口來供低功耗流程來調(diào)用啊,莫急,我們這就來實現(xiàn)供低功耗調(diào)用的接口,??? dpm_suspend和dpm_resume
(1)dpm_suspend:主要回調(diào)各個模塊注冊的保存信息的回調(diào)函數(shù),包括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:主要用在喚醒階段,按照優(yōu)先級回調(diào)各個模塊注冊的恢復(fù)信息的回調(diào)函數(shù),包括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、大家可以看到,上面兩個接口中分別調(diào)用了4個函數(shù),供8個函數(shù),分別用在suspend階段和resume階段,接下來我們簡單實現(xiàn)一下其中一個函數(shù)prepare
int prepare(void)
{
獲取互斥鎖;
遍歷dpm_list鏈表,檢查每個結(jié)點是否注冊prepare回調(diào)函數(shù),如果注冊,則執(zhí)行回調(diào)函數(shù):ret=dev->prepare(dev),如果成功,則移入prepare_list,否則,執(zhí)行恢復(fù)操作;
釋放互斥鎖;
}
其他的suspend_early()、suspend()、suspend_late()、resume()、resume_early()、resume_late()、complete()等具體函數(shù)實現(xiàn)基本大致相同,只不過所操作的鏈表不同罷了。
好了,我們的dpm框架實現(xiàn)完成了,簡單吧,我們嘗試注冊一個吧:
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;
};
在合適的地方調(diào)用dpm_register(&test_device)即可,需要注意的是,dpm回調(diào)函數(shù)注冊一定要配對:prepare--complete?????? suspend--resume??????? suspend_late--resume_early??????????????? suspend_late--resume_early
?
評論
查看更多