#include "pt_task.h" #include "pt_pm.h" #include "pt_ext.h" #include "stdio.h" // 绯荤粺绌洪棽鏉′欢 #define SYSTEM_IS_IDLE() (ALL_TASKS_IDLE()) #define DEEP_SLEEP_THRESHOLD 5 // 杩涘叆娣卞害浼戠湢鐨勭┖闂茶鏁伴槇鍊? static struct { pm_adapter_t default_adapter; pt_t pt; pm_mode_t current_mode; // 褰撳墠鍔熻€楁ā寮? uint32_t ref_count[PM_SLEEP_MODE_MAX]; // 寮曠敤璁℃暟鏁扮粍 } pm; static bool system_is_idle(void) { return pt_task_all_idle(); } /* 鍔熻€楃鐞嗭細閬嶅巻鎵€鏈変换鍔$姸鎬侊紝鐒跺悗鏍规嵁鐢ㄤ簬璇锋眰鐨勫姛鑰楁ā寮忥紝璋冪敤閫傞厤鍣ㄦ帴鍙o紝璋冩暣MCU鐨勮繍琛屾ā寮? */ static void pt_pm_handler(void) { if (system_is_idle()) { // 鍒囨崲鍒颁笅涓€涓彲鐢ㄧ殑鍔熻€楁ā寮? pm_mode_t next_mode = PM_SLEEP_MODE_NONE; for (pm_mode_t m = PM_SLEEP_MODE_NONE; m < PM_SLEEP_MODE_MAX; m++) { if (pm.ref_count[m] > 0 ) { next_mode = m; } } if (next_mode != pm.current_mode && pm.default_adapter.sleep) { pm.default_adapter.sleep(next_mode); pm.current_mode = next_mode; } } else { pt_pm_release(PM_SLEEP_MODE_NONE); // 鍞ら啋绯荤粺 if (pm.default_adapter.wakeup) { pm.default_adapter.wakeup(); } pm.current_mode = PM_SLEEP_MODE_NONE; } } void pt_pm_adapter_init(pm_adapter_t *adapter) { if (adapter) { pm.default_adapter = *adapter; // 澶嶅埗鏁翠釜缁撴瀯浣? } else { pm.default_adapter.sleep = 0; pm.default_adapter.wakeup = 0; } } void pt_pm_init(void) { PT_INIT(&pm.pt); } int pt_task_pm(void) { PT_BEGIN(&pm.pt); while (1) { pt_pm_handler(); // 澶勭悊鍔熻€楃姸鎬? PT_DELAY_MS(&pm.pt, system_is_idle() ? 1000 : 100); } PT_END(&pm.pt); } /* 璇锋眰鍔熻€楁ā寮忥細寮曠敤璁℃暟鑷锛屽鏋滀负1锛屽垯璋冪敤閫傞厤鍣ㄦ帴鍙o紝璋冩暣MCU鐨勮繍琛屾ā寮? */ void pt_pm_request(pm_mode_t mode) { if (mode >= PM_SLEEP_MODE_MAX) { return; // 鏃犳晥妯″紡 } pm.ref_count[mode]++; // 浠呮搷浣滃紩鐢ㄨ鏁? } /* 閲婃斁鍔熻€楁ā寮忥細寮曠敤璁℃暟鑷噺锛屽鏋滀负0锛屽垯璋冪敤閫傞厤鍣ㄦ帴鍙o紝璋冩暣MCU鐨勮繍琛屾ā寮? */ void pt_pm_release(pm_mode_t mode) { if (mode >= PM_SLEEP_MODE_MAX) { return; // 鏃犳晥妯″紡 } if (pm.ref_count[mode] > 0) { pm.ref_count[mode]--; // 浠呮搷浣滃紩鐢ㄨ鏁? } }