Application Startup Flow

SF32LB52X is a dual-core chip with multiple on-chip and off-chip memory interfaces. MPI1 is the on-chip memory interface and can connect PSRAM and NOR Flash. MPI2 and SDMMC are off-chip; MPI2 can connect NOR/PSRAM/NAND, and SDMMC can connect SD-NAND or SD-eMMC. The application runs on the big core. The Bluetooth Controller stack runs on the small core, which is not open to users. The small core is started by the Bluetooth Host stack on the big core; users do not need to care about it.

The application startup on the big core consists of three stages:

  1. First‑stage Bootloader: Burned in the SF32LB52X internal ROM; loads the second‑stage bootloader from Flash to RAM and jumps to run it

  2. Second‑stage Bootloader: Loads the application from Flash and jumps to execute it

  3. Application: User program

First‑stage Bootloader

The first‑stage bootloader is burned in the chip ROM with the interrupt vector table address at 0. After power‑on, the first‑stage bootloader runs first. Depending on the package type, it determines the location of the Flash partition table (internal or external Flash, referred to as the boot Flash below; Flash includes NOR, NAND, SD and eMMC). According to the second‑stage bootloader address indicated by the partition table (must be on the boot Flash), it copies the second‑stage bootloader code to RAM and jumps to run it.

During the first‑stage bootloader, the big core runs at the default clock frequency after power‑up and initializes the boot Flash IO configuration. For the numeric series, both cold boot and hibernate resumes wait for 2 seconds at the first‑stage boot; for the letter series, only cold boot waits 2 seconds.

For numeric‑series chips, VDD33_LDO2 (corresponding to the chip’s VDD33_VOUT1 output) is turned on during the first‑stage bootloader. For letter‑series chips, PA21 is driven high during the first‑stage bootloader.

Warning

If booting from NOR Flash, make sure the Flash device is in 3‑byte address mode (for devices larger than 16 MB, normal operation may set 4‑byte address mode to access the full address space), otherwise the first‑stage bootloader cannot correctly read from Flash. For the numeric series, calling HAL_PMU_Reboot to reboot or HAL_PMU_EnterHibernate to power off will automatically turn off VDD33_LDO2, so on the next power‑up the device returns to the default 3‑byte address mode.

Second‑stage Bootloader

The second‑stage bootloader loads the application and jumps to execute it according to the package type and the Flash partition table. Depending on the package type, applications support the following boot modes. Execution modes include XIP (execute directly at a NOR Flash address; code storage address equals execution address) and non‑XIP (copy code from Flash into RAM for execution; the storage address differs from the execution address). Regardless of boot mode, the application and the second‑stage bootloader reside on the same boot Flash; the difference is only how the application code executes:

  1. On‑chip NOR Flash (MPI1): Boot Flash is on‑chip NOR; the application is stored on on‑chip NOR and runs in XIP mode

  2. No on‑chip NOR Flash:

    1. External NOR Flash (MPI2): Boot Flash is external NOR; the application is stored on external NOR and runs in XIP mode

    2. On‑chip PSRAM (MPI1), external NAND Flash (MPI2): Boot Flash is external NAND; the application is stored on external NAND and runs in non‑XIP mode, i.e., code is copied to on‑chip PSRAM for execution

    3. On‑chip PSRAM, external SD Flash (SDIO): Same as item 2.

For packages with on‑chip PSRAM, the 52 numeric series turns on LDO1V8 and initializes PSRAM in the second‑stage bootloader. For letter series, whether to use LDO1V8 to power PSRAM depends on the board configuration.

The second‑stage bootloader adjusts clock settings; the modified configuration is shown below:

Module

Clock Source

Frequency (MHz)

DLL1

/

144 MHz

DLL2

/

288 MHz

Big‑core system clock

DLL1

144 MHz

On‑chip NOR Flash

System clock

48 MHz

On‑chip PSRAM

DLL2

144 MHz

External Flash

DLL2

48 MHz

External SD

DLL2

The second‑stage bootloader does not load PMU calibration parameters; it only modifies the IO settings related to the storage being used. Cache is disabled, and MPU is disabled.

Module

Setting

PMU

Default

MPU

Disabled

Cache

Disabled

Application

ResetHandler

The application entry function is ResetHandler (in drivers\cmsis\sf32lb52x\Templates\arm\startup_bf0_hcpu.S). Its flow is shown below. The user main function is called by the main thread created in rt_application_init. See main_thread_entry flow.

reset_handler_flow

SystemInit

SystemInit (in drivers/cmsis/sf32lb52x/Templates/system_bf0_ap.c) runs before variable initialization (therefore do not use variables with initial values during this period, and avoid relying on the zero‑initialized section being 0). It updates the VTOR register to redirect the interrupt vector table, and calls mpu_config and cache_enable to initialize the MPU and enable Cache. These two functions are weak symbols, so applications can override them.

system_init_flow

rt_hw_board_init

rt_hw_board_init performs low‑level hardware initialization such as clock and IO configuration, PSRAM and NOR Flash initialization, heap and serial console initialization. rt_components_board_init is an application‑defined initialization hook and calls different functions depending on the application configuration.

rt_hw_board_init

HAL_Init

HAL_Init completes HAL initialization: it loads PMU calibration parameters, updates clock and IO settings, and initializes PSRAM and NOR Flash (according to the new clock configuration). In the diagram, green functions are board‑level driver functions with board‑specific implementations (HAL_PreInit, BSP_IO_Init, BSP_PIN_Init, BSP_Power_Up, etc.). Gray functions are virtual hooks implemented by the application (or not), independent of the board, so different applications on the same board can customize behavior (e.g., different IO configurations). Horizontally, the flow shows nested calls inside functions (e.g., HAL_PreInit calls clock‑configuration helpers; HAL_MspInit calls BSP_IO_Init). Vertically, it shows serially executed functions (e.g., after HAL_PreInit finishes, HAL_PostMspInit runs).

hal_init_flow

Config Clock adjusts:

  • Load PMU calibration values

  • Start GTimer

  • Switch PMU to RC32K

  • If external XT32K is used, switch RTC to XT32K

  • Set system clock to 240 MHz (DLL1)

  • Set DLL2 to 288 MHz (same as the second‑stage bootloader)

Loaded PMU calibration registers 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 (added in Xiaomi branch; previously loaded in the rt_component_board_init stage). The calibration‑loading code may run from Flash or PSRAM.

The details of the PMU parameters initialized by HAL_PMU_Init can be found in the HAL_PMU_Init function in drivers/hal/bf0_hal_pmu.c.

rt_application_init

rt_application_init creates the main thread with entry main_thread_entry. After thread scheduling is enabled (i.e., after rt_system_scheduler_start), the main thread is scheduled and enters main_thread_entry, first calling rt_components_init to initialize components, then calling main (implemented by the application). User code starts from main. For example, the rt_driver sample’s main function is in example/rt_driver/src/main.c.

main_thread_entry_flow

Board‑level Driver Interfaces

Each board needs to implement the following board‑level driver functions. Refer to files under customer/boards/eh-lb52xu.

Function

Required

Description

HAL_PreInit

YES

Recommend referencing a board with similar hardware form

BSP_Power_Up

NO

Called after cold boot and wake‑up

BSP_IO_Power_Down

NO

Called before sleep

BSP_LCD_Reset

NO

BSP_LCD_PowerUp

NO

Called when powering the display on

BSP_LCD_PowerDown

NO

Called when powering the display off

BSP_TP_Reset

NO

BSP_TP_PowerUp

NO

Called when powering touch on

BSP_TP_PowerDown

NO

Called when powering touch off

HAL_MspInit

NO

Called by HAL_PreInit; virtual default calls BSP_IO_Init

HAL_PostMspInit

NO

BSP_IO_Init

NO

Called by HAL_MspInit by default

BSP_PIN_Init

NO

Called by BSP_IO_Init; IO configuration function

Application‑defined Driver Interfaces

If different applications on the same board need different HAL_MspInit behavior, you can implement HAL_MspInit under the application directory; otherwise, it can reside under the board directory.

Function

Required

Description

HAL_MspInit

NO

HAL_PostMspInit

NO