From 8d79f27d517ca46612168d31d8134e52974faee8 Mon Sep 17 00:00:00 2001 From: Maciej Gibowicz Date: Thu, 11 Feb 2021 15:54:17 +0100 Subject: [PATCH] [EGD-5324] Add Low Power documentation Documentation describing the Low Power control algorithm and synchronization with the system using dedicated sentinels and drivers. --- .../SystemManager/doc/PowerManagement.md | 65 +++++++++++++++++ .../doc/data/CpuFreqChangeAlgorithm.puml | 40 +++++++++++ .../doc/data/CpuFreqChangeAlgorithm.svg | 52 ++++++++++++++ .../doc/data/CpuFrequencyUpdate.puml | 19 +++++ .../doc/data/CpuFrequencyUpdate.svg | 31 ++++++++ .../doc/data/ResourceRequest.puml | 70 +++++++++++++++++++ .../doc/data/cellularResourceRequest.svg | 42 +++++++++++ .../doc/data/eInkResourceRequest.svg | 48 +++++++++++++ 8 files changed, 367 insertions(+) create mode 100644 module-sys/SystemManager/doc/PowerManagement.md create mode 100644 module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.puml create mode 100644 module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.svg create mode 100644 module-sys/SystemManager/doc/data/CpuFrequencyUpdate.puml create mode 100644 module-sys/SystemManager/doc/data/CpuFrequencyUpdate.svg create mode 100644 module-sys/SystemManager/doc/data/ResourceRequest.puml create mode 100644 module-sys/SystemManager/doc/data/cellularResourceRequest.svg create mode 100644 module-sys/SystemManager/doc/data/eInkResourceRequest.svg diff --git a/module-sys/SystemManager/doc/PowerManagement.md b/module-sys/SystemManager/doc/PowerManagement.md new file mode 100644 index 0000000000000000000000000000000000000000..49376b85af313f8cf241feb23c914e760a1c28df --- /dev/null +++ b/module-sys/SystemManager/doc/PowerManagement.md @@ -0,0 +1,65 @@ +# Power Management + +Power management is based on the frequency control of the CPU. + +## CPU frequency switching + +The CPU frequency control is dependent on the CPU load measured from the time spent in the task Idle. This control is also influenced by requests from interested services via sentinels (`minFrequencyRequested`). By increasing the CPU frequency, we always jump to the maximum possible frequency value. On the other hand, the reduction of the CPU frequency occurs gradually one level down. + +![](./data/CpuFreqChangeAlgorithm.svg) + +## Low Power synchronization + +Synchronization in Low Power mode covers 3 issues: + +* immediate informing services about changing the CPU frequency so that they can update their resources (e.g. PWM filling) + +* immediate switching on of peripherals that have been turned off by Low Power control (e.g. PLL2) + +* request from the service of the minimum CPU frequency in order to perform a task (e.g. screen redraw, telephone conversation) + +### Implementation + +To cover these issues, several classes have been implemented. + +* Sentinel class + +Each sentinel manages the requests, i.e. when it is needed it sends messages to `CpuGovernor` with the required minimum CPU frequency to perform the task (e.g. screen redraw). Furthermore, every sentinel is informed immediately after changing the frequency. This allows it to invoke a callback to the service to update its resources (e.g. PWM filling). Every sentinel must register itself on startup to `CpuGovernor` by sending `SentinelRegistrationMessage`. + +* CpuGovernor class + +`CpuGovernor` manages all sentinels in the system and has CPU frequency requests from them (e.g. `eInkSentinel`). + +* Driver class + +Dedicated drivers control the clocks. For example, `driverLPSPI` enables/disables the clock from LPSPI. + +* PLL2 class + +DriverPLL2 controls the PLL2 bus clock and if all dependent clocks are turned off, it turns off the PLL2 bus clock. + +* Device class + +Each driver (eg LPSPI) inherits from the Device class. Therefore, we can manage all drivers. Every device must register itself on startup to `DeviceManager` by sending `DeviceRegistrationMessage`. + +* DeviceManager class + +`DeviceManager` manages all devices on the system. It can turn off all devices and thus dedicated clocks. + +### CPU frequency update + +`PowerManager` periodically checks the CPU load and queries `CpuGovernor` to determine the conditions for changing the CPU frequency. +After changing CPU frequency, all sentinels must be synchronously updated (e.g. `eInkSentinel`, `cellularSentinel`) so that they can update their resources (e.g. PWM fill) + +![](./data/CpuFrequencyUpdate.svg) + +### Resource request + +Below is an example of requesting resources from `service_eInk` to redraw the screen: + +![](./data/eInkResourceRequest.svg) + +and requesting resources from `service_cellular` to make a phone call: + +![](./data/cellularResourceRequest.svg) + diff --git a/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.puml b/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.puml new file mode 100644 index 0000000000000000000000000000000000000000..c422dd080cfdd0a06d2be61733e0f3088b3e7319 --- /dev/null +++ b/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.puml @@ -0,0 +1,40 @@ +@startuml +start + +if (cpuLoad > frequencyShiftUpperThreshold) then (yes) + : aboveThresholdCounter++ + belowThresholdCounter = 0; +else (no) + if (cpuLoad < frequencyShiftLowerThreshold) then (yes) + : belowThresholdCounter++ + aboveThresholdCounter = 0; + else (no) + : belowThresholdCounter = 0 + aboveThresholdCounter = 0; + endif +endif + +if ( + aboveThresholdCounter >= maxAboveThresholdCount + or + minFrequencyRequested > currentCpuFrequency + ) then (yes) + : IncreaseCpuFrequency() + + belowThresholdCounter = 0 + aboveThresholdCounter = 0; +else (no) + if ( + belowThresholdCounter >= maxBelowThresholdCount + and + currentCpuFreq > minFrequencyRequested + ) then (yes) + : DecreaseCpuFrequency() + + belowThresholdCounter = 0 + aboveThresholdCounter = 0; + endif +endif + +stop +@enduml \ No newline at end of file diff --git a/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.svg b/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.svg new file mode 100644 index 0000000000000000000000000000000000000000..f852edb1a9d79a39992d728ad99d941c1cbc4fb2 --- /dev/null +++ b/module-sys/SystemManager/doc/data/CpuFreqChangeAlgorithm.svg @@ -0,0 +1,52 @@ +cpuLoad > frequencyShiftUpperThresholdyesnoaboveThresholdCounter++belowThresholdCounter = 0cpuLoad < frequencyShiftLowerThresholdyesnobelowThresholdCounter++aboveThresholdCounter = 0belowThresholdCounter = 0aboveThresholdCounter = 0aboveThresholdCounter >= maxAboveThresholdCountorminFrequencyRequested > currentCpuFrequencyyesnoIncreaseCpuFrequency()belowThresholdCounter = 0aboveThresholdCounter = 0DecreaseCpuFrequency()belowThresholdCounter = 0aboveThresholdCounter = 0yesbelowThresholdCounter >= maxBelowThresholdCountandcurrentCpuFreq > minFrequencyRequested \ No newline at end of file diff --git a/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.puml b/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.puml new file mode 100644 index 0000000000000000000000000000000000000000..c6fc8616605c073f6aeac7032bad4ee022ae4533 --- /dev/null +++ b/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.puml @@ -0,0 +1,19 @@ +@startuml + +PowerManager -> CpuGovernor : GetMinimumFrequencyRequested +CpuGovernor --> PowerManager : minimumFrequency + +...CPU frequency change... + +PowerManager -> CpuGovernor : CpuFrequencyHasChanged + +CpuGovernor -> cellularSentinel : CpuFrequencyHasChanged + +CpuGovernor -> eInkSentinel : CpuFrequencyHasChanged +eInkSentinel -> DriverPWM : updatePWM +note right +Critical section! +mutex necessary +end note + +@enduml diff --git a/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.svg b/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.svg new file mode 100644 index 0000000000000000000000000000000000000000..1480faaa8f1398831510a27d052f50c4c670ae98 --- /dev/null +++ b/module-sys/SystemManager/doc/data/CpuFrequencyUpdate.svg @@ -0,0 +1,31 @@ +PowerManagerPowerManagerCpuGovernorCpuGovernorcellularSentinelcellularSentineleInkSentineleInkSentinelDriverPWMDriverPWMGetMinimumFrequencyRequestedminimumFrequencyCPU frequency changeCpuFrequencyHasChangedCpuFrequencyHasChangedCpuFrequencyHasChangedupdatePWMCritical section!mutex necessary \ No newline at end of file diff --git a/module-sys/SystemManager/doc/data/ResourceRequest.puml b/module-sys/SystemManager/doc/data/ResourceRequest.puml new file mode 100644 index 0000000000000000000000000000000000000000..bf0add2b3facfebca8fe6542abd34926813a8223 --- /dev/null +++ b/module-sys/SystemManager/doc/data/ResourceRequest.puml @@ -0,0 +1,70 @@ +@startuml + +service_eInk -> eInkSentinel : SetFrequencyValueRequest +eInkSentinel -> PowerManager : RequestCpuFrequencyMessage + +PowerManager -> CpuGovernor : SetCpuFrequencyRequest + +service_eInk -> EinkDisplay : powerOn +EinkDisplay -> driverLPSPI : Enable + +driverLPSPI -> driverPLL2 : Pll2ClockEnable +note right +Critical section! +mutex necessary +end note + +driverLPSPI -> clock_config : LPSPIClockEnable + +...screen redraw... + +EinkDisplay -> driverLPSPI : Disable + +driverLPSPI -> clock_config : LPSPIClockDisable + +driverLPSPI -> driverPLL2 : Pll2ClockDisable +note right +Critical section! +mutex necessary +end note + +service_eInk -> eInkSentinel : ResetCpuFrequencyRequest +eInkSentinel -> PowerManager : RequestCpuFrequencyMessage + +PowerManager -> CpuGovernor : ResetCpuFrequencyRequest + +@enduml + + + + +@startuml + +service_cellular -> cellularSentinel : SetFrequencyValueRequest +cellularSentinel -> PowerManager : RequestCpuFrequencyMessage + +PowerManager -> CpuGovernor : SetCpuFrequencyRequest + +service_cellular -> bsp_cellular : wakeUp +bsp_cellular -> driverUART : Enable + +driverUART -> clock_config : ExternalOscillatorEnable +note right +Critical section! +mutex necessary +end note + +driverUART -> clock_config : UARTClockEnable + +...call ended... + +bsp_cellular -> driverUART : Disable + +driverUART -> clock_config : UARTClockDisable + +service_cellular -> cellularSentinel : ResetCpuFrequencyRequest +cellularSentinel -> PowerManager : RequestCpuFrequencyMessage + +PowerManager -> CpuGovernor : ResetCpuFrequencyRequest + +@enduml diff --git a/module-sys/SystemManager/doc/data/cellularResourceRequest.svg b/module-sys/SystemManager/doc/data/cellularResourceRequest.svg new file mode 100644 index 0000000000000000000000000000000000000000..33f5ca32e555efe27af738022a99b90642e6eec8 --- /dev/null +++ b/module-sys/SystemManager/doc/data/cellularResourceRequest.svg @@ -0,0 +1,42 @@ +service_cellularservice_cellularcellularSentinelcellularSentinelPowerManagerPowerManagerCpuGovernorCpuGovernorbsp_cellularbsp_cellulardriverUARTdriverUARTclock_configclock_configSetFrequencyValueRequestRequestCpuFrequencyMessageSetCpuFrequencyRequestwakeUpEnableExternalOscillatorEnableCritical section!mutex necessaryUARTClockEnablecall endedDisableUARTClockDisableResetCpuFrequencyRequestRequestCpuFrequencyMessageResetCpuFrequencyRequest \ No newline at end of file diff --git a/module-sys/SystemManager/doc/data/eInkResourceRequest.svg b/module-sys/SystemManager/doc/data/eInkResourceRequest.svg new file mode 100644 index 0000000000000000000000000000000000000000..c48defed678a45b245db7599dd0254a95bbd0e0c --- /dev/null +++ b/module-sys/SystemManager/doc/data/eInkResourceRequest.svg @@ -0,0 +1,48 @@ +service_eInkservice_eInkeInkSentineleInkSentinelPowerManagerPowerManagerCpuGovernorCpuGovernorEinkDisplayEinkDisplaydriverLPSPIdriverLPSPIdriverPLL2driverPLL2clock_configclock_configSetFrequencyValueRequestRequestCpuFrequencyMessageSetCpuFrequencyRequestpowerOnEnablePll2ClockEnableCritical section!mutex necessaryLPSPIClockEnablescreen redrawDisableLPSPIClockDisablePll2ClockDisableCritical section!mutex necessaryResetCpuFrequencyRequestRequestCpuFrequencyMessageResetCpuFrequencyRequest \ No newline at end of file