API GUIDE / AON / API OVERVIEW
AON API 概述
1. 文档范围
本文档定义 G32S10 SDK 当前 CPM 模块的正式接口,覆盖以下两层:
HAL CPM:面向应用、BSP 和驱动上层的时钟、分频、父时钟和 gate 控制接口LL CPM/AON:面向 CPM/AON 寄存器与位域操作的低层接口
本文档基于以下实现与头文件编写:
code/include/drivers/g32s10/cpm/hal_cpm.hcode/include/drivers/g32s10/cpm/cpm_regs.hcode/include/drivers/g32s10/cpm/ll_cpm.hcode/include/drivers/g32s10/cpm/ll_cdr.hcode/include/drivers/g32s10/cpm/ll_aon.hcode/include/drivers/g32s10/cpm/ll_pm.hcode/drivers/g32s10/cpm/hal_cpm_core.ccode/drivers/g32s10/cpm/hal_cpm_clk.ccode/drivers/g32s10/cpm/hal_cpm_pll.ccode/drivers/g32s10/cpm/hal_cpm_cgu.ccode/drivers/g32s10/cpm/hal_cpm_i2s_cgu.ccode/drivers/g32s10/cpm/hal_cpm_gate.ccode/drivers/g32s10/cpm/hal_cpm_summary.c
2. 分层关系
Application / BSP / Driver / Test
|
v
HAL CPM
|
v
LL CPM / LL CDR / LL AON / LL PM
|
v
CPM and AON Registers
分层职责如下:
HAL CPM- 使用统一
hal_cpm_id_t描述 clock 和 gate 资源 - 封装 clock enable、disable、rate、parent 和 gate open/close 语义
- 维护 clock 软件缓存,包括 parent、rate 和 clock enable 引用计数
- 对参数进行 SDK 统一检查并返回
error_code_t
- 使用统一
LL CPM/AON- 提供
static inline寄存器和位域访问入口 - 不维护软件状态,不做 clock tree 或引用计数语义
- 不返回 SDK 错误码;读取接口返回寄存器值或
bool
- 提供
cpm_regs.h- 定义
cpm_regs_t、aon_regs_t、寄存器实例宏、bit/field mask 和硬件枚举值
- 定义
3. 构建配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
CONFIG_DRIVER_CPM |
y |
编译 G32S10 CPM 驱动。 |
CONFIG_CPM_ENABLE_STUB |
n |
编译 CPM HAL 空实现。开启后 public HAL 符号保留,但不访问 CPM/AON 硬件。 |
CONFIG_CPM_ENABLE_STUB=y 时,code/drivers/g32s10/cpm/CMakeLists.txt 只编译 hal_cpm_stub.c。stub 行为如下:
| 接口 | stub 行为 |
|---|---|
hal_cpm_init() |
返回 IM_OK。 |
hal_cpm_clk_enable() / hal_cpm_clk_disable() / hal_cpm_clk_set_rate_hz() / hal_cpm_clk_set_parent() |
参数占位后返回 IM_OK。 |
hal_cpm_clk_is_enabled() |
输出 false,返回 IM_OK。 |
hal_cpm_clk_get_rate_hz() |
输出 0,返回 IM_OK。 |
hal_cpm_clk_get_parent() |
输出 HAL_CPM_ID_INVALID,返回 IM_OK。 |
hal_cpm_rosc2_trim() |
空操作,返回 IM_OK。 |
4. 资源模型与公开类型
4.1 基地址与寄存器实例
CPM HAL/LL 访问两个硬件寄存器块,基地址由 base.h 提供:
#define CPM_IOBASE 0x10000000
#define AON_IOBASE 0x100CD000
cpm_regs.h 基于这两个基地址定义寄存器实例宏:
#define CPM ((cpm_regs_t *)(uintptr_t)CPM_IOBASE)
#define AON ((aon_regs_t *)(uintptr_t)AON_IOBASE)
其中 CPM 覆盖主 CPM 寄存器、PLL、CPCCR/CPCCR1 和各类 CDR;AON 覆盖 ROSC、LP/RT clock、AON gate 和 AON I2S CDR 等低功耗域寄存器。
4.2 统一资源 ID
CPM HAL 使用一个公开枚举类型描述 clock 和 gate:
typedef enum {
HAL_CPM_ID_CLK_EXTAL = 0,
...
HAL_CPM_ID_GATE_BASE = 0x1000U,
...
HAL_CPM_ID_CLK_NONE = 0xFFFEU,
HAL_CPM_ID_INVALID = 0xFFFFU,
} hal_cpm_id_t;
ID 空间按范围组织:
| 范围 | 说明 |
|---|---|
HAL_CPM_ID_CLK_BASE_BEGIN ~ HAL_CPM_ID_CLK_BASE_END - 1 |
根时钟、主时钟、LPCLK 和 RTCLK。 |
HAL_CPM_ID_CLK_PLL_BEGIN ~ HAL_CPM_ID_CLK_PLL_END - 1 |
PLL 相关 clock。 |
HAL_CPM_ID_CLK_CGU_BEGIN ~ HAL_CPM_ID_CLK_CGU_END - 1 |
普通 CGU CDR clock。 |
HAL_CPM_ID_CLK_I2S_CGU_BEGIN ~ HAL_CPM_ID_CLK_I2S_CGU_END - 1 |
I2S TX/RX CGU clock。 |
HAL_CPM_ID_GATE_BASE ~ HAL_CPM_ID_GATE_END - 1 |
AON LP/HP0/HP1 gate。 |
HAL_CPM_ID_CLK_NONE |
伪 parent id,表示支持无时钟输出的 mux 选择 none。 |
说明:
- clock id 可用于 enable、disable、is_enabled、get_rate、set_rate、get_parent、set_parent。
HAL_CPM_ID_CLK_NONE不属于普通 clock range,只能作为 parent 值或get_parent的返回值使用。- gate id 只支持 enable、disable、is_enabled。
- 对 gate id 调用 rate 或 parent 接口返回
IM_ERR_UNSUPPORTED。 - gate id 通过
HAL_CPM_ID_GATE_BASE加硬件 stop bit offset 表示,中间保留位不是有效 gate。
4.3 Base Clock ID
| ID | 说明 | 可设置 rate | 可设置 parent |
|---|---|---|---|
HAL_CPM_ID_CLK_EXTAL |
外部晶振时钟。 | 仅接受当前频率值 | 否 |
HAL_CPM_ID_CLK_ROSC2 |
ROSC2 时钟。 | 是,支持 16/24/32/48 MHz | 否 |
HAL_CPM_ID_CLK_SCLK_A |
SCLK_A。 | 否;仅接受当前 parent 频率 | 是,可选 EXTAL / APLL / HAL_CPM_ID_CLK_NONE |
HAL_CPM_ID_CLK_CCLK |
CPU clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE |
HAL_CPM_ID_CLK_L2CLK |
L2 clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE,与 CCLK 共用 source mux |
HAL_CPM_ID_CLK_H1CLK |
H1 clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE |
HAL_CPM_ID_CLK_H2CLK |
H2 clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE |
HAL_CPM_ID_CLK_PCLK |
PCLK。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE,与 H2CLK 共用 source mux |
HAL_CPM_ID_CLK_HMCLK |
HM clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE / LPCLK |
HAL_CPM_ID_CLK_PMCLK |
PM clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE / LPCLK,与 HMCLK 共用 source mux |
HAL_CPM_ID_CLK_CPU_V0 |
LP V0 CPU clock。 | 是 | SCLK_A / MPLL / HAL_CPM_ID_CLK_NONE / LPCLK |
HAL_CPM_ID_CLK_LPCLK |
AON LPCLK。 | 仅接受当前有效频率 | 是,CPU_V0 或 ROSC2 |
HAL_CPM_ID_CLK_RTCLK |
AON RTCLK。 | 否 | 是,ROSC2 或 EXTAL,输出为 parent/512 |
Base clock enable 是软件引用计数入口。硬件层当前不对 base clock 执行额外开启动作,disable 对不可硬关闭节点不会关硬件。
CCLK / L2CLK 共用 CPU source mux,但两者 divider 独立;H2CLK / PCLK 共用 H2/P source mux,但两者 divider 独立;HMCLK / PMCLK 共用 HM/PM source mux,并共用 PMCLK divider;H1CLK 和 CPU_V0 使用独立 source mux 和 divider。修改同一 source 组内任一时钟的 parent 会改变另一时钟的有效 parent;修改 HMCLK / PMCLK 中任一时钟的 rate 会同时改变另一时钟的频率。对 HMCLK / PMCLK / CPU_V0 设置 LPCLK 会把 AON LPCLKSEL 切到 ROSC2,而设置其他 parent 会切回 CPM。
HAL_CPM_ID_CLK_ROSC2 的 rate 由 ROSCC.ROSC2_FSEL 档位推导为标称频率(16/24/32/48 MHz),不是 trim 后的实测频率。
当 AON LPCLKSEL 选择 ROSC2 时,HMCLK、PMCLK 和 CPU_V0 的有效 parent 会显示为 LPCLK,rate 跟随 ROSC2;此时对这三个 clock 调用 set_rate_hz() 只接受当前频率值。
4.4 PLL ID
| ID | 说明 | Parent | 备注 |
|---|---|---|---|
HAL_CPM_ID_CLK_APLL |
APLL 输出。 | HAL_CPM_ID_CLK_EXTAL |
支持 set_rate。 |
HAL_CPM_ID_CLK_MPLL |
MPLL 输出。 | HAL_CPM_ID_CLK_EXTAL |
支持 set_rate。 |
HAL_CPM_ID_CLK_APLL_DIV8 |
APLL/8 派生输出。 | HAL_CPM_ID_CLK_APLL |
只读 rate,不支持直接 set_rate。 |
PLL rate 计算公式:
rate = parent_rate * M / N / OD1 / OD2
当前 HAL 对 APLL/MPLL set_rate 使用动态计算出的 M/N/OD1/OD2 配置,并轮询 PLL on 状态直至置位(最多 100000 次),超时返回 IM_ERR_TIMEOUT。HAL_CPM_ID_CLK_APLL_DIV8 的 rate 来自 APLL rate 除以 8。
4.5 CGU ID
普通 CGU clock 由 CPM CDR 寄存器控制。HAL 统一使用 Hz 作为 rate 参数;底层会转换成 CDR divider 字段。
HAL_CPM_ID_CLK_CGU_UART 与 HAL_CPM_ID_CLK_CGU_LP_UART 映射到同一个 uartcdr,共享 source、divider 和 STOP 使能位,不存在独立的 LP_UART 使能位。为避免一个逻辑域关闭仍被另一域使用的物理时钟,enable、disable、is_enabled 以及 hal_cpm_clk_get_info().enable_count 都对 LP_UART 使用同一个物理 UART clock 状态及软件引用计数。get_parent 和 get_rate_hz 仍按传入逻辑 ID 返回有效状态,因为 LP_UART 还可能经 AON LPCLKSEL 直连 LPCLK;set_parent 和 set_rate_hz 也保留逻辑域参数,以支持 LPCLK 路径切换。LP_UART 未走 LPCLK 时两者共同使用 uartcdr,成功的 parent/rate 更新会同步刷新两个逻辑 clock 的缓存,避免一个 ID 修改后另一个 ID 返回旧值。
LP 域 CGU(LP UART、SSI0、SSI_SLV0)共用 AON LPCLKSEL,但 parent 集合不完全相同:LP_UART 支持 SCLK_A / MPLL / EXTAL / LPCLK,SSI0 和 SSI_SLV0 支持 SCLK_A / MPLL / LPCLK。当 LPCLKSEL=ROSC2 时,这三个 clock 的有效 parent 都显示为 LPCLK,rate 等于当前 LPCLK,CPM CDR divider 不参与计算;此时 SSI0/SSI_SLV0 的 enable/disable 不操作 CDR,is_enabled 返回 true,而 LP_UART 的 enable/disable/is_enabled 仍作用于共享 uartcdr STOP 状态;这三个 clock 的 set_rate_hz() 都只接受当前 LPCLK 频率。任一 LP clock 调用 set_parent(LPCLK) 都会把三者一起切到 LPCLK 路径;任一 LP clock 切回 SCLK_A / MPLL(LP_UART 还可选 EXTAL)时,会先配置该 clock 的 CDR,再把 LPCLKSEL 切回 CPM。
| ID | CDR 寄存器 | Divider 位宽 | 系数 | 可选 parent |
|---|---|---|---|---|
HAL_CPM_ID_CLK_CGU_PSRAM |
psramcdr |
4 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_RSA |
rsacdr |
4 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_UART |
uartcdr |
8 | 1 | SCLK_A / MPLL / EXTAL,用于 UART2~7 |
HAL_CPM_ID_CLK_CGU_LP_UART |
uartcdr |
8 | 1 | SCLK_A / MPLL / EXTAL / LPCLK,用于 UART0/1 |
HAL_CPM_ID_CLK_CGU_MAC |
maccdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_MAC_PTP |
mac_ptpcdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_SFC |
sfccdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_PWM |
pwmcdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_PWMA |
pwmacdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_SSI0 |
ssi0cdr |
8 | 1 | SCLK_A / MPLL / LPCLK |
HAL_CPM_ID_CLK_CGU_SSI1 |
ssi1cdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_SSI_SLV0 |
ssi_slv0cdr |
8 | 1 | SCLK_A / MPLL / LPCLK |
HAL_CPM_ID_CLK_CGU_SSI_SLV1 |
ssi_slv1cdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_LCD |
lpcdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_MSC0 |
msc0cdr |
8 | 4 | SCLK_A / MPLL / APLL_DIV8 / EXTAL |
HAL_CPM_ID_CLK_CGU_MSC1 |
msc1cdr |
8 | 4 | SCLK_A / MPLL / APLL_DIV8 / EXTAL |
HAL_CPM_ID_CLK_CGU_TPC |
tpccdr |
4 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_CIM0 |
cim0cdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_CIM1 |
cim1cdr |
8 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_CAN0 |
can0cdr |
8 | 1 | SCLK_A / MPLL / EXTAL |
HAL_CPM_ID_CLK_CGU_CAN1 |
can1cdr |
8 | 1 | SCLK_A / MPLL / EXTAL |
HAL_CPM_ID_CLK_CGU_SADC0 |
sadc0cdr |
8 | 1 | SCLK_A / MPLL / EXTAL |
HAL_CPM_ID_CLK_CGU_SADC1 |
sadc1cdr |
8 | 1 | SCLK_A / MPLL / EXTAL |
HAL_CPM_ID_CLK_CGU_JPEG |
jpegcdr |
4 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_MSCALER |
mscalercdr |
4 | 1 | SCLK_A / MPLL |
HAL_CPM_ID_CLK_CGU_ISPM |
ispmcdr |
4 | 1 | SCLK_A / MPLL |
CGU 分频关系:
rate = parent_rate / ((divider_field + 1) * coefficient)
HAL set_rate 向上取整计算分频值,使输出频率不大于目标频率;受分频字段上限限制时,实际输出可能低于目标。set_parent 会根据目标 parent 写入对应 CDR source 字段,并在需要时控制 UART/MSC/CAN/SADC 的 EXCLK enable 位;其中 MSC EXCLK 只在该路径切到 EXTAL 时置位,HAL 不会在这里清除 MSC EXCLK。
4.6 I2S CGU ID
| ID | 说明 | 可选 parent |
|---|---|---|
HAL_CPM_ID_CLK_CGU_I2S_TX |
I2S TX clock。 | SCLK_A / MPLL / ROSC2 |
HAL_CPM_ID_CLK_CGU_I2S_RX |
I2S RX clock。 | SCLK_A / MPLL / ROSC2 |
选择 SCLK_A 或 MPLL 时走 CPM I2S CDR 路径;选择 ROSC2 时走 AON
I2S CDR 路径。TX/RX 共用 source mux,切换 source 会影响两个方向。
I2S CGU 使用 M/N 分频:
rate = parent_rate * M / N
当前实现对未使能的 I2S clock 支持保存待写入的 M/N 配置;后续 enable 时再写入硬件。切换 parent 时,如果旧 rate 非 0,HAL 会尝试按新 parent 重新计算 M/N 以保持原频率。
由于 source mux 由 TX/RX 共用,set_parent() 在切换前会检查 peer:如果 peer 已使能且其当前 source 与目标 source 不同,或 peer 未使能但保存的 M/N 是针对旧 source 计算的,则拒绝本次切换并返回 IM_ERR_UNSUPPORTED,避免把 peer 切到错误频率。
4.7 Gate ID
Gate 资源映射到 AON LPCLKGR、HPCLKGR0 和 HPCLKGR1 stop bit。HAL 语义如下:
| HAL 操作 | 硬件动作 |
|---|---|
hal_cpm_clk_enable(gate_id) |
清 stop bit,打开 gate。 |
hal_cpm_clk_disable(gate_id) |
置 stop bit,关闭 gate。 |
hal_cpm_clk_is_enabled(gate_id, &open) |
读取 stop bit;stop bit 为 0 时输出 true。 |
LP gate:
| ID | AON bit |
|---|---|
HAL_CPM_ID_GATE_CPU_V0 |
AON_LPCLKGR_CPU_V0_BIT |
HAL_CPM_ID_GATE_AHB_MCU |
AON_LPCLKGR_AHB_MCU_BIT |
HAL_CPM_ID_GATE_APB_MCU |
AON_LPCLKGR_APB_MCU_BIT |
HAL_CPM_ID_GATE_DMA |
AON_LPCLKGR_DMA_BIT |
HAL_CPM_ID_GATE_WDT |
AON_LPCLKGR_WDT_BIT |
HAL_CPM_ID_GATE_UART0 |
AON_LPCLKGR_UART0_BIT |
HAL_CPM_ID_GATE_UART1 |
AON_LPCLKGR_UART1_BIT |
HAL_CPM_ID_GATE_SMB0 |
AON_LPCLKGR_SMB0_BIT |
HAL_CPM_ID_GATE_SSI0 |
AON_LPCLKGR_SSI0_BIT |
HAL_CPM_ID_GATE_SSI_SLV0 |
AON_LPCLKGR_SSI_SLV0_BIT |
HAL_CPM_ID_GATE_AIC |
AON_LPCLKGR_AIC_BIT |
HAL_CPM_ID_GATE_ROSC_HP |
AON_LPCLKGR_ROSC_HP_BIT |
HP0 gate:
| ID | AON bit |
|---|---|
HAL_CPM_ID_GATE_NEMC |
AON_HPCLKGR0_NEMC_BIT |
HAL_CPM_ID_GATE_EFUSE |
AON_HPCLKGR0_EFUSE_BIT |
HAL_CPM_ID_GATE_OTG |
AON_HPCLKGR0_OTG_BIT |
HAL_CPM_ID_GATE_MSC0 |
AON_HPCLKGR0_MSC0_BIT |
HAL_CPM_ID_GATE_MSC1 |
AON_HPCLKGR0_MSC1_BIT |
HAL_CPM_ID_GATE_LP_EXCLK |
AON_HPCLKGR0_LP_EXCLK_BIT |
HAL_CPM_ID_GATE_SMB1 |
AON_HPCLKGR0_SMB1_BIT |
HAL_CPM_ID_GATE_SMB2 |
AON_HPCLKGR0_SMB2_BIT |
HAL_CPM_ID_GATE_SADC0 |
AON_HPCLKGR0_SADC0_BIT |
HAL_CPM_ID_GATE_TCU |
AON_HPCLKGR0_TCU_BIT |
HAL_CPM_ID_GATE_UART2 |
AON_HPCLKGR0_UART2_BIT |
HAL_CPM_ID_GATE_UART3 |
AON_HPCLKGR0_UART3_BIT |
HAL_CPM_ID_GATE_SC_HASH |
AON_HPCLKGR0_SC_HASH_BIT |
HAL_CPM_ID_GATE_UART4 |
AON_HPCLKGR0_UART4_BIT |
HAL_CPM_ID_GATE_UART5 |
AON_HPCLKGR0_UART5_BIT |
HAL_CPM_ID_GATE_PDMA |
AON_HPCLKGR0_PDMA_BIT |
HAL_CPM_ID_GATE_UART6 |
AON_HPCLKGR0_UART6_BIT |
HAL_CPM_ID_GATE_LCD |
AON_HPCLKGR0_LCD_BIT |
HAL_CPM_ID_GATE_MIPI_CSI |
AON_HPCLKGR0_MIPI_CSI_BIT |
HAL_CPM_ID_GATE_UART7 |
AON_HPCLKGR0_UART7_BIT |
HAL_CPM_ID_GATE_RSA |
AON_HPCLKGR0_RSA_BIT |
HAL_CPM_ID_GATE_SSI1 |
AON_HPCLKGR0_SSI1_BIT |
HAL_CPM_ID_GATE_TNPU |
AON_HPCLKGR0_TNPU_BIT |
HAL_CPM_ID_GATE_MIPI_DSI |
AON_HPCLKGR0_MIPI_DSI_BIT |
HAL_CPM_ID_GATE_CAN0 |
AON_HPCLKGR0_CAN0_BIT |
HAL_CPM_ID_GATE_DTRNG |
AON_HPCLKGR0_DTRNG_BIT |
HAL_CPM_ID_GATE_CAN1 |
AON_HPCLKGR0_CAN1_BIT |
HAL_CPM_ID_GATE_CIM |
AON_HPCLKGR0_CIM_BIT |
HP1 gate:
| ID | AON bit |
|---|---|
HAL_CPM_ID_GATE_MAC |
AON_HPCLKGR1_MAC_BIT |
HAL_CPM_ID_GATE_AES |
AON_HPCLKGR1_AES_BIT |
HAL_CPM_ID_GATE_JPEG_DEC |
AON_HPCLKGR1_JPEG_DEC_BIT |
HAL_CPM_ID_GATE_TPC |
AON_HPCLKGR1_TPC_BIT |
HAL_CPM_ID_GATE_SADC1 |
AON_HPCLKGR1_SADC1_BIT |
HAL_CPM_ID_GATE_AHB1 |
AON_HPCLKGR1_AHB1_BIT |
HAL_CPM_ID_GATE_SSI_SLV1 |
AON_HPCLKGR1_SSI_SLV1_BIT |
HAL_CPM_ID_GATE_I2D |
AON_HPCLKGR1_I2D_BIT |
HAL_CPM_ID_GATE_PWM |
AON_HPCLKGR1_PWM_BIT |
HAL_CPM_ID_GATE_APB0 |
AON_HPCLKGR1_APB0_BIT |
HAL_CPM_ID_GATE_PWMA |
AON_HPCLKGR1_PWMA_BIT |
HAL_CPM_ID_GATE_IPU |
AON_HPCLKGR1_IPU_BIT |
HAL_CPM_ID_GATE_SFC |
AON_HPCLKGR1_SFC_BIT |
HAL_CPM_ID_GATE_PSRAM |
AON_HPCLKGR1_PSRAM_BIT |
HAL_CPM_ID_GATE_OST |
AON_HPCLKGR1_OST_BIT |
HAL_CPM_ID_GATE_JPEG |
AON_HPCLKGR1_JPEG_BIT |
HAL_CPM_ID_GATE_MSCALER |
AON_HPCLKGR1_MSCALER_BIT |
5. 文档范围
本文档定义 G32S10 SDK CPM/AON 低功耗(PM)middleware(MID)层的正式接口,面向在应用、BSP 或示例代码中发起低功耗请求、注册设备 PM 客户端、读取 PM 状态以及完成唤醒恢复的调用方。
本文档以当前 SDK 源码为准,主要核对文件如下:
| 类型 | 路径 |
|---|---|
| MID 公开接口 | code/middleware/pm/include/im_pm.h |
| MID 实现 | code/middleware/pm/src/im_pm.c |
| V1 上下文辅助接口 | code/middleware/pm/include/pm_context.h |
| V1 上下文汇编实现 | code/middleware/pm/src/pm_context.S |
| HAL 公开接口 | code/include/drivers/g32s10/pm/hal_pm.h |
| HAL 实现 | code/drivers/g32s10/pm/hal_pm.c |
| AON HAL | code/include/drivers/g32s10/aon/hal_aon.h、code/drivers/g32s10/aon/hal_aon.c |
| 构建配置 | code/middleware/pm/Kconfig、code/middleware/pm/CMakeLists.txt |
| MID 示例 | code/middleware/pm/example/ |
| 硬件规格参考 | G32S10_CPM&AON_spec_CN.docx(3.3 CPM 功耗管理、3.4 AON 功耗管理) |
本文覆盖 MID 层公开 API,并对以下模式给出状态、流程和能力说明:
| 模式 | MID 枚举 | 当前覆盖 |
|---|---|---|
| Active | IM_PM_MODE_ACTIVE |
正常运行态,不是请求目标 |
| Idle | IM_PM_MODE_IDLE |
V1 支持 |
| Light-nor | IM_PM_MODE_LIGHT_NOR |
V1 与 SRAM-only V0 支持 |
| Light-pd | IM_PM_MODE_LIGHT_PD |
V1 与 SRAM-only V0 支持,含双核上下文保存/恢复 |
| Retention | IM_PM_MODE_RETENTION |
SRAM-only V0 支持 |
| Deep-sleep | IM_PM_MODE_DEEP_SLEEP |
SRAM-only V0 支持 |
| Hibernate | IM_PM_MODE_HIBERNATE |
SRAM-only V0 支持 |
| Power-down | IM_PM_MODE_POWER_OFF |
板级/PMIC 整机掉电目标;接口定义存在,当前 HAL 不支持 |
补充说明:
- 本文的
MID PM指code/middleware/pm/中的电源管理中间件;公开 API 均以im_pm_开头。 - MID 只通过
hal_pm_*()访问低功耗硬件序列,不直接调用 CPM/AON LL 寄存器接口。CPM 时钟树和 gate 的 HAL/LL 接口见G32S10 CPM HAL/LL 正式接口文档。 - 文档中的芯片模式(
Active、Idle、Light-nor等)描述硬件低功耗形态;im_pm_state_t描述 MID 一次事务的软件状态,两者不是同一状态机。 - 本文列出的模式能力、状态迁移、回滚行为和返回值均以当前源码为准。文中寄存器级流程仅用于解释硬件语义,不构成 MID 公开 API。
目录
- 1. 文档范围
- 6. AON 状态说明
- 7. 分层关系与依赖
- 8. 构建配置与文件组织
- 9. 资源模型与公开类型
- 1. 接口规范
- 2. 行为约束与实现说明
- 3. 典型用法
- 4. 示例程序与使用方式
- 5. MID 错误码
6. AON 状态说明
AON 是芯片常供电模块,负责 LP 域的总线/时钟控制,以及全芯片 HP 域的断电和上电控制。CPM 负责 IDLE、SLEEP 等时钟控制流程,AON 在此基础上扩展 RETENTION、DEEP_SLEEP 和 HIBERNATE 等断电流程。
本节先给出产品级运行模式总览,再说明 AON 状态转移及各模式的关键动作。图中“Active”等节点是芯片工作模式,不是 MID 事务状态。
6.1 状态转移图

状态图建议按以下四条主线阅读:
- 运行主线:
Active在空闲且无中断时执行 WFI 进入Idle;Idle只关闭 V1 CPU 时钟,中断到来后自动回到Active。 - HP 时钟/供电主线:
Light-nor停止 HP 时钟但保留供电;Light-pd进一步关闭 CPU_V1/TNPU 电源并允许模块 SRAM power down;Retention保持 PSRAM 的 VDDMEM 和 V1 恢复上下文;Deep-sleep断开 HP 域且不保留 V1 执行上下文。 - 最深睡眠主线:
Deep-sleep下 V0 进入 sleep 后形成Hibernate,V0 SRAM 进入 retention、模块 SRAM 进入 power down;GPIO 中断唤醒 V0 后回到Deep-sleep路径。 - 外部掉电主线:
Active或Deep-sleep可由应用控制外部电源进入Power-down;Power-down重新上电后走冷启动回到Active。该过程不属于 G32S10 PM HAL 的软件请求范围。
状态图中的关键迁移和相关动作如下:
| 状态迁移 | 关键动作 |
|---|---|
Active -> Idle |
空闲且无中断时执行 WFI;仅关闭 V1 CPU 时钟,中断唤醒后恢复。 |
Idle -> Active |
中断到来,自动退出 IDLE。 |
Active -> Light-nor |
停止 HP 时钟;V1 进入 WFI/休眠,LP 域保持工作;唤醒后恢复 HP 时钟和 V1 指令状态。 |
Light-nor -> Active |
中断唤醒,恢复 HP 时钟和 V1 指令状态。 |
Active -> Light-pd |
停止 HP 时钟,断开 CPU_V1/TNPU 电源,模块 SRAM power down,保存 V1 上下文并执行 WFI/休眠。 |
Light-pd -> Active |
中断唤醒后恢复 SRAM 供电、CPU_V1/TNPU 和 V1 上下文。 |
Active -> Retention |
保存 V1 上下文,PSRAM 进入 half-sleep,由 V0 请求 HP 域掉电。 |
Retention -> Active |
V0 控制 HP 域上电,恢复 PSRAM、时钟和 GPIO,并恢复 V1 上下文。 |
Active -> Deep-sleep |
V1 不保存执行上下文,V0 请求 HP 域掉电。 |
Deep-sleep -> Active |
V0 控制 HP 域上电,V1 冷启动。 |
Deep-sleep -> Hibernate |
V0 SRAM 进入 retention、模块 SRAM 进入 power down;Hibernate 使用 Deep-sleep 作为内部基础状态。 |
Hibernate -> Deep-sleep |
V0 GPIO 中断触发,V0/LP 域恢复,系统回到 Deep-sleep 基础状态。 |
Active -> Power-down |
应用控制外部电源掉电。 |
Deep-sleep -> Power-down |
在深睡状态下由应用控制外部电源掉电;该迁移属于板级/PMIC 外部电源路径。 |
Power-down -> Active |
应用控制外部电源重新上电,执行冷启动。 |
从 MID 角度看,Active 对应正常业务运行;im_pm_request() 成功后进入 SLEEPING,但此时硬件可能已处于 Idle、Light-pd、Retention、Deep-sleep 或 Hibernate。唤醒后必须先完成对应 hal_pm_exit_*() 序列,再调用 im_pm_resume() 完成软件事务恢复。
6.2 各模式资源表现

该图按 V1、HP 外设、PSRAM、V0 和 LP 外设五个维度描述各工作模式。整体上,状态越往后,V1、HP 外设和 PSRAM 的资源关闭得越彻底,V0 和 LP 外设的可用能力也越有限。
active
V1 运行在 800 MHz,V0 运行在 400 MHz,HP/LP 外设和 PSRAM 均正常工作。该状态处理全部业务和中断,是其他睡眠状态的返回点。
idle
仅关闭 V1 CPU 时钟,V0 仍以 400 MHz 运行,HP/LP 外设和 PSRAM 保持工作,中断可以唤醒 V1。该状态适合短时间无任务但仍需保持外设和内存可用的场景。
light-nor
V1 时钟关闭,HP 外设停止工作,PSRAM 进入自刷新;V0 运行在 16~48 MHz,LP 外设可继续工作。唤醒后恢复 HP 时钟和 V1 指令状态。
light-pd
V1 和 TNPU 断电,HP 外设不工作且模块 SRAM 可 power down;PSRAM 保持自刷新,IO 可进入 idle;V0 运行在 16~48 MHz,LP 外设可工作。该状态需要保存 V1 上下文,唤醒后恢复 SRAM 供电、CPU_V1/TNPU 和 V1 上下文。
retention
V1 断电,HP 外设断电并保留 PSRAM 的 VDDMEM,PSRAM 进入 half-sleep;V0 运行在 16~48 MHz,LP 外设可工作。该状态保存 PSRAM 数据和 V1 恢复上下文,唤醒后恢复 PSRAM、时钟、GPIO 和 V1 上下文。
deep-sleep
V1、HP 外设和 PSRAM 均断电,V0 运行在 16~48 MHz,LP 外设可工作。该状态不保存 V1 执行上下文,唤醒后 HP 域重新上电、V1 冷启动。
hibernate
V1、HP 外设和 PSRAM 断电,LP 域剩余模块关闭时钟,仅保留 AON 内部休眠状态机;V0 进入 sleep,仅计时和 GPIOD 中断唤醒可用,V0 SRAM 保持 retention、模块 SRAM 进入 power down。GPIO 唤醒后 LP 域时钟恢复并回到 deep-sleep 基础状态。
powerdown
V1、HP 外设、PSRAM、V0 和 LP 外设全部断电,由应用控制外部电源完成整机掉电。重新上电后执行冷启动。该状态不同于 CPM 内部的 POWER DOWN 模式,也不是普通软件可请求的低功耗模式。
7. 分层关系与依赖
Application / BSP / Example
|
v
MID PM
|
v
HAL PM
|
v
LL CPM / LL AON / LL PM
|
v
CPM and AON Registers
MID 层职责:
- 以“一次低功耗事务”为单位编排 PM 生命周期:校验请求、按顺序调用客户端、提交恢复记录、调用 HAL 进入/退出,并在失败时回滚。
- 维护调用方可见的
im_pm_state_t状态、当前目标模式、最近一次故障和初始化时保存的能力快照。 - 要求设备以静态链表注册
prepare/suspend/resume_early/resume/complete回调,统一处理业务设备的停机和恢复顺序。 - 在进入低功耗前保存恢复记录,并在唤醒初始化或
im_pm_resume()时校验 magic、版本、owner、客户端数量、模式、序列号、挂起掩码和 CRC。
MID 当前使用的 HAL 接口:
| HAL 接口 | MID 用途 |
|---|---|
hal_pm_init() / hal_pm_deinit() |
初始化/反初始化 AON 及 PM HAL 上下文 |
hal_pm_get_capabilities() |
获取当前核和构建配置支持的模式掩码 |
hal_pm_enter_idle() / hal_pm_exit_idle() |
IDLE 进入/退出 |
hal_pm_enter_light_nor() / hal_pm_exit_light_nor() |
Light-nor 进入/退出 |
hal_pm_enter_light_pd() / hal_pm_exit_light_pd() |
Light-pd 进入/退出及 V0/V1 唤醒配合 |
hal_pm_enter_retention() / hal_pm_exit_retention() |
RETENTION 进入/退出 |
hal_pm_enter_deep_sleep() / hal_pm_exit_deep_sleep() |
DEEP_SLEEP 进入/退出 |
hal_pm_enter_hibernate() / hal_pm_exit_hibernate() |
HIBERNATE 进入/退出 |
MID 依赖的 SDK 组件:
hal_pm.h:模式、唤醒源、能力结构和每模式 enter/exit 接口。hal_aon.h/hal_aon.c:AON 模式、复位/隔离/断电、PSRAM retention、握手区及 retained resume entry。im_error.h:统一error_code_t错误码。- OS mutex:
im_pm.c使用递归互斥锁保护事务状态和客户端回调。 - V1 上下文支持:
pm_context.S提供pm_v1_ctx_save()/pm_v1_ctx_restore(),用于 LIGHT-PD/RETENTION 后从 retained resume entry 返回原执行点。
MID 不负责:
- 具体 AON/CPM 寄存器写入顺序、PSRAM 控制器初始化或 TNPU/模块 SRAM 上电时序;这些由 HAL PM 和 AON HAL 完成。
- 板级唤醒源配置、pending 位清理、GPIO 路由和 PMIC 控制;这些由应用/板级路径负责。
- 执行 WFI、保存 V1 CPU 上下文或驱动 V0/V1 握手;MID 只提供模式请求和恢复事务管理。
- 实现
IM_PM_MODE_POWER_OFF;该模式在当前 G32S10 HAL 中始终不支持。
8. 构建配置与文件组织
8.1 Kconfig
MID PM 配置项定义在 code/middleware/pm/Kconfig:
config MIDDLEWARE_PM
bool "Power-management middleware"
default n
depends on SOC_SERIES_G32S10
select DRIVER_PM
CONFIG_MIDDLEWARE_PM=y 会同时选择 CONFIG_DRIVER_PM=y。V0-only 断电模式还要求 CONFIG_G32S10_V0_RUN_IN_SRAM_ONLY=y;未满足时 V0 的能力快照为 0。
8.2 文件职责
code/middleware/pm/
include/
im_pm.h
pm_context.h
src/
im_pm.c
pm_context.S
code/include/drivers/g32s10/pm/
hal_pm.h
code/drivers/g32s10/pm/
hal_pm.c
retention_stub.S
retention_stub.c
retention_stub.h
code/middleware/pm/example/
CMakeLists.txt
README.md
build.sh
pm_example_defconfig
pm_example_slt_v0_defconfig
pm_example_slt_v1_defconfig
firmware/
g32s10_v0_pm_slt.bin
main/
CMakeLists.txt
main.c
v0_main.c
| 文件 | 说明 |
|---|---|
im_pm.h |
MID PM 公开模式、状态、客户端、配置和 API 声明 |
im_pm.c |
PM 事务管理、客户端回调编排、状态机、恢复记录和 HAL 调用 |
pm_context.h |
PM V1 恢复路径使用的 pm_v1_ctx_save() / pm_v1_ctx_restore() 上下文辅助接口,不是普通业务设备客户端 API |
pm_context.S |
PM V1 恢复路径的上下文保存和恢复汇编实现 |
hal_pm.h |
HAL PM 模式、唤醒源、能力和进入/退出 API 声明 |
hal_pm.c |
AON/CPM 低功耗模式硬件进入、退出和状态检查 |
retention_stub.S / retention_stub.c |
V0 retained resume 和低功耗启动辅助实现 |
example/ |
V0/V1 PM 示例、SLT defconfig、预置 V0 SLT 镜像和两段式构建脚本 |
code/middleware/pm/CMakeLists.txt 在 CONFIG_MIDDLEWARE_PM 生效时编译 src/im_pm.c;V1 构建还编译 src/pm_context.S,V0 构建注册独立的 im_pm 组件。
9. 资源模型与公开类型
9.1 模式与能力
typedef enum {
IM_PM_MODE_ACTIVE = 0,
IM_PM_MODE_IDLE,
IM_PM_MODE_LIGHT_NOR,
IM_PM_MODE_LIGHT_PD,
IM_PM_MODE_RETENTION,
IM_PM_MODE_DEEP_SLEEP,
IM_PM_MODE_HIBERNATE,
IM_PM_MODE_POWER_OFF,
IM_PM_MODE_COUNT,
} im_pm_mode_t;
| 枚举 | 含义 |
|---|---|
IM_PM_MODE_ACTIVE |
正常运行状态,不能作为请求目标 |
IM_PM_MODE_IDLE |
停止 V1 CPU 时钟;任意 V1 可路由中断可唤醒 |
IM_PM_MODE_LIGHT_NOR |
停止 HP 时钟,保留供电;LP/AON 继续时钟化 |
IM_PM_MODE_LIGHT_PD |
关闭 CPU_V1/TNPU 并停止 HP 时钟;需保存 V1 上下文 |
IM_PM_MODE_RETENTION |
关闭 HP,保留 PSRAM 数据和 V1 恢复上下文 |
IM_PM_MODE_DEEP_SLEEP |
关闭 HP,不保留 V1 执行上下文 |
IM_PM_MODE_HIBERNATE |
DEEP_SLEEP 加 LP 时钟门控,仅保留 AON 休眠状态机 |
IM_PM_MODE_POWER_OFF |
板级/PMIC 掉电目标,G32S10 PM HAL 不支持 |
IM_PM_MODE_COUNT |
模式数量,不是合法请求目标 |
模式能力由 hal_pm_get_capabilities() 按构建配置决定,im_pm_get_capabilities() 返回初始化时保存的同一份快照:
| 核 / 构建配置 | supported_mode_mask |
|---|---|
V1(CONFIG_BUILD_CORE_V1) |
IDLE、LIGHT_NOR、LIGHT_PD |
V0(CONFIG_BUILD_CORE_V0 且 CONFIG_G32S10_V0_RUN_IN_SRAM_ONLY=y) |
LIGHT_NOR、LIGHT_PD、RETENTION、DEEP_SLEEP、HIBERNATE |
| V0 未运行在 SRAM-only 模式 | 0,不支持任何低功耗模式 |
说明:
POWER_OFF在 G32S10 上始终不支持,power_off_supported恒为false。hal_pm_get_capabilities()只读取编译配置,不要求先调用hal_pm_init()。im_pm_get_capabilities()返回初始化时保存的快照;初始化前该快照为全零。- 客户端使用
IM_PM_MODE_MASK(mode)表达自己支持的模式,不能把ACTIVE或COUNT放入掩码。
9.2 MID 事务状态
typedef enum {
IM_PM_STATE_RESET = 0,
IM_PM_STATE_READY,
IM_PM_STATE_PREPARING,
IM_PM_STATE_SUSPENDING,
IM_PM_STATE_ARMED,
IM_PM_STATE_ENTERING,
IM_PM_STATE_SLEEPING,
IM_PM_STATE_WAKING,
IM_PM_STATE_RESUMING,
IM_PM_STATE_FAULT,
} im_pm_state_t;
typedef struct {
im_pm_state_t state;
im_pm_mode_t mode;
error_code_t fault;
} im_pm_status_t;
事务状态迁移:
RESET -> READY
READY -> PREPARING -> SUSPENDING -> ARMED -> ENTERING -> SLEEPING
SLEEPING -> WAKING -> RESUMING -> READY
失败路径 -> READY 或 FAULT
状态说明:
RESET:im_pm_init()之前或im_pm_deinit()成功之后。READY:可以接受新的im_pm_request(),也是唯一允许调用im_pm_deinit()的状态。PREPARING/SUSPENDING:正在按客户端链表顺序执行回调。ARMED:恢复记录已提交,即将调用 HAL 进入接口。ENTERING:HAL 进入成功后的瞬时状态。代码在同一临界区内立即将其改为SLEEPING,因此im_pm_get_status()观察不到ENTERING。SLEEPING:事务已提交,等待平台唤醒路径调用im_pm_resume()。WAKING/RESUMING:正在调用 HAL 退出接口和客户端恢复回调。FAULT:不可恢复的事务错误。当前没有公共 API 将状态从FAULT拉回READY,通常只能复位系统后重新初始化。
fault 保存最近一次事务错误。实现会在 im_pm_init() 开始时清零,并在初始化成功、恢复成功或 deinit 成功时置回 IM_OK;事务失败期间保存对应错误。im_pm_get_status() 在未初始化时返回 state=RESET、mode=ACTIVE、fault=IM_OK。
9.3 PM 客户端与回调
设备客户端通过 im_pm_client_t 和 im_pm_device_ops_t 注册:
typedef struct {
error_code_t (*prepare)(void *context, im_pm_mode_t mode);
error_code_t (*suspend)(void *context, im_pm_mode_t mode);
error_code_t (*resume_early)(void *context, im_pm_mode_t mode);
error_code_t (*resume)(void *context, im_pm_mode_t mode);
void (*complete)(void *context, im_pm_mode_t mode, error_code_t status);
} im_pm_device_ops_t;
typedef struct im_pm_client {
const char *name;
const im_pm_device_ops_t *ops;
void *context;
uint32_t supported_mode_mask;
const struct im_pm_client *next;
} im_pm_client_t;
客户端约束(im_pm_init() 逐项校验):
- 最多 16 个客户端。
client_count == 0时suspend_list必须为NULL;非零时链表长度必须与client_count完全一致。name、ops、ops->prepare、ops->suspend必须非空。supported_mode_mask不得包含ACTIVE、COUNT或超出范围的位,允许为0。suspend_list、客户端节点和回调表必须在im_pm_deinit()之前保持有效。prepare和suspend是必需回调;resume_early、resume、complete可省略。
回调顺序:
- 应用应按设备依赖关系静态定义
suspend_list;MID 只保证 prepare/suspend 正序和 resume 逆序,不自动推导消费者/提供者关系。 - prepare 和 suspend 按
suspend_list正序执行,只处理supported_mode_mask包含目标模式的客户端。 - 恢复时先按相反顺序对所有已 suspend 客户端调用
resume_early,再按相反顺序对resume_early成功的客户端调用resume。 resume_early失败的客户端跳过resume,但仍以该错误码调用complete;其余客户端继续恢复。- prepare 失败的客户端本身不调用
complete;此前 prepare 成功的客户端按链表正序调用complete(prepare_error)。 - suspend 失败时,已 suspend 的客户端按相反顺序恢复;恢复成功的客户端收到
complete(suspend_error)。随后包括失败客户端在内的所有已 prepare 客户端各调用一次complete。 - 所有回调都在 MID 的递归互斥锁内执行。回调中不能无限等待另一个线程调用
im_pm_*(),否则会死锁。
9.4 初始化配置
typedef struct {
const im_pm_client_t *suspend_list;
uint32_t client_count;
bool resume_from_retained_record;
} im_pm_config_t;
im_pm_config_default()将suspend_list置为NULL、client_count置为0、resume_from_retained_record置为false。resume_from_retained_record=true时,必须存在与当前镜像、当前 owner、当前客户端数量和当前模式能力匹配的SLEEPING恢复记录;否则im_pm_init()返回IM_ERR_IO并进入FAULT。- 客户端链表是静态链表,MID 不复制节点,也不接管节点内存。
- 同一时刻只允许一个活动 PM 事务;状态不是
READY时im_pm_request()返回IM_ERR_BUSY。
9.5 唤醒源请求配置
typedef enum {
HAL_PM_WAKE_NONE = 0,
HAL_PM_WAKE_V1_TIMER,
HAL_PM_WAKE_V0_TIMER,
HAL_PM_WAKE_LP_IRQ,
HAL_PM_WAKE_GPIO,
HAL_PM_WAKE_COUNT,
} hal_pm_wake_source_t;
typedef struct {
hal_pm_wake_source_t wake_source;
} hal_pm_request_config_t;
hal_pm_request_config_t只有wake_source一个字段。im_pm_request()的request_config可以为NULL,等价于HAL_PM_WAKE_NONE。- 唤醒源只是事务元数据,会写入恢复记录并原样传给 HAL;MID 和 HAL 都不配置实际唤醒源,也不清理挂起位,这些由应用/板级路径负责。
HAL_PM_WAKE_V1_TIMER只允许用于IM_PM_MODE_IDLE,其它模式返回IM_ERR_INVALID_PARAM。wake_source >= HAL_PM_WAKE_COUNT返回IM_ERR_INVALID_PARAM。
当前示例和已验证流程使用的唤醒源约定如下:
| MID 模式 | 典型唤醒源 | 说明 |
|---|---|---|
IM_PM_MODE_IDLE |
HAL_PM_WAKE_V1_TIMER 或任意 V1 可路由中断 |
只有 IDLE 允许 V1 timer 元数据 |
IM_PM_MODE_LIGHT_NOR |
HAL_PM_WAKE_V0_TIMER / HAL_PM_WAKE_LP_IRQ |
进入后 HP 时钟关闭,需 LP/AON 可达事件 |
IM_PM_MODE_LIGHT_PD |
HAL_PM_WAKE_NONE 或 LP/AON 事件 |
V0 控制示例使用主动恢复,不依赖一次性 timer |
IM_PM_MODE_RETENTION |
HAL_PM_WAKE_V0_TIMER / HAL_PM_WAKE_LP_IRQ |
V0 在 LP 域保持运行 |
IM_PM_MODE_DEEP_SLEEP |
HAL_PM_WAKE_V0_TIMER / HAL_PM_WAKE_LP_IRQ |
V0 负责 HP 上电与 V1 冷启动配合 |
IM_PM_MODE_HIBERNATE |
HAL_PM_WAKE_GPIO |
当前示例使用 GPIOD 下降沿唤醒 |
唤醒源字段仍只是元数据;上表不表示 MID 会替应用配置中断、timer 或 GPIO。
9.6 模式对象与生命周期
MID 没有需要调用方逐实例分配的“PM 设备对象”;一个核上的 PM 中间件由静态全局状态维护。调用方生命周期应满足:
- 保持客户端链表、节点和回调表有效。
- 调用
im_pm_config_default()和im_pm_init()。 - 发起一次
im_pm_request(),等待硬件进入目标模式。 - 平台唤醒路径完成硬件退出或恢复入口后,调用一次
im_pm_resume()。 - 需要释放时,仅在
READY状态调用im_pm_deinit()。
同一事务只能恢复一次;重复 im_pm_resume() 或未成功请求就恢复都会返回 IM_ERR_BUSY。