STM32的启动过程分析,图文并茂

对于stm32的启动过程一直心存疑惑。今天找了很多资料,进行了一个大致的分析。

1.cortex M3的复位过程(来自官方资料)

上述开机启动流程比较详细,内容较为全面,但部分步骤可以省略(红字可省略标出),因为对于某些初始化,我们可能会在main函数中重新配置。

2.复位程序的详细跟踪分析(重点)

此次分析基于单步跟踪stm32从复位到main()函数的汇编代码。

1.stm32复位程序

 
  1. ; 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();

2.SystemInit()

功能:初始化时钟(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 
}

3.__main();重点

该函数属于C/C++库函数。

该函数的作用是

1.完成全局/静态变量的初始化工作

2.初始化堆栈

3.库函数的初始化

4.程序的跳转,进入main()函数。

1.加载_main()函数的相应汇编代码

2._main()函数的汇编代码

功能:跳转进入__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-------------------------------------------------用户的初始化堆栈函数

7._fp_init和__rt_fp_status_addr(C库函数)------------------------------------------------------两个函数调用实现浮点运算的支持

调用结束跳转进入main()函数

8.main()函数

猜你喜欢

转载自blog.csdn.net/r_m_AA/article/details/82503086