上述開機啟動流程比較詳細,内容較為全面,但部分步驟可以省略(紅字可省略标出),因為對于某些初始化,我們可能會在main函數中重新配置。
2.複位程序的詳細跟蹤分析(重點)此次分析基于單步跟蹤stm32從複位到main()函數的彙編代碼。
0.過程補充
中斷向量表:
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
内核設置堆棧從中斷向量表偏移量為0的位置,也就是執行__inital_sp,代碼如下:
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
僞指令AREA,表示開辟一段内存空間,段名是STACK
NOINIT:指定此數據段僅僅保留了内存單元,而沒有将各初始值寫入内存單元,或者将各個内存單元值初始化為0
READWRITE可讀可寫
ALIGN=3-- 2 的3次方表示以8字節對齊
然後設置pc=Rest_handler,執行stm32複位程序。。。。。。。。。
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
這個程序的可以大緻分解為以下兩個函數的調用
SystemInit();
__main();
功能:初始化時鐘(SYSCLK, HCLK, PCLK2 and PCLK1 prescalers)、配置中斷向量表(中斷向量表的定位是在flash還是SRAM)。
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
該函數屬于C/C 庫函數。
該函數的作用是:
功能:跳轉進入__scatterload_rt2函數。
3.__scatterload_rt2函數彙編代碼(C庫函數)
該函數的作用是設置四個寄存器為後續__scatterload_cpy()函數服務的。
設置待copy内容(靜态變量、全局變量、常量)的的加載域和運行域,設置待copy内容的大小,跳轉進入__scatterload_cpy函數
4.__scatterload_cpy函數(C庫函數)
完成靜态變量、全局變量、常量的從flash到SRAM的加載以及程序的跳轉進入__scatterload_zeroinit函數
5.__scatterload_zeroinit函數(C庫函數)
功能:未初始化的全局變量的初始化,跳轉進入__user_steup_stackheap函數
6.__user_steup_stackheap函數(C庫函數)
功能:實現用戶的堆棧的配置
__user_steup_stackheap函數包含了以下函數的調用:
a.__user_libspace------------------------__user_libspace為C庫保持了靜态數據。這是一個96字節,0初始化的數據塊,該塊由C庫創建。在C庫初始化期間可以用來當做臨時棧。
b.__user_initial_stackheap-------------------------------------------------用戶的初始化堆棧函數
調用結束跳轉進入main()函數
8.main()函數
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!