小猫爪:S32K3学习笔记16-S32K3之PMC和MC_RGM

1 前言

  这一节来看看S32K3的PMC(Power Management Controller)和MC_RGM(Reset Generation Module)。其中PMC提供了电压检测机制,当电源输入电压高于或者低于正常工作电压,那么就会触发一个中断,如果电压再低,就触发复位。而MC_RGM是K3的复位管理器,控制着K3的复位时序,让S32K3进行破坏性复位和功能性复位,在复位前会记录复位的详细原因,在复位之后可被读出。

2 PMC的电压检测

2.1 简介

  S32K3有三种电源检测机制,分别是LVR,LVD和HVD,其功能主要如下:

  1. LVR:低于一个域值后,复位
  2. LVD:低于一个域值后,产生中断
  3. HVD:高于一个域值后,产生中断

  首先LVR触发复位是默认使能的,LVD和HVD触发中断则是可以配置使能或者使能。这里需要注意的是,LVR,LVD和HVD触发的复位不会记录在MC_RGM模块中,而是记录在PMC->LVSC寄存器中。

2.2 MCAL配置

  PMC相关功能在MCAL中被集成到了Mcu模块中,首先需要配置相关的callback函数如下:
在这里插入图片描述

  这里需要注意的是,图中得PMC错误callback函数不仅仅是在PMC的HVD和LVD事件发生后触发中断被调用,相关复位源触发中断MC_RGM的也会调用这个Callback函数,进入standy模式前发现正在有Flash操作也会调用,具体可由该函数的传参来判断,如下:

void McuErrorIsrNotification(uint8 u8ErrorCode)//McuErrorIsrNotification
{
	if(u8ErrorCode == POWER_IP_E_ISR_VOLTAGE_ERROR)
	{
		//HVD,LVD事件
	}
	if((u8ErrorCode == POWER_IP_E_ISR_FUNC_RESET_ALT_FAILURE)||(u8ErrorCode == POWER_IP_E_ISR_FUNC_RESET_ALT_FAILURE) )
	{
		//MC_RGM Function复位源触发
	}
	if(u8ErrorCode == POWER_IP_E_FLASH_HV_OPERATION_ONGOING)
	{
		//进入Standy模式前发现Last-mile配置错误或者发现正在有flash操作
	}
	else
	{
		while(1);
	}
	return;
}
void McuPerformResetCallout(void)//McuPerformResetCallout 
{
	//调用Mcu_PerformReset()软件复位函数的callback
}
void McuPmcNotification(uint8 u8ErrorCode)//McuPmcNotification
{
	if(u8ErrorCode == POWER_IP_LAST_MILE_REGULATOR_DISABLED)
	{
		//进入standy模式前发现Last-mile使能了
	}
}

  随后使能HVD,LVD中断,如下:
在这里插入图片描述
  最后再去Platform模块中使能PMC的中断以及注册中断服务函数:
在这里插入图片描述
在这里插入图片描述
  这样关于PMC的HVD,LVD就配置完了。

3 MC_RGM

3.1 简介

  MC_RGM是S32K3的复位管理,它在S32K3的整个功能安全下有着至关重要的作用,因为大多数错误都是需要通过复位来消除的,在前面的文章已经很多次提到它,基本上大多数模块的触发复位信号都会被发送到MC_RGM模块,然后由MC_RGM执行整个MCU的复位操作。MC_RGM支持两种复位类型,功能性复位(Functional reset)和(Destructive sequence)。

  可以触发Functional reset的复位源如下:
在这里插入图片描述
  可以触发Destructive reset的复位源如下:
在这里插入图片描述
  在表中有两个词可能不太容易理解,分别是Demotable to IRQ和Escalation,那这两个功能代表什么意思呢?

  1. Demotable to IRQ
      有一些可以触发Functional reset的复位源,可以将其配置为不触发Functional reset,而是转而去触发一个中断。表中Yes的意思就代表着这个复位源可以被配置成触发成中断。
  2. Escalation
      Escalation类似一个复位计数功能,可以对Functional reset和Destructive reset分别预先设置个阈值FRETDRET,然后K3每执行一次Functional复位或者Destructive复位,Functional复位或Destructive复位所对应的计数器就会加1。
      如果Functional reset复位的次数超过阈值FRET,则会直接会触发一次Destructive reset。如果Destructive reset复位的次数超过阈值DRET,则会让K3卡在DEST0状态(就是处于复位状态,CPU不会运行)中,直到下一次的Power-On事件发生,一切从来。
      当然这两个复位次数计数器是可以手动清零的,在目前RTD的驱动代码中,只有Power-On才会清零Destructive复位次数计数器,而每发生一次破坏性复位,都会清零Functional复位次数计数器。

3.2 MCAL配置

  MC_RGM的相关功能在MCAL中被集成到了Mcu模块中,如下:
在这里插入图片描述
  其中如果FRET和DRET设置的值为0,则Escalation功能则不使能。如果你选择了一些复位源去触发中断的话,那么还需要使能下面选项:
在这里插入图片描述
  除此之外,还需要去Platform模块中使能MC_RGM的中断,以及注册MC_RGM中断服务函数MC_RGM_ResetAlt_IRQHandler,这个功能相信用的人不多,在这里就不详细截图做介绍了。

  另外还有一个函数需要提一下,那就是复位后可通过函数Mcu_GetResetReason来获取上次导致MCU的复位源:

typedef enum
{
    /* 'Destructive' Event Status Register (MC_RGM_DES) */
    MCU_POWER_ON_RESET = McuConf_McuResetReasonConf_MCU_POWER_ON_RESET,                     /**< @brief Power on reset event. RGM_DES[F_DR0]. */
    MCU_FCCU_FTR_RESET = McuConf_McuResetReasonConf_MCU_FCCU_FTR_RESET,                 /**< @brief Non-critical supply presence detector fail. RGM_DES[F_DR1]. */
    MCU_STCU_URF_RESET = McuConf_McuResetReasonConf_MCU_STCU_URF_RESET,                     /**< @brief FCCU failure to react. RGM_DES[F_DR3]. */
    MCU_MC_RGM_FRE_RESET = McuConf_McuResetReasonConf_MCU_MC_RGM_FRE_RESET,                     /**< @brief STCU unrecoverable fault. RGM_DES[F_DR4]. */
    MCU_FXOSC_FAIL_RESET = McuConf_McuResetReasonConf_MCU_FXOSC_FAIL_RESET,                 /**< @brief Functional reset escalation. RGM_DES[F_DR6]. */
    MCU_PLL_LOL_RESET = McuConf_McuResetReasonConf_MCU_PLL_LOL_RESET,                 /**< @brief FXOSC failure. RGM_DES[F_DR8]. */
    MCU_CORE_CLK_FAIL_RESET = McuConf_McuResetReasonConf_MCU_CORE_CLK_FAIL_RESET,                     /**< @brief CORE_PLL and related DFS loss of lock. RGM_DES[F_DR9]. */
    MCU_AIPS_PLAT_CLK_FAIL_RESET = McuConf_McuResetReasonConf_MCU_AIPS_PLAT_CLK_FAIL_RESET,                 /**< @brief PERIPH_PLL and related DFS loss of lock. RGM_DES[F_DR10]. */
    MCU_HSE_CLK_FAIL_RESET = McuConf_McuResetReasonConf_MCU_HSE_CLK_FAIL_RESET,                       /**< @brief DDR_PLL loss of lock. RGM_DES[F_DR11]. */
    MCU_SYS_DIV_FAIL_RESET = McuConf_McuResetReasonConf_MCU_SYS_DIV_FAIL_RESET,                       /**< @brief ACCEL_PLL loss of lock. RGM_DES[F_DR12]. */
    MCU_HSE_TMPR_RST_RESET = McuConf_McuResetReasonConf_MCU_HSE_TMPR_RST_RESET, /**< @brief XBAR_DIV3_CLK failure. RGM_DES[F_DR13]. */
    MCU_HSE_SNVS_RST_RESET = McuConf_McuResetReasonConf_MCU_HSE_SNVS_RST_RESET,                 /**< @brief Life-cycle error. RGM_DES[F_DR16]. */
    MCU_SW_DEST_RESET = McuConf_McuResetReasonConf_MCU_SW_DEST_RESET,             /**< @brief HSE SNVS tamper detected. RGM_DES[F_DR17]. */
    MCU_DEBUG_DEST_RESET = McuConf_McuResetReasonConf_MCU_DEBUG_DEST_RESET,               /**< @brief HSE SWT timeout. RGM_DES[F_DR18]. */

    /* 'Functional' Event Status Register (MC_RGM_FES) */
    MCU_F_EXR_RESET = McuConf_McuResetReasonConf_MCU_F_EXR_RESET,                       /**< @brief Software destructive reset. RGM_DES[F_DR30]. */
    MCU_FCCU_RST_RESET = McuConf_McuResetReasonConf_MCU_FCCU_RST_RESET,                     /**< @brief FCCU Reset Reaction. RGM_FES[F_FR3]. */
    MCU_ST_DONE_RESET = McuConf_McuResetReasonConf_MCU_ST_DONE_RESET,                       /**< @brief Self-Test Done. RGM_FES[F_FR4]. */
    MCU_SWT0_RST_RESET = McuConf_McuResetReasonConf_MCU_SWT0_RST_RESET,                     /**< @brief SWT0 Timeout. RGM_FES[F_FR6]. */
    MCU_SWT1_RST_RESET = McuConf_McuResetReasonConf_MCU_SWT1_RST_RESET,                     /**< @brief SWT1 Timeout. RGM_FES[F_FR6]. */
    MCU_JTAG_RST_RESET = McuConf_McuResetReasonConf_MCU_JTAG_RST_RESET,       /**< @brief HSE Memory ECC Error. RGM_FES[F_FR18]. */
    MCU_HSE_SWT_RST_RESET = McuConf_McuResetReasonConf_MCU_HSE_SWT_RST_RESET,     /**< @brief HSE Boot Failure Error. RGM_FES[F_FR20]. */
    MCU_HSE_BOOT_RST_RESET = McuConf_McuResetReasonConf_MCU_HSE_BOOT_RST_RESET,   /**< @brief HSE M7 Core Lock. RGM_FES[F_FR21]. */
    MCU_SW_FUNC_RESET = McuConf_McuResetReasonConf_MCU_SW_FUNC_RESET,                       /**< @brief Software functional reset. RGM_FES[F_FR30]. */
    MCU_DEBUG_FUNC_RESET = McuConf_McuResetReasonConf_MCU_DEBUG_FUNC_RESET,                 /**< @brief Debug functional reset. RGM_FES[F_FR31]. */

    MCU_WAKEUP_REASON = McuConf_McuResetReasonConf_MCU_WAKEUP_REASON,                       /**< @brief Wake-up event detected. */
    MCU_NO_RESET_REASON = McuConf_McuResetReasonConf_MCU_NO_RESET_REASON,                   /**< @brief No reset reason found */
    MCU_MULTIPLE_RESET_REASON = McuConf_McuResetReasonConf_MCU_MULTIPLE_RESET_REASON,       /**< @brief More than one reset events are logged except "Power on event" */
    MCU_RESET_UNDEFINED = McuConf_McuResetReasonConf_MCU_RESET_UNDEFINED                    /**< @brief Undefined reset source. */

} Power_Ip_ResetType;

Mcu_ResetType Mcu_GetResetReason(void)//另外如果使用此函数不利于调试,也可直接去读取寄存器FES和DES的值

END

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小猫爪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值