SylixOS電源管理概述(shu)以及(ji)接口介紹
時間:2018-09-28 來源:未知
1. 概述
電(dian)(dian)源管(guan)理是(shi)操作(zuo)(zuo)系(xi)統中重要(yao)的一部分。要(yao)實現(xian)電(dian)(dian)源管(guan)理功能,首(shou)先需要(yao)設備本身(shen)支持(chi)電(dian)(dian)源管(guan)理操作(zuo)(zuo),其次是(shi)操作(zuo)(zuo)系(xi)統支持(chi)電(dian)(dian)源管(guan)理操作(zuo)(zuo)。
SylixOS支持(chi)電源(yuan)管(guan)理(li)功能,電源(yuan)管(guan)理(li)分為兩大部分:CPU功耗(hao)管(guan)理(li)和外設功耗(hao)管(guan)理(li)。
1.1 CPU功耗管理
SylixOS中(zhong),CPU功耗(hao)管理分為三個能級:
1.正常運(yun)行(Running):CPU正常執行指令。
2.省電模式(PowerSaving):所有(you)具(ju)有(you)電源管理功能的設備進(jin)入(ru) PowerSaving 模式,同時CPU主頻降低,多(duo)核CPU僅保(bao)留一(yi)個CPU運行。
3.休(xiu)(xiu)(xiu)眠模(mo)式(Sleep):系(xi)統休(xiu)(xiu)(xiu)眠所有具有電源管理功能的設備進入 Suspend 模(mo)式,系(xi)統需(xu)要通過指定事件喚醒休(xiu)(xiu)(xiu)眠模(mo)式系(xi)統,會從復位向量(liang)處恢(hui)復,需(xu)要 bootloader/BIOS 程序配合。
需要的(de)(de)注意的(de)(de)是,在SMP多核中(zhong),可(ke)以動態調(diao)整(zheng)CPU運行的(de)(de)核心數。
1.2 外設功耗管(guan)理
SylixOS中(zhong),外設功耗管(guan)理分為四個狀態:
1.正(zheng)常(chang)運行(xing)狀(zhuang)態(tai):設備(bei)被打(da)開(kai),驅動程序請求(qiu)電源(yuan)管理適配器(qi)連(lian)通(tong)設備(bei)電源(yuan)與時鐘,開(kai)始工作。
2.設(she)備(bei)(bei)關閉(bi)狀態(tai):設(she)備(bei)(bei)被(bei)關閉(bi),驅動程序(xu)請求電源管理適配器斷開(kai)設(she)備(bei)(bei)電源與時鐘,停止工(gong)作(zuo)。
3.省(sheng)電模式(shi)狀態(tai):系統進入(ru)省(sheng)電模式(shi),請(qing)求高能耗(hao)設備(bei)進入(ru)省(sheng)電模式(shi)。
4.設備(bei)空閑(xian)狀(zhuang)態(tai):設備(bei)功(gong)耗管理單元具有看門狗功(gong)能,一旦空閑(xian)時間超過設置,系統會將設備(bei)變為(wei)空閑(xian)狀(zhuang)態(tai)。
1.3 系統框架(jia)
SylixOS下電源管理結構
每個電源管(guan)理(li)(li)適(shi)配(pei)器(qi)(PM Adapter)可以管(guan)理(li)(li)多個設(she)備(由相應的(de)通道(dao)號(hao)區分(fen)),電源管(guan)理(li)(li)適(shi)配(pei)器(qi)管(guan)理(li)(li)的(de)通道(dao)號(hao)總數(shu)決定(ding)這個適(shi)配(pei)器(qi)可以管(guan)理(li)(li)多少個設(she)備。應用(yong)層可以對支持電源管(guan)理(li)(li)的(de)設(she)備進(jin)(jin)行(xing)進(jin)(jin)入(ru)休眠(mian)模式(shi)、進(jin)(jin)入(ru)省電模式(shi)、恢復(fu)正(zheng)常(chang)模式(shi)等(deng)電源管(guan)理(li)(li)操作。
2. 系統接(jie)口及(ji)實現
2.1 系統接(jie)口(kou)概(gai)述
SylixOS中,電源管理部分提供了下面6個函數接(jie)口(kou)供應用(yong)層使(shi)用(yong),如表2-1所示。
2-1 電源管理系統接口
系(xi)統接口 功能
API_PowerMSuspend 系統休(xiu)眠
API_PowerMResume 系統喚醒
API_PowerMCpuSet 設置CPU節電參(can)數
API_PowerMCpuGet 獲取CPU節(jie)電參數
API_PowerMSavingEnter 系統(tong)進(jin)入(ru)省電模(mo)式
API_PowerMSavingExit 系統退出省(sheng)電模式(shi)
2.1.1 系統(tong)休眠(mian)
控制所有支(zhi)持休眠功能的外設進入(ru)休眠狀(zhuang)態,同(tong)時內核進入(ru)休眠狀(zhuang)態。
[html] view plain copy print?
1. VOID Lw_PowerM_Suspend(VOID);
2.1.2 系統喚(huan)醒(xing)
控制所有支持(chi)休眠(mian)功(gong)能的(de)外設從休眠(mian)狀態(tai)(tai)恢(hui)復正常狀態(tai)(tai),同時內核(he)恢(hui)復正常狀態(tai)(tai)。
[html] view plain copy print?
1. VOID Lw_PowerM_Resume(VOID);
2.1.3 設置CPU節(jie)能參數(shu)
設置多核(he)系(xi)(xi)統(tong)中運行的(de)(de)CPU核(he)數(shu)目以(yi)及CPU能(neng)耗級別,系(xi)(xi)統(tong)根據參(can)(can)數(shu)關閉或(huo)打開(kai)CPU核(he),同時(shi)設置CPU能(neng)耗級別,設置CPU以(yi)不(bu)同的(de)(de)主(zhu)頻運行,進入(ru)節能(neng)模(mo)式時(shi)降(jiang)低主(zhu)頻,反之(zhi)則升高主(zhu)頻。本函數(shu)還會將CPU參(can)(can)數(shu)的(de)(de)改變通知到所有支持電(dian)源管理的(de)(de)外設。
[html] view plain copy print?
1. VOID Lw_PowerM_CpuSet(ULONG ulNCpus, UINT uiPowerLevel);
其中參(can)數:參(can)數 ulNCpus是運行態(tai)的CPU核(he)個數;
參數 uiPowerLevel是(shi)CPU能(neng)耗級別。
2.1.4 獲取CPU節能參(can)數
該函數獲得當前(qian)運行的CPU個數和CPU能(neng)耗(hao)級別。
[html] view plain copy print?
1. VOID Lw_PowerM_CpuGet(ULONG *pulNCpus, UINT *puiPowerLevel);
其中參數:參數 pulNCpus返回運行(xing)態的CPU核(he)個數;
參數 puiPowerLevel返(fan)回CPU能耗級(ji)別。
2.1.5 系(xi)統(tong)進入省電(dian)模式
使系統進入省(sheng)電(dian)模式(shi)。控制所有支持電(dian)源管理的設備進入省(sheng)電(dian)模式(shi),同時設置運行的CPU核數目以及能耗級別。
[html] view plain copy print?
1. VOID Lw_PowerM_SavingEnter(ULONG ulNCpus, UINT uiPowerLevel);
其(qi)中參數:參數 ulNCpus是(shi)運(yun)行態的(de)CPU核個數;
參數(shu) uiPowerLevel是CPU能耗級(ji)別。
2.1.6 系(xi)統退出省電模式(shi)
控(kong)制系統(tong)退出(chu)省電(dian)模式(shi),控(kong)制所有支持電(dian)源(yuan)管理的設備退出(chu)省電(dian)模式(shi),同時設置運(yun)行(xing)的CPU核數(shu)目以及能耗級別(bie)。
[html] view plain copy print?
1. VOID Lw_PowerM_SavingExit(ULONG ulNCpus, UINT uiPowerLevel);
其中(zhong)參數(shu):參數(shu) ulNCpus是(shi)運行態的CPU核個數(shu);
參數 uiPowerLevel是CPU能耗級別。
2.2 系統接口實現
2.2.1 系統(tong)休眠(mian)和喚醒
統(tong)(tong)在進(jin)行休(xiu)眠(mian)或者喚醒(xing)操(cao)作(zuo)時,首(shou)先(xian)遍歷電源設備管理鏈表,對鏈表中(zhong)支持電源管理的(de)設備進(jin)行休(xiu)眠(mian)或者喚醒(xing)操(cao)作(zuo),然后對系(xi)統(tong)(tong)內核進(jin)行休(xiu)眠(mian)或喚醒(xing)操(cao)作(zuo)。系(xi)統(tong)(tong)接口實現流程
1. 系統休眠
對系(xi)統(tong)進行休(xiu)眠(mian)操作,需調(diao)用API_PowerMSuspend系(xi)統(tong)接口,實現外設(she)和系(xi)統(tong)內核進入(ru)休(xiu)眠(mian)狀態。函(han)數(shu)原型如程序清單 2 - 1所示(shi)。
程序清單2 - 1 系統休眠
[html] view plain copy print?
1. VOID API_PowerMSuspend (VOID)
2. {
3. PLW_LIST_LINE plineTemp;
4. PLW_PM_DEV pmdev;
5.
6. __POWERM_LOCK();
7. /*
8. * 遍(bian)歷電源管理(li)鏈表,對鏈表中(zhong)設(she)備進行休眠處理(li)
9. */
10. for (plineTemp = _G_plinePMDev;
11. plineTemp != LW_NULL;
12. plineTemp = _list_line_get_next(plineTemp)) {
13. pmdev = _LIST_ENTRY(plineTemp, LW_PM_DEV, PMD_lineManage);
14. if (pmdev->PMD_pmdfunc &&
15. pmdev->PMD_pmdfunc->PMDF_pfuncSuspend) {
16. pmdev->PMD_pmdfunc->PMDF_pfuncSuspend(pmdev);
17. }
18. }
19.
20. __POWERM_UNLOCK();
21.
22. API_KernelSuspend(); /* 內核休眠處(chu)理 */
23. }
該函數實現以下(xia)功(gong)能:
1.
遍歷電(dian)源設(she)備管理(li)鏈表中(zhong)支持電(dian)源管理(li)的設(she)備;
2.
3.
調用PMDF_pfuncSuspend函數,對加(jia)入電(dian)源管理鏈表(biao)中的外設依次進行休眠處理;
4.
5.
調用API_KernelSuspend函數,使(shi)內核進入休眠狀態。
6.
2. 系統(tong)喚醒
系統從(cong)休眠(mian)狀態喚(huan)醒,需調用API_PowerMResume系統接口,實現外設(she)和內核從(cong)休眠(mian)狀態喚(huan)醒,函數原型(xing)如程序(xu)清(qing)單(dan)2- 2所示(shi)。
程序(xu)清單2 - 2 系(xi)統喚(huan)醒
[cpp] view plain copy print?
1. VOID API_PowerMResume (VOID)
2. {
3. PLW_LIST_LINE plineTemp;
4. PLW_PM_DEV pmdev;
5.
6. __POWERM_LOCK();
7.
8. /*
9. * 遍(bian)歷電(dian)源管理鏈表,對鏈表中設備進行喚醒(xing)處(chu)理
10. */
11. for (plineTemp = _G_plinePMDev;
12. plineTemp != LW_NULL;
13. plineTemp = _list_line_get_next(plineTemp)) {
14.
15. pmdev = _LIST_ENTRY(plineTemp, LW_PM_DEV, PMD_lineManage);
16. if (pmdev->PMD_pmdfunc &&
17. pmdev->PMD_pmdfunc->PMDF_pfuncResume) {
18. pmdev->PMD_pmdfunc->PMDF_pfuncResume(pmdev);
19. }
20. }
21. __POWERM_UNLOCK();
22.
23. API_KernelResume(); /* 內核喚醒處理 */
24. }
該函數實現以下(xia)功能:
1.遍歷電源設備(bei)管(guan)理鏈表中支持電源管(guan)理的設備(bei);
2.調用(yong)PMDF_pfuncResume函(han)數,對加(jia)入(ru)電源(yuan)管理(li)鏈表中(zhong)的外設(she)進行喚醒(xing)處(chu)理(li);
3.調用API_KernelResume函數(shu),使內核從休眠中喚醒。
2.2.2 CPU節電參(can)數設(she)置和獲取
CPU節電(dian)參數(shu)(shu)的設置,根(gen)據傳入(ru)參數(shu)(shu)對(dui)CPU核進行關閉和打開,然(ran)后(hou)設置CPU能耗(hao)等級。獲取(qu)CPU節電(dian)參數(shu)(shu),首先獲取(qu)當前系(xi)統運行CPU核個數(shu)(shu),然(ran)后(hou)獲取(qu)CPU能耗(hao)等級。系(xi)統接口實現流程
1. 設置CPU節電參數
設置CPU節電參數,需調用API_PowerMCpuSet系統接(jie)口,函(han)數原型(xing)如程序清單2-3所示。
程(cheng)序清單2 - 3 設置(zhi)CPU節電參數
[html] view plain copy print?
1. VOID API_PowerMCpuSet (ULONG ulNCpus, UINT uiPowerLevel)
2. {
3. PLW_LIST_LINE plineTemp;
4. PLW_PM_DEV pmdev;
5. UINT uiOldPowerLevel;
6.
7. #if LW_CFG_SMP_EN > 0
8. ULONG i;
9. ULONG ulActCnt = 0;
10. #endif /* LW_CFG_SMP_EN > 0 */
11. if (ulNCpus == 0) {
12. _ErrorHandle(EINVAL);
13. return;
14. }
15. if (ulNCpus > LW_NCPUS) {
16. ulNCpus = LW_NCPUS;
17. }
18.
19. #if LW_CFG_SMP_EN > 0
20. for (i = 0; i < LW_NCPUS; i++) { /* 獲取當前系統(tong)運行CPU數 */
21. if (API_CpuIsUp(i)) {
22. ulActCnt++;
23. }
24. }
25.
26. if (ulActCnt > ulNCpus) { /* 需要關閉一些 CPU */
27. #if LW_CFG_SMP_CPU_DOWN_EN > 0
28. ULONG ulDownCnt = ulActCnt - ulNCpus;
29. for (i = 1; i < LW_NCPUS; i++) {
30. if (API_CpuIsUp(i)) {
31. API_CpuDown(i);
32. ulDownCnt--;
33. }
34. if (ulDownCnt == 0) {
35. break;
36. }
37. }
38. #endif /* LW_CFG_SMP_CPU_DOWN_EN > 0 */
39.
40. } else if (ulActCnt < ulNCpus) { /* 需(xu)要(yao)打(da)開(kai)一些 CPU */
41. ULONG ulUpCnt = ulNCpus - ulActCnt;
42. for (i = 1; i < LW_NCPUS; i++) {
43. if (!API_CpuIsUp(i)) {
44. API_CpuUp(i);
45. ulUpCnt--;
46. }
47.
48. if (ulUpCnt == 0) {
49. break;
50. }
51. }
52. }
53. #endif /* LW_CFG_SMP_EN > 0 */
54.
55. API_CpuPowerGet(&uiOldPowerLevel); /* 獲得CPU運(yun)行(xing)能級 */
56. if (uiOldPowerLevel != uiPowerLevel) {
57. API_CpuPowerSet(uiPowerLevel); /* 設置CPU運行能級 */
58. __POWERM_LOCK();
59. /*
60. * 遍歷電源管理(li)鏈表,將節電參數通知支持電源管理(li)的外(wai)設
61. */
62. for (plineTemp = _G_plinePMDev;
63. plineTemp != LW_NULL;
64. plineTemp = _list_line_get_next(plineTemp)) {
65. pmdev = _LIST_ENTRY(plineTemp, LW_PM_DEV, PMD_lineManage);
66. if (pmdev->PMD_pmdfunc &&
67. pmdev->PMD_pmdfunc->PMDF_pfuncCpuPower) {
68. pmdev->PMD_pmdfunc->PMDF_pfuncCpuPower(pmdev);
69. }
70. }
71.
72. __POWERM_UNLOCK();
73. }
74. }
該函數實現(xian)以(yi)下(xia)功能:
1.
獲取當前系(xi)統運行(xing)的CPU核數;
2.
3.
若傳(chuan)入參數(shu)小于當前(qian)系統運行CPU核(he)數(shu),則關閉一(yi)些CPU核(he);
4.
5.
若(ruo)傳入參(can)數大于當前(qian)系(xi)統運行(xing)CPU核數,則打開一(yi)些(xie)CPU核;
6.
獲(huo)取當(dang)前CPU能耗(hao)等(deng)級,根據傳(chuan)入參(can)數設置CPU能耗(hao)等(deng)級;
7.
8.
遍(bian)歷(li)電源(yuan)管理設(she)(she)備(bei)鏈表,將CPU節電參數通(tong)知所有支持電源(yuan)管理的外設(she)(she)。
9.
2. 獲取(qu)CPU節(jie)電參數
獲取CPU節電參數,需(xu)調(diao)用API_PowerMCpuGet系統接(jie)口,函數原型(xing)如(ru)程序清單2-4所示。
程序清單2-4 獲(huo)取CPU節電參數
[html] view plain copy print?
1. VOID API_PowerMCpuGet (ULONG *pulNCpus, UINT *puiPowerLevel)
2. {
3. #if LW_CFG_SMP_EN > 0
4. ULONG i;
5. ULONG ulActCnt = 0;
6. /*
7. * 獲取CPU運(yun)行(xing)核數(shu)
8. */
9. if (pulNCpus) {
10. for (i = 0; i < LW_NCPUS; i++) {
11. if (API_CpuIsUp(i)) {
12. ulActCnt++;
13. }
14. }
15. *pulNCpus = ulActCnt;
16. }
17. #else
18. if (pulNCpus) {
19. *pulNCpus = 1ul;
20. }
21. #endif /* LW_CFG_SMP_EN > 0 */
22. if (puiPowerLevel) {
23. API_CpuPowerGet(puiPowerLevel); /* 獲取(qu)CPU運行能級 */
24. }
25. }
該函數實(shi)現以下(xia)功能(neng):
1.
獲取當前系統(tong)CPU核(he)數;
2.
3.
獲取當前系(xi)統CPU運行能(neng)級(ji)。
4.
2.2.3 系統省電(dian)模(mo)式進入和退出
系統(tong)進入或退(tui)出(chu)省電(dian)模式(shi),首先(xian)通知所有支持(chi)電(dian)源管理(li)的外設進入或者退(tui)出(chu)省電(dian)模式(shi),然后(hou)根據傳(chuan)入參數設置CPU節電(dian)參數。系統(tong)接口(kou)實現(xian)流(liu)程
1. 進入省電(dian)模式
系統進入省電(dian)模式(shi),需調用API_PowerMSavingEnter系統接口,函數原型如(ru)程序清單2 - 5所(suo)示。
程序清單2 - 5 進入省(sheng)電(dian)模式
[html] view plain copy print?
1. VOID API_PowerMSavingEnter (ULONG ulNCpus, UINT uiPowerLevel)
2. {
3. PLW_LIST_LINE plineTemp;
4. PLW_PM_DEV pmdev;
5.
6. if (ulNCpus == 0) {
7. _ErrorHandle(EINVAL);
8. return;
9. }
10. __POWERM_LOCK();
11. /*
12. * 遍歷電(dian)源管理鏈表,使(shi)外設(she)進入省電(dian)模式(shi)
13. */
14. for (plineTemp = _G_plinePMDev;
15. plineTemp != LW_NULL;
16. plineTemp = _list_line_get_next(plineTemp)) {
17. pmdev = _LIST_ENTRY(plineTemp, LW_PM_DEV, PMD_lineManage);
18. if (pmdev->PMD_pmdfunc &&
19. pmdev->PMD_pmdfunc->PMDF_pfuncPowerSavingEnter) {
20. pmdev->PMD_pmdfunc->PMDF_pfuncPowerSavingEnter(pmdev);
21. }
22. }
23.
24. _G_bPowerSavingMode = LW_TRUE;
25. __POWERM_UNLOCK();
26.
27. API_PowerMCpuSet(ulNCpus, uiPowerLevel); /* CPU節電參數設置 */
28. }
該(gai)函數(shu)實現以下功能:
1.
遍歷電(dian)(dian)源(yuan)管理鏈表(biao)(biao),把(ba)電(dian)(dian)源(yuan)管理鏈表(biao)(biao)中所有支持電(dian)(dian)源(yuan)管理的設備設置為(wei)省電(dian)(dian)模(mo)式;
2.
3.
設置(zhi)CPU節電參數,根據傳入(ru)參數,對CPU節電參數進行設置(zhi),調(diao)用2.2.2節中API_PowerMCpuSet接口函(han)數。
4.
2. 退出省(sheng)電模式
系統退出(chu)省電模式,需(xu)調用API_PowerMSavingExit系統接口(kou),函數原(yuan)型如程序清(qing)單(dan)2 - 6所示(shi)。
程序清單2 - 6 退(tui)出省(sheng)電模式
[html] view plain copy print?
1. VOID API_PowerMSavingExit (ULONG ulNCpus, UINT uiPowerLevel)
2. {
3. PLW_LIST_LINE plineTemp;
4. PLW_PM_DEV pmdev;
5.
6. if (ulNCpus == 0) {
7. _ErrorHandle(EINVAL);
8. return;
9. }
10. __POWERM_LOCK();
11. /*
12. * 遍歷電源管(guan)理鏈表,使外設外設省電模式
13. */
14. for (plineTemp = _G_plinePMDev;
15. plineTemp != LW_NULL;
16. plineTemp = _list_line_get_next(plineTemp)) {
17. pmdev = _LIST_ENTRY(plineTemp, LW_PM_DEV, PMD_lineManage);
18. if (pmdev->PMD_pmdfunc &&
19. pmdev->PMD_pmdfunc->PMDF_pfuncPowerSavingExit) {
20. pmdev->PMD_pmdfunc->PMDF_pfuncPowerSavingExit(pmdev);
21. }
22. }
23. _G_bPowerSavingMode = LW_FALSE;
24. __POWERM_UNLOCK();
25.
26. API_PowerMCpuSet(ulNCpus, uiPowerLevel); /* CPU節電(dian)參數設置 */
27. }
該函數實現以下功能:
1.
遍歷(li)電(dian)源管(guan)(guan)理(li)鏈表,把電(dian)源管(guan)(guan)理(li)鏈表中所有支持(chi)電(dian)源管(guan)(guan)理(li)的設備退出省電(dian)模式;
2.
3.
設(she)置CPU節電參(can)數(shu)(shu),根據(ju)傳(chuan)入參(can)數(shu)(shu),對CPU節電參(can)數(shu)(shu)進行(xing)設(she)置,調(diao)用(yong)2.2.2節中API_PowerMCpuSet接口(kou)函數(shu)(shu)。
4.
3. 小結
本文檔介紹了SylixOS向應用層(ceng)提(ti)供的(de)(de)電源管(guan)理系統接(jie)(jie)口,以(yi)及接(jie)(jie)口的(de)(de)實現流程。應用層(ceng)可以(yi)調用這些系統接(jie)(jie)口,實現系統的(de)(de)電源管(guan)理工作。

