SF32LB52X启动与低功耗流程¶
1 Application program启动流程¶
SF32LB52X is a dual-core chip with multiple built-in and external storage interfaces,MPI1 is a built-in storage interface that can connect to PSRAM and NOR Flash,MPI2 and SDMMC are external storage, MPI2 can connect to NOR/PSRAM/NAND, SDMMC can connect to SD-NAND or SD-eMMC。The application runs on the big core, and the Bluetooth Controller protocol stack runs on the small core. The small core is not open to users, and its startup is controlled by the Bluetooth Host protocol stack on the big core, so users don’t need to worry about it。
The application startup process on the big core is divided into three stages:
First stage Bootloader: embedded in the ROM inside SF32LB52X, loads the second stage Bootloader from Flash into RAM and jumps to run
Second stage Bootloader: loads the application from Flash and jumps to execute
Application: user program
1.1 一级Bootloader¶
The first stage Bootloader is solidified in the ROM of the chip, and its interrupt vector table address is 0。After power-on, the first stage Bootloader will run first, and determine the location of the Flash partition table according to the chip package type(内部或者外部Flash,下文称为启动Flash),根据Flash分区表指示的二级Bootloader地址(必须在启动Flash上),拷贝二级Bootloader代码到RAM中并跳转运行。
In the first stage Bootloader phase, the big core runs at the default clock frequency after power-on, and initializes the IO configuration of the boot Flash。
1.2 二级Bootloader¶
The second stage Bootloader loads the application and jumps to execute according to the chip package type and Flash partition table。根据芯片封装类型,Application program分为以下几种启动方式,运行方式分为XIP(直接以NOR Flash地址执行代码,代码的存储地址与执行地址相同)和非XIP(从Flash拷贝代码到RAM中执行,即代码的存储地址与执行地址不同)两种,不论是哪种启动方式,Application program与二级Bootloader均存放在同一个启动Flash上,区别只是Application program代码的运行方式不同:
内置NOR Flash(MPI1):启动Flash为内置NOR Flash,Application program存储在内置NOR Flash上,以XIP方式运行
无内置NOR Flash:
a. 外置NOR Flash(MPI2):启动Flash为外置NOR Flash,Application program存储在外置NOR Flash上,以XIP方式运行
b. 内置PSRAM(MPI1),外置NAND Flash(MPI2):启动Flash为外置NAND Flash,Application program存储在外置NAND Flash上,非XIP执行,即代码被拷贝到内置PSRAM执行
c. 内置PSRAM,外置SD Flash(SDIO):同 b)
For package types with built-in PSRAM, the second stage bootloader will turn on LDO1V8 and initialize PSRAM。
二级Bootloader会修改默认的时钟配置,具体见下表
模块 |
时钟源 |
频率(MHz) |
---|---|---|
DLL1 |
/ |
144MHz |
DLL2 |
/ |
288MHz |
大核系统时钟 |
DLL1 |
144MHz |
内置NOR Flash |
系统时钟 |
48MHz |
内置PSRAM |
DLL2 |
144MHz |
外置Flash |
DLL2 |
48MHz |
外置SD |
DLL2 |
|
PMU |
默认值 |
|
MPU |
Disabled |
|
Cache |
Disabled |
The second stage Bootloader does not load the calibration parameters of PMU, it only modifies the IO settings related to the storage used。
Cache is not enabled, MPU is not enabled
1.3 Application program¶
The entry function of the application is ResetHandler(位于drivers\cmsis\sf32lb52x\Templates\arm\startup_bf0_hcpu.S),其执行流程如图1所示,用户主函数main则由rt_application_init创建的main线程调用,见图5 main_thread_entry流程。
Figure 1 ResetHandler流程
SystemInit(drivers/cmsis/sf32lb52x/Templates/system_bf0_ap.c)在变量初始化之前执行(因此这期间不能使用带初值的变量,零段变量也要避免依赖于初值0),Update VTOR register to redirect interrupt vector table, call mpu_config and cache_enable to initialize MPU and enable Cache,这两个函数为weak函数,Application program中可以重新实现来替换默认的实现。
Figure 2 SystemInit流程
rt_hw_board_init completes the initialization of the underlying hardware, such as clock and IO configuration, PSRAM and NOR Flash initialization, heap and serial console initialization。rt_component_board_init是Application program自定义的初始化函数,随Application program配置的不同而调用不同的函数。
Figure 3 rt_hw_board_init流程
HAL_Init completes HAL initialization, loads PMU calibration parameters, updates clock, IO settings, initializes PSRAM and NOR Flash(根据新的时钟配置),下图中绿色函数为板级驱动函数,每个板子有独立的实现,包括HAL_PreInit、BSP_IO_Init、BSP_PIN_Init和BSP_Power_Up等,灰色函数为虚函数,由Application program实现,独立于板子,目的是相同板子不同的Application program可以有自定义的实现,比如不同Application program在同一块板子上使用不同的IO配置。图4流程图中横向为函数内的嵌套调用子函数,比如HAL_PreInit调用了时钟配置的函数,HAL_MspInit调用BSP_IO_Init,纵向为串行执行的几个函数,如HAL_PreInit执行完再执行HAL_PostMspInit。
Figure 4 HAL_Init流程
The settings modified by Config Clock include:
Load PMU calibration values
Start GTimer
Switch PMU to RC32K
If using external XT32K, switch RTC to XT32K
Configure system clock to 240MHz (DLL1)
Configure DLL2 to 288MHz (same as the setting of the second stage bootloader)
The loaded PMU calibration values include:
BUCK_CR1_BG_BUF_VOS_POLAR
BUCK_CR1_BG_BUF_VOS_TRIM
LPSYS_VOUT_VOUT
VRET_CR_TRIM
PERI_LDO_LDO18_VREF_SEL
PERI_LDO_LDO33_LDO2_SET_VOUT
PERI_LDO_LDO33_LDO3_SET_VOUT
AON_BG_BUF_VOS_POLAR
AON_BG_BUF_VOS_TRIM
HXT_CR1_CBANK_SEL(小米分支新增,之前是在rt_component_board_init阶段) The code for loading calibration values may run on Flash or PSRAM。
HAL_PMU_Init初始化的PMU参数见下图
In rt_application_init, the main thread is created, and the thread entry function is main_thread_entry,When the thread scheduling is released (that is, after calling rt_system_scheduler_start), the main thread gets scheduled, enters the main_thread_entry function, first calls rt_components_init to initialize components, then calls the main function(Application program实现),用户代码即从main函数开始,比如rt_driver示例的主函数在example/rt_driver/src/main.c中。
Figure 5 main_thread_entry流程
For the SF32LB523 watch solution using external NOR, it can be considered that there are two applications, one is OTA Manager, and the other is User App,二级bootloader先跳转到OTA Manager执行完上述的Application program启动流程,再跳转到User App中再执行一遍相同的启动流程,区别是一些Application program自定义的模块初始化会有所不同
1.4 板级驱动接口¶
Each board needs to implement the following board-level driver functions,可参考customer/boards/eh-lb52xu,
函数名 |
必选 |
说明 |
---|---|---|
HAL_PreInit |
YES |
建议保持HDK的默认实现 |
BSP_Power_Up |
NO |
唤醒后调用 |
BSP_IO_Power_Down |
NO |
睡眠前调用 |
BSP_LCD_Reset |
NO |
|
BSP_LCD_PowerUp |
NO |
屏幕上电时调用 |
BSP_LCD_PowerDown |
NO |
屏幕断电时调用 |
BSP_TP_Reset |
NO |
|
BSP_TP_PowerUp |
NO |
Called when the touch control powers up |
BSP_TP_PowerDown |
NO |
Called when the touch control powers down |
HAL_MspInit |
NO |
Application program |
HAL_PostMspInit |
NO |
|
BSP_IO_Init |
NO(?) |
Determined by HAL_MspInit whether to call or not, the default implementation of HAL_MspInit is an empty function now, but it can be changed to call BSP_IO_Init later, providing a standard implementation of BSP_IO_Init that sequentially calls BSP_IO_Init and BSP_Power_Up |
BSP_PIN_Init |
NO(?) |
Called by BSP_IO_Init, IO configuration function |
1.5 Application program自定义驱动接口¶
If different applications on the same board need to implement different HAL_MspInit functions, it is recommended to place the implementation of HAL_MspInit under the application directory, otherwise, it can be placed under the board directory.
函数名 |
必选 |
说明 |
---|---|---|
HAL_MspInit |
NO |
|
HAL_PostMspInit |
NO |
2 低功耗流程¶
2.1 睡眠流程¶
It is recommended to use the deepsleep low-power mode (sleep mode). In this mode, all RAM data and hardware configurations can be maintained, and the recovery time required to return from sleep mode to the working state is relatively short. The IO level can remain in the working state during sleep. However, peripherals stop working in sleep mode, and the CPU can only be woken up by a few limited wake-up sources, including GPIO interrupts, RTC interrupts, LPTIM interrupts, and inter-core communication interrupts. For the application, the switch between sleep mode and working mode is transparent. Whether to enter the sleep mode is controlled by the lowest priority IDLE thread. When all high-priority threads have no tasks to execute and the IDLE thread is scheduled, the IDLE thread will check if the sleep conditions are met. Once all the following conditions are satisfied, it can enter the sleep mode:
Sleep mode is not prohibited
The timeout time of the most recent timer in the operating system is greater than the threshold, with a default threshold of 100ms
The wake-up condition is not met, for example, a wake-up source is enabled but has not been activated
The data sent to the small core has been read
Before entering the sleep mode, the LPTIM will be started according to the timeout time of the most recent timer in the operating system. The interrupt time of the LPTIM is set to the timeout time of the operating system timer. For example, if the most recent timer times out after 200ms, the LPTIM will be configured to trigger an interrupt after 200ms, which means waking up the large core after 200ms. Therefore, even if it enters the sleep mode, the application can still wake up on time to call the operating system timer timeout function.
The application uses rt_pm_request(PM_SLEEP_MODE_IDLE) to prohibit entering the sleep mode until rt_pm_release(PM_SLEEP_MODE_IDLE) is called to release the request. When the peripheral is working, the RT-Thread based driver framework will automatically call rt_pm_request to prohibit sleep, avoiding mistakenly entering the sleep mode in the interrupt mode.
The default timer threshold for deepsleep mode is 100ms(见下表,定义在bf0_pm.c中),You can use rt_pm_policy_register to register a custom policy table, where thresh represents the timer threshold, and mode represents the sleep mode that can be entered after exceeding this threshold.
RT_WEAK const pm_policy_t pm_policy[] =
{
#ifdef PM_STANDBY_ENABLE
#ifdef SOC_BF0_HCPU
{100, PM_SLEEP_MODE_STANDBY},
#else
{10, PM_SLEEP_MODE_STANDBY},
#endif /* SOC_BF0_HCPU */
#elif defined(PM_DEEP_ENABLE)
#ifdef SOC_BF0_HCPU
{100, PM_SLEEP_MODE_DEEP},
#else
{10, PM_SLEEP_MODE_DEEP},
#endif /* SOC_BF0_HCPU */
#else
#ifdef SOC_BF0_HCPU
{100, PM_SLEEP_MODE_LIGHT},
#else
{15, PM_SLEEP_MODE_LIGHT},
#endif /* SOC_BF0_HCPU */
#endif /* PM_STANDBY_ENABLE */
};
When entering sleep mode, if there are peripherals that need to power down to reduce power consumption, the configuration can be modified in BSP_IO_Power_Down, and correspondingly, the peripherals can be powered up in BSP_Power_Up, which will be called after waking up from sleep.
2.2 WFI自动降频¶
进入IDLE线程,但不满足睡眠条件时,大核可以通过降频来降低WFI期间的电流,降频的条件为高速外设不在工作,高速外设包括:
EPIC
EZIP
LCDC
USB
SD
Checking whether EPIC/EZIP is working is not placed in the HAL driver but integrated into the LVGL graphics library. If the LVGL implementation that comes with the SDK is not used, rt_pm_hw_device_start needs to be called to indicate that the high-speed peripheral starts working, avoiding executing WFI at a reduced frequency. After the peripheral finishes working, rt_pm_hw_device_stop is called.
The judgment of whether LCDC/USB/SD is working is integrated into the LCD Device driver of RT_Thread.
The WFI frequency after downclocking is configured by the function HAL_RCC_HCPU_SetDeepWFIDiv. It should be noted that when an audio peripheral is working, it can only be downclocked to 48MHz otherwise, it can be downclocked to 4MHz. At the same time, the HPSYS_RCC_DBGR_FORCE_HP bit of hwp_hpsys_rcc->DBGR must be set to 1.
2.3 场景化动态调频¶
For scenarios that do not require high-performance computing, the main core can also reduce the operating power consumption by downclocking and reducing voltage. For example, after the watch screen turns off and runs the wrist-raising algorithm, the system frequency can be reduced to 48MHz
使用rt_pm_run_enter函数配置当前的运行模式,大核支持下表四个运行模式,推荐使用HIGH_SPEED和MEDIUM_SPEED两个模式。Application program启动后默认工作在HIGH_SPEED模式。
往高速模式切换为立即生效,即当rt_pm_run_enter退出后已切换到高速模式,往低速模式切会延迟到IDLE线程完成,即退出函数后仍旧在原模式,需要等到IDLE得到调度后才会完成切换。
模式 |
系统时钟(MHz) |
---|---|
PM_RUN_MODE_HIGH_SPEED |
240 |
PM_RUN_MODE_NORMAL_SPEED |
144 |
PM_RUN_MODE_MEDIUM_SPEED |
48 |
PM_RUN_MODE_LOW_SPEED |
24 |
SDK还提供了pm_scenario_start、pm_scenario_stop两个函数方便Application program根据场景切换,目前支持的场景有UI和Audio,当UI或者Audio场景开启后,使用HIGH_SPEED模式,UI和Audio均为开启时,使用MEDIUM_SPEED模式。