當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > SylixOS電源管理概述以及接口介紹
SylixOS電源管理概述以及接口介紹
時間:2018-09-28 來源:未知
1. 概述
電源管理是操作系統(tǒng)中重要的一部分。要實現(xiàn)電源管理功能,首先需要設(shè)備本身支持電源管理操作,其次是操作系統(tǒng)支持電源管理操作。
SylixOS支持電源管理功能,電源管理分為兩大部分:CPU功耗管理和外設(shè)功耗管理。
1.1 CPU功耗管理
SylixOS中,CPU功耗管理分為三個能級:
1.正常運行(Running):CPU正常執(zhí)行指令。
2.省電模式(PowerSaving):所有具有電源管理功能的設(shè)備進入 PowerSaving 模式,同時CPU主頻降低,多核CPU僅保留一個CPU運行。
3.休眠模式(Sleep):系統(tǒng)休眠所有具有電源管理功能的設(shè)備進入 Suspend 模式,系統(tǒng)需要通過指定事件喚醒休眠模式系統(tǒng),會從復(fù)位向量處恢復(fù),需要 bootloader/BIOS 程序配合。
需要的注意的是,在SMP多核中,可以動態(tài)調(diào)整CPU運行的核心數(shù)。
1.2 外設(shè)功耗管理
SylixOS中,外設(shè)功耗管理分為四個狀態(tài):
1.正常運行狀態(tài):設(shè)備被打開,驅(qū)動程序請求電源管理適配器連通設(shè)備電源與時鐘,開始工作。
2.設(shè)備關(guān)閉狀態(tài):設(shè)備被關(guān)閉,驅(qū)動程序請求電源管理適配器斷開設(shè)備電源與時鐘,停止工作。
3.省電模式狀態(tài):系統(tǒng)進入省電模式,請求高能耗設(shè)備進入省電模式。
4.設(shè)備空閑狀態(tài):設(shè)備功耗管理單元具有看門狗功能,一旦空閑時間超過設(shè)置,系統(tǒng)會將設(shè)備變?yōu)榭臻e狀態(tài)。
1.3 系統(tǒng)框架
SylixOS下電源管理結(jié)構(gòu)
每個電源管理適配器(PM Adapter)可以管理多個設(shè)備(由相應(yīng)的通道號區(qū)分),電源管理適配器管理的通道號總數(shù)決定這個適配器可以管理多少個設(shè)備。應(yīng)用層可以對支持電源管理的設(shè)備進行進入休眠模式、進入省電模式、恢復(fù)正常模式等電源管理操作。
2. 系統(tǒng)接口及實現(xiàn)
2.1 系統(tǒng)接口概述
SylixOS中,電源管理部分提供了下面6個函數(shù)接口供應(yīng)用層使用,如表2-1所示。
2-1 電源管理系統(tǒng)接口
系統(tǒng)接口 功能
API_PowerMSuspend 系統(tǒng)休眠
API_PowerMResume 系統(tǒng)喚醒
API_PowerMCpuSet 設(shè)置CPU節(jié)電參數(shù)
API_PowerMCpuGet 獲取CPU節(jié)電參數(shù)
API_PowerMSavingEnter 系統(tǒng)進入省電模式
API_PowerMSavingExit 系統(tǒng)退出省電模式
2.1.1 系統(tǒng)休眠
控制所有支持休眠功能的外設(shè)進入休眠狀態(tài),同時內(nèi)核進入休眠狀態(tài)。
[html] view plain copy print?
1. VOID Lw_PowerM_Suspend(VOID);
2.1.2 系統(tǒng)喚醒
控制所有支持休眠功能的外設(shè)從休眠狀態(tài)恢復(fù)正常狀態(tài),同時內(nèi)核恢復(fù)正常狀態(tài)。
[html] view plain copy print?
1. VOID Lw_PowerM_Resume(VOID);
2.1.3 設(shè)置CPU節(jié)能參數(shù)
設(shè)置多核系統(tǒng)中運行的CPU核數(shù)目以及CPU能耗級別,系統(tǒng)根據(jù)參數(shù)關(guān)閉或打開CPU核,同時設(shè)置CPU能耗級別,設(shè)置CPU以不同的主頻運行,進入節(jié)能模式時降低主頻,反之則升高主頻。本函數(shù)還會將CPU參數(shù)的改變通知到所有支持電源管理的外設(shè)。
[html] view plain copy print?
1. VOID Lw_PowerM_CpuSet(ULONG ulNCpus, UINT uiPowerLevel);
其中參數(shù):參數(shù) ulNCpus是運行態(tài)的CPU核個數(shù);
參數(shù) uiPowerLevel是CPU能耗級別。
2.1.4 獲取CPU節(jié)能參數(shù)
該函數(shù)獲得當(dāng)前運行的CPU個數(shù)和CPU能耗級別。
[html] view plain copy print?
1. VOID Lw_PowerM_CpuGet(ULONG *pulNCpus, UINT *puiPowerLevel);
其中參數(shù):參數(shù) pulNCpus返回運行態(tài)的CPU核個數(shù);
參數(shù) puiPowerLevel返回CPU能耗級別。
2.1.5 系統(tǒng)進入省電模式
使系統(tǒng)進入省電模式。控制所有支持電源管理的設(shè)備進入省電模式,同時設(shè)置運行的CPU核數(shù)目以及能耗級別。
[html] view plain copy print?
1. VOID Lw_PowerM_SavingEnter(ULONG ulNCpus, UINT uiPowerLevel);
其中參數(shù):參數(shù) ulNCpus是運行態(tài)的CPU核個數(shù);
參數(shù) uiPowerLevel是CPU能耗級別。
2.1.6 系統(tǒng)退出省電模式
控制系統(tǒng)退出省電模式,控制所有支持電源管理的設(shè)備退出省電模式,同時設(shè)置運行的CPU核數(shù)目以及能耗級別。
[html] view plain copy print?
1. VOID Lw_PowerM_SavingExit(ULONG ulNCpus, UINT uiPowerLevel);
其中參數(shù):參數(shù) ulNCpus是運行態(tài)的CPU核個數(shù);
參數(shù) uiPowerLevel是CPU能耗級別。
2.2 系統(tǒng)接口實現(xiàn)
2.2.1 系統(tǒng)休眠和喚醒
統(tǒng)在進行休眠或者喚醒操作時,首先遍歷電源設(shè)備管理鏈表,對鏈表中支持電源管理的設(shè)備進行休眠或者喚醒操作,然后對系統(tǒng)內(nèi)核進行休眠或喚醒操作。系統(tǒng)接口實現(xiàn)流程
1. 系統(tǒng)休眠
對系統(tǒng)進行休眠操作,需調(diào)用API_PowerMSuspend系統(tǒng)接口,實現(xiàn)外設(shè)和系統(tǒng)內(nèi)核進入休眠狀態(tài)。函數(shù)原型如程序清單 2 - 1所示。
程序清單2 - 1 系統(tǒng)休眠
[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. * 遍歷電源管理鏈表,對鏈表中設(shè)備進行休眠處理
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(); /* 內(nèi)核休眠處理 */
23. }
該函數(shù)實現(xiàn)以下功能:
1.
遍歷電源設(shè)備管理鏈表中支持電源管理的設(shè)備;
2.
3.
調(diào)用PMDF_pfuncSuspend函數(shù),對加入電源管理鏈表中的外設(shè)依次進行休眠處理;
4.
5.
調(diào)用API_KernelSuspend函數(shù),使內(nèi)核進入休眠狀態(tài)。
6.
2. 系統(tǒng)喚醒
系統(tǒng)從休眠狀態(tài)喚醒,需調(diào)用API_PowerMResume系統(tǒng)接口,實現(xiàn)外設(shè)和內(nèi)核從休眠狀態(tài)喚醒,函數(shù)原型如程序清單2- 2所示。
程序清單2 - 2 系統(tǒng)喚醒
[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. * 遍歷電源管理鏈表,對鏈表中設(shè)備進行喚醒處理
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(); /* 內(nèi)核喚醒處理 */
24. }
該函數(shù)實現(xiàn)以下功能:
1.遍歷電源設(shè)備管理鏈表中支持電源管理的設(shè)備;
2.調(diào)用PMDF_pfuncResume函數(shù),對加入電源管理鏈表中的外設(shè)進行喚醒處理;
3.調(diào)用API_KernelResume函數(shù),使內(nèi)核從休眠中喚醒。
2.2.2 CPU節(jié)電參數(shù)設(shè)置和獲取
CPU節(jié)電參數(shù)的設(shè)置,根據(jù)傳入?yún)?shù)對CPU核進行關(guān)閉和打開,然后設(shè)置CPU能耗等級。獲取CPU節(jié)電參數(shù),首先獲取當(dāng)前系統(tǒng)運行CPU核個數(shù),然后獲取CPU能耗等級。系統(tǒng)接口實現(xiàn)流程
1. 設(shè)置CPU節(jié)電參數(shù)
設(shè)置CPU節(jié)電參數(shù),需調(diào)用API_PowerMCpuSet系統(tǒng)接口,函數(shù)原型如程序清單2-3所示。
程序清單2 - 3 設(shè)置CPU節(jié)電參數(shù)
[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++) { /* 獲取當(dāng)前系統(tǒng)運行CPU數(shù) */
21. if (API_CpuIsUp(i)) {
22. ulActCnt++;
23. }
24. }
25.
26. if (ulActCnt > ulNCpus) { /* 需要關(guān)閉一些 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) { /* 需要打開一些 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運行能級 */
56. if (uiOldPowerLevel != uiPowerLevel) {
57. API_CpuPowerSet(uiPowerLevel); /* 設(shè)置CPU運行能級 */
58. __POWERM_LOCK();
59. /*
60. * 遍歷電源管理鏈表,將節(jié)電參數(shù)通知支持電源管理的外設(shè)
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. }
該函數(shù)實現(xiàn)以下功能:
1.
獲取當(dāng)前系統(tǒng)運行的CPU核數(shù);
2.
3.
若傳入?yún)?shù)小于當(dāng)前系統(tǒng)運行CPU核數(shù),則關(guān)閉一些CPU核;
4.
5.
若傳入?yún)?shù)大于當(dāng)前系統(tǒng)運行CPU核數(shù),則打開一些CPU核;
6.
獲取當(dāng)前CPU能耗等級,根據(jù)傳入?yún)?shù)設(shè)置CPU能耗等級;
7.
8.
遍歷電源管理設(shè)備鏈表,將CPU節(jié)電參數(shù)通知所有支持電源管理的外設(shè)。
9.
2. 獲取CPU節(jié)電參數(shù)
獲取CPU節(jié)電參數(shù),需調(diào)用API_PowerMCpuGet系統(tǒng)接口,函數(shù)原型如程序清單2-4所示。
程序清單2-4 獲取CPU節(jié)電參數(shù)
[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運行核數(shù)
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); /* 獲取CPU運行能級 */
24. }
25. }
該函數(shù)實現(xiàn)以下功能:
1.
獲取當(dāng)前系統(tǒng)CPU核數(shù);
2.
3.
獲取當(dāng)前系統(tǒng)CPU運行能級。
4.
2.2.3 系統(tǒng)省電模式進入和退出
系統(tǒng)進入或退出省電模式,首先通知所有支持電源管理的外設(shè)進入或者退出省電模式,然后根據(jù)傳入?yún)?shù)設(shè)置CPU節(jié)電參數(shù)。系統(tǒng)接口實現(xiàn)流程
1. 進入省電模式
系統(tǒng)進入省電模式,需調(diào)用API_PowerMSavingEnter系統(tǒng)接口,函數(shù)原型如程序清單2 - 5所示。
程序清單2 - 5 進入省電模式
[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. * 遍歷電源管理鏈表,使外設(shè)進入省電模式
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節(jié)電參數(shù)設(shè)置 */
28. }
該函數(shù)實現(xiàn)以下功能:
1.
遍歷電源管理鏈表,把電源管理鏈表中所有支持電源管理的設(shè)備設(shè)置為省電模式;
2.
3.
設(shè)置CPU節(jié)電參數(shù),根據(jù)傳入?yún)?shù),對CPU節(jié)電參數(shù)進行設(shè)置,調(diào)用2.2.2節(jié)中API_PowerMCpuSet接口函數(shù)。
4.
2. 退出省電模式
系統(tǒng)退出省電模式,需調(diào)用API_PowerMSavingExit系統(tǒng)接口,函數(shù)原型如程序清單2 - 6所示。
程序清單2 - 6 退出省電模式
[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. * 遍歷電源管理鏈表,使外設(shè)外設(shè)省電模式
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節(jié)電參數(shù)設(shè)置 */
27. }
該函數(shù)實現(xiàn)以下功能:
1.
遍歷電源管理鏈表,把電源管理鏈表中所有支持電源管理的設(shè)備退出省電模式;
2.
3.
設(shè)置CPU節(jié)電參數(shù),根據(jù)傳入?yún)?shù),對CPU節(jié)電參數(shù)進行設(shè)置,調(diào)用2.2.2節(jié)中API_PowerMCpuSet接口函數(shù)。
4.
3. 小結(jié)
本文檔介紹了SylixOS向應(yīng)用層提供的電源管理系統(tǒng)接口,以及接口的實現(xiàn)流程。應(yīng)用層可以調(diào)用這些系統(tǒng)接口,實現(xiàn)系統(tǒng)的電源管理工作。

