STM32的启动过程分析

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

上述开机启动流程比较详细,内容较为全面,但部分步骤可以省略(红字可省略标出),因为对于某些初始化,我们可能会在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复位程序。。。。。。。。。

 

 

1.stm32复位程序

 
  1. ; Reset handler

  2. Reset_Handler PROC

  3. EXPORT Reset_Handler [WEAK]

  4. IMPORT __main

  5. IMPORT SystemInit

  6. LDR R0, =SystemInit

  7. BLX R0

  8. LDR R0, =__main

  9. BX R0

  10. ENDP

这个程序的可以大致分解为以下两个函数的调用

SystemInit();

__main();

 

 

2.SystemInit()

功能:初始化时钟(SYSCLK, HCLK, PCLK2 and PCLK1 prescalers)、配置中断向量表(中断向量表的定位是在flash还是SRAM)。

 
  1. void SystemInit (void)

  2. {

  3. /* Reset the RCC clock configuration to the default reset state(for debug purpose) */

  4. /* Set HSION bit */

  5. RCC->CR |= (uint32_t)0x00000001;

  6.  
  7. /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */

  8. #ifndef STM32F10X_CL

  9. RCC->CFGR &= (uint32_t)0xF8FF0000;

  10. #else

  11. RCC->CFGR &= (uint32_t)0xF0FF0000;

  12. #endif /* STM32F10X_CL */

  13.  
  14. /* Reset HSEON, CSSON and PLLON bits */

  15. RCC->CR &= (uint32_t)0xFEF6FFFF;

  16.  
  17. /* Reset HSEBYP bit */

  18. RCC->CR &= (uint32_t)0xFFFBFFFF;

  19.  
  20. /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */

  21. RCC->CFGR &= (uint32_t)0xFF80FFFF;

  22.  
  23. #ifdef STM32F10X_CL

  24. /* Reset PLL2ON and PLL3ON bits */

  25. RCC->CR &= (uint32_t)0xEBFFFFFF;

  26.  
  27. /* Disable all interrupts and clear pending bits */

  28. RCC->CIR = 0x00FF0000;

  29.  
  30. /* Reset CFGR2 register */

  31. RCC->CFGR2 = 0x00000000;

  32. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)

  33. /* Disable all interrupts and clear pending bits */

  34. RCC->CIR = 0x009F0000;

  35.  
  36. /* Reset CFGR2 register */

  37. RCC->CFGR2 = 0x00000000;

  38. #else

  39. /* Disable all interrupts and clear pending bits */

  40. RCC->CIR = 0x009F0000;

  41. #endif /* STM32F10X_CL */

  42.  
  43. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)

  44. #ifdef DATA_IN_ExtSRAM

  45. SystemInit_ExtMemCtl();

  46. #endif /* DATA_IN_ExtSRAM */

  47. #endif

  48.  
  49. /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */

  50. /* Configure the Flash Latency cycles and enable prefetch buffer */

  51. SetSysClock();

  52.  
  53. #ifdef VECT_TAB_SRAM

  54. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */

  55. #else

  56. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */

  57. #endif

  58. }

 

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()函数

 

  • 5
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值