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

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

3天內(nèi)不再提示

電源管理入門:驅(qū)動Runtime PM管理

yzcdx ? 來源:OS與AUTOSAR研究 ? 2023-11-29 10:13 ? 次閱讀

Runtime PM管理也就是設備驅(qū)動里面的電源管理,即設備驅(qū)動結(jié)構(gòu)體里面的struct dev_pm_ops,只控制設備自己的電源。這樣可以在設備不需要工作的時候可以進入到低功耗狀態(tài),更好的管理設備自己的電源,所謂:“各掃門前雪”。

為什么需要Runtime PM?

不同于系統(tǒng)的電源管理,設備自己的電源管理更加的細化。這就像一個層級關(guān)系,系統(tǒng)整體的是一個大的電源狀態(tài)管理,但是對于眾多的集成外國設備也不能一刀切,就是不能要干活都干活要休息都休息,要細化管理不能懶政,就對每個設備自己也來一套電源狀態(tài)管理,直接把機制從系統(tǒng)哪里復制過來一份一個閹割版的就夠用,采用分而治之的思想,只要系統(tǒng)要統(tǒng)一指揮的時候聽話就可以,其他時候可以自己決策執(zhí)行就是runtime PM管理。這里的設備有可能是外設,比如sensor、lcdc等。這里的設備也有可能是SOC內(nèi)部的某些IP,比如codec、dsp、usb等。

1. 框架介紹

1.1 為什么需要Runtime PM Framework?

系統(tǒng)基本的電源管理,例如關(guān)機休眠等,需要調(diào)用device的電源Runtime API就是ops回調(diào)函數(shù),而且需要按一個順序的queue去實施,而且系統(tǒng)跟設備狀態(tài)發(fā)生沖突的時候也需要去處理,綜上就需要一個Framework去統(tǒng)一做這些事情

設備驅(qū)動需要根據(jù)系統(tǒng)的一些參數(shù)來決定自己的電源狀態(tài),例如CPU是否idle等,就需要系統(tǒng)框架的支持

當設備處于低功耗模式時,wakeup signal常常需要platform或者bus的支持。

1.2 系統(tǒng)框架圖

3f1a5378-8dda-11ee-939d-92fbcf53809c.png

數(shù)據(jù)結(jié)構(gòu):

3f326544-8dda-11ee-939d-92fbcf53809c.png

image.png

關(guān)機舉例:

3f575624-8dda-11ee-939d-92fbcf53809c.png

休眠舉例:

3f6d659a-8dda-11ee-939d-92fbcf53809c.png

2. Drivers

Device drivers(包括bus、class、power domain)實現(xiàn)了runtime pm相關(guān)的runtime_idle/runtime_suspend/runtime_resume三個回調(diào):

runtime_suspend用于實現(xiàn)設備的低功耗操作

runtime_resume用于實現(xiàn)設備的低功耗恢復相關(guān)的操作

runtime_idle屬于runtime_suspend的一個過渡,用于緩沖頻繁的suspend與resume,它會判斷設備是否具備suspend的條件,如果具備在合適的時機,就會suspend設備。

runtime_suspend與runtime_resume回調(diào)函數(shù)里會調(diào)用clock framework/reset framework/regulator framework提供的時鐘開關(guān)、復位、電源開關(guān)接口。這里以SPI驅(qū)動為例進行說明:

subsys_initcall(pl022_init);

static int __init pl022_init(void)
{
        return amba_driver_register(&pl022_driver);
}

static struct amba_driver pl022_driver = {
        .drv = {
                .name        = "ssp-pl022",
                .pm        = &pl022_dev_pm_ops,
        },
        .id_table        = pl022_ids,
        .probe                = pl022_probe,
        .remove                = pl022_remove,
};

static const struct dev_pm_ops pl022_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
        SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
};
                         
#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) 
        .runtime_suspend = suspend_fn, 
        .runtime_resume = resume_fn, 
        .runtime_idle = idle_fn,

pm結(jié)構(gòu)體dev_pm_ops 中的有3個以runtime開頭的成員函數(shù):runtime_suspend()、runtime_resume()和runtime_idle(),它們輔助設備完成運行時的電源管理

struct dev_pm_ops {
    ...
    int (*runtime_suspend)(struct device *dev);
    int (*runtime_resume)(struct device *dev);
    int (*runtime_idle)(struct device *dev);
    ...
};

運行時的PM與前文描述的系統(tǒng)級掛起到RAM時候的PM不太一樣,它是針對單個設備,指系統(tǒng)在非睡眠狀態(tài)的情況下,某個設備在空閑時可以進入運行時掛起狀態(tài),而在不是空閑時執(zhí)行運行時恢復使得設備進入正常工作狀態(tài),如此,這個設備在運行時會省電。

3f8f8fda-8dda-11ee-939d-92fbcf53809c.png

每個設備處理好自己的電源管理,在不需要工作時進入低功耗狀態(tài)。也就是"各人自掃門前雪"。Linux提供了一系列API,以便于設備可以聲明自己的運行時PM狀態(tài):

函數(shù)名字 功能
pm_runtime_suspend 引發(fā)設備的掛起,執(zhí)行相關(guān)的runtime_suspend()函數(shù)。
pm_schedule_suspend “調(diào)度”設備的掛起,延遲delay毫秒后將掛起工作掛入pm_wq等待隊列,結(jié)果等價于delay毫秒后執(zhí)行相關(guān)的runtime_suspend()函數(shù)。
pm_runtime_resume 引發(fā)設備的恢復,執(zhí)行相關(guān)的runtime_resume()函數(shù)。
pm_request_resume 發(fā)起一個設備恢復的請求,該請求也是掛入pm_wq等待隊列。
pm_runtime_idle 引發(fā)設備的空閑,執(zhí)行相關(guān)的runtime_idle()函數(shù)。
pm_request_idle 發(fā)起一個設備空閑的請求,該請求也是掛入pm_wq等待隊列。
pm_runtime_enable 使能設備的運行時PM支持。
pm_runtime_disable 禁止設備的運行時PM支持。
pm_runtime_getpm_runtime_get_sync 增加設備的引用計數(shù)(usage_count),這類似于clk_get(),會間接引發(fā)設備的runtime_resume()。
pm_runtime_putpm_runtime_put_sync 減小設備的引用計數(shù),這類似于clk_put(),會間接引發(fā)設備的runtime_idle()。

3. Runtime PM core

Runtime pm core主要提供了三類函數(shù)接口:

提供enable/disable接口給設備驅(qū)動,用于該設備驅(qū)動決定是否打開或關(guān)閉RPM,

提供get、put類接口給設備驅(qū)動,用于決定什么時候進入或者恢復設備低功耗,

在設備驅(qū)動調(diào)用了get、put接口后RPM會調(diào)用各設備驅(qū)動實現(xiàn)的runtime_suspend/runtime_resume接口

對于決定設備是否進入低功耗的get/put接口的調(diào)用時機,一般會在操作設備相關(guān)寄存器前調(diào)用get接口,在操作完相關(guān)寄存器后調(diào)用put接口?;蛘咴谠O備驅(qū)動的open、release、start、stop等接口里調(diào)用,用戶層的services通過ioctrl或者驅(qū)動提供的文件節(jié)點調(diào)用驅(qū)動的這些接口。

我們可以這樣簡單地理解Linux運行時PM的機制,每個設備(總線的控制器自身也屬于一個設備)都 有引用計數(shù)usage_count和活躍子設備(Active Children,子設備的意思就是該級總線上掛的設備)計數(shù)child_count,當兩個計數(shù)都為0的時候,就進入空閑狀態(tài),調(diào)用pm_request_idle(dev)。

當設備進入空閑狀態(tài),與pm_request_idle(dev)對應的PM核并不一定直接調(diào)用設備驅(qū)動的runtime_suspend(),它實際上在多數(shù)情況下是調(diào)用與該設備對應的bus_type的runtime_idle()。

在具體的設備驅(qū)動中,一般的用法則是在設備驅(qū)動probe()時運行pm_runtime_enable()使能運行時PM支持,在運行過程中動態(tài)地執(zhí)行“pm_runtime_get_xxx()->做工作->pm_runtime_put_xxx()”的序列。如代碼清單19.19中的drivers/watchdog/omap_wdt.c OMAP的看門狗驅(qū)動。

在omap_wdt_start()中啟動了pm_runtime_get_sync(),

而在omap_wdt_stop()中調(diào)用了pm_runtime_put_sync()。

static const struct watchdog_ops omap_wdt_ops = {
        .owner                = THIS_MODULE,
        .start                = omap_wdt_start,
        .stop                = omap_wdt_stop,
        .ping                = omap_wdt_ping,
        .set_timeout        = omap_wdt_set_timeout,
        .get_timeleft        = omap_wdt_get_timeleft,
};

static int omap_wdt_start(struct watchdog_device *wdog)
{

    pm_runtime_get_sync(wdev->dev);//告訴內(nèi)核要開始用看門狗這個設備了,如果看門狗設備已經(jīng)進入省電模式(之前引用計數(shù)為0且執(zhí)行了運行時掛起),會導致該設備的運行時恢復
    
static int omap_wdt_stop(struct watchdog_device *wdog)
{
    pm_runtime_put_sync(wdev->dev);//告訴內(nèi)核不用這個設備了,如果引用計數(shù)變?yōu)?且活躍子設備為0,則導致該看門狗設備的運行時掛起。

在一些設備上不使用的時候不能立即掛起,,因為掛起狀態(tài)的進入和恢復需要一些時間,如果設備不在掛起之間保留一定的時間,頻繁進出掛起反而會帶來新的開銷。因此,我們可根據(jù)情況決定只有設備在空閑了一段時間后才進入掛起(一般來說,一個一段時間沒有被使用的設備,還會有一段時間不會被使用),基于此,一些設備驅(qū)動也常常使用自動掛動模式進行編程。

3fa8a93e-8dda-11ee-939d-92fbcf53809c.png

在執(zhí)行操作的時候聲明pm_runtime_get(),操作完成后執(zhí)行pm_runtime_mark_last_busy()和pm_runtime_put_autosuspend(),一旦自動掛動的延時到期且設備的使用計數(shù)為0,則引發(fā)相關(guān)runtime_suspend()入口函數(shù)的調(diào)用。

設備驅(qū)動PM成員的runtime_suspend()一般完成保存上下文、切到省電模式的工作,而runtime_resume()一般完成對硬件上電、恢復上下文的工作

4. power domain framework

一個power domain上可能包含多個IP,每個IP可能對應一個或多個設備。這些設備會在dts中描述與power domain的綁定關(guān)系。系統(tǒng)初始化的時候,會將這個power domain放到一個鏈表中,然后根據(jù)設備中dts描述的與power domain的關(guān)系,將設備掛在power domain節(jié)點下的鏈表中。

當某個設備驅(qū)動通過put接口調(diào)用,將usage_count從1減少到0,這時會先調(diào)用power domain注冊的runtime_suspend接口,在這個接口中,會先調(diào)用該設備驅(qū)動的runtime_suspend,然后遍歷該power domain下所有的設備是否都允許suspend(各設備驅(qū)動的usage_count是否為0),若允許就會直接調(diào)用關(guān)閉power domian的接口,否則直接返回。當某個設備驅(qū)動通過get接口調(diào)用,將usage_count從0增加到1,這時會先調(diào)用power domain注冊的runtime_resume接口,在這個接口中,會先將power domain上電,然后再調(diào)用設備驅(qū)動對應的runtime_resume回調(diào)函數(shù),讓設備退出低功耗。

5. runtime pm的sysfs

對于支持rpm的設備,在相應的設備節(jié)點下有多個rpm相關(guān)屬性的文件節(jié)點,分別為control,runtime_susupend_time,runtime_active_time,autosuspend_delay_ms,runtime_status。接口在文件: /kernel/drivers/base/power/sysfs.c中描述。

/sys/devices/.../power/control

on - 調(diào)用pm_runtime_forbid接口,增加設備的引用計數(shù),然后resume設備。

auto - 調(diào)用pm_runtime_allow接口,減少設備的引用計數(shù),如果設備的引用計數(shù)為0,則idle設備。

3fcbb53c-8dda-11ee-939d-92fbcf53809c.png

/sys/devices/.../power/runtime_status

active - 設備的狀態(tài)是正常工作狀態(tài)。

suspend- 設備的狀態(tài)是低功耗模式。

suspending-設備的狀態(tài)正在從active->suspend轉(zhuǎn)化。

resuming-設備的狀態(tài)正在從suspend->active轉(zhuǎn)化。

error-設備runtime出現(xiàn)錯誤,此時runtime_error的標志置位。

unsupported-設備的runtime 沒有使能,此時disable_depth標志置位。

/sys/devices/.../power/runtime_suspend_time

設備在suspend狀態(tài)的時間

/sys/devices/.../power/runtime_active_time

設備在active狀態(tài)的時間

/sys/devices/.../power/autosuspend_delay_ms

設備在idle狀態(tài)多久之后suspend,設置延遲suspend的延遲時間。

后記:

在編寫驅(qū)動的時候,如果涉及電源管理的功耗需求,就需要實現(xiàn)struct dev_pm_ops,為驅(qū)動程序增加一個電源管理的功能,會更加的靈活,也是我們?nèi)?yōu)化系統(tǒng)功耗的一個重要方向。因為大多數(shù)程序估計是供應商提供的,但是我們自己的加的硬件的程序估計是我們自己去寫的,并且做業(yè)務挺耗電,給自己寫的驅(qū)動加個電源管理就挺好。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 電源管理
    +關(guān)注

    關(guān)注

    115

    文章

    6183

    瀏覽量

    144511
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10863

    瀏覽量

    211797
  • soc
    soc
    +關(guān)注

    關(guān)注

    38

    文章

    4166

    瀏覽量

    218280
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62630
  • runtime
    +關(guān)注

    關(guān)注

    0

    文章

    17

    瀏覽量

    2174

原文標題:電源管理入門-16 驅(qū)動Runtime PM管理

文章出處:【微信號:OS與AUTOSAR研究,微信公眾號:OS與AUTOSAR研究】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux電源管理Runtime PM的軟件框架

    device driver(或者driver所在的bus、class等)需要提供3個回調(diào)函數(shù),runtime_suspend、runtime_resume和runtime_idle,分別用于suspend device、resu
    發(fā)表于 09-15 15:57 ?2139次閱讀
    Linux<b class='flag-5'>電源</b><b class='flag-5'>管理</b>:<b class='flag-5'>Runtime</b> <b class='flag-5'>PM</b>的軟件框架

    電源管理入門-Regulator驅(qū)動是什么?Regulator的作用是什么?

    Regulator是Linux系統(tǒng)中電源管理的基礎設施之一,用于穩(wěn)壓電源管理,是各種驅(qū)動子系統(tǒng)中設置 電壓的標準接口。
    的頭像 發(fā)表于 11-16 16:51 ?1w次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>-Regulator<b class='flag-5'>驅(qū)動</b>是什么?Regulator的作用是什么?

    電源管理入門:Thermal熱管理

    管理指的是在電子設備或系統(tǒng)中通過各種方式控制其溫度來保證其正常工作或延長壽命的過程。其中包括散熱設計、溫度監(jiān)測、溫度控制等方面。熱管理的重要性越來越凸顯,尤其在高性能計算、人工智能等領域的應用中更為重要。
    的頭像 發(fā)表于 11-29 10:09 ?4917次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>:Thermal熱<b class='flag-5'>管理</b>

    電源管理入門:Power supply子系統(tǒng)

    對于便攜設備來說,電源管理更加的重要,因為電池電量有限,容易電量焦慮。除了省電管理外,還需要對電池進行監(jiān)控管理和充放電管理,這樣保護好電池和
    的頭像 發(fā)表于 11-29 10:15 ?4244次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>:Power supply子系統(tǒng)

    電源管理入門:Power Domain管理

    SoC中通常有很多IP,按邏輯可以把幾個相關(guān)功能的IP劃為一個電源域。一個電源域內(nèi)的IP,通常按相同的方式由同一個硬件模塊PMIC供電,電壓一樣并且電源管理例如休眠喚醒一致。
    的頭像 發(fā)表于 11-29 10:16 ?3433次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>:Power Domain<b class='flag-5'>管理</b>

    電源管理入門-芯片設計中的電源管理介紹

    SCP直接控制SoC的電源和時鐘,而AP通過硬件和軟件接口協(xié)同管理。
    的頭像 發(fā)表于 12-06 09:16 ?3307次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>-芯片設計中的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>介紹

    電源管理入門:Hypervisor中的電源管理

    很多時候聽說Hypervisor,但是對底層軟件技術(shù)不了解的人感覺挺神秘。本篇文章簡單介紹下Hypervisor的基本概念,另外介紹下電源管理在Hypervisor之上多OS間怎么應用。
    的頭像 發(fā)表于 12-06 09:27 ?1460次閱讀
    <b class='flag-5'>電源</b><b class='flag-5'>管理入門</b>:Hypervisor中的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>

    LINUX電源管理的相關(guān)資料分享

    Linux的系統(tǒng)suspend和resumeLinux內(nèi)核 runtime_PM 框架Linux內(nèi)核電源管理綜述
    發(fā)表于 11-15 07:10

    如何對PCI設備的電源進行管理

    1 PCI設備的電源管理PCI設備的電源管理包括系統(tǒng)PMruntime
    發(fā)表于 12-27 07:17

    Linux電源管理的系統(tǒng)架構(gòu)和驅(qū)動

    ,牽扯到系統(tǒng)級的待機、頻率電壓變換、系統(tǒng)空閑時的處理以及每個設備驅(qū)動對系統(tǒng)待機的支持和每個設備的運行時( Runtime )電源管理,可以說它和系統(tǒng)中的每個設備
    發(fā)表于 01-03 06:36

    Linux電源管理之Generic PM Suspend功能簡析

    管理接口”的描述。設備驅(qū)動----具體設備驅(qū)動的位置,不再涉及。3)平臺依賴PMinclude/linux/suspend.h----定義平臺依賴PM相關(guān)的操作函數(shù)集arch/xxx/
    發(fā)表于 08-10 15:20

    LINUX電源管理

    Linux的系統(tǒng)suspend和resumeLinux內(nèi)核 runtime_PM 框架Linux內(nèi)核電源管理綜述
    發(fā)表于 11-07 19:36 ?8次下載
    LINUX<b class='flag-5'>電源</b><b class='flag-5'>管理</b>

    Linux電源管理--PM QoS

    (requester)。PM QoS framework針對兩種對象分別提供了電源管理的基礎框架和接口。 那么在電源管理的范疇內(nèi)要如何理解服
    發(fā)表于 01-05 14:37 ?1次下載
    Linux<b class='flag-5'>電源</b><b class='flag-5'>管理</b>--<b class='flag-5'>PM</b> QoS

    PCI設備的電源管理

    1 PCI設備的電源管理PCI設備的電源管理包括系統(tǒng)PMruntime
    發(fā)表于 01-05 14:37 ?3次下載
    PCI設備的<b class='flag-5'>電源</b><b class='flag-5'>管理</b>

    驅(qū)動篇:inux 電源管理的系統(tǒng)架構(gòu)和驅(qū)動(一)

    ,牽扯到系統(tǒng)級的待機、頻率電壓變換、系統(tǒng)空閑時的處理以及每個設備驅(qū)動對系統(tǒng)待機的支持和每個設備的運行時( Runtime )電源管理,可以說它和系統(tǒng)中的每個設備
    發(fā)表于 01-11 16:03 ?11次下載
    <b class='flag-5'>驅(qū)動</b>篇:inux <b class='flag-5'>電源</b><b class='flag-5'>管理</b>的系統(tǒng)架構(gòu)和<b class='flag-5'>驅(qū)動</b>(一)