在好多實時操作系統中,并沒有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
?
評論
查看更多