本文基于 S32K3xx系列芯片和S32 Design Studio for S32 Platform开发平台,介绍 电源管理基于 MCAL层的开发。
1. Abbreviation:
PMC Power Management Controller
LVR Low Voltage Reset
LVD Low voltage detect
HVD High voltage detect
WFI Wait for interrupt
FPM Full Performance mode
LPM Low Performance mode
PMIC Power management integrated chip
LMR Last Mile Regulator
POR Power-on reset(safe state)
HSE_B Hardware Security Engine
WKPU Wake Up Unit
RTI Real Time Interrupt
NMI Non-maskable interrupt
NVM non-volatile memory
PCU Power Control Unit
COFB Collection of functional blocks also referred as number of peripherals
LBIST Logic built-in self-test
ICU Input Capture Unit
MSCR Multiplexed Signal Configuration Register
Pad keeping: 如果使能,可以在standby模式下保持IO的配置功能。
The last-mile regulator is the full-performance regulator
Partition: Subdivision of the Flash Module. Used for read-while-write operation, where addresses in the partition being written may not be read. Partitions is always equal to 1 block, and contains multiple sectors.
MC_ME: Initiates entry into Low-Power mode
MC_PCU: Controls entry into and exit from Low-Power mode
PMC: Regulates and monitors power supplies of the Run and the Standby domains
MC_RGM: Ensures a clean state and Run domain sanity by controlling the reset sequence
2. 电源模式
S32K3xx仅有两种电源模式,RUN模式和STANDBY模式。
S32K1xx之所以有Run、Sleep、Deep Sleep三种电源状态,是因为S32k1xx使用的ARM Cortex M4的内核,其内核就规定了这三种电源模式:
Run:正常工作模式,允许PLL 倍频,内核、系统、总线频率运行在芯片的最高频率,功耗可达数十mA–上百mA
Sleep:普通睡眠模式,大部分外设停止工作,内核、系统和总线部分关闭或降频工作,功耗可降至几个mA
Deep Sleep:深度睡眠,几乎所有外设停止工作、NVIC停止工作,内核、系统和总线关闭,CPU内核停止工作,仅AWIC(异步唤醒中断控制器)这个用于唤醒的外设保持功能,功耗仅几十个uA。
ARM cortex M系列内核进入低功耗模式是通过CPU执行汇编指令WFI(Wait for Interrupt)或者WFE(Wait for Event)完成。
3. Standby mode entry sequence
The standby mode entry sequence includes these three phases of operation:
- standby mode enty configuration phase or software standby mode entry sequence
- standby mode entry handshake phase or hardware standby mode entry sequence
- standby mode entry or PMC standby mode entry
3.1 he software standby mode entry sequence
The software standby mode entry sequence sonsits of four steps:
SW1: Module shutdown process
SW2: Application core shutdown process
SW3: Flash memory low-power handshake and PMC last-mile regulator control
SW4: Main core shutdown process
3.2 The hardware standby mode entry sequence
The hardware standby mode entry sequence consists of handshaking between MC_PCU and MC_ME occuring after software standby mode entry sequence completes. The FSM(Finite state machine) in MC_PCU performs these steps automatically and does not require your intervention.
3.3 The PMC standbymode entry sequence
The PMC standbymode entry sequence consists of these phases:
- Standby mode entry acknowledgment and initiation of an internal low-power process on receiving standby mode entry requst.
- Disabling of the boot regulator within the PMC low-power process.
- Disabling of the V25 regulator and the FPM LVR(Low voltage reset) monitors.
- Disabling of the V25 regulator(oscillator and flash memory supply) and the LPM monitor, unless it is enabled during standby mode.
- Disabling of the VDD_HV_B LPM monitors.
4. EB配置
4.1 MCU配置
4.1.1 run模式与standby模式配置
在operating mode中可以看到有多种可选模式:RUN、CORE_STANDBY、SOC_STANDBY、SOC_PREPARE_STANDBY、STANDBY等,目前只有SOC_STANDBY可用,且此模式就是真正的standby模式。
在run模式和standby模式中的peripheral中,都需要使能WKPU外设模块,以及用到的替他模块
4.1.2 时钟配置
如图所示,在MCU module中的McuClockSettingConfig中添加一个时钟配置。
其中时钟0为正常运行时的时钟,时钟1为standby模式下的时钟。每个index中有多个选项需要配置,如下图所示
上图中时钟相关配置是与LLD中的时钟树一一对应的。如图所示:
也就是说,对于正常模式,我们使用FXOSC,通过PLL倍频后,到SCS_CLK,然后分到各种外设和core的时钟总线上,相应的对应EB中的McuCgm0ClockMux0~11。Standby模式同理。
一般来说,对时钟的配置一般关心如下方面:
- 时钟源的选择(FXOSC/SXOSC/PLL/FIRC/SIRC)
- 合理的分频系数设置,保证各外设工作在适合的频率。
EB中
- McuCgm0ClockMux0对应CORE_CLK、AIPS_PLAT_CLK、AIPS_SLOW_CLK、HSE_CLK、QSPI_MEM_CLK的时钟配置
- McuCgm0ClockMux1对应STM0_CLK的时钟配置
- McuCgm0ClockMux2对应STM1_CLK的时钟配置
…
…
PLL模块:
上述标注的参数与LLD中的时钟树一一对应
- RDIV为输入时钟预分频器,比如外部晶振16M,图示中RDIV为2,即时钟为8M
- MFI为倍频系数,图中MFI为120,经过MFI后, 时钟为960M
- OVDIV2是与RDIV相对应的一个后置的分频器,图中为1,即时钟仍然为960M
- PHI0 Divider是PHI0的一个独立分频器,分频的实际值位填入的值加1,图中为5,实际分频系数为6,即160M
- PHI1 Divider是PHI1的一个独立分频器,分频的实际值位填入的值加1,图中为3,实际分频系数为4,即240M
三个主要的时钟节点如图所示:
4.2 Platform配置
于外部引脚唤醒源WKPU[0]–WKPU[59],除了作为唤醒源以外,同时还可用WKPU的功能当做普通引脚中断使用。若要实现这个功能,就需要进行下面的中断配置,若作为唤醒源,那么不需要下面的操作。(配置wakeup功能的同时,在正常模式下,可用作GPIO中断)
使能WKUP的中断
配置中断处理函数:
4.3 唤醒源配置
唤醒源主要通过ICU模块来配置,但需要注意的是ICU模块对外依赖多个模块,包括但不限于Port、Mcl、Mcu、EcuM等,根据实际需求添加相应的模块,完整依赖如下所示。建议全部添加,否则编译的时候容易报错。
分类:
4.3.1 Port配置
PORT配置主要是引脚的硬件属性配置。
4.3.1.1 PortContainer配置
PortPin Mscr是引脚的唯一编号,PortPin Mscr参数可通过两种方式获得:
1.查表,数据手册的表格中给出了对应的参数。如PTD14为110
2.通过公式计算
如下图所示,每个port被分为L和H两部分,L表示0-15,H表示16-31。每个port的L和H对应着相应index。
如PTD14,对应index为6,用6*16+14=110.
本质上,引脚计算的原理是一个PORT对应32个pin,因此我们可以这样计算:
A – 0
B – 1
C – 2
以此类推:
如计算PTC25, 则直接用 2 * 32 + 25 = 89
4.3.1.3 UntouchedIMCR配置
对于在原有工程的基础上,新添加port模块需要特别注意。将调试器用到的引脚添加到其中,否则代码在初始化过程中会把所有不用的引脚初始化一遍,即我们的调试引脚会被初始化为非调试功能,导致调试报错。
添加port模块时进行如下选择会自动生成UntouchedIMCR
若添加port时忘记上述操作,后续手动添加如下:
图中的4个引脚均为PE调试引脚
如果这个模块中不添加引脚,那么调试代码执行到如下模块后就会出错:
4.3.2 Icu配置
4.3.2.1 ICUWkpu配置
在Icu中进入IcuWkpu模块,添加一个唤醒源的container:
在添加的container中加入具体的唤醒通道,并配置通道号、是否使能滤波和上拉。
通道号配置注意:
对于外部中断引脚的唤醒源,Wkpu Channel号需要在唤醒源号上加4.
原因:
在60个外部引脚唤醒源之前还有四个特殊的唤醒源,因此0-59的外部引脚唤醒源对应的是4-63的唤醒通道。
例子:
我们用PTB19做为唤醒源,可以看到WKPU号为38,实际填入Wkpu Channel的号为42.
4.3.2.2 IcuChannel配置
Icu通道的配置,包括了唤醒源通道(Wkpu)、外部中断引脚通道(Suil2)、eMios通道、低功耗比较器通道(LpCmp)等。如图,仅添加了一个唤醒通道。
在通道中需要选择通道的依赖、检测方式等,如下所示:
我们可以看到在ICUSignalEdgeDetection的第二个参数为回调函数配置,作为低功耗唤醒中断,唤醒后代码从头开始执行,这个回调函数其实没有用的,但是为什么还会设置回调函数呢?
原因在RTD_ICU_UM手册中:
唤醒中断在run模式下为普通外部中断,唤醒回调函数在这种情况下使用。
4.3.2.3 IcuHwInterruptConfigList配置
可以看到,我们在使用Wkpu功能的时候,没有配置Icu的硬件中断通道。
为什么不需要配置:
因为Wkpu等一些特殊功能时默认路由的,在硬件上是直接选通的。
例子:
以PTA1为例
如图所示,可以看到ADC0_S9、CMP1_IN1、WKPU[5]功能选择寄存器是 - 的状态,即默认选通的。
同时通过S32Ds引脚配置也可以看出来,在这三个模块后面均有:routed by default.
相反的,哪些中断模块需要在IcuHwInterruptConfigList中添加就不言而喻了,比如我们常用的外部引脚中断就需要。
对于这些routed by default功能模块,中断也不需要使能也可以正常使用。
特别的,在Platform章节提到的将WKPU功能当做普通中断使用时,在这儿配置硬件通道就必不可少,并且还需要使能中断才行。
当然,ICU的后续操作都要配置好,中断功能才能实现。(当做中断使用后,不具有唤醒功能)
4.3.3 EcuM配置
4.3.3.1 EcuMSleepMode配置
代码中EcuMSleepModeId没有被使用
EcuMSleepModeSuspend没有修改代码
4.3.3.2 EcuMWakeupSource配置
EcuMWakeupSourceId没有对生成的代码做任何修改。
EcuMWakeupSourcePolling没有修改代码
为什么要配置:
Icu对这个模块的Cfg.c和cfg.h文件有依赖,不配置编译不能通过。但是实际没有使用,因为这个不属于Mcal层,而是属于Autosar这一层的模块(偏应用层),我们暂时用不着。
EcuM简介:
EcuM是ECU状态管理器,
1.负责ECU在off、run、sleep等状态之间切换。
2.负责所有基本软件模块的初始化和去初始化,包括OS和RTE。
3.与COMM合作,在网络管理需要关闭ECU时,关闭ECU。
4.管理所有唤醒事件。
5. S32DS配置
5.1 Mcal_Plugins配置
在EB中打开的模块,相应的在S32DS中也要添加,如下图所示:
5.2 代码
需要添加Wkup.c和Wkup.h两个文件,实现WKup的一些软件配置。
5.2.1 进入低功耗
1.关闭正在使用的外设
2.初始化低功耗时钟。经验证,不配置低功耗相应的时钟也可以进入低功耗模式并且正常唤醒,但在复杂电磁环境下可能对程序的可靠性造成影响,因此建议配置。
3.唤醒配置。
4.设置低功耗模式并进入低功耗状态。
5.2.2 唤醒配置
WKUP_USE_FAST:用于配置唤醒时是fast exit还是normal exit.其主要区别为使用fast exit后,App core从唤醒事件到执行第一条代码的时间比normal exit要短很多,fast exit大概900us,normal exit时间会受HSE 固件的影响,大概22ms左右。
Icu_Init(NULL_PTR):初始化唤醒源的相关引脚
Icu_EnableEdgeDetection(IcuChannel_SW5):使能边缘触发
pad keeping配置:用户在读取唤醒源的时候,不需要考虑是fast唤醒还是Noramal唤醒,也不需要用Standby RAM去存储唤醒源,因为MCU唤醒后,WKUP模块对应的寄存器都不会被复位,那么客户可以直接在main函数一开始先读取WISR_64 和WISR的值,然后把Pad_Keeping 功能Disable。
为什么用户读取的唤醒源和实际想要的唤醒源不一致,都是Pad_keeping的功能导致的
那么关于Pad_keeping功能的使用需要注意:
只要工程中有GPIO下降沿唤醒MCU,那么必须使能Pad_keeping功能。原因是如果睡眠之前没有使能Pad_Keeping,一旦MCU唤醒后,所有的GPIO都是高阻态,对应MCU GPIO内部电路就是产生了一个下降沿,所以会误导致WISR_64 或WISR对应唤醒置1;
通常情况都是建议把Pad_Keeping 功能给使能,然后唤醒后,先读取WISR_64 和WISR的值,然后把Pad_Keeping 功能Disable
注意:
图中为fast exit,改为normal exit后退出状态不正常,原因是:MCU在进入低功耗之前把Standby IO enable了,需要手动在main函数引脚初始化前,加上下面一条语句
/* Disable standby IO pad keeping */
IP_DCM_GPR->DCMRWF1 |= DCM_GPR_DCMRWF1_STANDBY_IO_CONFIG_MASK;
当一个引脚在port和icu中被配置为wake up功能时,其同时在正常模式下具有中断的功能。要实现其正常模式下的中断功能,不需要额外的icu模块的配置,只需要在Platform中打开wake up中断功能即可。