4.4.11. 低功耗模式调试指南

4.4.11.1. 概述介绍

低功耗管理系统 (Low Power Management System) 旨在通过优化电子设备能耗,减少能源消耗延长电池续航。它通过硬件软件调节,使设备待机状态保持最低能耗,同时不同使用场景实现最佳功耗性能平衡。

4.4.11.2. 低功耗调试详细介绍

系统支持三种不同模式工作:关闭模式 (off mode)、睡眠模式 (sleep mode)、工作模式 (work mode)。根据对应工作状态应用,可分为九个电源域:

  • AON (Always On) 电源域:始终保持开启状态。

  • DSP(DSP 子系统)电源域:与数字信号处理相关。

  • SOC(芯片顶层子系统)电源域:涉及芯片顶层子系统功能。

  • CPU(CPU 子系统)电源域:包括 CPU 相关电源管理。

  • BPU(BPU 子系统)电源域:与处理单元相关电源域。

  • DDR(DDR 子系统)电源域:与内存子系统相关电源域。

  • VIDEO(视频子系统)电源域:与视频处理相关电源域。

  • GPU(GPU 子系统)电源域:与图形处理单元相关电源域。

  • ISP(ISP 子系统)电源域:与图像信号处理相关电源域。

下面表格描述当前系统电源划分,包含电源域、默认电源状态电源切换控制模式:

Sub Power Domain Primary Power Supply Logic Domain Switch Control Default Status
AON VDD_AON RTC PMIC ON
GPIO
PMU
AON_CRM
DSP_NOC
SRAM
SLCR
APB BUS
DSP VDD_DSP DSP_DMA PMIC OFF
DSP_AXI_NOC
APB BUS
Timer
I2C
12S x2
UART
PDM
SPI
dsp_crm
SRAM0/SRMA0 CTL
SRAM1/SRMA1 CTL
TZC-400
Mailbox
DSP.HIFI5 VDD_HIFI5_SW HIFI5 SW-SWT OFF
SOC VDD_SOC display PMIC ON
camera
GPU
EMMC
SDIO/SDIO CTL
USB2
USB3
GMAC
QSPI
DMA
WDT
SYS_CTRL
ADC
Timer
PVT
E-Fuse
SPI x6
UART x5
12C x5
GPIO x16
LPWM x8
SOC.VIDEO VDD_VIDEO_SW video SW-SWT OFF
SOC.ISP VDD_ISP_SW isp8000 SW-SWT ON
CPU VDD_CPU CPU_NOC PMIC ON
asynchronous bridge
debug block
CPU.COREO VDD_CORE0_SW A55 COREO SW-SWT ON
CPU.CORE1 VDD_CORE1_SW A55 CORE1 SW-SWT OFF
CPU.CORE2 VDD_CORE2_SW A55 CORE2 SW-SWT OFF
CPU.CORE3 VDD_CORE3_SW A55 CORE3 SW-SWT OFF
CPU.CORE4 VDD_CORE4_SW A55 CORE4 SW-SWT OFF
CPU.CORE5 VDD_CORE5_SW A55 CORE5 SW-SWT OFF
CPU.CORE6 VDD_CORE6_SW A55 CORE6 SW-SWT OFF
CPU.CORE7 VDD_CORE7_SW A55 CORE7 SW-SWT OFF
DDR VDD_DDR DDR PMIC OFF
BPU VDD_BPU BPU PMIC OFF
GPU VDD_BPU BPU PMIC OFF

这个表格可以看出一个低功耗管理系统各个电源电源状态、控制方式管理结构:

  • Sub Power Domain(子电源域):表示电源区域名称,每个电源代表系统一部分硬件电源管理区域。例如, AON 电源域、 DSP 电源域、 SOC 电源等。

  • Primary Power Supply(主要电源供应):表示电源主要电源供应源,即该子电源提供电力主要电源。例如, AON 电源依赖 VDD_AON 电源, DSP 电源依赖 VDD_DSP 电源等。

  • Logic Domain(逻辑功能域):表示电源管理逻辑功能区域。即电源内,管理控制各种功能模块。例如, AON 电源管理 RTC(实时时钟)、 GPIO(通用输入输出)、 PMU(电源管理单元)等;而 DSP 电源管理数字信号处理相关模块如 DSP_DMA、 I2C、 UART 等。

  • Switch Control(电源切换控制):表示电源开关控制机制,通常涉及如何启用关闭电源域。例如, AON 电源通过 PMIC 控制电源开关,而 DSP.HIFI5 电源通过 SW-SWT(软件开关)控制。

  • Default Status(默认状态):表示电源系统启动默认情况电源状态( ON 或 OFF)。 ON 表示电源默认状态开启, OFF 表示电源默认状态关闭。例如, AON 电源默认状态是 ON,表示区域始终保持开启状态;而 DSP 电源默认状态是 OFF,表示区域通常待机需要关闭节省能量。

系统电源管理基于不同工作模式,在每个模式下会启用不同电源域:

  • OFF(关闭模式):此模式所有电源关闭。

  • SLEEP(睡眠模式):在模式下, AON、 DSP 和 HIFI5 电源保持开启,支持硬件唤醒( RTC、 GPIO、计数器唤醒)和语音唤醒。 HIFI5 看门狗中断可以系统唤醒工作模式。

  • WORK(工作模式):在工作模式下, AON、 DSP、 SOC、 CPU 和 DDR 电源必须开启。 HIFI5 和各个 CPU 核心( CORE0 到 CORE7 )以及其他子系统(如 BPU、 GPU、 ISP、 VIDEO)可根据需要选择开启关闭。至少一个 A55 核心处于开启状态。系统可以通过软件配置进入睡眠模式。

为了优化功耗,系统往往需要根据不同工作负载动态调整资源使用状态。两种常见有效低功耗管理方法动态电压频率调整( Dynamic Voltage and Frequency Scaling, DVFS)和休眠唤醒机制。 DVFS 通过实时调整处理器电压频率,以适应不同工作需求,从而保证性能前提有效降低功耗。而休眠唤醒机制通过使系统活动进入低功耗状态,并需要快速唤醒,进一步优化电力消耗。接下来,将详细探讨两种方法工作原理实现方式。

4.4.11.3. 动态电压频率调整

动态调频调压 (DVFS) 是一种根据系统负载动态调整处理器及其组件频率电压技术。 DVFS 可以有效降低需要高性能功耗,从而优化系统能效。

芯片功耗工作电压、时钟频率以及环境温度密切相关。在负载保持不变情况下,电压、时钟频率环境温度升高通常导致功耗增加。因此,降低功耗有效途径包括降低电压、降低时钟频率以及改善散热。本章讨论低功耗方法主要集中电压时钟频率调节控制。

除了调节电压频率,减轻负载降低功耗有效手段,客户根据自身产品需求优化电路设计。然而需要注意是,进入低功耗状态可能对系统性能造成一定负面影响,因此,是否启用低功耗模式根据具体使用场景决定。

调频调压方式

平台中, CPU、 GPU 3D、 BPU 以及 DDR 均支持调频功能,此外, CPU 还支持调压,以便实现灵活功耗管理。

CPU 调频调压

  • 板端路径/sys/devices/system/cpu/cpufreq/policy0/

  • 目前支持频率

    root@buildroot:~# cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
    300000 600000 1200000 1500000
    

    查看当前 CPU 频率:

    cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq
    

    设置 CPU 频率,可以通过以下命令:

    # 设置 CPU 频率为 1200000
    echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    echo 1200000 >/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed
    
  • 超频功能: CPU 提供超频功能,超频频率为 1.8G。

    • 启用超频:

    echo 1 >/sys/devices/system/cpu/cpufreq/boost
    echo performance >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

    1.8G 超频时, CPU 工作电压为 1V,其余频点对应工作电压为 850mV。

    注意:仅 X5H 支持超频, X5M 不可超频。 芯片类型通过以下命令查看,例如以下查询芯片是X5M

    root@buildroot:~# cat /sys/class/socinfo/soc_name
    X5M
    

    注意:如果芯片类型是”UKNOWN”,则属于早期出厂芯片,未在eFUSE中烧写对应bit,需要根据芯片丝印区分芯片类型。

  • 目前 CPU 支持的 governor 如下

    • performance:以最高频率运行。

    • ondemand:根据负载动态调整频率。

    • userspace:用户自定义频率。

    • powersave:以最低频率运行。

    • schedutil:结合 CPU 调度动态调整频率(当前 CPU 的默认 governor)。

    调整 CPU 的 governor,可以通过以下命令:

    echo performance >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    echo powersave >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    echo schedutil >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

BPU 调频

  • 板端路径/sys/class/devfreq/3a000000.bpu

  • 目前支持频率

    root@buildroot:~# cat /sys/class/devfreq/3a000000.bpu/available_frequencies
    500000000 1000000000
    

    查看当前 BPU 频率:

    cat /sys/class/devfreq/3a000000.bpu/cur_freq
    

    调整 BPU 频率命令如下:

    echo userspace >/sys/class/devfreq/3a000000.bpu/governor
    echo 500000000 >/sys/class/devfreq/3a000000.bpu/userspace/set_freq
    
  • BPU 支持的 governor 如下

    • userspace:根据客户配置指定频率。

    • performance:设置最高频率(当前 BPU 的默认 governor)。

    • powersave:以最低频率运行。

    调整 BPU 的 governor,可以通过以下命令:

    echo userspace >/sys/class/devfreq/3a000000.bpu/governor
    echo performance >/sys/class/devfreq/3a000000.bpu/governor
    echo powersave >/sys/class/devfreq/3a000000.bpu/governor
    

GPU 3D 调频

  • 板端路径/sys/class/devfreq/3c000000.gc8000

  • 目前支持频率

    root@buildroot:~# cat /sys/class/devfreq/3c000000.gc8000/available_frequencies
    200000000 400000000 750000000 1000000000
    

    查看当前频率:

    cat /sys/class/devfreq/3c000000.gc8000/cur_freq
    

    调整 GPU 3D 频率命令如下:

    echo userspace >/sys/class/devfreq/3c000000.gc8000/governor
    echo 750000000 >/sys/class/devfreq/3c000000.gc8000/userspace/set_freq
    
  • GPU 3D 支持的 governor 如下:

    • userspace:根据客户配置指定频率。

    • performance: GPU 3D 设置最高频率。

    • powersave:以最低频率运行。

    • simple_ondemand:结合工作负载,按调整频率。

    调整 GPU 3D 的 governor,可以通过以下命令

    echo userspace >/sys/class/devfreq/3c000000.gc8000/governor
    echo performance >/sys/class/devfreq/3c000000.gc8000/governor
    echo powersave >/sys/class/devfreq/3c000000.gc8000/governor
    echo simple_ondemand >/sys/class/devfreq/3c000000.gc8000/governor
    

DDR 调频

  • 板端路径/sys/class/devfreq/soc:ddrc-freq

  • 目前支持频率

    root@buildroot:~# cat /sys/class/devfreq/soc:ddrc-freq/available_frequencies
    266000000 2133000000 2844000000 4266000000
    

    查看当前 DDR 频率:

    cat /sys/class/devfreq/soc\:ddrc-freq/cur_freq
    

    调整 DDR 频率命令如下:

    echo userspace >/sys/class/devfreq/soc:ddrc-freq/governor
    echo 266000000 >/sys/class/devfreq/soc:ddrc-freq/userspace/set_freq
    
  • DDR 支持的 governor 如下:

    • userspace:根据客户配置指定频率。

    • performance: DDR 设置最高频率。

    • simple_ondemand:根据 DDR 的负载调整频率。

    • powersave:以最低频率运行。

    调整 ddr 的 governor,可以通过以下命令:

    echo userspace >/sys/class/devfreq/soc\:ddrc-freq/governor
    echo performance >/sys/class/devfreq/soc\:ddrc-freq/governor
    echo simple_ondemand >/sys/class/devfreq/soc\:ddrc-freq/governor
    echo powersave >/sys/class/devfreq/soc\:ddrc-freq/governor
    

动态调整说明

基于负载动态调整

负载低时,系统自动降低处理器频率电压,以节省能源;而负载高时,系统自动提升频率电压,以确保处理器能够满足性能需求。操作系统通过调度策略,动态根据系统负载选择合适频率。

例如,当 CPU 负载低时,ondemand governor 会频率降低最低可用频率,而负载增大时,它会自动提升频率,以保持性能。下面一个基于负载自动调节例子:

echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

此时,操作系统根据 CPU 的负载自动调整频率,用户需要手动干预。

基于温度动态调整

温度影响功耗重要因素之一。当芯片温度过高时,可以配置使系统自动降低频率电压,以避免过热,保护硬件延长使用寿命。系统通过 thermal 机制检测温度变化触发相应调整策略。

平台中,thermal 系统定期监测处理器温度,一旦超过设定温度阈值(如 95 ° C),系统自动调低 CPU 的频率电压,以降低功耗防止温度过高。这个过程自动进行的,无需用户手动干预。

这个过程中,温度变化触发动态频率电压调整,确保系统不同工作环境能够自动适应,达到最佳功耗表现。关于温度动态调整详细内容可以参考 驱动平台 thermal 系统调试说明 章节。

其他动态调整策略

除了温度负载, DVFS 系统可能依据其他因素,如系统功耗需求、可用资源等,动态调整频率电压。在许多情况下,这些调整硬件操作系统调度自动执行的,无需用户干预。这种自动调整使得系统低功耗高性能之间保持动态平衡,既可以应对突发负载需求,又空闲节省能源。

例如,使用以下命令切换schedutil governor 时,系统结合 CPU 调度决策动态调整频率:

echo schedutil >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

当前,系统默认使用schedutil governor:

root@buildroot:~# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
schedutil

另外, CPU core 在使用时,可以拔出,也可以进一步降低功耗,除了 core0 不支持 hotpulg, core1~core7 均支持 hotplug。具体方式如下:

echo 0 >/sys/devices/system/cpu/cpu1/online  #disable cpu1
echo 1 >/sys/devices/system/cpu/cpu1/online  #enable cpu1

移植开发

内核配置

移植 Linux 内核硬件平台时,需要确保内核配置启用了 DVFS 关功能。以下一些常见内核配置选项:

DVFS 支持:

  • CONFIG_CPU_FREQ:启用 CPU 频率调整。

  • CONFIG_CPU_FREQ_STAT:启用 CPU 频率统计功能。

  • CONFIG_CPU_FREQ_GOV_PERFORMANCE:启用性能 governor。

  • CONFIG_CPU_FREQ_GOV_ONDEMAND:启用需 governor。

  • CONFIG_CPU_FREQ_GOV_USERSPACE:启用用户空间 governor。

  • CONFIG_CPU_FREQ_GOV_POWERSAVE:启用节能 governor。

  • CONFIG_CPU_FREQ_GOV_SCHEDUTIL:启用调度结合的 governor。

CPU hotplug 支持:

  • CONFIG_HOTPLUG_CPU:启用 CPU hotplug 功能。

设备电源管理:

  • CONFIG_PM:启用电源管理支持。

  • CONFIG_PM_DEBUG:启用电源管理调试。

  • CONFIG_PM_ADVANCED_DEBUG:启用详细电源管理调试信息。

  • CONFIG_PM_TEST_SUSPEND:启用电源管理测试功能。

  • CONFIG_PM_DEVFREQ:启用设备频率管理(devfreq)。

  • CONFIG_PM_DEVFREQ_EVENT:启用设备频率管理事件支持。

用户可以根据需要,使用 ./bd.sh boot menuconfig选择上述功能,例如配置如下:

CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y
CONFIG_PM_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y

Linux Power Management 核心框架

Linux 的电源管理框架两个主要部分:系统电源管理设备电源管理

  • 系统电源管理(System Power Management):管理系统整体功耗状态,包括对 CPU 的空闲状态( C-state)、系统起( suspend)、休眠( hibernate)等状态控制。它确保系统空闲时, CPU 和其他关键硬件进入低功耗状态。

  • 设备电源管理(Device Power Management):管理外部设备功耗,包括驱动程序如何管理硬件设备电源开关、挂起、恢复行为。

Linux 内核通过 PM 框架设备驱动程序接口协同工作。每个设备驱动可以注册电源管理接口,告诉内核何时启用关闭设备电源,如何进入低功耗状态等。 Linux PM 框架具体如下所示:

low_power-Linux_Power_software_framework

可以看到一些与 DVFS 相关的 Linux 关键组件:

  • cpufreq 子系统

    cpufreq 是 Linux 内核专门用于 CPU 调频子系统。它提供一个统一接口,允许内核用户空间应用程序动态调整 CPU 的频率。

    • 调频驱动:不同硬件平台通常需要不同调频驱动支持 CPU 的调频操作。常见驱动包括 intel_pstate(适用于 Intel 处理器)和 acpi-cpufreq(适用支持 ACPI 的系统)。

    • 调度策略cpufreq 提供几种调度策略,例如 ondemandconservativeperformancepowersave,每种策略根据系统负载动态调整频率。

  • cpuidle 子系统

    cpuidle 子系统管理 CPU 的空闲状态。通过将 CPU 置于不同空闲状态,系统能够进一步降低功耗。cpuidlecpufreq 协同工作,当 CPU 进入空闲状态时,频率电压降低,以减少功耗。

  • devfreq 子系统

    devfreq一个用于控制设备(如 GPU、内存等)频率子系统。它允许设备根据负载调节频率,以实现低功耗运行。

Linux 系统的 DVFS 流程通过调节 CPU 和其他硬件组件频率电压,实现功耗性能优化。具体而言,内核通过 cpufreq、 cpuidle、 devfreq 等子系统管理这一过程,同时用户可以利用相关工具接口对 DVFS 进行配置优化。通过采用合理的 DVFS 策略, Linux 系统能够确保性能前提下,有效降低功耗。

DVFS 测试

基于温度动态调整为例,板端系统可以通过以下方式进行测试:

查看当前 CPU 调频温度阈值(默认是 95 ° C 开始调频):

root@buildroot:~# cat /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp
95000

查看当前系统温度频率信息,可以看到当前 CPU 的频率已经是 1500MHz、 1200MHz,温度为 45.7 ℃ :

root@buildroot:~# hrut_somstatus 
=====================1=====================
temperature-->
        DDR      : 46.9 (C)
        BPU      : 45.6 (C)
        CPU      : 45.7 (C)
cpu frequency-->
              min(M)    cur(M)  max(M)
        cpu0    : 300   1500    1500
        cpu1    : 300   1200    1500
        cpu2    : 300   300     1500
        cpu3    : 300   1200    1500
        cpu4    : 300   1200    1500
        cpu5    : 300   1200    1500
        cpu6    : 300   1200    1500
        cpu7    : 300   300     1500
bpu status information---->
              min(M)    cur(M)  max(M)  ratio
        bpu0    : 500   1000    1000    0
ddr frequency information---->
              min(M)    cur(M)  max(M)
        ddr     : 266   4266    4266
GPU gc8000 frequency information---->
              min(M)    cur(M)  max(M)
        gc8000  : 200   1000    1000

设置 CPU 调频温度阈值为 45 ℃,触发 CPU 的调频机制:

echo 45000 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp

再次查看当前温度频率信息,可以看到当前 CPU 的频率已经变成了 300MHz,明显降低功耗。这表明系统成功根据温度变化进行频率调整,从而有效避免过热,同时降低功耗:

root@buildroot:~# hrut_somstatus 
=====================1=====================
temperature-->
        DDR      : 47.6 (C)
        BPU      : 46.4 (C)
        CPU      : 46.4 (C)
cpu frequency-->
              min(M)    cur(M)  max(M)
        cpu0    : 300   1500    1500
        cpu1    : 300   1200    1500
        cpu2    : 300   1200    1500
        cpu3    : 300   1200    1500
        cpu4    : 300   300     1500
        cpu5    : 300   1200    1500
        cpu6    : 300   1200    1500
        cpu7    : 300   1200    1500
bpu status information---->
              min(M)    cur(M)  max(M)  ratio
        bpu0    : 500   1000    1000    0
ddr frequency information---->
              min(M)    cur(M)  max(M)
        ddr     : 266   4266    4266
GPU gc8000 frequency information---->
              min(M)    cur(M)  max(M)
        gc8000  : 200   1000    1000

上述过程展示基于温度的 DVFS 功能。系统能够温度变化动态调整处理器频率,以适应不同功耗需求。此外,在实际使用中,其他系统组件(如 BPU、 DDR、 GPU)也能够根据实际需求进行频率调节,进一步优化整体功耗。

注意: 测试功能时,需依据当前CPU的实际温度设定温度阈值。为触发 DVFS 响应,应阈值设置低于当前温度值,以便系统检测温度下降相应调整频率。

DVFS 调频调压常见问题

  • 问题:调整 CPU 频率后,系统性能下降明显。

    • 解决方法:检查调整频率是否在 CPU 支持范围内,避免设置过低频率。同时,可以尝试使用不同的 governor,例如 ondemandschedutil,以根据系统负载动态调整频率。

  • 问题:调整 GPU 频率后,出现图形渲染问题。

    • 解决方法:确保 GPU 驱动程序支持动态频率调整,并且调整频率在 GPU 支持范围内。同时,可以检查 GPU 的电压是否频率匹配,避免电压不足导致渲染问题。

  • 问题:禁用 CPU 核心后,系统响应变慢。

    • 解决方法:根据系统实际负载情况,合理配置 CPU 核心启用禁用策略。例如,在负载启用的 CPU 核心,在负载禁用部分 CPU 核心。同时,可以使用 isolcpus 参数关键任务绑定特定的 CPU 核心,以保证系统响应速度。

4.4.11.4. 休眠唤醒

休眠唤醒机制一个常见低功耗管理手段,它与 DVFS 密切结合。在系统处于空闲状态时,硬件组件进入休眠模式,关闭不必要电源,以减少功耗。当有外部事件触发时,系统快速唤醒,恢复正常工作状态,并根据当前负载自动调整频率电压。

系统支持多种休眠模式,以降低功耗需要可以快速恢复。当前支持唤醒包括 RTC 唤醒, GPIO 唤醒和 DSP 语音唤醒等。

休眠唤醒方式

休眠命令

休眠命令如下:

echo mem > /sys/power/state

命令触发系统进入 内存休眠 (mem) 模式,系统暂停所有非必要硬件进程,但会当前内存状态保存物理内存中,然后关闭处理器其他硬件组件,进入低功耗状态。一般通过按键外部设备恢复。

唤醒命令

  • RTC 唤醒命令

    rtcwake -s 2 -m mem
    
    • -s:休眠时间,单位秒;

    • -m:休眠模式(如 suspend to ram)。

  • GPIO 唤醒

    只有 AON 的 GPIO 可以作为唤醒源,如在 EVB 上,使用了 AON GPIO2 作为唤醒源,拉低 AON GPIO2 唤醒系统,在 dts 中需要配置唤醒源。

    设备树( DTS )中配置 AON GPIO 为唤醒源,如下:

    	gpio-keys {
    		compatible = "gpio-keys";
    		autorepeat;
    		pinctrl-names = "default";
    		pinctrl-0 = <&aon_gpio_2>;
    
    		key-power {
    			debounce-interval = <100>;
    			gpios = <&aon_gpio_porta 2 GPIO_ACTIVE_LOW>;
    			label = "GPIO Key Power";
    			linux,code = <KEY_POWER>;
    			wakeup-source;
    		};
    	};
    

    拉低 AON GPIO2 即可唤醒系统。用户可以根据自身硬件设计,将对应的 GPIO 配置唤醒源。

移植开发

内核配置

移植 Linux 内核硬件平台时,需要确保内核配置启用休眠唤醒支持相关功能。以下内核配置选项:

  • CONFIG_SUSPEND:启用系统休眠支持。

用户可以编译使用 ./bd.sh boot menuconfig选择配置这些功能。

Linux 系统休眠 / 恢复流程概述

Linux 系统休眠主要分为 起(Suspend)休眠(Hibernate) 两种模式。挂模式系统状态保存内存中( STR, Suspend to RAM),硬件进入低功耗状态;休眠模式系统状态保存磁盘上,完全关闭电源,恢复磁盘加载系统状态。

系统休眠基本流程包括以下几个步骤:

  1. 准备

    • 调用 pm_suspend() 函数,将系统切换状态。

    • 调用 pm_suspend() 之前, Linux 内核执行一系列准备工作,如停止正在运行进程、关闭不必要设备等。

  2. 保存系统状态

    • 系统调用 suspend_devices()所有支持设备。

    • 调用 platform_suspend() 保存平台特定硬件状态。

  3. 进入低功耗状态

    • 一旦所有设备系统状态保存, CPU 会进入低功耗状态。此时,系统大部分硬件处于状态,只有必要硬件(如内存)保持工作。

  4. 恢复系统状态

    • 系统休眠状态恢复时,调用 resume_devices() 恢复所有设备状态。

    • 内核重新启动所有进程,并内存硬盘加载系统状态,恢复休眠工作状态。

在 Linux 系统起(Suspend)休眠(Hibernate) 状态恢复时,系统需要一系列步骤重新启动设备恢复之前保存状态。恢复流程关键是从低功耗状态磁盘加载系统工作状态,确保设备进程能够预期恢复运行。

系统恢复基本流程包括以下几个步骤:

  1. 准备恢复

    • 系统低功耗状态磁盘恢复后,首先调用 pm_resume() 函数,开始恢复系统。

    • 调用 pm_resume() 之前, Linux 内核执行一系列准备工作,如重新激活需要硬件、恢复系统状态等。

  2. 恢复系统状态

    • 系统调用 resume_devices()恢复所有设备状态。此过程根据设备驱动程序恢复工作状态。

    • 对于起( Suspend)模式,设备状态保存内存中,因此需要内存恢复设备状态。

    • 对于休眠( Hibernate)模式,系统硬盘读取保存系统状态,并恢复休眠状态。

  3. 恢复进程内存状态

    • 系统休眠状态恢复后,内核恢复所有进程状态,确保每个进程能够暂停状态继续执行。

    • 对于休眠模式,内核磁盘休眠镜像加载进程内存状态,恢复系统休眠状态。

  4. 设备恢复初始化

    • 恢复过程不仅仅恢复内存进程,所有硬件设备需要重新初始化。具体而言:

      • 对于 PCI 设备、 USB 控制器硬件设备,系统通过调用设备resume 方法重新启用设备。

      • 驱动程序确保硬件设备恢复正确工作状态,例如重新启用中断、恢复数据传输等。

  5. 系统恢复完成

    • 恢复过程中,所有设备恢复正常工作状态,内存数据恢复,进程重新启动继续执行。

    • 系统恢复完成后,用户可以继续使用计算机,系统状态休眠基本相同。

系统休眠恢复流程如下所示:

log_buf_size

Linux 系统休眠流程涉及用户空间程序,内核空间, Secure Monitor 三个部分,三者之间相互配合完成休眠操作。该过程可以描述如下图:

low_power-Linux_Power_software_framework

可以休眠唤醒电源管理工作流程概括如下:

  • 应用程序通过特定接口与 Linux PM 交互, Linux PM 通过 PM API 与设备驱动核心服务交互,最终影响硬件电源状态。

  • Secure Monitor 在整个过程起到监控保护作用,确保电源管理安全性。

以下部分说明:

  1. Hobot 软件(蓝色)

    • Power Manager Services:负责管理电源软件服务。

    • App1 和 App2:应用程序,其中 App2 没有 CAP_BLOCK_SUSPEND 权限,因此不能调用 /sys/power/wake_unlock 接口。

  2. Linux 内核软件(绿色)

    • autosleep work:自动休眠工作机制,可能用于系统空闲自动进入低功耗状态。

    • Linux PM(电源管理):核心电源管理模块,负责协调系统电源状态。

    • Driver1 和 Driver2:设备驱动程序,一般用于管理特定硬件电源状态。

    • CPU Driver (PSCI): CPU 驱动,使用 PSCI( Power State Coordination Interface)接口管理 CPU 的电源状态。

    • Others Core Services:其他核心服务,一般包括系统日志、安全监控等。

  3. 接口

    • /sys/power/autosleep:用于设置查询自动休眠接口。

    • /sys/power/wake_unlock:用于解锁唤醒接口, App2 由于权限问题无法使用。

  4. Secure Monitor(安全监控)

    • 负责监控管理硬件层面电源状态,确保系统安全稳定。

  5. Hardware(硬件)

    • 底层硬件,与软件交互实现电源管理功能。

系统休眠唤醒测试

进行 GPIO 睡眠唤醒测试,测试命令如下:

# 准备打印日志
dmesg -w&
# 系统休眠
echo mem > /sys/power/state

输入以上指令时,系统将会进入休眠状态,在此时按下板端的 wakeup 按键即可唤醒。

在 X5 EVB 板端, wakeup 按键位置可以参考 功能模块布局 章节查看“接口 6 复位功能按键”(以 EVB 1_b 为例)。

按下 wakeup 按键唤醒系统后,系统睡眠唤醒过程日志如下:

root@buildroot:~# dmesg -w&
root@buildroot:~# echo mem > /sys/power/state
NOTICE:  mmu enabled from [LIGHT] sleep, pll: 1:1:1:1:1:0 relock: 0:0:0:0:0:0
[   69.484694] hobot_gmac 35010000.horizon_tsn eth0: mac_config_rx_queues_routing, not support packet mode :
[   69.644730] usb usb1: root hub lost power or was reset
[   69.644736] usb usb2: root hub lost power or was reset
[   69.928800] random: crng reseeded on system resumption
[   69.145044] PM: suspend entry (deep)
[   69.148213] Filesystems sync: 0.003 seconds
[   69.149837] Freezing user space processes
[   69.150455] remoteproc remoteproc0: clr: 866
[   69.150475] remoteproc remoteproc0: clr: 866,  0   866
[   69.151679] Freezing user space processes completed (elapsed 0.001 seconds)
[   69.151699] OOM killer disabled.
[   69.151707] Freezing remaining freezable tasks
[   69.153204] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[   69.153223] printk: Suspending console(s) (use no_console_suspend to debug)
[   69.154767] HOBOT GDC 3d0c0000.gdc: hobot_gdc_suspend
[   69.154860] hobot-sif 3d050000.sif: cim_suspend
[   69.154874] hobot-sif 3d040000.sif: cim_suspend
[   69.154887] hobot-sif 3d030000.sif: cim_suspend
[   69.154900] hobot-sif 3d020000.sif: cim_suspend
[   69.154971] hobot_vpu_dev: [VPUDRV]vpu_suspend:7842: [-]vpu_suspend leave
[   69.154981] hobot_jpu_dev: [JPUDRV]jpu_suspend:3833: [+]jpu_suspend enter
[   69.154985] hobot_jpu_dev: [JPUDRV]jpu_suspend:3834: [-]jpu_suspend leave
[   69.195792] hobot-dsp dsp0: hobot_dsp_suspend dsp0
[   69.195884] vin mipi0: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_suspend_do enter suspend...
[   69.195893] vin mipi2: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_suspend_do enter suspend...
[   69.195900] vin mipi3: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_suspend_do enter suspend...
[   69.202999] CAM_SUBSYS soc:cam:cam_sys@0: camsys_suspend
[   69.203140] vin mipi1: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_suspend_do enter suspend...
[   69.203151] [INFO][HOBOT_OSD](hb_osd_suspend) done
[   69.203172] [CODEC_NODE]:[L731]hobot_codec_node_suspend 731
[   69.203281] PM: suspend devices took 0.050 seconds
[   69.205883] Disabling non-boot CPUs ...
[   69.206416] psci: CPU1 killed (polled 0 ms)
[   69.207251] psci: CPU2 killed (polled 0 ms)
[   69.208016] psci: CPU3 killed (polled 0 ms)
[   69.208612] psci: CPU4 killed (polled 0 ms)
[   69.209135] psci: CPU5 killed (polled 0 ms)
[   69.209687] psci: CPU6 killed (polled 0 ms)
[   69.211256] psci: CPU7 killed (polled 0 ms)
[   69.211484] Enabling non-boot CPUs ...
[   69.222647] Detected VIPT I-cache on CPU1
[   69.222707] GICv3: CPU1: found redistributor 100 region 0:0x0000000030160000
[   69.222741] CPU1: Booted secondary processor 0x0000000100 [0x412fd050]
[   69.223109] CPU1 is up
[   69.234201] Detected VIPT I-cache on CPU2
[   69.234235] GICv3: CPU2: found redistributor 200 region 0:0x0000000030180000
[   69.234259] CPU2: Booted secondary processor 0x0000000200 [0x412fd050]
[   69.234559] CPU2 is up
[   69.245647] Detected VIPT I-cache on CPU3
[   69.245679] GICv3: CPU3: found redistributor 300 region 0:0x00000000301a0000
[   69.245699] CPU3: Booted secondary processor 0x0000000300 [0x412fd050]
[   69.246028] CPU3 is up
[   69.257116] Detected VIPT I-cache on CPU4
[   69.257151] GICv3: CPU4: found redistributor 400 region 0:0x00000000301c0000
[   69.257174] CPU4: Booted secondary processor 0x0000000400 [0x412fd050]
[   69.257509] CPU4 is up
[   69.268597] Detected VIPT I-cache on CPU5
[   69.268645] GICv3: CPU5: found redistributor 500 region 0:0x00000000301e0000
[   69.268667] CPU5: Booted secondary processor 0x0000000500 [0x412fd050]
[   69.269009] CPU5 is up
[   69.280099] Detected VIPT I-cache on CPU6
[   69.280148] GICv3: CPU6: found redistributor 600 region 0:0x0000000030200000
[   69.280171] CPU6: Booted secondary processor 0x0000000600 [0x412fd050]
[   69.280538] CPU6 is up
[   69.291624] Detected VIPT I-cache on CPU7
[   69.291673] GICv3: CPU7: found redistributor 700 region 0:0x0000000030220000
[   69.291695] CPU7: Booted secondary processor 0x0000000700 [0x412fd050]
[   69.292097] CPU7 is up
[   69.306467] [CODEC_NODE]:[L751]hobot_codec_node_resume 751
[   69.306487] [INFO][HOBOT_OSD](hb_osd_resume) done
[   69.306494] vin mipi1: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_resume_do enter resume...
[   69.306575] CAM_SUBSYS soc:cam:cam_sys@0: camsys_resume
[   69.484694] hobot_gmac 35010000.horizon_tsn eth0: mac_config_rx_queues_routing, not support packet mode :\x02
[   69.484746] hobot_gmac 35010000.horizon_tsn eth0: configuring for phy/rgmii-id link mode
[   69.524503] vin mipi3: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_resume_do enter resume...
[   69.524512] vin mipi2: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_resume_do enter resume...
[   69.524518] vin mipi0: drivers/media/platform/horizon/camsys/mipi/hobot_mipi_host_ops.c:hobot_mipi_host_resume_do enter resume...
[   69.524826] hobot-dsp dsp0: hobot_dsp_resume dsp0
[   69.644730] usb usb1: root hub lost power or was reset
[   69.644736] usb usb2: root hub lost power or was reset
[   69.647123] hobot_jpu_dev: [JPUDRV]jpu_resume:3862: [+]jpu_resume enter
[   69.647129] hobot_jpu_dev: [JPUDRV]jpu_resume:3863: [-]jpu_resume leave
[   69.647137] hobot_vpu_dev: [VPUDRV]vpu_resume:7887: [+]vpu_resume enter
[   69.647141] hobot_vpu_dev: [VPUDRV]vpu_resume:8033: [-]vpu_resume leave
[   69.702201] hobot-sif 3d020000.sif: cim_resume
[   69.702213] hobot-sif 3d030000.sif: cim_resume
[   69.702224] hobot-sif 3d040000.sif: cim_resume
[   69.702234] hobot-sif 3d050000.sif: cim_resume
[   69.702299] HOBOT GDC 3d0c0000.gdc: hobot_gdc_resume
[   69.906154] PM: resume devices took 0.600 seconds
[   69.926659] OOM killer enabled.
[   69.926675] Restarting tasks ... done.
[   69.928800] random: crng reseeded on system resumption
[   69.934105] PM: suspend exit
[   69.968824] remoteproc remoteproc0: new: 866, 0   0

以下日志详细分析:

1 ) 休眠过程

  • 进入休眠

    • echo mem > /sys/power/state:该命令系统置于休眠状态,具体是“深度休眠”( deep sleep)。

    • PM: suspend entry:系统开始进入休眠状态。

  • 文件系统同步

    • Filesystems sync: 0.003 seconds:在进入休眠之前,系统进行文件系统同步,确保所有数据写入磁盘。

  • 冻结用户空间进程

    • Freezing user space processes:系统冻结用户空间进程,防止休眠期间进程状态变化。

    • Freezing user space processes completed (elapsed 0.001 seconds):冻结过程完成。

  • 禁用引导 CPU

    • Disabling non-boot CPUs ...:系统禁用引导 CPU(即除了引导 CPU 以外其他 CPU),以节省功耗。

2 ) 设备

  • 设备

    • 多个设备操作记录,例如:

      • hobot_gdc_suspendcim_suspendvpu_suspendjpu_suspend 等,表明这些设备进入休眠状态起。

    • PM: suspend devices took 0.050 seconds:设备操作耗时 50 毫秒。

3 ) 恢复过程

  • 恢复设备

    • PM: resume devices took 0.600 seconds:恢复设备过程耗时 600 毫秒。

    • 设备恢复日志信息表明多个设备(如 hobot_gdc_resumecim_resumevpu_resumejpu_resume 等)被重新激活。

  • 重新启用引导 CPU

    • Enabling non-boot CPUs ...:系统重新启用之前禁用引导 CPU。

    • 日志显示每个 CPU 的启动信息,例如 CPU1 is up,表明 CPU 已成功恢复。

4 ) 其他事件

  • USB 设备状态

    • usb usb1: root hub lost power or was reset: USB 根集线器休眠恢复过程失去电源重置,这可能影响 USB 设备正常工作。

  • 随机数生成器

    • random: crng reseeded on system resumption:在系统恢复时,随机数生成器重新播种,这是确保系统安全性一部分。

  • OOM Killer

    • OOM killer disabledOOM killer enabled:在休眠期间禁用了 OOM( Out Of Memory)杀手,以防止内存情况杀死进程,而恢复重新启用。

休眠唤醒常见问题

  • 问题:系统休眠无法正常唤醒。

    • 解决方法:检查休眠唤醒配置是否正确,例如 RTC 唤醒设置是否正确, GPIO 唤醒的 GPIO 引脚是否配置唤醒源。同时,可以检查系统日志,查看休眠唤醒过程是否错误信息异常情况。

  • 问题:休眠唤醒后,系统性能下降。

    • 解决方法:在系统唤醒后,检查设备驱动程序状态是否正常,确保所有设备驱动程序正确恢复工作状态。同时,可以尝试调整休眠唤醒策略,例如使用不同休眠方式调整休眠时间,以减少对系统性能影响。

4.4.11.5. 典型场景功耗

以 X5 EVB 主板为例,以下典型应用场景功耗数据

  • 硬件环境: X5 EVB 主板

  • 场景负载

    • 8x CPU @ 1.5G,负载 80%

    • 1x BPU @ 1.0G,负载 80%

    • LPDDR4 @ 3200MHz,带宽 100%

    • 双路 Camera 接入,负载 2x 1080p @ 30fps

  • 测试方法

    • 结温85度下,统计 X5 芯片各路电源平均电流数据

  • 测试结果

    • X5芯片平均功耗最大值为 4335mW

Voltage Domains Voltage(V) Avg Current(mA) Avg Power(mW)
CH0 SOC_1V8 1.8 16 28.8
CH1 DDR_0V8 0.8 817 653.6
CH2 GPU_0V8 0.8 0 0
CH3 SOC_0V8 0.8 992 793.6
CH4 DSP_0V8 0.8 80 64
CH5 18_DSP 1.8 4 7.2
CH6 CSI_0V8 0.8 4 3.2
CH7 SOC_3V3 3.3 0 0
CH8 DSI_0V8 0.8 0 0
CH9 AON_0V8 0.8 7 5.6
CH10 AON_1V8 1.8 0 0
CH11 18_SOC 1.8 40 72
CH12 USB_3V3 3.3 28 92.4
CH13 CSI_1V8 1.8 4 7.2
CH14 USB_0V8 0.8 28 22.4
CH15 BPU_0V8 0.8 1033 826.4
CH16 DDR_1V1 1.1 639 702.9
CH17 CPU_0V8 0.8 1295 1036
CH18 VDDA_1V 1.8 4 7.2
CH19 DDR_PLL 1.8 4 7.2
CH20 DSI_1V8 1.8 0 0
CH21 ADC_1V8 1.8 3 5.4
Total Power 4335.1

注意事项

以上表格电源域,可通过 X5 EVB 原理图 PMIC 和 Power Combine 小节找到硬件对应位置,用户电流探头串入对应电路获取电流功耗。

low_power-PMIC

low_power-Power_Combine