8 低功耗相关

8.1 Hcpu不能进入standby睡眠的debug方法

The CPU needs to meet the following conditions to enter sleep mode. If it cannot sleep, you can troubleshoot one by one according to the following methods;
a,Ensure that the following macros have been generated in rtconfig.h;

#define RT_USING_PM 1
#define BSP_USING_PM 1 //Enable low power mode;
#define PM_STANDBY_ENABLE 1 //Enter standby mode for low power consumption;,
//#define PM_DEEP_ENABLE 1  //It is recommended to turn off the above standby for the 52 series and switch to deep sleep;
#define BSP_PM_DEBUG 1 //Turn on the low power mode debugging log;

开启方法:,menuconfig选择如下::

alt text


alt text

b,Entering sleep mode is not prohibited;:

If the function rt_pm_request(PM_SLEEP_MODE_IDLE); is called in the program, entering sleep will be prohibited. You can check by entering the command pm_dump via the serial port. If the value is 1 or greater than 1, sleep prohibition is enabled; if it is 0, sleep is allowed;

alt text

备注:
rt_pm_request(PM_SLEEP_MODE_IDLE); rt_pm_release(PM_SLEEP_MODE_IDLE);需要成对使用;
c,The timeout time of the operating system timer is greater than the sleep threshold;
见const pm_policy_t pm_policy[]的配置,如下所示, 如果hcpu这里设置为100,即100ms,
If there is a timer in the program that needs to wake up in less than 100ms, it will not enter sleep;

alt text
For example, in the following task, there exists rt_thread_mdelay(90); 90<100, so it will not sleep. You can also use the serial command list_timer to check the status of the timer;
alt text
d,唤醒源存在,
If there are wakeup sources that haven’t been cleared, it won’t enter sleep because it would be woken up immediately after sleeping;
A common issue is the incorrect level state of each wakeup pin. For instance, if it’s set to wake up at a low level, but the pin level remains continuously low;
You can read the WSR registers of hcpu and lcpu through serial commands, Jllink, or log voltage. The addresses of the WSR registers and the definitions of each bit vary across different series. Please refer to the corresponding chip manual to compare with the specific wakeup source of WSR;

regop unlock 0000
regop read 4007001c 1
regop read 4003001c 1


alt text
e,The data sent to another core has not been read;
Here, you can connect via Ozone or dump memory using trace32 to check the tx buffer of the ipc_ctx variable to see if there is any data that hasn’t been fetched;
As shown in the figure below, read_idx_mirror and write_idx_mirror should normally be equal or empty. If they are not equal, it means that there is data that has not been fetched, which will prevent entering sleep. As shown below, non-empty data that hasn’t been fetched prevents sleep:

alt text
The figure below shows the normal situation:

alt text

As shown below, an Hcpu does not enter sleep because the Lcpu has not started the data service, missing the channel with qid=1. The data sent by the Hcpu was not fetched by the Lcpu, causing the Hcpu not to enter sleep;

alt text
f,The CPU did not enter the idle process;
You can use the serial command: list_thread to check the status of all threads. Only tshell and tidle should be ready, others should be in the suspend state, otherwise, it will prevent entering sleep;
As shown in the figure below, I added a __asm(“B .”); infinite loop instruction in the app_watch_entry() function, causing the app_watch thread to be unable to enter suspend, resulting in inability to sleep;

alt text

下面是检查的一些命令截图:

alt text

Explanation of the status of list_timer,
The first column “timer” is the name of the timer;
The second column “periodic” is the timer period (in hexadecimal);
The third column “timeout” is the timestamp for the next timer arrival;
The fourth column “flag” indicates whether the timer is active;
如上图,生效的定时器只有”main”的定时器(延时函数也是一个定时器),唤醒周期为0x4e20(20000ms)。

8.2 Hcpu已睡眠但Lcpu不睡眠

The reasons why Lcpu does not enter sleep are basically the same as problem ## 8.1. You can refer to ## 8.1. Here, only a few details about how Lcpu does not debug through serial commands are discussed:
a,由于此时Jlink不能连接,可以在Hcpu未睡眠时,执行SDK\tools\segger\jlink_lcpu_a0.bat切换Jlink连接到Lcpu,再进行debug。
b, 检查是否存在唤醒源,在jlink连接到Lcpu后, mem32 0x4007001c 1 读取WSR寄存器。
c, 发给Hcpu的数没有被读走
可以通过编译出的map文件找到ipc_ctx变量,用jlink mem32读取,打印ipc_ctx变量或者Ozone.exe连接,读取该变量是不是发送数据没有被Hcpu读走。

Common cause 1;:
Jlink通过 mem32 0x4007001c 1 读取WSR寄存器值为: 0x200,提示PB47存在唤醒源未清掉,如下图为55X相关机器:

alt text
因为唤醒沿被配成了双沿触发,如下:

pm_enable_pin_wakeup(4, AON_PIN_MODE_DOUBLE_EDGE);  /* PB47 */

而,GPIO中断又配置了成了下降沿触发:

rt_pin_attach_irq(BATT_USB_POW_PIN, PIN_IRQ_MODE_FALLING, battery_device_calback, RT_NULL);

而清唤醒源又在GPIO中断回调函数内,这样就会导致上升沿的唤醒源,会出现不能清掉,导致Lcpu不睡的情况。

8.3 关机充电唤醒问题

参考例程:SDK\example\rt_device\pm\project Note;唤醒分为standby/deep休眠唤醒和hibernate关机唤醒两种情况, 支持hibernate关机唤醒的IO通常支持休眠唤醒,要查看芯片手册哪些IO支持关机唤醒;
待机唤醒由AON寄存器配置,如下:

HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_PIN3, AON_PIN_MODE_LOW); //55x PA80 #WKUP_A3
HAL_LPAON_EnableWakeupSrc(LPAON_WAKEUP_SRC_PIN5, AON_PIN_MODE_NEG_EDGE);//55x PB48 #WKUP_PIN5

关机唤醒由PMU和RTC寄存器配置,如下:

HAL_PMU_EnablePinWakeup(5, AON_PIN_MODE_NEG_EDGE); //55x PB48 #WKUP_PIN5

充电唤醒,关机和待机通常都需要充电唤醒,因此需要AON/PMU唤醒都要配置,参考下面配置方式:

  1. 把充电检测pin,配置为唤醒源, 配置为在hibernate/standby模式下都能被唤醒,如下:

//此函数已包含了配置AON和PMU的两种唤醒方式,要Note;看该函数内具体实现
pm_enable_pin_wakeup(4, AON_PIN_MODE_NEG_EDGE); //4-> 对应为PB47,可以通过GPIO映射表来查找

如下图:

alt text
2. 设置唤醒pin的中断:

#define PIN_CHG_DET (47 + 96) /* PB47 */
    rt_pin_mode(PIN_CHG_DET, PIN_MODE_INPUT); /*设置为输入模式*/
    rt_pin_attach_irq(PIN_CHG_DET, PIN_IRQ_MODE_FALLING, (void *) battery_charger_Input;_handle,(void *)(rt_uint32_t) PIN_CHG_DET); /*Configure PB47 as a falling edge interrupt;*/
    rt_pin_irq_enable(PIN_CHG_DET, 1); /* Enable interrupt; */
  1. Register the pin interrupt function, and it will enter the following interrupt function after waking up;;

void battery_charger_Input;_handle(void)
{
    rt_sem_release(&charger_int_sem);
}

The following is an explanation of the charging detection initialization code;:

#define PIN_CHG_DET (47 + 96) /* PB47 needs to add 96; */
int battery_charger_pin_init(void)
{
#ifdef BSP_USING_PM
#ifdef BSP_USING_CHARGER
    GPIO_TypeDef *gpio = GET_GPIO_INSTANCE(PIN_CHG_DET);
    uint16_t gpio_pin = GET_GPIOx_PIN(PIN_CHG_DET);
    int8_t wakeup_pin = HAL_LPAON_QueryWakeupPin(gpio, gpio_pin);/* Query which wake-up source PB47 is; */
    RT_ASSERT(wakeup_pin >= 0); /* Non-wakeup pin, will assert; */
    //rt_kprintf("HAL_LPAON_QueryWakeupPin :%d\n", wakeup_pin);
    pm_enable_pin_wakeup(wakeup_pin, AON_PIN_MODE_NEG_EDGE); /* Configure the wakeup source, the value of wakeup_pin 0-5 corresponds to #WKUP_PIN0 - 5 in the table above; */
#endif
#endif /* BSP_USING_PM */
    _batt_filter_init(&batt_inf);
    rt_pin_mode(PIN_CHG_EN, PIN_MODE_INPUT);
    rt_pin_mode(PIN_CHG_DET, PIN_MODE_INPUT);/*Set PB47 to input mode;*/
    rt_pin_attach_irq(PIN_CHG_DET, PIN_IRQ_MODE_FALLING, (void *) battery_charger_Input;_handle,(void *)(rt_uint32_t) PIN_CHG_DET); /*Configure PB47 as a falling edge interrupt;*/
    rt_pin_irq_enable(PIN_CHG_DET, 1); /* Enable interrupt; */
    return 0;
}


Note;:
a,If the wakeup source is configured as AON_PIN_MODE_NEG_EDGE or AON_PIN_MODE_POS_EDGE edge wakeup mode;,
则AON_PIN_MODE_NEG_EDGE and PIN_IRQ_MODE_FALLING wakeup trigger modes must be consistent with the pin interrupt trigger mode;(都是下降沿触发或都是上升沿触发),
Because clearing WSR is done in the pin interrupt function HAL_GPIO_EXTI_IRQHandler;,Otherwise, it will result in the WSR register not being cleared after being awakened once, making it impossible to enter sleep;。
b,If the wakeup source is configured as AON_PIN_MODE_HIGH or AON_PIN_MODE_LOW level trigger mode;,The wakeup WSR flag bit does not need to be cleared by software, and the WSR flag bit will be automatically cleared after the level changes;。

8.4 进入Hibernate后,机器重启

Common cause 1;:
It is the abnormal level of the wakeup pin configured before entering hibernate;,For example, PB44 is configured as a low-level wakeup key pin, but PB44 is not pulled up, causing the pin to always be at a low level, and once it enters hibernate, it powers on;.
Common cause 2;:
比如Lcpu sensor interrupt wakeup uses pm_enable_pin_wakeup function to configure interrupt wakeup;,This function also configures hibernate shutdown wakeup by default;,
And the sensor’s interrupt level changes during shutdown, causing it to go to sleep and then be woken up again;,

alt text
Solution;:
Replace the wakeup function call of pm_enable_pin_wakeup with HAL_LPAON_EnableWakeupSrc(src, mode); only configure interrupt wakeup, do not configure shutdown wakeup, problem solved;。
Common cause 3;:
For example, after charging wakeup or button wakeup, the PMU’s WSR flag bit is set to 1, but the user program does not handle clearing this WSR flag bit, resulting in waking up again after sleeping;
Solution;:
Before entering shutdown, that is, within the pm_shutdown function, call HAL_PMU_CLEAR_WSR(hwp_pmuc->WSR); to clear the WSR flag bit first, then enter sleep;。

void pm_shutdown(void)
{
#ifdef BSP_PM_STANDBY_SHUTDOWN
    rt_err_t err;
    s_sys_poweron_mng.is_poweron = false;
    gui_pm_fsm(GUI_PM_ACTION_SLEEP);
#else
   HAL_PMU_CLEAR_WSR(hwp_pmuc->WSR);//清掉PMU_WSR
    rt_hw_interrupt_disable();
    HAL_PMU_EnterHibernate();
    while (1) {};
#endif
}

Common cause 4;:
Not following our standard operation, that is, after HAL_PMU_EnterHibernate(); is executed, the machine does not immediately enter Hibernate mode, but continues to run;。
It must be done as shown in the figure below, first disable interrupts, execute HAL_PMU_EnterHibernate(); then add a while(1); infinite loop;。Avoid executing subsequent code, leading to unpredictable problems such as crashes or restarts;。 如下图:
alt text

8.5 hibernate唤醒后启动流程

After entering hibernate sleep mode, rtc, wdt, and lcpu wakeup pins can wake up the entire machine, but hcpu wakeup pins cannot wake up from hibernate sleep;,
After waking up, the startup is equivalent to a cold start, and the program starts running from Hcpu;.
Configure the wakeup source, hcpu cannot wake up from hibernate sleep, lcpu uses: HAL_LPAON_EnableWakeupSrc function configuration;,
The corresponding wakeup source can be found in the SF32LB55X_Pin config_xxx.xlsx document;,如下图:

alt text
The method of cold start can be determined within the function rt_application_init_power_on_mode;,如下图:
alt text
The startup method will be stored in the variable g_pwron_mode, and the wakeup source will be saved in g_wakeup_src;
alt text
The function sys_pwron_fsm_handle_evt_init handles post-wakeup events;
alt text
You can manually read the pmu’s wsr register to check the status;,如下命令:(各个系列的WSR寄存器地址会不一样,请查询对应芯片手册)

regop unlock 0000
regop read 4007a008 1

In the code, it corresponds to: *wakeup_src = hwp_pmuc->WSR;;
alt text
寄存器对应的bit:

alt text

8.6 Serial port command control to enter sleep;

1, In the main function, add the call to rt_pm_request(PM_SLEEP_MODE_IDLE); which by default disables entering sleep;

alt text
2, Add the control command sleep;

int sleep(int argc, char **argv)
{
char i;
    if (argc > 1)
    {
        if (strcmp("standby", argv[1]) == 0)
        {
        		rt_kprintf("sleep on\r\n");
		rt_pm_release(PM_SLEEP_MODE_IDLE);
        }
        else if (strcmp("off", argv[1]) == 0)
        {
        		rt_kprintf("sleep off\r\n");   
		rt_pm_request(PM_SLEEP_MODE_IDLE);
        }
        else if (strcmp("down", argv[1]) == 0)
        {
		rt_kprintf("entry_hibernate\r\n");
		rt_hw_interrupt_disable();
		HAL_PMU_EnterHibernate(); 
		while (1) {};
        }		
        else
        {
        	rt_kprintf("sleep err\r\n");
        }
    }
    return 0;
}
MSH_CMD_EXPORT(sleep, forward sleep command); /* 导出到 msh 命令列表中 */

3,Serial shell, input sleep standby, allow sleep;,Input sleep off, not allowed to enter sleep;,Enter hibernate shutdown mode by inputting sleep down;。

8.7 Standby待机和Standby关机IO内部常见的漏电模型

8.7.1 Standard IO port model;


alt text
Function description is as follows;:

DS

Driving strength;

OE

Output enable;

O

Output;

I

Input;

IE

Input enable;

PE

Pull enable;

PS

Pull select;


Combined control can achieve functions for daily use;;

Push-pull output;(push-pull)

  • OE = 1,O = 0/1
    Open-drain output;(open-drain)

  • OE = 0/1,O = 0

8.7.2 IO漏电模型一

OE=1,O=1,PE = 1, PS= 0;
OE=1, O=1 indicates high output;;
PE=1, PS=0 indicates there is a pull-down resistor;;
Current flows as follows;:
Current value;:I = Vo/Rpd; Rpd下拉电阻;

alt text
The corresponding leakage model is as follows;

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_PULLDOWN, 1);  //PA31 configured as pull-down;
BSP_GPIO_Set(31, 1, 1); //PA31 outputs high level;

The correct configuration should be;

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);  //PA31 configured without pull-up or pull-down;
BSP_GPIO_Set(31, 1, 1); //PA31 outputs high level;

8.7.3 IO漏电模型二

OE=1,O=0,PE = 1, PS= 1;
OE=1, O=1 indicates low output;;
PE=1, PS=1 indicates there is a pull-up resistor;;
Current flows as follows;:
Current value;:I = VDDIO/Rpu; Rpu 上拉电阻;

alt text
The corresponding leakage model is as follows;

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_PULLUP, 1);  //PA31 configured as pull-up;
BSP_GPIO_Set(LCD_VCC_EN, 0, 1); //PA31输出低电平

The correct configuration should be;

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);  //PA31 configured without pull-up or pull-down;
BSP_GPIO_Set(LCD_VCC_EN, 0, 1); //PA31输出低电平

8.7.4 IO漏电模型三

IE= 1, OE=0,O=0,PE = 0, PS= 0;
If the out voltage is at a certain voltage between 0~VDDIO, it will cause the NMOS and PMOS of the input IO unit to be in a semi-on state, causing leakage;,According to this leakage model, the internal leakage of IO is about 0uA - 200uA varies;(不同板子会有差异)

alt text
Current value;:I=VDD/(Rnmos+Rpmos)

  • 对应的漏电模型如下

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);  //PA31 configured without pull-up or pull-down;

同时满足下列两项条件
A, BSP_GPIO_Set or rt_pin_write has not been called to output high or low level;
B, The IO is floating externally, without corresponding pull-up or pull-down fixed level;

  • 正确配置可以为下面任意一种

  • The IO port is NC, unused IOs do not need to be initialized, IOs have default pull-up and pull-down, no configuration is needed;,下图为IO默认上下拉状态
    alt text

  • IO serves as an output port, outputting high or low level;

HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);  //PA31 configured without pull-up or pull-down;
BSP_GPIO_Set(LCD_VCC_EN, 0, 1); //PA31输出低电平
  • IO serves as an input port, with external pull-up and pull-down resistors or peripherals that can continuously provide stable levels;

    HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_NOPULL, 0);           // USART3 TX/SPI3_INT
    HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_NOPULL, 0);           // USART3 RX

或者:

    HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLUP, 0);           // USART3 TX/SPI3_INT
    HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_PULLUP, 0);           // USART3 RX

External pull-up exists externally;
alt text

  • IO serves as an input port, there is no external pull-up or pull-down, and no peripherals can provide continuous stable levels;
    Configure as internal pull-up or pull-down according to the external circuit;(适用所有IO)

    HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLUP, 0);        // USART3 TX
    HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_PULLUP, 0);        // USART3 RX

Non-wakeup IO, configured as high impedance state, the corresponding PAD’s IE bit will be turned off;

	HAL_PIN_Set_Analog(PAD_PB45, 0);  //Set to high impedance;
	HAL_PIN_Set_Analog(PAD_PB46, 0);  //Set to high impedance;

IO ports with wakeup function, there is another set of wakeup input channels, configured as high impedance state, there is still a risk of leakage in the wakeup input channel, there must be internal or external pull-up;,如下图,Different chips have different wakeup source IOs, need to check the corresponding Pin_config document;

alt text

8.8 Hibernate关机常见的唤醒IO内部漏电模型

8.8.1 Hibernate关机下IO的状态

Ordinary IO (without wakeup function);<br>

After entering hibernate shutdown, all are in high impedance state, no internal leakage, externally high impedance;
IO with wakeup function;
Compared with ordinary IO, it has one more wakeup input circuit. This part of the circuit needs to wake up the MCU under hibernate, requiring an internal or external pull-up or pull-down level to ensure that the wakeup IO does not leak;
After 55X hibernate shutdown, the pinmux’s pull-up and pull-down will lose power, the wakeup IO internally does not have PMU pull-up and pull-down, can only rely on external pull-up and pull-down;
After 56X, 52X hibernate shutdown, the pinmux’s pull-up and pull-down will lose power, the wakeup IO has another configurable non - power - loss PMU pull-up and pull-down;

8.8.2 Hibernate关机下55X唤醒IO漏电模型

After 55X hibernate shutdown, the pinmux’s pull-up and pull-down lose power, the wakeup IO internally does not have PMU pull-up and pull-down, can only rely on external pull-up and pull-down;。
In the case of external suspension, according to this leakage model, the internal leakage of the wakeup IO is about 0uA - 200uA varies;(不同板子会有差异)

alt text

8.8.3 Hibernate关机下52X唤醒IO漏电模型一

After 52X hibernate shutdown, the wakeup IO has configurable PMU pull-up and pull-down;,Before hibernate shutdown, configured as PMU without pull-up or pull-down, and the external circuit also does not have a determined pull-up or pull-down level;,According to this leakage model (as shown in Figure ## 8.7.2), the internal leakage of the wakeup IO is approximately between 0uA and 200uA (varies depending on the board);

HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_NOPULL, 1);//唤醒IO PA24配置为无上下拉,外部也无上下拉

The correct configuration is as follows;:
In the pm_shutdown function, the unified configuration for wakeup IO, PA28-PA44, is as follows;

hwp_rtc->PAWK1R = 0x0001ffff;; //PA28-PA44唤醒IO上下拉使能,bit0:PA28,bit1:PA29
hwp_rtc->PAWK2R = 0x0000; //PA28-PA44唤醒IO都配置为下拉,对应bit, 0:下拉,1:上拉 

In the figure below, the PE corresponding bit is pull-up/pull-down enable, and PS is pull-up/pull-down selection;

alt text

PA24~PA27 share the same PAD with PBR0~3, PA24~PA44 can all use the HAL_PIN_Set function to configure PMU pull-up and pull-down;,例如

HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_PULLDOWN, 1); //唤醒IO PA24 同时设置pinmux下拉和PMU下拉
HAL_PIN_Set(PAD_PA25, GPIO_A25, PIN_PULLDOWN, 1); 
HAL_PIN_Set(PAD_PA26, GPIO_A26, PIN_PULLDOWN, 1); 
HAL_PIN_Set(PAD_PA27, GPIO_A27, PIN_PULLDOWN, 1); 

HAL_PIN_Set操作对应的唤醒脚PA24~PA44时,会把IO的pinmux配成上下拉,PMU内部的上下拉也会同时配置,
During Hibernate shutdown, the pinmux pull-up and pull-down of the IO will become invalid, but the pull-up and pull-down of the PMU part will not lose power and will still exist;
alt text

8.8.4 Hibernate关机下52X唤醒IO漏电模型二

After 52X hibernate shutdown, the wakeup IO has configurable non-power-off PMU pull-up and pull-down;,Before hibernate shutdown, when configured as PMU pull-up and pull-down opposite to the external level;

HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_PULLUP, 1);//唤醒IO PA24配置为PMU内部上拉,导致外设漏电

8.9 低功耗调试经验分享

Power consumption under Hibernate;
55 series MCU;:
The software does not need to do any processing, the IOs are already in high impedance state, because the wakeup PIN has no internal pull-up or pull-down, external pull-up or pull-down is required to ensure the level so that the wakeup PIN does not leak electricity;;
58, 56, 52 series MCU;:
Except for the wakeup PIN, all other IOs are already in high impedance state, the software only needs to confirm that the corresponding correct PIN pull-up and pull-down have been configured before entering Hibernate;;
The 52 series also has three internal LDOs that need to be turned off;;
Hibernate usually consumes less than 5uA, other power consumptions come from peripheral hardware circuits;;
Deep/Standby standby power consumption;
First, ensure that Hcpu/Lcpu have entered low power consumption, Log has printed pm[s], and can be woken up by pm[w], ensuring that the sleep-wake process does not crash;;
It is also possible to determine whether it has entered low power consumption by measuring the voltage of the ldo of the hardware’s hpsys and lpsys;;电压睡眠会下降,唤醒会恢复;
Power consumption mainly focuses on three aspects;:

1,Peripheral leakage, including leakage caused by the level difference between MCU and peripheral IO;<br>
2,Internal IO leakage of MCU, see FAQ's IO leakage model;,<br>
Common output high and pull-down, internal pull-up and external pull-down, input port without pull-up or pull-down;,<br>
3,Internal or external storage units Flash, Psram, EMMC of MCU have not entered low power consumption;,<br>
  • 关于第一点:The best way is to remove all peripherals, making the system into a minimal system, and eliminate peripheral leakage one by one;;

  • 关于第二点,See the code below, change the common IO sleep to high impedance, and configure the wakeup pin pull-up or pull-down according to the external circuit;;
    Note;点:
    1,After configuring the IOs that need to be used as high impedance, they need to be reconfigured after waking up, otherwise it will affect the function;;
    2,Some peripherals, such as nor flash, like QSPI’s CS, need to be configured high, configuring them as high impedance will instead cause more leakage;;

    HAL_PIN_Set_Analog(PAD_PA44, 1);
    HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_PULLDOWN, 1); //set pulldown or pullup all wakesrc pin
  • Regarding the third point, according to the power supply and IO of the internal and external flash, psrma, emmc of the MCU, perform power-off (corresponding IO pull-down or high impedance), sleep operation;;
    Specifically, for each storage device, choosing between power-off or sleep operation needs to be based on whether the data of the storage device will be lost after waking up from hibernation, whether it needs to be retained, the time cost of entering and exiting hibernation, and the current parameters in the memory specification book to select the optimal solution that meets the function;;
    下面是一些psram和flash进出睡眠的一些操作接口;

#ifdef BSP_USING_PSRAM1
    rt_psram_enter_low_power("psram1");
#endif
#ifdef BSP_USING_PSRAM1
    rt_psram_exit_low_power("psram1");
#endif
#if defined(BSP_USING_NOR_FLASH1)
        FLASH_HandleTypeDef hflash;
        hflash.Instance = FLASH1;
        HAL_FLASH_RELEASE_DPD(&hflash);
        HAL_Delay_us(8);
#endif /* BSP_USING_NOR_FLASH2 */