R52 和 M7 双核独立 OS 的休眠设计方案
R52 和 M7 双核独立 OS 的休眠设计方案
1. 整体架构认知
S32K5 的电源域(Power Domain)划分决定了休眠策略的根本约束:
| 电源域 | 包含内容 | 可独立开关 |
|---|---|---|
| PD0(Always-On) | PMC、RGM、WKPU、MC_PCU、FRO、SIRC、384KB SRAM 等 | 否(始终供电) |
| PD1(低功耗引擎) | CM4、DMA、ADC、LPUART、LPSPI、FTM、STM 等 | 是(可独立于 PD2) |
| PD2(全性能域) | CM7、R52、MRAM、HSE2 + 所有其他外设 | 是(可独立于 PD1) |
关键约束:CM7 和 R52 都位于 PD2 中,这意味着——无法单独让 CM7 休眠而 R52 继续运行,反之亦然。PD2 要么全上,要么全下。
2. 支持的电源模式及各核心状态
| 电源模式 | 供电域 | R52 | M7 | CM4(LPE) | HSE2 |
|---|---|---|---|---|---|
| RUN | PD2+PD1+PD0 | Run/Wait | Run/Wait | Run/Wait/Stop1/Stop2 | Run |
| LPRUN | PD1+PD0 | Off | Off | Run/Wait/Stop1/Stop2 | Off |
| STANDBY | PD0 | Off | Off | Off | Off |
也就是说,R52 和 M7 的休眠是绑定的,它们必须一起进入 LPRUN/STANDBY 或一起唤醒。
注 1:CM4 在 RUN 和 LPRUN 下均为
Run / Wait / Stop1 / Stop2,其中 Stop1 与 Stop2 是两种不同的低功耗状态,配置时不可合并处理。注 2(LPRUN 时钟):LPRUN/Standby 下 PLL 不可用,可用时钟仅为 FXOSC、SXOSC、SIRC、FIRC 及其派生。FIRC 在这些模式下处于活动状态但不可配置(资源仅 HSE2 可访问)。因此若要走 Run → LPRUN → Standby 路径,FIRC 必须在 Run 模式下配置好,因为 LPRUN 中 HSE2 已不可用。
3. 推荐的休眠设计方案
方案一:LPRUN 模式(推荐,最常用)
当 M7 和 R52 都无事可做时,两者都执行 WFI,PD2 断电,仅保留 LPE(CM4)在 PD1 中运行。
正常 RUN(M7+R52 全速运行)
|
v
M7 OS 和 R52 OS 各自完成关断前准备
|
v
Requestor Core 通过 MU 中断通知 CM4,CM4 停止使用 PD2 外设后确认
|
v
M7 和 R52 各自执行 WFI
|
v
Requestor Core 轮询 MC_ME 中对方 WFI 状态
|
v
PCFS ramp-down(降频到初始频率)
|
v
写 CTL_KEY 密钥序列,再通过 MC_ME[COREx_PCONF] 关闭 M7 和 R52 的时钟
|
v
关停 PD2 外设的时钟(写 CTL_KEY + MC_ME[COFB_CLKEN])
|
v
切换时钟源到 FRO,关闭 PLL
|
v
Pad Keeping 配置(可选)
|
v
停止 HSE2 服务(可选)
|
v
PMIC handshake 配置(使用外部 PMIC 时必需)
|
v
执行 DSB + ISB 屏障,确保无挂起指令
|
v
写 CTL_KEY + MC_RGM 的 MODE_CONF[LPRUN] 请求进入 LPRUN
--------------------------------
LPRUN 模式(仅 CM4 运行在 PD1)
方案二:STANDBY 模式(最低功耗)
正常 RUN(M7+R52)
|
v
(可选先进入 LPRUN)
|
v
CM4 接管关断流程(作为 Requestor Core)
|
v
关停 PD1 外设(写 CTL_KEY + MC_ME[COFB_CLKEN])
|
v
配置 WKUP 唤醒源
|
v
Pad Keeping 配置
|
v
PMIC handshake 配置(使用外部 PMIC 时必需)
|
v
执行 DSB + ISB 屏障
|
v
写 CTL_KEY + MC_RGM 的 MODE_CONF[STANDBY] 请求进入 STANDBY
--------------------------------
STANDBY(仅 PD0 供电,384KB RAM 保持)
4. 多核休眠协调流程(关键)
S32K5 的 MC_ME 模块提供了 WFI 状态监测机制,用于多核协调。
与 MCU 驱动的对应关系:NXP S32K5 MCU 驱动(UM85MCUASRR23-11)将整个 Standby 进入过程划分为 SW1–SW4 四个软件阶段,由
Mcu_SetMode/Mcu_InitClock驱动,下表已按此阶段组织。实际项目中这些寄存器级操作由 MCU 驱动内部完成,应用层只需调用 API。
阶段 名称 驱动 API 本文对应步骤 SW1 Peripheral Shutdown Mcu_SetMode(外设集)Step 4.1–4.3 SW2 Application Core Shutdown 应用核 Mcu_SetMode(CORE_STANDBY);主核Mcu_SetMode(McuCoreUnderMcuControl勾选 +McuCoreClockEnable取消)Step 4.2–4.3 SW3 Flash 低功耗握手 + PMC_LASTMILE 关闭 Mcu_InitClock、Mcu_SetMode(SOC_PREPARE_STANDBY)Step 4.6 SW4 Main Core Shutdown Mcu_SetMode(SOC_STANDBY),McuMainCoreSelect选主核Step 4.12 相关 Tresos/MCAL 配置参数:
McuPowerMode(CORE_STANDBY/SOC_PREPARE_STANDBY/SOC_STANDBY)、McuCoreUnderMcuControl、McuCoreClockEnable、McuMainCoreSelect。
Step 1:各 OS 各自完成睡眠前准备
| M7 OS 要做的事 | R52 OS 要做的事 |
|---|---|
| 关闭非必要中断源 | 关闭非必要中断源 |
| 保存上下文(保存到 PD0 SRAM) | 保存上下文(保存到 PD0 SRAM) |
| 停止 M7 上的 HSE2 服务请求 | 停止 R52 上的 HSE2 服务请求 |
| 设置唤醒中断 | 设置唤醒中断 |
| 通知 R52 OS 准备休眠(MU 中断) | 确认并回复 M7 |
| 执行 WFI | 执行 WFI |
此外,Requestor Core 必须通过 MU 中断通知 CM4(LPE):即使 PD1 在 LPRUN 下保持供电,CM4 仍可能正在访问 PD2 域的资源(如 FLEXCAN、SENT 等位于 PD2 的外设)。Requestor Core 需通知 CM4 停止使用这些 PD2 外设,CM4 确认后方可继续关断流程。
Step 2:Requestor Core 检查 WFI 状态
由任一核心(M7 或 R52)担任 Requestor Core,轮询检查各核心的 WFI 状态。
⚠️ 关键:WFI 状态寄存器分属三个不同的 MC_ME 分区,各核心的寄存器不可混用。
| 核心 | WFI 状态寄存器 | 所属分区 |
|---|---|---|
| Cortex-M7_0 | MC_ME.PRTN0_CORE0_STAT[WFI] |
SoC MC_ME |
| Cortex-M7_1 | MC_ME.PRTN0_CORE2_STAT[WFI] |
SoC MC_ME |
| Cortex-M7_2 | MC_ME.PRTN0_CORE3_STAT[WFI] |
SoC MC_ME |
| Cortex-M7_3 | MC_ME.PRTN0_CORE4_STAT[WFI] |
SoC MC_ME |
| Cortex-R52_0 | CPE_MC_ME.PRTN0_CORE0_STAT[WFI] |
CPE MC_ME |
| Cortex-R52_1 | CPE_MC_ME.PRTN0_CORE1_STAT[WFI] |
CPE MC_ME |
| Cortex-M4 (LPE) | LPE_MC_ME.PRTN0_CORE0_STAT[WFI] |
LPE MC_ME |
注意 M7 的编号不连续:M7_0 对应
CORE0,M7_1 对应CORE2,M7_2 对应CORE3,M7_3 对应CORE4。CORE1不属于 M7,索引时不可按连续数组处理。
因此,当 R52 作为 Requestor Core 时,读取 M7 的 WFI 状态需访问 SoC MC_ME 分区(MC_ME.PRTN0_CORE0_STAT 等),而非 CPE_MC_ME。
Step 3:时钟降频、关断与复位
1. 设置时钟到初始频率,完成 PCFS ramp-down(降频)
2. 确认对方核心 WFI 已置位(读上表对应寄存器)
3. 写 CTL_KEY 密钥序列(0x5AF0,然后 0xA50F)
4. 通过 MC_ME[COREn_PCONF][CCE] 关断目标核心的时钟
5. 确认 MC_ME[COREn_STAT][CCS] 时钟已停止(CCS=0 表示时钟 inactive)
6. 通过 MC_RGM_PRST 断言核心复位
7. 读 MC_RGM_PSTAT 确认复位已生效 -> 核心正式关断
Step 4:关停 PD2 外设与请求模式切换
1. 写 CTL_KEY 密钥序列(0x5AF0,然后 0xA50F)
2. 关停 PD2 外设时钟:MC_ME[PRTNn_COFB_CLKEN][REQnz] = 0
3. 写 PRTNn_PUPD 并轮询,读 PRTNn_COFB_STAT[BLOCKnz] 确认时钟已关
4. 切换系统时钟到 FIRC,关闭 PLL
- Standby 入口**必须切到 FIRC**(PLLDIG 在 Standby 下不可用)
- 若 2.5V 供电可用且已配置 PMC.CONFIG[LPM25EN],可改用 FXOSC
- 所有时钟源均可选关闭(含 FIRC),全关即 no-clock 最低功耗模式
5. 配置 Pad Keeping(PD2 引脚由 WKPU.GPIO_QUAL[PD2_PD0] 统一控制)
6. **SW3:Flash 低功耗握手与 PMC_LASTMILE 稳压器关闭**
a. 挂起或等待进行中的 Flash 高压操作结束(否则 Flash 编程中途掉电导致非确定性行为)
b. 切换系统时钟到 FIRC 并关闭 PLL
c. 配置 SoC 进入 Standby 预备态
7. 停止 HSE2 服务(可选,等待进行中的服务完成)
8. 配置 WKPU 唤醒源(Standby 入口必做;Standby 下无活动核心)
9. PMIC handshake 配置(使用外部 PMIC 供电时必需)
10. **一次只关闭一个 CPE 分区**(CPE_0 与 CPE_1 同时禁用会导致 HardFault)
11. 执行 DSB + ISB 屏障,确保无挂起指令
12. 写 CTL_KEY 密钥序列 + MC_RGM 的 MODE_CONF[LPRUN] 或 MODE_CONF[STANDBY]
-> 启动硬件模式转换
⚠️ CPE 分区关断硬约束:同时禁用
PARTITION_CPE_0_INDEX和PARTITION_CPE_1_INDEX会关闭整个 CPE 系统,导致后续禁用 CPE_0 时触发 HardFault。必须一次只关一个 CPE 分区。⚠️ CPE_LLC 注意:对 CPE_LLC0/CPE_LLC1 选择 PowerOffState 会导致 HardFault(驱动仍会访问已断电的分区),应选 PowerOnState。
5. 唤醒流程
从 LPRUN 唤醒 M7+R52
唤醒主体由 LPE(CM4) 执行:
外部/内部唤醒事件触发
|
v
WKPU 检测到唤醒源 -> 中断 LPE CM4
|
v
CM4 执行 PMIC handshake(断言 EXTWAKE,见下表)
|
v
PD2 上电(连接 PD1-PD2 的 distributed switch)
|
v
PD2 发生 destructive reset
|
v
HSE2 BootROM -> sBAF 完整性检查 -> HSE2_FW 使能 PD2 应用核
|
v
M7 和 R52 各自的 OS 恢复上下文
|
v
恢复到 RUN 模式
注意:从 LPRUN 唤醒 M7+R52 时,PD2 上电后 M7 和 R52 会经历 destructive reset(见 Ch58 Table 308:LPRUN → RUN 时 PD2 发生 destructive reset,PD1/PD0 保持),必须通过启动链重新启动。因此两个 OS 的上下文保存至关重要。
启动链说明(S32K5 无 IVT 概念):硬件复位完成后,唯一先运行的是 HSE2 上的 ZenV 核,经 BootROM → sBAF(Secure Boot Assist Firmware)→ HSE2_FW 由 HSE2_FW 使能 PD2 中的应用核。S32K5 不使用 IVT(Image Vector Table)机制。
唤醒导致的复位域范围
| 模式转换 | PD2 | PD1 | PD0 |
|---|---|---|---|
| Standby → LPRUN | 保持 OFF | destructive reset | 保持活动 |
| Standby → RUN | destructive reset | destructive reset | 保持活动 |
| LPRUN → RUN | destructive reset | 保持活动 | 保持活动 |
省电关键路径:Standby → LPRUN 转换时 PD2 保持 OFF,仅 PD1 上电。这是唤醒后 CM4 先跑起来、PD2 应用核稍后才启动的分级上电路径。
唤醒源支持
外部唤醒源
| 唤醒源类型 | 来源 | 说明 |
|---|---|---|
| 外部 GPIO | 最少 60 个 WKPU 引脚(WKPU[0]-WKPU[59]) | 实际引脚需查 IOMUX 表;每个源均带独立毛刺滤波器 |
内部唤醒源(共 8 个,依据 Ch57 Table 299)
| # | 内部唤醒源 | 说明 |
|---|---|---|
| 1 | LPE_SWT0 | 看门狗定时器 |
| 2 | (NOR (CMPn Round Robin Mode)) AND (LPE_RTC_API Timeout) | 比较器轮询模式与 RTC 超时的组合逻辑源 |
| 3 | LPE_RTC_API Timeout | RTC 唤醒计数器溢出或超时 |
| 4 | LPE_CMP0 Async | 比较器 0 异步边沿 |
| 5 | LPE_CMP1 Async | 比较器 1 异步边沿 |
| 6 | LPE_CMP2 Async | 比较器 2 异步边沿(S32K511 不支持) |
| 7 | LPE_PIT_RTI | PIT 实时中断 |
| 8 | LPE_LCU | 逻辑控制单元 |
⚠️ 关键约束:内部唤醒源仅支持正极性,不可配置为下降沿触发。这是休眠后无法唤醒的最常见原因。
模式关联:每个唤醒事件都可通过软件配置关联到不同的模式转换(Standby→Run 或 Standby→LPRUN),并非固定支持所有模式。
NMI 不支持从 Standby 唤醒。
多源同时到达时的仲裁
- 第一个到达 MCU 的唤醒源决定整个模式转换序列,该序列会执行到底,除非发生 POR / functional / destructive reset
- 两个及以上唤醒源同时采样且指示不同的模式转换时,Standby → Run 优先级最高
- 所有唤醒事件无论设备当前处于何种模式、也无论是否正在进行模式转换,都会在 WKPU 中置位对应标志
6. STANDBY RAM 使用建议
PD0 域有 384KB 的 SRAM 可供数据保持(SRAM UPPER PD0 = 256KB,SRAM LOWER PD0 = 128KB),建议在两个 OS 的休眠方案中这样分配:
| 区域 | 用途 | 建议容量 |
|---|---|---|
| M7 保留区 | M7 OS 上下文、关键变量 | ~192KB |
| R52 保留区 | R52 OS 上下文、关键变量 | ~128KB |
| 共享保留区 | 核间通信标志、唤醒原因 | ~64KB |
注:上述 192/128/64KB 的切分是建议值,非硬件约束。实际分配需按两个 OS 的实测上下文大小调整,且总容量不得超过 384KB。PD0 SRAM 在低功耗模式下由保持电压供电以维持数据。
7. 推荐实施总结
| 事项 | 建议 |
|---|---|
| 目标模式 | LPRUN(CM4 保持运行,M7+R52 休眠) |
| 协调机制 | Requestor Core 通过各分区 MC_ME 的 WFI 状态位确认双方就绪(M7 查 MC_ME,R52 查 CPE_MC_ME,CM4 查 LPE_MC_ME) |
| 核间通信 | 用 MU(Message Unit) 通知其他核心启动关断流程;共享 PD0 SRAM 用于握手数据 |
| CM4 通知 | Requestor Core 必须通知 CM4 停止使用 PD2 外设并确认 |
| 上下文保存 | 每个 OS 将上下文保存到 PD0 SRAM(384KB) |
| 时钟降频 | 关钟前先完成 PCFS ramp-down;LPRUN/Standby 下 FIRC 须在 Run 模式预配置 |
| Flash 低功耗 | Standby 前须等待 Flash 高压操作结束并关闭 PMC_LASTMILE,否则 Flash 阵列仍耗电 |
| 分区关断顺序 | 一次只关一个 CPE 分区;CPE_LLC0/1 须选 PowerOnState,否则 HardFault |
| 寄存器写保护 | 所有受控寄存器写入前须执行 CTL_KEY 密钥序列(0x5AF0 / 0xA50F) |
| 模式切换屏障 | 写 MODE_CONF 前须执行 DSB + ISB |
| 唤醒源 | 依 RM Table 299 配置 8 个内部源之一或 WKPU 外部引脚;内部源仅支持正极性 |
| 中断责任 | 请求模式切换前必须屏蔽所有中断;EcuM 负责确保无唤醒中断丢失(MCU 驱动无法感知) |
| PLL 恢复 | 唤醒后需显式调用 Mcu_DistributePllClock 恢复 PLL 时钟(切 PLL 动作不由 Mcu_InitClock 完成) |
| 唤醒源判定 | 用 Mcu_GetResetReason 判断唤醒原因 |
| PMIC 协同 | 推荐 FS25 SBC(专为 S32K5/S32J 设计,ASIL D),通过 PGOOD + EXTWAKE(1)/(2) 完成 handshake |
注:以上第 4 节中大量寄存器级步骤(PCFS ramp-down、CTL_KEY 密钥序列、
COREn_PCONF[CCE]、COFB_CLKEN[REQnz]、MODE_CONF、DSB+ISB)在实际项目中由 MCU 驱动内部完成,应用层不应直接操作这些寄存器。详见MCAL_API_MAPPING.md。
PMIC Handshake 信号语义
S32K5 通过 PGOOD(输入)与 EXTWAKE(1)/EXTWAKE(2)(输出)与 PMIC/SBC 握手,最多使用 4 个 GPIO。EXTWAKE 的极性可通过 GPR_0 寄存器配置,映射通过 SIUL2 的 MSCR 配置。
| 设备模式转换 | EXTWAKE(1) | EXTWAKE(2) |
|---|---|---|
| Run → LPRUN | 信号解除断言 | 信号解除断言 |
| Run → Standby | 信号解除断言 | 信号解除断言 |
| LPRUN → Standby | 信号解除断言 | 信号解除断言 |
| LPRUN → Run | 信号断言 | 无变化 |
| Standby → Run | 信号断言 | 无变化 |
| Standby → LPRUN | 无变化 | 信号断言 |
PMIC 侧仅响应 EXTWAKE 的断言(assertion),解除断言应被忽略。
EXTWAKE 断言后 POR WDOG 被触发:若 PGOOD 在配置时间内未拉高,POR WDOG 将对芯片发出复位。
Run → Standby 需注意 PGOOD 毛刺:切换时可能检测到非预期复位状态。规避步骤为:① 置
PMC.CONFIG[PGOODMASK]暂时屏蔽 PGOOD;② 将 PMIC 配置进入 LPE 模式(带延时)。此两步必须受中断保护,确保序列不会在时间上被拆开。