SiFli 567+emmc Standby休眠报错问题
根本原因:
HAL_PBR0_FORCE1_ENABLE();没有调用,导致进入休眠后PBR0没有跟随睡眠打开,客户的板子PBR0控制了nor flash和psram的供电
死机过程分析:
在standby睡眠过程,uart或者jlink很可能出现不通的情况,此类情况下,SiFli 的MCU还可以采用其他方法来debug,比如通过写RTC的back寄存器,RTC寄存器,在软复位的情况下,还能保持不变,上电冷启动才会清零,利用这种特性,在standby的休眠和唤醒流程中,预先添加对RTC对应的寄存器写入对应的值,在出现死机的时候,通过长按 按键13秒触发软件复位开机,测试通过打印此时的RTC寄存器,就能看到standby待机死机时候的状态,代码如下:
typedef struct
{__IO uint32_t TR;__IO uint32_t DR;__IO uint32_t CR;__IO uint32_t ISR;__IO uint32_t PSCLR;__IO uint32_t WUTR;__IO uint32_t ALRMTR;__IO uint32_t ALRMDR;__IO uint32_t SHIFTR;__IO uint32_t TSTR;__IO uint32_t TSDR;__IO uint32_t OR;__IO uint32_t BKP0R;__IO uint32_t BKP1R;__IO uint32_t BKP2R;__IO uint32_t BKP3R;__IO uint32_t BKP4R;__IO uint32_t BKP5R;__IO uint32_t BKP6R;__IO uint32_t BKP7R;__IO uint32_t BKP8R;__IO uint32_t BKP9R;__IO uint32_t BKP10R;__IO uint32_t BKP11R;__IO uint32_t BKP12R;__IO uint32_t BKP13R;__IO uint32_t BKP14R;__IO uint32_t BKP15R;__IO uint32_t BKP16R;__IO uint32_t BKP17R;__IO uint32_t BKP18R;__IO uint32_t BKP19R;__IO uint32_t BKP20R;__IO uint32_t BKP21R;__IO uint32_t BKP22R;__IO uint32_t BKP23R;__IO uint32_t BKP24R;__IO uint32_t BKP25R;__IO uint32_t BKP26R;__IO uint32_t BKP27R;__IO uint32_t BKP28R;__IO uint32_t BKP29R;__IO uint32_t BKP30R;__IO uint32_t BKP31R;__IO uint32_t PBRCR;__IO uint32_t PBR0R;__IO uint32_t PBR1R;__IO uint32_t PBR2R;__IO uint32_t PBR3R;__IO uint32_t PAWKUP;__IO uint32_t PBWKUP;
} RTC_TypeDef;void SystemInitFromStandby(void)
{
...#ifndef BSP_PM_PIN_BACKUP_DISABLED/* restore pinmux and gpio register */pm_pin_restore();/* disable ISO as pinmux and gpio have been restored */HAL_HPAON_ENABLE_PAD();
#endif /* BSP_PM_PIN_BACKUP_DISABLED */#ifndef SF32LB52XHAL_HPAON_WakeCore(CORE_ID_LCPU);/* delay 1ms to workaround crash issue which might be caused by unstable state when LCPU wakeup*/HAL_Delay_us(1000);
#endif /* SF32LB52X */hwp_rtc->BKP24R = 0xf001; //添加log
#if defined(RT_DEBUG) && !defined(SF32LB55X)__HAL_SYSCFG_Enable_Assert_Trigger(1);
#endif // defined(RT_DEBUG) && !defined(SF32LB55X)#ifdef PM_PROFILING_ENABLEDtest_pm_data.restore_time.lcpu_wakeup = HAL_GTIMER_READ();
#endif /* PM_PROFILING_ENABLED */#ifndef LXT_DISABLEHAL_PIN_SetXT32();
#endif /* LXT_DISABLE */HAL_Init();hwp_rtc->BKP24R = 0xf002; //添加log
}RT_WEAK void rt_hw_board_init()
{
#ifdef SOC_BF0_HCPUrt_kprintf("Serial:%x,Chip:%x,Package:%x,Rev:%x Reason:%08x\r\n",__HAL_SYSCFG_GET_SID(), __HAL_SYSCFG_GET_CID(), __HAL_SYSCFG_GET_PID(), __HAL_SYSCFG_GET_REVID(), HAL_PMU_GET_WSR());#ifdef RT_USING_PMrt_kprintf("Serial PowerOnMOde:%d rtc_record:%08x\n", SystemPowerOnModeGet(), HAL_Get_backup(RTC_BACKUP_MODULE_RECORD));rt_kprintf("hwp_rtc->BKP24R:0x%x\n",hwp_rtc->BKP24R); //打印出来这个值#endif
#endif}
比如在standby的睡眠唤醒的流程函数中,添加如下的log,
hwp_rtc->BKP24R = 0xf002; //添加log
然后在rt_hw_board_init()函数中,添加如下的打印,
rt_kprintf("hwp_rtc->BKP24R:0x%x\n",hwp_rtc->BKP24R); //打印出来这个值
下面是当时调试打印的一些log信息,当时用到了BKP24R 到BKP31R寄存器,由于567的RTC的back寄存器比较多,随便用,525系列的,RTC BACK寄存器就比较少,可以看到上面代码中
rt_kprintf("Serial PowerOnMOde:%d rtc_record:%08x\n", SystemPowerOnModeGet(), HAL_Get_backup(RTC_BACKUP_MODULE_RECORD));
也是已经添加了部分RTC 的debug log
下面是用RTC寄存器,调试过程中要注意的点:
1,Hcpu和Lcpu都可以操作该寄存器,但是RTC的寄存器总线位于Lcpu中,因此Lcpu可以直接操作该寄存器,但是Hcpu操作,需要在HAL_HPAON_WakeCore(CORE_ID_LCPU); 也就是Lcpu被Hcpu唤醒值后之后,和 允许Lcpu进行休眠之前进行操作,
/* cancel active request after bsp_power_down because bsp_power_down may access LPSYS */
HAL_HPAON_CANCEL_LP_ACTIVE_REQUEST(); //Hcpu执行此函数后,则允许Lcpu进入睡眠
2,要注意上电和standby的流程,有些函数比如:BSP_Power_Up 、BSP_PIN_Init、 HAL_Init();和HAL_PreInit 等这些函数,上电和standby待机唤醒都会走,因此避免写入RTC的寄存器被软复位起来时重写,需要添加如下条件判断:
if (PM_STANDBY_BOOT == SystemPowerOnModeGet())
{
hwp_rtc->BKP24R = 0xf003;
}
void HAL_PreInit(void)
{
#ifdef SOC_BF0_HCPU//#ifndef CFG_BOOTLOADER
// __asm("B .");
//#endif//MODIFY_REG(hwp_hpsys_rcc->CFGR, HPSYS_RCC_CFGR_PDIV2_Msk,// MAKE_REG_VAL(5, HPSYS_RCC_CFGR_PDIV2_Msk, HPSYS_RCC_CFGR_PDIV2_Pos));// To avoid somebody cancel request.HAL_HPAON_EnableXT48();HAL_RCC_HCPU_ClockSelect(RCC_CLK_MOD_SYS, RCC_SYSCLK_HXT48);HAL_RCC_HCPU_ClockSelect(RCC_CLK_MOD_HP_PERI, RCC_CLK_PERI_HXT48);// Enable SA/SB for DLLsHAL_PIN_Set(PAD_PA72, GPIO_A72, PIN_PULLUP, 1); // SB_EN/MPI2_ENHAL_PIN_Set(PAD_PA74, GPIO_A74, PIN_PULLUP, 1); // SA_EN/MPI1_ENif (PM_STANDBY_BOOT == SystemPowerOnModeGet()){hwp_rtc->BKP24R = 0xf003;}
...
}
3, BSP_Power_Up 、BSP_PIN_Init、 HAL_Init();和HAL_PreInit 等这些函数 这些函数Hcpu和Lcpu都会编译,会跑,需要用#ifdef SOC_BF0_HCPU 宏来区分,你要调试的是Hcpu还是Lcpu