色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

處理器電源管理主要實現方式是什么?

lhl545545 ? 來源:RTThread物聯網操作系統 ? 作者:RTThread物聯網操作 ? 2020-06-09 15:27 ? 次閱讀

電源管理組件

嵌入式系統低功耗管理的目的在于滿足用戶對性能需求的前提下,盡可能降低系統能耗以延長設備待機時間。高性能與有限的電池能量在嵌入式系統中矛盾最為突出,硬件低功耗設計與軟件低功耗管理的聯合應用成為解決矛盾的有效手段。現在的各種 MCU 都或多或少的在低功耗方面提供了管理接口。比如對主控時鐘頻率的調整、工作電壓的改變、總線頻率的調整甚至關閉、外圍設備工作時鐘的關閉等。有了硬件上的支持,合理的軟件設計就成為節能的關鍵,一般可以把低功耗管理分為三個類別:

處理器電源管理主要實現方式:對 CPU 頻率的動態管理,以及系統空閑時對工作模式的調整。

設備電源管理主要實現方式:關閉個別閑置設備

系統平臺電源管理主要實現方式:針對特定系統平臺的非常見設備具體定制。

隨著物聯網IoT) 的興起,產品對功耗的需求越來越強烈。作為數據采集的傳感器節點通常需要在電池供電時長期工作,而作為聯網的 SOC 也需要有快速的響應功能和較低的功耗。

在產品開發的起始階段,首先考慮是盡快完成產品的功能開發。在產品功能逐步完善之后,就需要加入電源管理 (Power Management,以下簡稱 PM) 功能。為了適應 IoT 的這種需求,RT-Thread 提供了電源管理組件。電源管理組件的理念是盡量透明,使得產品加入低功耗功能更加輕松。

PM 組件介紹

RT-Thread 的 PM 組件采用分層設計思想,分離架構和芯片相關的部分,提取公共部分作為核心。在對上層提供通用的接口同時,也讓底層驅動對組件的適配變得更加簡單。

處理器電源管理主要實現方式是什么?

主要特點

RT-Thread PM 組件主要特點如下所示:

基于模式來管理功耗,空閑時動態調整工作模式,支持多個等級的休眠。

對應用透明,組件在底層自動完成電源管理。

支持運行模式下動態變頻,根據模式自動更新設備的頻率配置,確保在不同的運行模式都可以正常工作。

支持設備電源管理,根據模式自動管理設備的掛起和恢復,確保在不同的休眠模式下可以正確的掛起和恢復。

支持可選的休眠時間補償,讓依賴 OS Tick 的應用可以透明使用。

向上層提供設備接口,如果打開了 devfs 組件,那么也可以通過文件系統接口訪問。

工作原理

低功耗的本質是系統空閑時 CPU 停止工作,中斷或事件喚醒后繼續工作。在 RTOS 中,通常包含一個 IDLE 任務,該任務的優先級最低且一直保持就緒狀態,當高優先級任務未就緒時,OS 執行 IDLE 任務。一般地,未進行低功耗處理時,CPU 在 IDLE 任務中循環執行空指令。RT-Thread 的電源管理組件在 IDLE 任務中,通過對 CPU 、時鐘和設備等進行管理,從而有效降低系統的功耗。

處理器電源管理主要實現方式是什么?

在上圖所示,當高優先級任務運行結束或被掛起時,系統將進入 IDLE 任務中。在 IDLE 任務執行后,它將判斷系統是否可以進入到休眠狀態(以節省功耗)。如果可以進入休眠, 將根據芯片情況關閉部分硬件模塊,OS Tick 也非常有可能進入暫停狀態。此時電源管理框架會根據系統定時器情況,計算出下一個超時時間點,并設置低功耗定時器,讓設備能夠在這個時刻點喚醒,并進行后續的工作。當系統被(低功耗定時器中斷或其他喚醒中斷源)喚醒后,系統也需要知道睡眠時間長度是多少,并對OS Tick 進行補償,讓系統的OS tick值調整為一個正確的值。

低功耗狀態和模式

RT-Thread PM 組件將系統劃分為兩種狀態:運行狀態(RUN)和休眠狀態(Sleep)。運行狀態控制 CPU 的頻率,適用于變頻場景;休眠狀態根據 SOC 特性實現休眠 CPU,以降低功耗。兩種狀態分別使用不同的 API 接口,獨立控制。

休眠狀態休眠狀態也就是通常意義上的低功耗狀態,通過關閉外設、執行 SOC 電源管理接口,降低系統功耗。休眠狀態又分為六個模式,呈現為金字塔的形式。隨著模式增加,功耗逐級遞減的特點。下面是休眠狀態下模式的定義,開發者可根據具體的 SOC 實現相應的模式,但需要遵循功耗逐級降低的特點。

處理器電源管理主要實現方式是什么?

運行狀態運行狀態通常用于改變 CPU 的運行頻率,獨立于休眠模式。當前運行狀態劃分了四個等級:高速、正常、中速、低速,如下:

處理器電源管理主要實現方式是什么?

PM組件的實現接口

在 RT-Thrad PM 組件中,外設或應用通過投票機制對所需的功耗模式進行投票,當系統空閑時,根據投票數決策出合適的功耗模式,調用抽象接口,控制芯片進入低功耗狀態,從而降低系統功耗。當未進行進行任何投票時,會以默認模式進入(通常為空閑模式)。

pm組件的控制塊:

static struct rt_pm _pm;

API接口:

請求休眠模式

void rt_pm_request(uint8_t sleep_mode);

sleep_mode 取以下枚舉值:

enum { /* sleep modes */ PM_SLEEP_MODE_NONE = 0, /* 活躍狀態 */ PM_SLEEP_MODE_IDLE, /* 空閑模式(默認) */ PM_SLEEP_MODE_LIGHT, /* 輕度睡眠模式 */ PM_SLEEP_MODE_DEEP, /* 深度睡眠模式 */ PM_SLEEP_MODE_STANDBY, /* 待機模式 */ PM_SLEEP_MODE_SHUTDOWN, /* 關斷模式 */ PM_SLEEP_MODE_MAX, };

調用該函數會將對應的模式計數加1,并鎖住該模式。此時如果請求更低級別的功耗模式,將無法進入,只有釋放(解鎖)先前請求的模式后,系統才能進入更低的模式;向更高的功耗模式請求則不受此影響。該函數需要和 rt_pm_release 配合使用,用于對某一階段或過程進行保護。下面是具體代碼實現:

void rt_pm_request(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) return; if (mode 》 (PM_SLEEP_MODE_MAX - 1)) return; level = rt_hw_interrupt_disable(); pm = &_pm; if (pm-》modes[mode] 《 255) pm-》modes[mode] ++;//將對應的模式計數加1 rt_hw_interrupt_enable(level); }

釋放休眠模式

void rt_pm_release(uint8_t sleep_mode);

調用該函數會將對應的模式計數減1,配合 rt_pm_request 使用,釋放先前請求的模式。下面是具體代碼實現:

void rt_pm_release(rt_uint8_t mode) { rt_ubase_t level; struct rt_pm *pm; if (_pm_init_flag == 0) return; if (mode 》 (PM_SLEEP_MODE_MAX - 1)) return; level = rt_hw_interrupt_disable(); pm = &_pm; if (pm-》modes[mode] 》 0) pm-》modes[mode] --;//將對應的模式計數減1 rt_hw_interrupt_enable(level); }

特殊情況下,比如某個階段并不允許系統進入更低的功耗模式,此時可以通過 rt_pm_request 和 rt_pm_release 對該過程進行保護。如 I2C 讀取數據期間,不允許進入深度睡眠模式(可能會導致外設停止工作),因此可以做如下處理:

/* 請求輕度睡眠模式(I2C外設該模式下正常工作) */ rt_pm_request(PM_SLEEP_MODE_LIGHT); /* 讀取數據過程 */ /* 釋放該模式 */ rt_pm_release(PM_SLEEP_MODE_LIGHT);

設置運行模式

int rt_pm_run_enter(uint8_t run_mode);

run_mode 可以取以下枚舉值:

enum { /* run modes*/ PM_RUN_MODE_HIGH_SPEED = 0, /* 高速 */ PM_RUN_MODE_NORMAL_SPEED, /* 正常(默認) */ PM_RUN_MODE_MEDIUM_SPEED, /* 中速 */ PM_RUN_MODE_LOW_SPEED, /* 低速 */ PM_RUN_MODE_MAX, };

調用該函數改變 CPU 的運行頻率,從而降低運行時的功耗。此函數只提供級別,具體的 CPU 頻率應在移植階段視實際情況而定。

下面是具體代碼實現:

int rt_pm_run_enter(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) return -RT_EIO; if (mode 》 PM_RUN_MODE_MAX) return -RT_EINVAL; level = rt_hw_interrupt_disable(); pm = &_pm; if (mode 《 pm-》run_mode) { /* change system runing mode */ pm-》ops-》run(pm, mode); /* changer device frequency */ _pm_device_frequency_change(mode); } else { pm-》flags |= RT_PM_FREQUENCY_PENDING; } pm-》run_mode = mode; rt_hw_interrupt_enable(level); return RT_EOK; }

設置進入/退出休眠模式的回調通知

void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data);

event 為以下兩個枚舉值,分別標識進入/退出休眠模式。

enum { RT_PM_ENTER_SLEEP = 0, /* 進入休眠模式 */ RT_PM_EXIT_SLEEP, /* 退出休眠模式 */ };

在應用進入/退出休眠模式會觸發回調通知。下面是具體代碼實現:

void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data) { _pm_notify.notify = notify; _pm_notify.data = data; }

注冊PM設備

void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops)

與應用不同,某些外設可能在進入低功耗狀態時執行特定操作,退出低功耗時采取措施恢復,此時可以通過注冊PM設備來實現。通過注冊 PM 設備,在進入低功耗狀態之前,會觸發注冊設備的 suspend 回調,開發者可在回調里執行自己的操作;類似地,從低功耗狀態退出時,也會觸發 resume 回調。運行模式下的頻率改變同樣會觸發設備的 frequency_change 回調。下面是具體代碼實現:

void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops) { rt_base_t level; struct rt_device_pm *device_pm; RT_DEBUG_NOT_IN_INTERRUPT; level = rt_hw_interrupt_disable(); device_pm = (struct rt_device_pm *)RT_KERNEL_REALLOC(_pm.device_pm, (_pm.device_pm_number + 1) * sizeof(struct rt_device_pm)); if (device_pm != RT_NULL) { _pm.device_pm = device_pm; _pm.device_pm[_pm.device_pm_number].device = device; _pm.device_pm[_pm.device_pm_number].ops = ops; _pm.device_pm_number += 1; } rt_hw_interrupt_enable(level); }

設置進入/退出休眠模式的回調通知和注冊為設備的回調通知流程:

處理器電源管理主要實現方式是什么?

首先應用設置進出休眠狀態的回調函數,然后調用 rt_pm_request 請求休眠模式,觸發休眠操作;PM 組件在系統空閑時檢查休眠模式計數,根據投票數給出推薦的模式;接著 PM 組件調用 notfiy 通知應用,告知即將進入休眠模式;然后對注冊的 PM 設備執行掛起操作,返回 OK 后執行 SOC 實現的的休眠模式,系統進入休眠狀態(如果使能時間補償,休眠之前會先啟動低功耗定時器)。此時 CPU 停止工作,等待事件或者中斷喚醒。當系統被喚醒后,由于全局中斷為關閉狀態,系統繼續從該處執行,獲取睡眠時間補償系統的心跳,依次喚醒設備,通知應用從休眠模式退出。如此一個周期執行完畢,退出,等待系統下次空閑。模式的切換代碼實現:當任務進入到空閑線程,最終是調用此函數進入低功耗和喚醒的

static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode) { rt_tick_t timeout_tick, delta_tick; rt_base_t level; int ret = RT_EOK; if (mode == PM_SLEEP_MODE_NONE) { pm-》sleep_mode = mode; pm-》ops-》sleep(pm, PM_SLEEP_MODE_NONE); } else { level = rt_pm_enter_critical(mode); /* Notify app will enter sleep mode */ if (_pm_notify.notify) _pm_notify.notify(RT_PM_ENTER_SLEEP, mode, _pm_notify.data); /* Suspend all peripheral device */ ret = _pm_device_suspend(mode); if (ret != RT_EOK) { _pm_device_resume(mode); if (_pm_notify.notify) _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data); rt_pm_exit_critical(level, mode); return; } /* Tickless*/ if (pm-》timer_mask & (0x01 《《 mode)) { timeout_tick = rt_timer_next_timeout_tick(); if (timeout_tick == RT_TICK_MAX) { if (pm-》ops-》timer_start) { pm-》ops-》timer_start(pm, RT_TICK_MAX); } } else { timeout_tick = timeout_tick - rt_tick_get(); if (timeout_tick 《 RT_PM_TICKLESS_THRESH) { mode = PM_SLEEP_MODE_IDLE; } else { pm-》ops-》timer_start(pm, timeout_tick); } } } /* enter lower power state */ pm-》ops-》sleep(pm, mode); /* wake up from lower power state*/ if (pm-》timer_mask & (0x01 《《 mode)) { delta_tick = pm-》ops-》timer_get_tick(pm); pm-》ops-》timer_stop(pm); if (delta_tick) { rt_tick_set(rt_tick_get() + delta_tick); rt_timer_check(); } } /* resume all device */ _pm_device_resume(pm-》sleep_mode); if (_pm_notify.notify) _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data); rt_pm_exit_critical(level, mode); } }

移植的實現原理

RT-Thread 低功耗管理系統從設計上分離運行模式和休眠模式,獨立管理,運行模式用于變頻和變電壓,休眠調用芯片的休眠特性。對于多數芯片和開發來說,可能并不需要考慮變頻和變電壓,僅需關注休眠模式。底層功能的實現已經有Sunwancn大神對STM32做了全系列的適配,以下是底層實現原理,用戶也可以自行根據自身情況對底層進行裁剪或增強。(注意: 驅動可能有更新,移植請到gitee下載最新pm驅動。地址在pm-ports-stm32-new 分支:https://gitee.com/sunwancn/rt-thread/tree/pm-ports-stm32-new)

PM 組件的底層功能都是通過struct rt_pm_ops結構體里的函數完成:

/** * low power mode operations */ struct rt_pm_ops { void (*sleep)(struct rt_pm *pm, uint8_t mode); void (*run)(struct rt_pm *pm, uint8_t mode); void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout); void (*timer_stop)(struct rt_pm *pm); rt_tick_t (*timer_get_tick)(struct rt_pm *pm); };

移植休眠模式移植休眠模式僅需關注 sleep 接口,下面是具體的實現:

void stm32_sleep(struct rt_pm *pm, rt_uint8_t mode) { switch (mode) { case PM_SLEEP_MODE_NONE: break; case PM_SLEEP_MODE_IDLE: if (pm-》run_mode == PM_RUN_MODE_LOW_SPEED) { /* Enter LP SLEEP Mode, Enable low-power regulator */ HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); } else { /* Enter SLEEP Mode, Main regulator is ON */ HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); } break; case PM_SLEEP_MODE_LIGHT: if (pm-》run_mode == PM_RUN_MODE_LOW_SPEED) { __HAL_FLASH_SLEEP_POWERDOWN_ENABLE(); /* Enter LP SLEEP Mode, Enable low-power regulator */ HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); __HAL_FLASH_SLEEP_POWERDOWN_DISABLE(); } else { /* Enter SLEEP Mode, Main regulator is ON */ HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); } break; case PM_SLEEP_MODE_DEEP: /* Disable SysTick interrupt */ CLEAR_BIT(SysTick-》CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk); if (pm-》run_mode == PM_RUN_MODE_LOW_SPEED) { /* Clear LPR bit to back the normal run mode */ CLEAR_BIT(PWR-》CR1, PWR_CR1_LPR); /* Enter STOP 2 mode */ HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); /* Set Regulator parameter to lowpower run mode */ SET_BIT(PWR-》CR1, PWR_CR1_LPR); } else { /* Enter STOP 2 mode */ HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); } /* Enable SysTick interrupt */ SET_BIT(SysTick-》CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk); /* Re-configure the system clock */ systemclock_reconfig(pm-》run_mode); break; case PM_SLEEP_MODE_STANDBY: __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); /* Enter STANDBY mode */ HAL_PWR_EnterSTANDBYMode(); break; case PM_SLEEP_MODE_SHUTDOWN: __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); /* Enter SHUTDOWNN mode */ HAL_PWREx_EnterSHUTDOWNMode(); break; default: RT_ASSERT(0); break; } }

移植時間補償接口某些情況下,我們可能需要系統在空閑時進入 Stop 模式,以達到更低的降功耗效果。根據手冊可知,Stop 2 模式會關閉系統時鐘,當前的 OS Tick 基于內核的 Systick 定時器。那么在系統時鐘停止后,OS Tick 也會停止,對于某些依賴 OS Tick 的應用,在進入 Stop 2 模式,又被中斷喚醒后,就會出現問題,因此需要在系統喚醒后,對 OS Tick 進行補償。Stop 2 模式下,絕大多數外設都停止工作,僅低功耗定時器 1(LP_TIM1)和RTC,選擇 LSI 作為時鐘源后,仍然能正常運行,所以可以選擇 LP_TIM1 或者RTC 作為 Stop 2 模式的時間補償定時器。

休眠的時間補償需要實現三個接口,分別用于啟動低功耗定時器、停止定時器、喚醒后獲取休眠的 Tick,下面是具體的實現:

static void stm32_pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout) { RT_ASSERT(pm != RT_NULL); RT_ASSERT(timeout 》 0); if (timeout != RT_TICK_MAX) { /* Convert OS Tick to PM timer timeout value */ timeout = stm32_pm_tick_from_os_tick(timeout); if (timeout 》 stm32_pmtim_get_tick_max()) { timeout = stm32_pmtim_get_tick_max(); } /* Enter PM_TIMER_MODE */ stm32_pmtim_start(timeout); } }

static void stm32_pm_timer_stop(struct rt_pm *pm) { RT_ASSERT(pm != RT_NULL); /* Reset PM timer status */ stm32_pmtim_stop(); }

static rt_tick_t stm32_pm_timer_get_tick(struct rt_pm *pm) { rt_uint32_t timer_tick; RT_ASSERT(pm != RT_NULL); timer_tick = stm32_pmtim_get_current_tick(); return stm32_os_tick_from_pm_tick(timer_tick); }

休眠時間補償的移植相對并不復雜,根據 Tick 配置低功耗定時器超時,喚醒后獲取實際休眠時間并轉換為OS Tick,告知 PM 組件即可。

移植運行模式移植休眠模式僅需關注 run接口,下面是具體的實現:

void stm32_run(struct rt_pm *pm, rt_uint8_t mode) { static rt_uint32_t last_mode; static char *run_str[] = PM_RUN_MODE_NAMES; struct rcc_conf_struct sconf = _rcc_conf[mode]; if (mode == last_mode) return; if (stm32_run_freq[mode][0] != stm32_run_freq[last_mode][0]) { if (_rcc_conf[last_mode].low_pow_run_en && !sconf.low_pow_run_en) { /* Disable the Low-power Run mode */ HAL_PWREx_DisableLowPowerRunMode(); } systemclock_msi_on(last_mode); if (mode 《 last_mode) { /* Frequency increase */ HAL_PWREx_ControlVoltageScaling(sconf.volt_scale); _set_sysclock[mode](); } else { /* Frequency reduce */ _set_sysclock[mode](); HAL_PWREx_ControlVoltageScaling(sconf.volt_scale); } if (sconf.volt_scale == PWR_REGULATOR_VOLTAGE_SCALE2 || _osc_conf.osc_type == RCC_OSCILLATORTYPE_MSI) { /* Configure the wake up from stop clock to MSI */ __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); } else { /* Configure the wake up from stop clock to HSI */ __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); } if (sconf.low_pow_run_en) { /* Enable the Low-power Run mode */ HAL_PWREx_EnableLowPowerRunMode(); } systemclock_msi_off(mode); #if defined(RT_USING_SERIAL) /* Re-Configure the UARTs */ uart_console_reconfig(); #endif /* Re-Configure the Systick time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND); /* Re-Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); } last_mode = mode; rt_kprintf(“switch to %s mode, frequency = %d %sHz ”, run_str[mode], stm32_run_freq[mode][0], (stm32_run_freq[mode][1] == 1) ? “M” : “K”); if ((stm32_run_freq[mode][0] / stm32_run_freq[mode][1]) 》 OSC_CONF_SYS_FREQ_MAX) rt_kprintf(“warning: The frequency has over than %d MHz ”, OSC_CONF_SYS_FREQ_MAX); }

自定義運行級別時鐘樹配置函數PM 組件驅動在給定運行頻率時,已經盡量自動最優化配置時鐘樹,但有時外設時鐘還是沒有達到自己想要的頻率,這時可以自己配置時鐘樹,在 board.c 添加以下單個或所有函數,代碼可參考 SystemClock_Config() 函數:

rt_uint16_t stm32_run_freq[PM_RUN_MODE_MAX][2] = { /* The actual frequency is 1/divisor MHz, divisor = {1, 1000} */ /* {sysclk frequency, divisor} */ {/* 配置高頻運行時的時鐘 */, /* 分頻系數 */}, /* High speed */ {/* 配置普通運行時的時鐘 */, /* 分頻系數 */}, /* Normal speed */ {/* 配置中低運行時的時鐘 */, /* 分頻系數 */}, /* Medium speed */ {/* 配置低頻運行時的時鐘 */, /* 分頻系數 */}, /* Low speed, MSI clock 2.0 MHz */ }; void stm32_systemclock_high(void) { /* 添加代碼,配置高頻運行時的時鐘樹 */ } void stm32_systemclock_normal(void) { /* 添加代碼,配置普通速度運行時的時鐘樹 */ } void stm32_systemclock_medium(void) { /* 添加代碼,配置中低頻運行時的時鐘樹 */ } void stm32_systemclock_low(void) { /* 添加代碼,配置低頻運行時的時鐘樹 */ }

當低速的頻率小于2MHz時,要注意以下2點:

串口波特率如果設置過高,將不能正常通信

在時鐘頻率很低時,要適當減小 RT_TICK_PER_SECOND 值,不然由于 OS_tick 過短,某些線程將不能完成任務,從而不能進入低功耗模式

初始化PM組件注意:休眠模式的時間補償需要在初始化階段通過設置 timer_mask 的對應模式的 bit 控制開啟。例如需要開啟 Deep Sleep 模式下的時間補償,在實現 timer 相關的 ops 接口后,初始化時設置相應的bit:

int drv_pm_hw_init(void) { static const struct rt_pm_ops _ops = { stm32_sleep, stm32_run, stm32_pm_timer_start, stm32_pm_timer_stop, stm32_pm_timer_get_tick }; rt_uint8_t timer_mask = 0; /* Enable Power Clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* initialize timer mask */ timer_mask = 1UL 《《 PM_SLEEP_MODE_DEEP; /* initialize system pm module */ rt_system_pm_init(&_ops, timer_mask, RT_NULL); return 0; } INIT_BOARD_EXPORT(drv_pm_hw_init);

void rt_system_pm_init(const struct rt_pm_ops *ops, rt_uint8_t timer_mask, void *user_data) { struct rt_device *device; struct rt_pm *pm; pm = &_pm; device = &(_pm.parent); device-》type = RT_Device_Class_PM; device-》rx_indicate = RT_NULL; device-》tx_complete = RT_NULL; #ifdef RT_USING_DEVICE_OPS device-》ops = &pm_ops; #else device-》init = RT_NULL; device-》open = RT_NULL; device-》close = RT_NULL; device-》read = _rt_pm_device_read; device-》write = _rt_pm_device_write; device-》control = _rt_pm_device_control; #endif device-》user_data = user_data; /* register PM device to the system */ rt_device_register(device, “pm”, RT_DEVICE_FLAG_RDWR); rt_memset(pm-》modes, 0, sizeof(pm-》modes)); pm-》sleep_mode = _pm_default_sleep; pm-》run_mode = RT_PM_DEFAULT_RUN_MODE; pm-》timer_mask = timer_mask; pm-》ops = ops; pm-》device_pm = RT_NULL; pm-》device_pm_number = 0; _pm_init_flag = 1; }

STM32L4 移植 PM

STM32L4 的低功耗模式簡介:

STM32L4系列 是 ST 公司推出的一款超低功耗的 Crotex-M4 內核的 MCU,支持多個電源管理模式,其中最低功耗 Shutdown 模式下,待機電流僅 30 nA。ST 公司 把 L4系列 的電管管理分為很多種,但各個模式的并非功耗逐級遞減的特點,下面是各個模式之間的狀態轉換圖:

處理器電源管理主要實現方式是什么?

盡管 STM32L4系列 的低功耗模式很多,但本質上并不復雜,理解它的原理有助于我們移植驅動,同時更好的在產品中選擇合適的模式。最終決定 STM32L4系列 系統功耗的主要是三個因素:穩壓器(voltage regulator)、CPU 工作頻率、芯片自身低功耗的處理,下面分別對三個因素進行闡述。

穩壓器L4 使用兩個嵌入式線性穩壓器為所有數字電路、待機電路以及備份時鐘域供電,分別是主穩壓器(main regulator,下文簡稱 MR)和低功耗穩壓器(low-power regulator,下文簡稱 LPR)。穩壓器在復位后處于使能狀態,根據應用模式,選擇不同的穩壓器對 Vcore 域供電。其中,MR 的輸出電壓可以由軟件配置為不同的范圍(Range 1 和 Rnage 2)。穩壓器應用場合

穩壓器應用場合

MR(Range 1)Vcore = 1.2V,用于運行模式、睡眠模式和停止模式0,MR 未 Vcore 域提供全功率

MR(Range 2)Vcore = 1.0V,使用的場景同上

LPR用于低功耗運行模式、低功耗休眠模式、停止模式 1、停止模式2

OFFStandby 和 Shutdown 模式下,MR 和 LPR 都被關閉

CPU 工作頻率通過降低 CPU 的主頻達到降低功耗的目的:MR 工作在 Range 1 正常模式時,SYSCLK 最高可以工作在 80M;MR 工作在 Range 2 時,SYSCLK 最高不能超過 26 M;低功耗運行模式和低功耗休眠模式,即 Vcore 域由 LPR 供電,SYSCLK 必須小于 2M。

芯片本身的低功耗處理芯片本身定義了一系列的休眠模式,如 Sleeep、Stop、Standby 和 Shutdown,前面的四種模式功耗逐漸降低,實質是芯片內部通過關閉外設和時鐘來實現。

配置工程

配置 PM 組件:

配置內核選項:使用 PM 組件需要更大的 IDLE 線程的棧,這里使用了1024 字節

在空閑線程中會調用rt_system_power_manager接口來進入低功耗模式:

/** * This function will enter corresponding power mode. */ void rt_system_power_manager(void) { rt_uint8_t mode; if (_pm_init_flag == 0) return; /* CPU frequency scaling according to the runing mode settings */ _pm_frequency_scaling(&_pm); /* Low Power Mode Processing */ mode = _pm_select_sleep_mode(&_pm); _pm_change_sleep_mode(&_pm, mode); }

保存后,可以看到pm.c已經被添加到了工程:

處理器電源管理主要實現方式是什么?

然后添加PM組件的設備驅動,驅動的最新地址:pm-ports-stm32-new 分支:https://gitee.com/sunwancn/rt-thread/tree/pm-ports-stm32-new注意: 目前所使用的驅動不是最新版本,移植請到gitee下載最新pm驅動。

從 t-threadspstm32librariesHAL_Drivers,拷貝如下四個文件到工程的drivers文件夾下:

本項目選擇的是使用RTC作為STOP后的時間補償,所以需要打開rtc設備和所使用的宏:

處理器電源管理主要實現方式是什么?

注: 如果沒有使用RTT的自身的RTC函數的話,前面2個宏可以不要。
責任編輯:pj

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 電源
    +關注

    關注

    184

    文章

    17774

    瀏覽量

    250780
  • 處理器
    +關注

    關注

    68

    文章

    19348

    瀏覽量

    230269
收藏 人收藏

    評論

    相關推薦

    EE-172:使用ADSP-BF535 Blackfin處理器的動態電源管理功能

    電子發燒友網站提供《EE-172:使用ADSP-BF535 Blackfin處理器的動態電源管理功能.pdf》資料免費下載
    發表于 01-07 14:32 ?0次下載
    EE-172:使用ADSP-BF535 Blackfin<b class='flag-5'>處理器</b>的動態<b class='flag-5'>電源</b><b class='flag-5'>管理</b>功能

    對稱多處理器和非對稱多處理器的區別

    隨著計算需求的日益增長,單處理器系統已經無法滿足高性能計算的需求。多處理器系統應運而生,它們通過將多個處理器集成到一個系統中來提高計算能力。在多處理器系統中,有兩種
    的頭像 發表于 10-10 15:58 ?1061次閱讀

    如何利用PMICs設計靈活的處理器電源系統

    電子發燒友網站提供《如何利用PMICs設計靈活的處理器電源系統.pdf》資料免費下載
    發表于 10-08 14:42 ?0次下載
    如何利用PMICs設計靈活的<b class='flag-5'>處理器</b><b class='flag-5'>電源</b>系統

    ARM處理器的尋址方式

    ARM處理器的尋址方式處理器在執行指令時,根據指令中給出的地址信息來尋找物理地址的方法。ARM處理器支持多種尋址方式,以滿足不同的編程需求
    的頭像 發表于 10-05 17:08 ?277次閱讀

    電源監控電路-電源管理芯片

    是對電源管理芯片的詳細解析: 一、基本概念 電源管理芯片是一種集成電路,主要負責將源電壓和電流轉換為可由微
    發表于 09-29 15:48

    盛顯科技:投影融合處理器如何實現圖像的處理和融合?

    相信大家都知道,投影融合處理器實現融合投影功能的過程是一個復雜但高度專業化的技術過程,它主要依賴于先進的投影技術和圖像融合技術,精妙地結合了尖端的投影技術與精細的圖像融合算法。那么您知道投影融合
    的頭像 發表于 09-26 18:14 ?360次閱讀
    盛顯科技:投影融合<b class='flag-5'>處理器</b>如何<b class='flag-5'>實現</b>圖像的<b class='flag-5'>處理</b>和融合?

    ARM處理器和CISC處理器的區別

    ARM處理器和CISC(復雜指令集計算機)處理器在多個方面存在顯著的區別。這些區別主要體現在架構原理、性能與功耗、設計目標、應用領域以及市場生態等方面。
    的頭像 發表于 09-10 11:10 ?505次閱讀

    嵌入式微處理器主要組成 嵌入式微處理器的分類和特點

    處理單元是嵌入式微處理器的核心組成部分,它主要包括運算單元(ALU)、寄存、控制單元和時鐘管理等。運算單元是用來執行算術和邏輯運算的部件,
    的頭像 發表于 05-04 15:48 ?2396次閱讀

    用于高級應用處理器電源管理單元LP3971數據表

    電子發燒友網站提供《用于高級應用處理器電源管理單元LP3971數據表.pdf》資料免費下載
    發表于 04-02 15:23 ?0次下載
    用于高級應用<b class='flag-5'>處理器</b>的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元LP3971數據表

    用于高級應用處理器電源管理單元LP3972數據表

    電子發燒友網站提供《用于高級應用處理器電源管理單元LP3972數據表.pdf》資料免費下載
    發表于 04-02 15:21 ?0次下載
    用于高級應用<b class='flag-5'>處理器</b>的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元LP3972數據表

    適用于ARM Cortex?—A53處理器A53處理器和FPGA的集成電源管理IC TPS65220數據表

    電子發燒友網站提供《適用于ARM Cortex?—A53處理器A53處理器和FPGA的集成電源管理IC TPS65220數據表.pdf》資料免費下載
    發表于 03-27 10:04 ?0次下載
    適用于ARM Cortex?—A53<b class='flag-5'>處理器</b>A53<b class='flag-5'>處理器</b>和FPGA的集成<b class='flag-5'>電源</b><b class='flag-5'>管理</b>IC TPS65220數據表

    汽車處理器電源管理單元 (PMU) TPS65903x-Q1數據表

    電子發燒友網站提供《汽車處理器電源管理單元 (PMU) TPS65903x-Q1數據表.pdf》資料免費下載
    發表于 03-06 11:25 ?0次下載
    汽車<b class='flag-5'>處理器</b><b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元 (PMU) TPS65903x-Q1數據表

    適用于處理器的TPS659037電源管理單元 (PMU)數據表

    電子發燒友網站提供《適用于處理器的TPS659037電源管理單元 (PMU)數據表.pdf》資料免費下載
    發表于 03-06 11:20 ?0次下載
    適用于<b class='flag-5'>處理器</b>的TPS659037<b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元 (PMU)數據表

    適用于處理器電源管理單元 (PMU) TPS65917-Q1數據表

    電子發燒友網站提供《適用于處理器電源管理單元 (PMU) TPS65917-Q1數據表.pdf》資料免費下載
    發表于 03-06 11:13 ?2次下載
    適用于<b class='flag-5'>處理器</b>的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元 (PMU) TPS65917-Q1數據表

    適用于處理器電源管理單元 (PMU) TPS65919-Q1數據表

    電子發燒友網站提供《適用于處理器電源管理單元 (PMU) TPS65919-Q1數據表.pdf》資料免費下載
    發表于 03-05 14:17 ?0次下載
    適用于<b class='flag-5'>處理器</b>的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>單元 (PMU) TPS65919-Q1數據表
    主站蜘蛛池模板: 人妻超级精品碰碰在线97视频| 国产99久9在线| 嫩交18xxxx| 国模丽丽啪啪一区二区| PORN白嫩内射合集| 在线一本码道高清| 无羞耻肉动漫在线观看| 美女网站免费久久久久久久| 国产三级视频在线| 处初女处夜情视频在线播放| 中文字幕在线视频在线看| 亚州AV中文无码乱人伦在线| 日产亚洲一区二区三区| 免费精品国产日韩热久久| 精品国产mmd在线观看| 国产成人综合在线观看| mm625亚洲人成电影网| 2021国产精品| 伊人久久亚洲精品一区| 亚洲国产女人aaa毛片在线| 色尼玛亚洲综合| 欧美另类videosbest| 久青草国产观看在线视频| 河南老太XXXXXHD| 国产精品一区二区三区四区五区| 白丝萝莉喷水| chinesetoilet美女沟| 97久久伊人精品影院| 稚嫩挤奶h调教h| 一本之道高清在线3线观看| 亚洲 色 欧美 爱 视频 日韩| 色即是空之甜性涩爱| 日操夜操天天操| 秋霞成人午夜鲁丝一区二区三区| 美女靠逼漫画| 两个奶被男人揉了一个晚上| 久久国产精品永久网站| 精品一品国产午夜福利视频| 国语自产拍在线视频普通话| 国产午夜精品一区二区三区| 国产手机在线亚洲精品观看|