应用程序启动流程

SF32LB55x为双核(大小核)架构,内置与外置存储接口丰富。其中QSPI1,QSPI2和QSPI3位于HPSYS,可向DMAC1发送请求;QSPI4位于LPSYS,可向DMAC2发送请求;OPI-PSRAM 位于 HPSYS,用于访问芯片内合封(SiP) 的8线pSRAM。 QSPI1的输入输出连接至IO(SIP),用于访问芯片内合封(SiP)的单片或双片NOR Flash。 QSPI2与QSPI3的输入输出连接至IO(PA),用于访问芯片外接的NOR/NAND Flash。 QSPI4的输入输出连接至IO(PB),用于访问芯片内合封(SiP)的4线pSRAM或芯片外接的NOR/NAND Flash。

在55系列的启动流程中,Flash1 通常指代通过 QSPI1接口连接的合封NOR Flash 大核上的应用程序启动流程分为两个阶段:

  1. 一级Bootloader:固化在SF32LB55X内部的ROM中,加载Flash1中的应用程序并跳转执行

  2. 应用程序:用户程序

一级Bootloader

一级Bootloader固化在了芯片的ROM中,其中断向量表地址为0。上电后会首先运行一级Bootloader,一级Bootloader阶段大核以上电默认的时钟频率运行,一级Bootloader完成基础初始化后,直接从Flash1 中加载用户应用程序。

55系列芯片在一级bootloader阶段会将PA58输出高电平来控制flash1供电。

二级Bootloader

55系列一级Bootloader完成基础初始化后,直接从Flash1 中加载用户应用程序,无二级Bootloader。

应用程序

ResetHandler

应用程序的入口函数为ResetHandler(位于drivers\cmsis\sf32lb55x\Templates\arm\startup_bf0_hcpu.S),其执行流程如下图所示,用户主函数main则由rt_application_init创建的main线程调用,见main_thread_entry流程

reset_handler_flow

SystemInit

SystemInit(在文件drivers/cmsis/sf32lb55x/Templates/system_bf0_ap.c里)在变量初始化之前执行(因此这期间不能使用带初值的变量,零段变量也要避免依赖于初值0),更新VTOR寄存器重定向中断向量表,调用mpu_configcache_enable初始化MPU并使能Cache,这两个函数为weak函数,应用程序中可以重新实现来替换默认的实现。

system_init_flow

rt_hw_board_init

rt_hw_board_init完成底层硬件初始化,例如时钟和IO配置,PSRAM和NOR Flash初始化,heap和串口console的初始化。rt_components_board_init是应用程序自定义的初始化函数,随应用程序配置的不同而调用不同的函数。

rt_hw_board_init

HAL_Init

HAL_Init完成HAL初始化,加载PMU的校准参数,更新时钟、IO设置, 初始化PSRAM和NOR Flash(根据新的时钟配置),下图中绿色函数为板级驱动函数,每个板子有独立的实现,包括HAL_PreInitBSP_IO_InitBSP_PIN_InitBSP_Power_Up等,灰色函数为虚函数,由应用程序实现(也可以不实现),独立于板子,目的是相同板子不同的应用程序可以有自定义的实现,比如不同应用程序在同一块板子上使用不同的IO配置。流程图中横向为函数内的嵌套调用子函数,比如HAL_PreInit调用了时钟配置的函数,HAL_MspInit调用BSP_IO_Init,纵向为串行执行的几个函数,如HAL_PreInit执行完再执行HAL_PostMspInit

hal_init_flow

Config Clock修改的设置包括:

  • 启动GTimer

  • 如果没使用外置XT32K,则切换RTC到RC10K

  • 如果使用外置XT32K,则切换RTC到XT32K

  • 配置系统时钟为240MHz(DLL1)

  • 配置DLL2为96MHz

rt_application_init

rt_application_init中创建main线程,线程入口函数为main_thread_entry,当放开线程调度后(即调用rt_system_scheduler_start之后),main线程得到调度,进入main_thread_entry函数,先调用rt_components_init初始化组件,随后即调用main函数(应用程序实现),用户代码即从main函数开始,比如rt_driver示例的主函数在example/rt_driver/src/main.c中。

main_thread_entry_flow

板级驱动接口

每块板子需要实现如下板级驱动函数,可参考customer/boards/ec-lb55x目录下的文件,

函数名

必选

说明

HAL_PreInit

YES

建议参考硬件形态相近的板子的实现

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

触控上电时调用

BSP_TP_PowerDown

NO

触控断电时调用

HAL_MspInit

NO

被HAL_PreInit调用,虚函数实现为调用BSP_IO_Init

HAL_PostMspInit

NO

BSP_IO_Init

NO

默认被HAL_MspInit调用,

BSP_PIN_Init

NO

由BSP_IO_Init调用,IO配置函数

应用程序自定义驱动接口

如果同一块板子的不同应用程序需要实现不同的HAL_MspInit功能,可以将HAL_MspInit的实现置于应用程序目录下,否则可以放在板子目录下。

函数名

必选

说明

HAL_MspInit

NO

HAL_PostMspInit

NO