您好
,我们正在为恩智浦的 MCU SW - S32K146 开发电源管理器。电源管理器使用以下三种状态。
运行模式
VPLR 模式
VPLS 模式
此外,还使用了以下时钟源选项。
FIRC
SIRC
在启动期间,我们的时钟源为FIRC,电源模式为运行模式。之后,我们将配置 SPLL。在此期间,MCU 电源模式仍为运行模式。在运行模式之后,当 MCU 需要进入 VLPR -> VLPS 模式时,我们要执行以下步骤:
正常运行:
在 VLPS 模式下,PORTE 上接收到监测引脚的中断,标志值为 true,首先禁用 IRQ,然后对 MCU 进行软复位,RESET MCU,操作从启动开始恢复正常。
我们遇到了以下问题,因此希望得到您的支持,以了解我们是否做错了什么。
问题:有时,MCU 会随机陷入一种状态,只有通过关闭电源和机才能 RESET。
我们的假设在 MCU 卡死的上述状态中,我们假设可能会发生以下情况。
嗨,@Sami2098、
目前,MCU 已不再处于这种状态。但是,如果这个问题再次发生,那么当MCU运行发行版本时,我应该如何获取寄存器值转储。
如果碰巧再次进入这种状态,可以尝试通过调试器中的"Attach to running target" 配置连接 MCU。例如,使用 S32DS"Registers" 查看和导出。或使用 TRACE32 将值导出为 CSV:调试 - 如何从 TRACE32 导出变量值 - Stack Overflow。
由于我们没有使用 "退出时休眠 "功能,我们是否需要"在进入 VLPS" 之前,我们是否需要使用 DSB + ISB 指令来确保适当的同步? 如果需要,那么以这种方式调用函数是否正确?
这只是两个建议,因为以前也出现过类似的问题,客户使用的是退出时休眠功能。我想确认配置是否相同。
DSB + ISB 在您的实施中看起来很好。这主要是为了确保在继续进行 VLPS 之前完成任何正在进行的数据处理。
调用INT_SYS_ClearPending()看起来也不错,这将在进入低功耗前检查是否有挂起的中断。
这是一个非常奇怪的问题,因为它很难重现。
致以最诚挚的问候,
Julián
您好@Julián_AragónM,
感谢您一直以来的支持。请在下面找到您问题的答案。
至于处于停机状态的设备... 你能测量电流消耗吗?
遗憾的是,在问题发生之前,我们没有连接电流表,而且由于问题很少发生,使用电流表需要中断蓄电池连接,从而导致 POR。
设备在 VLPS 上还是永远不会进入低功耗?
目前我们还不能确定。目的是让设备进入VLPS。不过,它也有可能陷入某种未知状态。
您能分享这个州的登记转储情况吗?
目前,MCU 已不再处于这种状态。但是,如果这个问题再次发生,那么当MCU运行发行版本时,我应该如何获取寄存器值转储。
此外,您是否配置了退出时休眠功能?
没有,目前我们没有使用退出时休眠功能。
/* ISR 退出时不重新进入(深度)睡眠状态 */
S32_SCB->SCR&= ~(S32_SCB_SCR_SLEEPONEXIT_MASK);
关于您的建议,我有几个问题。
由于我们没有使用 Sleep on Exit 功能,我们是否需要"使用 DSB + ISB 指令,以确保在进入 VLPS" 之前适当同步?
/* Cpu 将进入深度睡眠状态 */ asm( ISB ); STANDBY(); // where STADBY() - #define STANDBY() __asm volatile ( wfi )
__asm("DSB");
__""
>""
我们正在研究应用层。那么,在将电源模式切换到 VLPS 之前,我需要调用以下函数吗?
void int_sys_clearPending (irqn_Type IRQNumber);//<-在切换到 VLPS 之前调用这个函数?
power_sys_setMode(POWER_MANAGER_VLPS、POWER_MANAGER_POLICY_FORCIBLE);谢谢,最诚挚的问候,
嗨,@Sami2098、
是的,进入 VLPS 时,会请求非 CPU 总线主站进入停止模式:
您必须注意 VLPS 模式的 DMA 配置。这与 ERR011063 有关:
但是,如果禁用 DMA 时仍出现此问题,那么问题可能与此没有直接关系。 如果在 VLPS 中或之后不需要 DMA,则 EDMA_DRV_Deinit() 函数是正确的方法。
至于处于停机状态的设备... 你能测量电流消耗吗?设备在 VLPS 上还是永远不会进入低功耗?您能分享这个州的登记转储情况吗?
此外,您是否配置了退出时休眠功能?曾经报告过这样一个问题:当 MCU 尝试处理 ISR 并通过退出时休眠返回 VLPS 时,会卡死在停止状态。解决方法是设置数据同步障碍,以确保在继续之前完成任何数据操作。
我的建议是在进入 VLPS 之前确保没有待处理的中断(我认为一个简单的如果 ((NVIC->ISPR[0]& NVIC->ISER[0]) == 0) 检查就足够了),并使用 DSB + ISB 指令确保在再次进入 VLPS 之前正确同步。
致以最诚挚的问候,
Julián
我们目前使用 3 个 DMA 通道:0、1 和 3。
0 映射到 Flex I/O UART。
1 映射到 LPUART 0 RX
3 映射到 LPUART 1 RX
当我们进入 VLPS 时,发现只有 DMA 0 启用。我们使用
for (int ch = 0; ch< 16; ch++) { // S32K146 有 16 个通道
if (DMA->ERQ& (1<< ch)) {
printf("DMA 通道%d is ENABLED\r\n", ch);
}
}
此 for 循环仅用于调试版本,不用于发行版。我们没有明确禁用 DMA 1 和 3,但观察到它们可能仍被驱动程序函数static void LPUART_DRV_StopRxDma(uint32_t instance) 禁用。
我们尝试在进入 VLPS 之前使用 status_t EDMA_DRV_Deinit(void)明确禁用 DMA 通道。
我们的目的是确保在进入 VLPS 状态之前停止 DMA 传输。我们的方法是否正确?
但这一声明与我们目前面临的 MCU 停机问题无关。我们观察到,无论是否采取上述步骤,我们都得到了停止状态。我只想问,在进入 VLPS 之前,是否需要明确调用 status_t EDMA_DRV_Deinit(void)。
今天测试时,我们再次卡在 MCU 停止状态。过去三周以来,一切运行正常。我们完全绕过了 VLPR 状态。现在我们直接从 Run 到 VLPS(中间没有 VLPR)。我们还从时钟频率证实了这一点,总线时钟为4Mhz,系统时钟为8Mhz。我们还确认,在使用 VLPS 之前,时钟源是 SIRC,所有其他时钟源都已禁用。
在 MCU 停止状态下,我们连接了 JTag,并能使用 RTT 查看器进行连接。以下是 RTT 查看器在 MCU 停止状态下的截图。
没有什么能让 MCU 活起来。我们唯一能确定的办法就是断电。我们的 MCU 目前处于这种状态,如果您希望我们在这种状态下进行尝试,我们将等待您的回复。这是因为这个问题很难重现,而且我们也不知道什么时候会再次发生。等待您的回复。
嗨,@Sami2098、
是的,如果不用作唤醒中断,则应禁用 LPTRM IRQ 和时钟源。 这样可以减少不必要的电流,避免在离开 VLPS 时发生不必要的 ISR。
致以最诚挚的问候,
Julián
您好,
,感谢您的支持。你说得对。在我们的项目中,我们并不需要过渡到 VLPR,因此绕过了它。根据您的意见,我们想进一步询问是否有必要同时对 LPTMR IRQ 进行去初始化。LPTMR 中断每 1 毫秒触发一次,基本上是在运行整个 MCU 代码。当 MCU 转换到 VLPS 状态时,我们将不再使用该 LPTMR 中断。相反,我们使用 GPIO 引脚作为唤醒源。因此,在 VLPS 模式下,我们实际上并不需要 LPTMR IRQ。
那么,由于 LPTMR IRQ 是使用时钟源的外设,我们是否也应该对其进行去初始化?
嗨,@Sami2098、
除非您在 MCU 停止运行后尝试连接,否则我真的无法找出这个问题的根本原因。
项目是否需要 VLPR? 它可以从 RUN 直接转到 VLPS。这也会降低ERR011063 的风险。
有关模式过渡的信息,请参阅 AN5425 中的第 5.6 章:S32K1xx 的电源管理单元。但你的程序似乎是正确的;首先禁用使用时钟源的外设,将系统时钟切换到 SIRC,然后禁用所有其他时钟源。
致以最诚挚的问候,
Julián
同时,我们还使用 NXP API 检查了时钟频率:
uint32_t sysClk = 0;
uint32_t busClk = 0;
/* 获取系统时钟频率 */
CLOCK_SYS_GetFreq(CORE_CLOCK,&sysClk);
/* 获取总线时钟频率 */ cloc
k_sys_getFreq (BUS_CLOCK,& busCLK);
我们在运行模式下收到了以下值:内
核/系统时钟:8 MHz
总线时钟:4 MHz
我们在 VLPR 模式下收到了以下值:内
核/系统时钟:4 MHz
总线时钟:4 MHz
这些值是在调用恩智浦 API 从运行模式转为 VLPR 模式后收到的:
POWER_SYS_SetMode(POWER_MANAGER_VLPR,POWER_MANAGER_POLICY_FORCIBLE);
这种情况很少发生。这发生在两周前,但当时我们只做了 POR。从那以后,我们再也无法重现这个问题。
我目前正在使用恩智浦SDK API进行电源模式切换,在这些API中,正在设置SIRC时钟。那么,我是否需要在切换前手动检查时钟频率?我认为应用程序接口已经在处理这个问题了。
我使用的应用程序接口是
status_t POWER_SYS_SetMode(uint8_t powerModeIndex、
power_manager_policy_t policy);
我是这样说的:
POWER_SYS_SetMode(POWER_MANAGER_VLPR, POWER_MANAGER_POLICY_FORCIBLE);
POWER_SYS_SetMode(POWER_MANAGER_VLPS, POWER_MANAGER_POLICY_FORCIBLE);
问题
我们能找到问题的根源吗?
目前,我们会在进入 VLPR 之前去初始化看门狗。是否可以在 VLPR 之后但在进入 VLPS 模式之前对其进行去初始化?
是否有任何演示应用程序可用于手动配置 VCCR?
RUN->VLPR->VLPS 的步骤似乎是正确的。板进入 "halt" 状态后你能连接到它吗?(通过使用"Attach to target" 选项)。
这个问题可能是由时钟配置引起的。ERR011063(摘自S32K146_0N73V
这只适用于 从 VLPR 模式 进入 VLPS 模式 的例程 ,而您的情况正是如此。请尝试更改 VCCR 配置。
致以最诚挚的问候,
Julián
您好,
在 VLPS 模式下,我们将按以下方式初始化用于中断的 GPIO 引脚。
// 准备期间禁用中断
INT_SYS_DisableIRQ(PORTE_IRQn);
// 清除硬件标志
PORTE->ISFR = 0xFFFFFFFF;
// 清除 NVIC 挂起
INT_SYS_ClearPending(PORTE_IRQn);
// 现在启用中断
INT_SYS_EnableIRQ(PORTE_IRQn);
// 再次清除,以避免任何运行时事件
PORTE->ISFR = 0xFFFFFFFF;
INT_SYS_ClearPending(PORTE_IRQn);
// 进入 VLPS
POWER_SYS_SetMode(POWER_MANAGER_VLPS, POWER_MANAGER_POLICY_FORCIBLE);