1. 啟動模式與地址映射
STM32F103 的啟動模式由 BOOT0 和 BOOT1 引腳配置決定,不同的啟動模式對應不同的存儲器映射:
啟動模式 映射地址范圍 說明
主 Flash 0x08000000~0x0807FFFF 用戶程序存儲在 Flash 中,復位后從 Flash 啟動(默認模式)。
系統存儲器 0x1FFFF000~0x1FFFF7FF 內置 Bootloader(ISP 編程用),用于通過串口/USB 下載程序。
內置 SRAM 0x20000000~0x2000FFFF 調試或臨時運行代碼時使用,需手動加載程序到 SRAM。
地址重映射:Cortex-M3 內核復位后,始終從 0x00000000 讀取初始堆棧指針(SP)和復位向量。STM32 通過內部機制將上述物理地址映射到 0x00000000(例如,Flash 啟動時 0x08000000 被映射到 0x00000000)。
2. 啟動過程關鍵步驟
(1) 硬件復位
復位后,內核執行以下操作:
從 0x00000000 讀取 初始堆棧指針(MSP)。
從 0x00000004 讀取 復位向量地址(程序入口 Reset_Handler)。
跳轉到復位向量地址執行代碼。
(2) 啟動文件(Startup Code)
啟動文件(如 startup_stm32f103xe.s)是匯編代碼,負責初始化關鍵硬件并引導到 main() 函數。主要流程如下:
初始化堆棧指針
定義主堆棧(MSP)和可選的進程堆棧(PSP):
assembly
; 定義堆棧段
Stack_Size EQU 0x400AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
向量表(Vector Table)
中斷向量表位于 Flash 起始位置,包含中斷服務函數地址:
assembly
; 中斷向量表
Vector_Table DCD __initial_sp ; 初始堆棧指針DCD Reset_Handler ; 復位向量DCD NMI_Handler ; NMI 處理函數DCD HardFault_Handler ; 硬件錯誤處理函數... ; 其他中斷向量
復位處理函數(Reset_Handler)
復位后執行的核心初始化代碼:
assembly
Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT SystemInit ; 引入 SystemInit 函數IMPORT __main ; 引入 C 庫初始化函數LDR R0, =SystemInit ; 加載 SystemInit 地址BLX R0 ; 調用 SystemInit(初始化時鐘等)LDR R0, =__main ; 加載 __main 地址BX R0 ; 跳轉到 __main(初始化 C 庫并調用 main())ENDP
(3) SystemInit 函數
SystemInit() 在 system_stm32f1xx.c 中定義,負責初始化關鍵系統配置:
設置時鐘源(HSI/HSE/PLL)。
配置 Flash 預取、等待周期。
初始化 AHB/APB 總線時鐘。
可選:配置向量表偏移寄存器(VTOR)。
(4) __main 和 main()
__main:C 庫函數,負責初始化全局變量、堆棧,最終調用用戶 main()。
main():用戶程序入口。
- 關鍵指令說明
啟動文件中的匯編指令示例:
LDR R0, =label
將 label 的地址加載到寄存器 R0。
assembly
LDR R0, =SystemInit ; 將 SystemInit 函數的地址加載到 R0
BLX R0
跳轉到 R0 指向的地址(調用函數),并保存返回地址到 LR 寄存器。
assembly
BLX R0 ; 調用 SystemInit()
BX R0
跳轉到 R0 指向的地址(不保存返回地址)。
assembly
BX R0 ; 跳轉到 __main
PROC / ENDP
定義函數塊的開始和結束。
assembly
Reset_Handler PROC
…
ENDP
4. 內存布局與 VTOR
向量表偏移寄存器(VTOR):
默認向量表位于 Flash(0x08000000),可通過修改 VTOR 寄存器重定位向量表(如將向量表復制到 RAM):
c
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // 在 SystemInit 中配置
典型內存分布:
0x00000000: 映射到啟動存儲器(Flash/系統存儲器/SRAM)
0x08000000: Flash 實際地址
0x20000000: SRAM 地址
0x40000000: 外設寄存器
5. 常見問題
啟動失敗的可能原因
堆棧溢出導致 MSP 初始化錯誤。
復位向量未正確指向 Reset_Handler。
時鐘配置錯誤(如未啟用外部晶振 HSE)。
調試技巧
檢查向量表是否對齊到 0x200 的倍數。
使用調試器查看 SP 和 PC 的初始值。
總結
STM32F103 的啟動過程由硬件復位、啟動文件初始化、系統配置和用戶程序執行組成。理解地址映射、向量表和關鍵指令對調試和優化啟動流程至關重要。開發者可通過修改啟動文件或調整 BOOT 引腳選擇不同的啟動模式。