请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F4启动流程分析

[复制链接]
STMCU小助手 发布时间:2021-12-7 11:00
前言
因为在做有关STM32F407ZET6的项目,其中一项内容是通过IAP来对STM32进行在线升级,那么首先需要对STM32的启动流程需要做到详细了解。

硬件及调试配置说明:

使用芯片:STM32F407ZET6

调试软件:IAR6.3.0

软件库:STM32的HAL库,版本V1.3.0

启动文件:startup_stm32f407xx.s,版本V1.2.1

必须说明:   因为本人使用的IAR开发平台,因此程序中的指令都是IAR指令集(关于IAR指令,参见《EWARM_AssemblerReference.ENU.pdf》文档),因此会发现很多汇编指令会和在别的地方看到的不一样,但是基本指令的功能基本类似,比如IAR中的SECTION指令和标准ARM指令集中的AREA指令。而且,同类型的文件在扩展名上也可能不同,比如对于“分散加载文件”,IAR扩展名为.icf,但是keil扩展名是.scf,而且编辑命令也不同。

(一)启动文件
我们需要了解:一般的,工程文件件中会包含很多的C文件以及必要的S文件(汇编文件)。用户在使用IDE(集成开发平台)对工程进行一键式处理时,经预处理->编译->汇编->链接后生成可执行文件。其中,每一个S或C文件在经过汇编器“汇编”后都会生成对应的目标文件(.o或.obj或类似格式文件),然后由链接器对各个目标文件进行链接,决定各个目标文件在最终可执行文件(bin或hex或类似格式文件)里的位置。                                            

我们只需要知道:startup_stm32f407xx.s文件成成的目标文件在最终可执行文件中是第一个被执行的!

(我想:不同的源文件(C或S)之间是通过函数调用或参数引用而相互关联起来的。即使是main函数,也是被startup_stm32f407xx.s中汇编代码所调用的,而且此段汇编代码前不再存在其他代码,因此汇编程序应该在最前面执行;同时,通过在线调试,可以看到可执行文件的反汇编文件,其中startup_stm32f407xx.s程序确实是在最前面)

STM32F4和STM32F1的启动文件略不相同,但是基本内容是一样的。启动文件的工作按顺序依次分为以下几项:

- Set the initial SP
- Set the initial PC == _iar_program_start,
- Set the vector table entries with the exceptions ISR  address.

- Branches to main in the C library (which eventually  calls main()).

(1)设置堆栈
(2)初始化PC指针
(3)设置向量表

(4)跳转到main函数

下面进行分段是分析:

第一段说明:

  1.         MODULE  ?cstartup

  2.         ;; Forward declaration of sections.
  3.         SECTION CSTACK:DATA:NOROOT(3)

  4.         SECTION .intvec:CODE:NOROOT(2)

  5.         EXTERN  __iar_program_start
  6.         EXTERN  SystemInit
  7.         PUBLIC  __vector_table
复制代码

【1】MODULE 控制指令是用来标记 modules 源码的开始和结束,后边的 ?cstartup 是模块的名字,此文档的最后的 END 表明模块的结束
【2】SECTION 指令是声明段,一个段不能同时包含 public symbol 和 pubweak symbol ,模块只有在相同的名字的模块没有被链接进来的时候才会被链接进来。
        语法格式:SECTION section:type [flag] [(align)]
        align,是用于指定地址对齐到 2^align,他的取值是 0 到 30
        flag,取值NOROOT、ROOT、REORDER、NOREORDER,默认是ROOT,NOROOT表示如果这个段中的符号没有被引用,将会被连接器舍弃,即可被优化。ROOT表示不可被优化。REORDER表示开始一个新的名字是 section 的段(section),NOREORDER表示开始一个新的名字为 section 的片段(fragment),多个片段组成一个段(section)
        type,memory 的类型,取值是 CODE、CONST、DATA
        section,段的名字
【3】EXTERN 用导入(引用)其他模块的 symbol(符号)
【4】PUBLIC 导出 symbol(符号)

第二段:
  1.   DATA
  2. __vector_table
  3.         DCD     sfe(CSTACK)
  4.         DCD     Reset_Handler             ; Reset Handler

  5.         DCD     NMI_Handler               ; NMI Handler
  6.         DCD     HardFault_Handler         ; Hard Fault Handler
  7.         DCD     MemManage_Handler         ; MPU Fault Handler
  8.         DCD     BusFault_Handler          ; Bus Fault Handler
  9.         DCD     UsageFault_Handler        ; Usage Fault Handler
  10.         DCD     0                         ; Reserved
  11.         DCD     0                         ; Reserved
  12.         DCD     0                         ; Reserved
  13.         DCD     0                         ; Reserved
  14.         DCD     SVC_Handler               ; SVCall Handler
  15.         DCD     DebugMon_Handler          ; Debug Monitor Handler
  16.         DCD     0                         ; Reserved
  17.         DCD     PendSV_Handler            ; PendSV Handler
  18.         DCD     SysTick_Handler           ; SysTick Handler

  19.          ; External Interrupts
  20.         DCD     WWDG_IRQHandler                   ; Window WatchDog                                       
  21.         DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                        
  22.         DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line            
  23.         DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
  24.         DCD     FLASH_IRQHandler                  ; FLASH                                          
  25.         DCD     RCC_IRQHandler                    ; RCC                                             
  26.         DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
  27.         DCD     EXTI1_IRQHandler                  ; EXTI Line1                                             
  28.         DCD     EXTI2_IRQHandler                  ; EXTI Line2                                             
  29.         DCD     EXTI3_IRQHandler                  ; EXTI Line3                                             
  30.         DCD     EXTI4_IRQHandler                  ; EXTI Line4                                             
  31.         DCD     DMA1_Stream0_IRQHandler           ; DMA1 Stream 0                                   
  32.         DCD     DMA1_Stream1_IRQHandler           ; DMA1 Stream 1                                   
  33.         DCD     DMA1_Stream2_IRQHandler           ; DMA1 Stream 2                                   
  34.         DCD     DMA1_Stream3_IRQHandler           ; DMA1 Stream 3                                   
  35.         DCD     DMA1_Stream4_IRQHandler           ; DMA1 Stream 4                                   
  36.         DCD     DMA1_Stream5_IRQHandler           ; DMA1 Stream 5                                   
  37.         DCD     DMA1_Stream6_IRQHandler           ; DMA1 Stream 6                                   
  38.         DCD     ADC_IRQHandler                    ; ADC1, ADC2 and ADC3s                           
  39.         DCD     CAN1_TX_IRQHandler                ; CAN1 TX                                                
  40.         DCD     CAN1_RX0_IRQHandler               ; CAN1 RX0                                               
  41.         DCD     CAN1_RX1_IRQHandler               ; CAN1 RX1                                               
  42.         DCD     CAN1_SCE_IRQHandler               ; CAN1 SCE                                               
  43.         DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s                                    
  44.         DCD     TIM1_BRK_TIM9_IRQHandler          ; TIM1 Break and TIM9                  
  45.         DCD     TIM1_UP_TIM10_IRQHandler          ; TIM1 Update and TIM10                 
  46.         DCD     TIM1_TRG_COM_TIM11_IRQHandler     ; TIM1 Trigger and Commutation and TIM11
  47.         DCD     TIM1_CC_IRQHandler                ; TIM1 Capture Compare                                   
  48.         DCD     TIM2_IRQHandler                   ; TIM2                                            
  49.         DCD     TIM3_IRQHandler                   ; TIM3                                            
  50.         DCD     TIM4_IRQHandler                   ; TIM4                                            
  51.         DCD     I2C1_EV_IRQHandler                ; I2C1 Event                                             
  52.         DCD     I2C1_ER_IRQHandler                ; I2C1 Error                                             
  53.         DCD     I2C2_EV_IRQHandler                ; I2C2 Event                                             
  54.         DCD     I2C2_ER_IRQHandler                ; I2C2 Error                                               
  55.         DCD     SPI1_IRQHandler                   ; SPI1                                            
  56.         DCD     SPI2_IRQHandler                   ; SPI2                                            
  57.         DCD     USART1_IRQHandler                 ; USART1                                          
  58.         DCD     USART2_IRQHandler                 ; USART2                                          
  59.         DCD     USART3_IRQHandler                 ; USART3                                          
  60.         DCD     EXTI15_10_IRQHandler              ; External Line[15:10]s                                 
  61.         DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line                  
  62.         DCD     OTG_FS_WKUP_IRQHandler            ; USB OTG FS Wakeup through EXTI line                        
  63.         DCD     TIM8_BRK_TIM12_IRQHandler         ; TIM8 Break and TIM12                  
  64.         DCD     TIM8_UP_TIM13_IRQHandler          ; TIM8 Update and TIM13                 
  65.         DCD     TIM8_TRG_COM_TIM14_IRQHandler     ; TIM8 Trigger and Commutation and TIM14
  66.         DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare                                   
  67.         DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                          
  68.         DCD     FSMC_IRQHandler                   ; FSMC                                            
  69.         DCD     SDIO_IRQHandler                   ; SDIO                                            
  70.         DCD     TIM5_IRQHandler                   ; TIM5                                            
  71.         DCD     SPI3_IRQHandler                   ; SPI3                                            
  72.         DCD     UART4_IRQHandler                  ; UART4                                          
  73.         DCD     UART5_IRQHandler                  ; UART5                                          
  74.         DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                  
  75.         DCD     TIM7_IRQHandler                   ; TIM7                  
  76.         DCD     DMA2_Stream0_IRQHandler           ; DMA2 Stream 0                                   
  77.         DCD     DMA2_Stream1_IRQHandler           ; DMA2 Stream 1                                   
  78.         DCD     DMA2_Stream2_IRQHandler           ; DMA2 Stream 2                                   
  79.         DCD     DMA2_Stream3_IRQHandler           ; DMA2 Stream 3                                   
  80.         DCD     DMA2_Stream4_IRQHandler           ; DMA2 Stream 4                                   
  81.         DCD     ETH_IRQHandler                    ; Ethernet                                       
  82.         DCD     ETH_WKUP_IRQHandler               ; Ethernet Wakeup through EXTI line                     
  83.         DCD     CAN2_TX_IRQHandler                ; CAN2 TX                                                
  84.         DCD     CAN2_RX0_IRQHandler               ; CAN2 RX0                                               
  85.         DCD     CAN2_RX1_IRQHandler               ; CAN2 RX1                                               
  86.         DCD     CAN2_SCE_IRQHandler               ; CAN2 SCE                                               
  87.         DCD     OTG_FS_IRQHandler                 ; USB OTG FS                                      
  88.         DCD     DMA2_Stream5_IRQHandler           ; DMA2 Stream 5                                   
  89.         DCD     DMA2_Stream6_IRQHandler           ; DMA2 Stream 6                                   
  90.         DCD     DMA2_Stream7_IRQHandler           ; DMA2 Stream 7                                   
  91.         DCD     USART6_IRQHandler                 ; USART6                                          
  92.         DCD     I2C3_EV_IRQHandler                ; I2C3 event                                             
  93.         DCD     I2C3_ER_IRQHandler                ; I2C3 error                                             
  94.         DCD     OTG_HS_EP1_OUT_IRQHandler         ; USB OTG HS End Point 1 Out                     
  95.         DCD     OTG_HS_EP1_IN_IRQHandler          ; USB OTG HS End Point 1 In                       
  96.         DCD     OTG_HS_WKUP_IRQHandler            ; USB OTG HS Wakeup through EXTI                        
  97.         DCD     OTG_HS_IRQHandler                 ; USB OTG HS                                      
  98.         DCD     DCMI_IRQHandler                   ; DCMI                                            
  99.         DCD     0                                 ; Reserved                                    
  100.         DCD     HASH_RNG_IRQHandler               ; Hash and RNG
  101.         DCD     FPU_IRQHandler                    ; FPU

  102. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  103. ;;
复制代码

【1】DATA 表示下边中的标签是 32 位的标签,THUMB 表示下边的标签是 16 位的标签,所谓的标签是 地址的别名,不占用代码空间,给编译器看的
【2】 DCD 是数据定义或者 重定位指令,为的是定义一个值,或者保留 memory,DCD 别名是 DC32,用于声明一个 32 位的常量,这部分是中断向量表的内容,需要注意的是,他们的顺序不能改变,此部分会放到 flash 的最开始部分,当系统启动的时候会加载前另个地址,第一个地址是 c 程序的栈的栈顶地址,第二个地址是向量表的开始地址,中断发生时会根据向量表的首地址和偏移量来找到程序的入口
【3】sfe 指令作用是返回栈的结尾,因为栈的增长方向是反方向的

第三段:中断处理函数
  1. ;; Default interrupt handlers.
  2. ;;
  3.         THUMB
  4.         PUBWEAK Reset_Handler
  5.         SECTION .text:CODE:REORDER:NOROOT(2)
  6. Reset_Handler

  7.         LDR     R0, =SystemInit
  8.         BLX     R0
  9.         LDR     R0, =__iar_program_start
  10.         BX      R0

  11.         PUBWEAK NMI_Handler
  12.         SECTION .text:CODE:REORDER:NOROOT(1)
  13. NMI_Handler
  14.         B NMI_Handler

  15.         PUBWEAK HardFault_Handler
  16.         SECTION .text:CODE:REORDER:NOROOT(1)
  17. HardFault_Handler
  18.         B HardFault_Handler

  19.         PUBWEAK MemManage_Handler
  20.         SECTION .text:CODE:REORDER:NOROOT(1)
  21. MemManage_Handler
  22.         B MemManage_Handler

  23.         PUBWEAK BusFault_Handler
  24.         SECTION .text:CODE:REORDER:NOROOT(1)
  25. BusFault_Handler
  26.         B BusFault_Handler

  27.         PUBWEAK UsageFault_Handler
  28.         SECTION .text:CODE:REORDER:NOROOT(1)
  29. UsageFault_Handler
  30.         B UsageFault_Handler

  31.         PUBWEAK SVC_Handler
  32.         SECTION .text:CODE:REORDER:NOROOT(1)
  33. SVC_Handler
  34.         B SVC_Handler

  35.         PUBWEAK DebugMon_Handler
  36.         SECTION .text:CODE:REORDER:NOROOT(1)
  37. DebugMon_Handler
  38.         B DebugMon_Handler

  39.         PUBWEAK PendSV_Handler
  40.         SECTION .text:CODE:REORDER:NOROOT(1)
  41. PendSV_Handler
  42.         B PendSV_Handler

  43.         PUBWEAK SysTick_Handler
  44.         SECTION .text:CODE:REORDER:NOROOT(1)
  45. SysTick_Handler
  46.         B SysTick_Handler

  47.         PUBWEAK WWDG_IRQHandler
  48.         SECTION .text:CODE:REORDER:NOROOT(1)
  49. WWDG_IRQHandler  
  50.         B WWDG_IRQHandler

  51.         PUBWEAK PVD_IRQHandler
  52.         SECTION .text:CODE:REORDER:NOROOT(1)
  53. PVD_IRQHandler  
  54.         B PVD_IRQHandler

  55.         PUBWEAK TAMP_STAMP_IRQHandler
  56.         SECTION .text:CODE:REORDER:NOROOT(1)   
  57. TAMP_STAMP_IRQHandler  
  58.         B TAMP_STAMP_IRQHandler

  59.         PUBWEAK RTC_WKUP_IRQHandler
  60.         SECTION .text:CODE:REORDER:NOROOT(1)  
  61. RTC_WKUP_IRQHandler  
  62.         B RTC_WKUP_IRQHandler

  63.         PUBWEAK FLASH_IRQHandler
  64.         SECTION .text:CODE:REORDER:NOROOT(1)
  65. FLASH_IRQHandler  
  66.         B FLASH_IRQHandler

  67.         PUBWEAK RCC_IRQHandler
  68.         SECTION .text:CODE:REORDER:NOROOT(1)
  69. RCC_IRQHandler  
  70.         B RCC_IRQHandler

  71.         PUBWEAK EXTI0_IRQHandler
  72.         SECTION .text:CODE:REORDER:NOROOT(1)
  73. EXTI0_IRQHandler  
  74.         B EXTI0_IRQHandler

  75.         PUBWEAK EXTI1_IRQHandler
  76.         SECTION .text:CODE:REORDER:NOROOT(1)
  77. EXTI1_IRQHandler  
  78.         B EXTI1_IRQHandler

  79.         PUBWEAK EXTI2_IRQHandler
  80.         SECTION .text:CODE:REORDER:NOROOT(1)
  81. EXTI2_IRQHandler  
  82.         B EXTI2_IRQHandler

  83.         PUBWEAK EXTI3_IRQHandler
  84.         SECTION .text:CODE:REORDER:NOROOT(1)
  85. EXTI3_IRQHandler
  86.         B EXTI3_IRQHandler

  87.         PUBWEAK EXTI4_IRQHandler
  88.         SECTION .text:CODE:REORDER:NOROOT(1)   
  89. EXTI4_IRQHandler  
  90.         B EXTI4_IRQHandler

  91.         PUBWEAK DMA1_Stream0_IRQHandler
  92.         SECTION .text:CODE:REORDER:NOROOT(1)   
  93. DMA1_Stream0_IRQHandler  
  94.         B DMA1_Stream0_IRQHandler

  95.         PUBWEAK DMA1_Stream1_IRQHandler
  96.         SECTION .text:CODE:REORDER:NOROOT(1)   
  97. DMA1_Stream1_IRQHandler  
  98.         B DMA1_Stream1_IRQHandler

  99.         PUBWEAK DMA1_Stream2_IRQHandler
  100.         SECTION .text:CODE:REORDER:NOROOT(1)   
  101. DMA1_Stream2_IRQHandler  
  102.         B DMA1_Stream2_IRQHandler

  103.         PUBWEAK DMA1_Stream3_IRQHandler
  104.         SECTION .text:CODE:REORDER:NOROOT(1)   
  105. DMA1_Stream3_IRQHandler  
  106.         B DMA1_Stream3_IRQHandler

  107.         PUBWEAK DMA1_Stream4_IRQHandler
  108.         SECTION .text:CODE:REORDER:NOROOT(1)   
  109. DMA1_Stream4_IRQHandler  
  110.         B DMA1_Stream4_IRQHandler

  111.         PUBWEAK DMA1_Stream5_IRQHandler
  112.         SECTION .text:CODE:REORDER:NOROOT(1)   
  113. DMA1_Stream5_IRQHandler  
  114.         B DMA1_Stream5_IRQHandler

  115.         PUBWEAK DMA1_Stream6_IRQHandler
  116.         SECTION .text:CODE:REORDER:NOROOT(1)   
  117. DMA1_Stream6_IRQHandler  
  118.         B DMA1_Stream6_IRQHandler

  119.         PUBWEAK ADC_IRQHandler
  120.         SECTION .text:CODE:REORDER:NOROOT(1)
  121. ADC_IRQHandler  
  122.         B ADC_IRQHandler

  123.         PUBWEAK CAN1_TX_IRQHandler
  124.         SECTION .text:CODE:REORDER:NOROOT(1)
  125. CAN1_TX_IRQHandler  
  126.         B CAN1_TX_IRQHandler

  127.         PUBWEAK CAN1_RX0_IRQHandler
  128.         SECTION .text:CODE:REORDER:NOROOT(1)  
  129. CAN1_RX0_IRQHandler  
  130.         B CAN1_RX0_IRQHandler

  131.         PUBWEAK CAN1_RX1_IRQHandler
  132.         SECTION .text:CODE:REORDER:NOROOT(1)  
  133. CAN1_RX1_IRQHandler  
  134.         B CAN1_RX1_IRQHandler

  135.         PUBWEAK CAN1_SCE_IRQHandler
  136.         SECTION .text:CODE:REORDER:NOROOT(1)  
  137. CAN1_SCE_IRQHandler  
  138.         B CAN1_SCE_IRQHandler

  139.         PUBWEAK EXTI9_5_IRQHandler
  140.         SECTION .text:CODE:REORDER:NOROOT(1)
  141. EXTI9_5_IRQHandler  
  142.         B EXTI9_5_IRQHandler

  143.         PUBWEAK TIM1_BRK_TIM9_IRQHandler
  144.         SECTION .text:CODE:REORDER:NOROOT(1)   
  145. TIM1_BRK_TIM9_IRQHandler  
  146.         B TIM1_BRK_TIM9_IRQHandler

  147.         PUBWEAK TIM1_UP_TIM10_IRQHandler
  148.         SECTION .text:CODE:REORDER:NOROOT(1)   
  149. TIM1_UP_TIM10_IRQHandler  
  150.         B TIM1_UP_TIM10_IRQHandler

  151.         PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler
  152.         SECTION .text:CODE:REORDER:NOROOT(1)   
  153. TIM1_TRG_COM_TIM11_IRQHandler  
  154.         B TIM1_TRG_COM_TIM11_IRQHandler

  155.         PUBWEAK TIM1_CC_IRQHandler
  156.         SECTION .text:CODE:REORDER:NOROOT(1)   
  157. TIM1_CC_IRQHandler  
  158.         B TIM1_CC_IRQHandler

  159.         PUBWEAK TIM2_IRQHandler
  160.         SECTION .text:CODE:REORDER:NOROOT(1)
  161. TIM2_IRQHandler  
  162.         B TIM2_IRQHandler

  163.         PUBWEAK TIM3_IRQHandler
  164.         SECTION .text:CODE:REORDER:NOROOT(1)
  165. TIM3_IRQHandler  
  166.         B TIM3_IRQHandler

  167.         PUBWEAK TIM4_IRQHandler
  168.         SECTION .text:CODE:REORDER:NOROOT(1)
  169. TIM4_IRQHandler  
  170.         B TIM4_IRQHandler

  171.         PUBWEAK I2C1_EV_IRQHandler
  172.         SECTION .text:CODE:REORDER:NOROOT(1)
  173. I2C1_EV_IRQHandler  
  174.         B I2C1_EV_IRQHandler

  175.         PUBWEAK I2C1_ER_IRQHandler
  176.         SECTION .text:CODE:REORDER:NOROOT(1)
  177. I2C1_ER_IRQHandler  
  178.         B I2C1_ER_IRQHandler

  179.         PUBWEAK I2C2_EV_IRQHandler
  180.         SECTION .text:CODE:REORDER:NOROOT(1)
  181. I2C2_EV_IRQHandler  
  182.         B I2C2_EV_IRQHandler

  183.         PUBWEAK I2C2_ER_IRQHandler
  184.         SECTION .text:CODE:REORDER:NOROOT(1)
  185. I2C2_ER_IRQHandler  
  186.         B I2C2_ER_IRQHandler

  187.         PUBWEAK SPI1_IRQHandler
  188.         SECTION .text:CODE:REORDER:NOROOT(1)
  189. SPI1_IRQHandler  
  190.         B SPI1_IRQHandler

  191.         PUBWEAK SPI2_IRQHandler
  192.         SECTION .text:CODE:REORDER:NOROOT(1)
  193. SPI2_IRQHandler  
  194.         B SPI2_IRQHandler

  195.         PUBWEAK USART1_IRQHandler
  196.         SECTION .text:CODE:REORDER:NOROOT(1)
  197. USART1_IRQHandler  
  198.         B USART1_IRQHandler

  199.         PUBWEAK USART2_IRQHandler
  200.         SECTION .text:CODE:REORDER:NOROOT(1)
  201. USART2_IRQHandler  
  202.         B USART2_IRQHandler

  203.         PUBWEAK USART3_IRQHandler
  204.         SECTION .text:CODE:REORDER:NOROOT(1)
  205. USART3_IRQHandler  
  206.         B USART3_IRQHandler

  207.         PUBWEAK EXTI15_10_IRQHandler
  208.         SECTION .text:CODE:REORDER:NOROOT(1)   
  209. EXTI15_10_IRQHandler  
  210.         B EXTI15_10_IRQHandler

  211.         PUBWEAK RTC_Alarm_IRQHandler
  212.         SECTION .text:CODE:REORDER:NOROOT(1)   
  213. RTC_Alarm_IRQHandler  
  214.         B RTC_Alarm_IRQHandler

  215.         PUBWEAK OTG_FS_WKUP_IRQHandler
  216.         SECTION .text:CODE:REORDER:NOROOT(1)   
  217. OTG_FS_WKUP_IRQHandler  
  218.         B OTG_FS_WKUP_IRQHandler

  219.         PUBWEAK TIM8_BRK_TIM12_IRQHandler
  220.         SECTION .text:CODE:REORDER:NOROOT(1)   
  221. TIM8_BRK_TIM12_IRQHandler  
  222.         B TIM8_BRK_TIM12_IRQHandler

  223.         PUBWEAK TIM8_UP_TIM13_IRQHandler
  224.         SECTION .text:CODE:REORDER:NOROOT(1)   
  225. TIM8_UP_TIM13_IRQHandler  
  226.         B TIM8_UP_TIM13_IRQHandler

  227.         PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler
  228.         SECTION .text:CODE:REORDER:NOROOT(1)   
  229. TIM8_TRG_COM_TIM14_IRQHandler  
  230.         B TIM8_TRG_COM_TIM14_IRQHandler

  231.         PUBWEAK TIM8_CC_IRQHandler
  232.         SECTION .text:CODE:REORDER:NOROOT(1)
  233. TIM8_CC_IRQHandler  
  234.         B TIM8_CC_IRQHandler

  235.         PUBWEAK DMA1_Stream7_IRQHandler
  236.         SECTION .text:CODE:REORDER:NOROOT(1)   
  237. DMA1_Stream7_IRQHandler  
  238.         B DMA1_Stream7_IRQHandler

  239.         PUBWEAK FSMC_IRQHandler
  240.         SECTION .text:CODE:REORDER:NOROOT(1)
  241. FSMC_IRQHandler  
  242.         B FSMC_IRQHandler

  243.         PUBWEAK SDIO_IRQHandler
  244.         SECTION .text:CODE:REORDER:NOROOT(1)
  245. SDIO_IRQHandler  
  246.         B SDIO_IRQHandler

  247.         PUBWEAK TIM5_IRQHandler
  248.         SECTION .text:CODE:REORDER:NOROOT(1)
  249. TIM5_IRQHandler  
  250.         B TIM5_IRQHandler

  251.         PUBWEAK SPI3_IRQHandler
  252.         SECTION .text:CODE:REORDER:NOROOT(1)
  253. SPI3_IRQHandler  
  254.         B SPI3_IRQHandler

  255.         PUBWEAK UART4_IRQHandler
  256.         SECTION .text:CODE:REORDER:NOROOT(1)
  257. UART4_IRQHandler  
  258.         B UART4_IRQHandler

  259.         PUBWEAK UART5_IRQHandler
  260.         SECTION .text:CODE:REORDER:NOROOT(1)
  261. UART5_IRQHandler  
  262.         B UART5_IRQHandler

  263.         PUBWEAK TIM6_DAC_IRQHandler
  264.         SECTION .text:CODE:REORDER:NOROOT(1)   
  265. TIM6_DAC_IRQHandler  
  266.         B TIM6_DAC_IRQHandler

  267.         PUBWEAK TIM7_IRQHandler
  268.         SECTION .text:CODE:REORDER:NOROOT(1)   
  269. TIM7_IRQHandler  
  270.         B TIM7_IRQHandler

  271.         PUBWEAK DMA2_Stream0_IRQHandler
  272.         SECTION .text:CODE:REORDER:NOROOT(1)   
  273. DMA2_Stream0_IRQHandler  
  274.         B DMA2_Stream0_IRQHandler

  275.         PUBWEAK DMA2_Stream1_IRQHandler
  276.         SECTION .text:CODE:REORDER:NOROOT(1)   
  277. DMA2_Stream1_IRQHandler  
  278.         B DMA2_Stream1_IRQHandler

  279.         PUBWEAK DMA2_Stream2_IRQHandler
  280.         SECTION .text:CODE:REORDER:NOROOT(1)   
  281. DMA2_Stream2_IRQHandler  
  282.         B DMA2_Stream2_IRQHandler

  283.         PUBWEAK DMA2_Stream3_IRQHandler
  284.         SECTION .text:CODE:REORDER:NOROOT(1)   
  285. DMA2_Stream3_IRQHandler  
  286.         B DMA2_Stream3_IRQHandler

  287.         PUBWEAK DMA2_Stream4_IRQHandler
  288.         SECTION .text:CODE:REORDER:NOROOT(1)   
  289. DMA2_Stream4_IRQHandler  
  290.         B DMA2_Stream4_IRQHandler

  291.         PUBWEAK ETH_IRQHandler
  292.         SECTION .text:CODE:REORDER:NOROOT(1)
  293. ETH_IRQHandler  
  294.         B ETH_IRQHandler

  295.         PUBWEAK ETH_WKUP_IRQHandler
  296.         SECTION .text:CODE:REORDER:NOROOT(1)  
  297. ETH_WKUP_IRQHandler  
  298.         B ETH_WKUP_IRQHandler

  299.         PUBWEAK CAN2_TX_IRQHandler
  300.         SECTION .text:CODE:REORDER:NOROOT(1)
  301. CAN2_TX_IRQHandler  
  302.         B CAN2_TX_IRQHandler

  303.         PUBWEAK CAN2_RX0_IRQHandler
  304.         SECTION .text:CODE:REORDER:NOROOT(1)  
  305. CAN2_RX0_IRQHandler  
  306.         B CAN2_RX0_IRQHandler

  307.         PUBWEAK CAN2_RX1_IRQHandler
  308.         SECTION .text:CODE:REORDER:NOROOT(1)  
  309. CAN2_RX1_IRQHandler  
  310.         B CAN2_RX1_IRQHandler

  311.         PUBWEAK CAN2_SCE_IRQHandler
  312.         SECTION .text:CODE:REORDER:NOROOT(1)  
  313. CAN2_SCE_IRQHandler  
  314.         B CAN2_SCE_IRQHandler

  315.         PUBWEAK OTG_FS_IRQHandler
  316.         SECTION .text:CODE:REORDER:NOROOT(1)
  317. OTG_FS_IRQHandler  
  318.         B OTG_FS_IRQHandler

  319.         PUBWEAK DMA2_Stream5_IRQHandler
  320.         SECTION .text:CODE:REORDER:NOROOT(1)   
  321. DMA2_Stream5_IRQHandler  
  322.         B DMA2_Stream5_IRQHandler

  323.         PUBWEAK DMA2_Stream6_IRQHandler
  324.         SECTION .text:CODE:REORDER:NOROOT(1)   
  325. DMA2_Stream6_IRQHandler  
  326.         B DMA2_Stream6_IRQHandler

  327.         PUBWEAK DMA2_Stream7_IRQHandler
  328.         SECTION .text:CODE:REORDER:NOROOT(1)   
  329. DMA2_Stream7_IRQHandler  
  330.         B DMA2_Stream7_IRQHandler

  331.         PUBWEAK USART6_IRQHandler
  332.         SECTION .text:CODE:REORDER:NOROOT(1)
  333. USART6_IRQHandler  
  334.         B USART6_IRQHandler

  335.         PUBWEAK I2C3_EV_IRQHandler
  336.         SECTION .text:CODE:REORDER:NOROOT(1)
  337. I2C3_EV_IRQHandler  
  338.         B I2C3_EV_IRQHandler

  339.         PUBWEAK I2C3_ER_IRQHandler
  340.         SECTION .text:CODE:REORDER:NOROOT(1)
  341. I2C3_ER_IRQHandler  
  342.         B I2C3_ER_IRQHandler

  343.         PUBWEAK OTG_HS_EP1_OUT_IRQHandler
  344.         SECTION .text:CODE:REORDER:NOROOT(1)   
  345. OTG_HS_EP1_OUT_IRQHandler  
  346.         B OTG_HS_EP1_OUT_IRQHandler

  347.         PUBWEAK OTG_HS_EP1_IN_IRQHandler
  348.         SECTION .text:CODE:REORDER:NOROOT(1)   
  349. OTG_HS_EP1_IN_IRQHandler  
  350.         B OTG_HS_EP1_IN_IRQHandler

  351.         PUBWEAK OTG_HS_WKUP_IRQHandler
  352.         SECTION .text:CODE:REORDER:NOROOT(1)   
  353. OTG_HS_WKUP_IRQHandler  
  354.         B OTG_HS_WKUP_IRQHandler

  355.         PUBWEAK OTG_HS_IRQHandler
  356.         SECTION .text:CODE:REORDER:NOROOT(1)
  357. OTG_HS_IRQHandler  
  358.         B OTG_HS_IRQHandler

  359.         PUBWEAK DCMI_IRQHandler
  360.         SECTION .text:CODE:REORDER:NOROOT(1)
  361. DCMI_IRQHandler  
  362.         B DCMI_IRQHandler

  363.         PUBWEAK HASH_RNG_IRQHandler
  364.         SECTION .text:CODE:REORDER:NOROOT(1)  
  365. HASH_RNG_IRQHandler  
  366.         B HASH_RNG_IRQHandler

  367.         PUBWEAK FPU_IRQHandler
  368.         SECTION .text:CODE:REORDER:NOROOT(1)  
  369. FPU_IRQHandler  
  370.         B FPU_IRQHandler

  371.         END
复制代码

【1】THUMB 表明下边是 thumb 指令

【2】Reset_Handler:复位操作后,mcu执行的中断处理函数

R0 = SystemInit                        

BLX     R0                     跳转到 SystemInit 函数(stm32的第一个函数),并将处理器切换到 thumb 态                             

R0 = __iar_program_start            

BX      R0                      跳转到 __iar_program_start 函数,状态也是切换到 thumb 状态

注意:此处BLX 和BX 的用法与区别不过多介绍;

【3】SystemInit函数(大同小异),功能:完成芯片正常运行所需的必备功能项的配置

  1. //#define VECT_TAB_SRAM         //RAM或Flash2RAM中运行
  2. #define VECT_TAB_OFFSET  0x0    //!< Vector Table base offset field.
  3.                                 //This value must be a multiple of 0x200.
复制代码
  1. void SystemInit(void)
  2. {
  3.   /* FPU settings ------------------------------------------------------------*/
  4.   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  5.     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  6.   #endif
  7.   /* Reset the RCC clock configuration to the default reset state ------------*/
  8.   /* Set HSION bit */
  9.   RCC->CR |= (uint32_t)0x00000001;

  10.   /* Reset CFGR register */
  11.   RCC->CFGR = 0x00000000;

  12.   /* Reset HSEON, CSSON and PLLON bits */
  13.   RCC->CR &= (uint32_t)0xFEF6FFFF;

  14.   /* Reset PLLCFGR register */
  15.   RCC->PLLCFGR = 0x24003010;

  16.   /* Reset HSEBYP bit */
  17.   RCC->CR &= (uint32_t)0xFFFBFFFF;

  18.   /* Disable all interrupts */
  19.   RCC->CIR = 0x00000000;

  20. #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  21.   SystemInit_ExtMemCtl();
  22. #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

  23.   /* Configure the Vector Table location add offset address ------------------*/
  24. #ifdef VECT_TAB_SRAM
  25.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  26. #else
  27.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  28. #endif
  29. }
复制代码

【3.1】FPU浮点数运算设置,stm32f4系列支持浮点数运算;

【3.2】配置复位和时钟相关的寄存器:RCC结构体变量包含所有的寄存器成员;

【3.3】外部SRAM配置(一般没有使用外部SRAM);

【3.4】Vector向量表重定位(非常重要):配置中断向量表的基地址和偏移量

(1)当在RAM中调试代码时,需要将向量的基地址修改为RAM1的起始地址;这种情况不用这种模式;

(2)一般我们配置的是NAND FLASH启动模式,应该将向量的基地址修改为FLASH的起始地址;

(3)地址偏移量:当我们的工程文件是stm32上电第一个程序时,应设置VECT_TAB_OFFSET=0;如果在此工程文件前,还有另外的执行程序PRO(比如用于IAP在线升级的bootloader程序),那么需要根据PRO程序的大小来设置VECT_TAB_OFFSET的大小,同时需要注意VECT_TAB_OFFSET的值必须是0x200的2*n(n=1,2,3...)倍数;(此段内容后续 会详细介绍)

【4】此处的 __iar_program_start 在程序中找不到是因为它已经被封装到了 IAR 自带的C库启动代码中了,当我们编译的时候,在项目属性的 linker,library中勾选了 Automatic runtime library ,就告诉了编译器用库中的 __iar_program_start ,具体实现了什么,我们可以查看 IAR 工具为我们提供的源码,具体路径在 IAR 安装目录下的 arm\src\lib\thumb ,我们可以看到有的文件分别的提供了 汇编代码和 c 代码。

查看cstartup_M.c,里面定义了__iar_program_start函数

  1. void __iar_program_start( void )
  2. {
  3.   __iar_init_core();
  4.   __iar_init_vfp();
  5.   __cmain();
  6. }
复制代码

其中:

【4.1】此段的程序中前两个函数是弱函数,在工程共没有定义

【4.2】__cmain 函数作用是初始化段和底层硬件,最后调用main

至此,库文件中的启动文件先分析到这里

(二)启动流程总结:
(1)一般我们配置STM32从flash启动,启动流程如下:

【1.1】MCU上电后从0x0800 0000处读取栈顶地址并保存——>MCU从0x0800 0004处读取中断向量表的起始地址——>根据MCU系统设定的中断偏移量来计算出复位中断向量(起始地址+0),其内容=Reset_Handler,即复位中断处理程序入口地址——>跳转到复位中断处理程序入口处(通过设置PC指针,MCU自动完成,我们不需要管);

【1.2】复位中断函数:

R0 = SystemInit                        
BLX     R0                     跳转到 SystemInit 函数(stm32的第一个函数),并将处理器切换到 thumb 态                             
R0 = __iar_program_start            

BX      R0                      跳转到 __iar_program_start 函数,状态也是切换到 thumb 状态

最后的跳转函数时main函数,即进入用户程序

【1.3】main循环:

需要注意:用户main程序一般内部是一个while(1)死循环(否则,main函数执行完成后,MCU会跳进Hard Fault硬件错误处)

当发生xx中断时:MCU保存现场——>MCU从0x0800 0004处读取中断向量表的起始地址——>根据中断偏移量来计算出xx中断向量,然后取出xx中断处理程序入口地址

【1.4】MCU跳转到xx中断处理程序入口地址处,开始执行中断处理函数。

【1.5】xx中断处理程序完成后,MCU恢复现场,继续执行。

20180411151855472.png



(2)STM32的启动模式简述:

上面讲解的是STM32从flash启动(用户APP程序是从0x08000000开始),实际上STM32支持多种启动模式,这里进行简单介绍:

【2.1】STM32的启动模式由芯片的启动引脚BOOT0和BOOT1决定:MCU在上电时会读取BOOT0和BOOT1引脚的电平状态并锁存,系统根据电平状态来从选择启动方式(注意:这里说的启动是指正常的上电,当我们采用jlink/jtag进行程序烧写或调试时,MCU会会忽略引脚状态)。下面是官方使用指南的说明:

2018041115553187.png


【2.2】STM32三种启动模式对应的物理存储介质均是芯片内置的,它们是:
        a.    主闪存存储器 = 芯片内置的Flash。
        b.    系统存储器 = 芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后用户无法进行读写操作。

        c.  SRAM = 芯片内置的RAM区,具有掉电丢失性。

补充解释:我们知道MCU上电是从0x0000 0000开始执行代码,但是我们发现STM32三种启动模式对应的物理存储介质均不在0x0000 0000处(也不可能同时在),而且地址不连续。这就是,“根据启动引脚,映射到Flash、系统存储区或SRAM”这句话的奇妙,可以理解成一下2点:

A 根据不同的启动模式, 对应到各种启动模式的不同物理存储介质将被映像到第0块(启动存储区);

B  即使被映像到启动存储区,仍然可以在它原先的存储器空间内访问相关的存储器。(未验证,值得去探究!!)

A 就是:逻辑上讲MCU上电是从0x0000 0000开始执行代码,但是实际上PC指针是从实际对应的物理存储介质处开始执行。

比如我们从flash启动,通过IAR或KEIL在线调试,会发现MCU运行时的PC指针是从0x0800 0000开始的。

B就是:因为经过系统映射,那么对映射区的读写 = 对实际物理介质区的读写

比如:在00/01启动模式下,仍可读写执行0x08xxxxxx中的数据和代码, 并和读写执行0x00xxxxxx是一回事;在11启动模式下,仍可读写执行0x20xxxxxx 并和读写执行0x00xxxxxx是一回事

2018041116080763.png



【2.3】三种启动方式对比:

a.   主闪存存储器:最常用的方式,程序掉电不丢失,因此当我们确定工程完全达到使用要求后,一般是将文件烧写到flash中。
b.   系统存储器启动:这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。一般来说,我们选用这种启动模式时,是为了从串口(或是其他类似方式)下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:
        Step1:    将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader
        Step2:    最后在BootLoader的帮助下,通过串口下载程序到Flash中
        Step3:    程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动
可以看到,利用这种模式下载程序的流程稍显繁琐,但是可以通过普通串口代替专用烧写接口,不需要使用专用烧写工具。
c.    内置SRAM:因为SRAM掉电数据丢失,因此这个模式一般用于程序调试,而且SRAM的可擦除次数要远高于flash比如:当代码仅修改了局部内容,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,再将程序下载到Flash中。(还有,一般的,程序在RAM执行速度要比flash快一些)


(3)工程源文件与可执行文件的联系之“分散加载文件”

我们在使用ARM集成开发工具对工程进行开发时,基本流程如下:

20180411215505165.png


源文件经预处理->编译->汇编->链接生成目标文件,生产目标文件之前,我们基本上都可以不用深入研究;目标文件经过连接器连接,生成可执行文件。这里我们需要关注一个问题:不同的目标文件是按照什么规则连接在一起的呢?

所依靠的文件即是:分散加载脚本,

【3.1】简单介绍:对于分散加载的概念,在《ARM体系结构与编程》书中第11章有明确介绍。

    分散加载文件(即scatter file,IAR工程中其后缀为.scf)是一个文本文件,通过编写一个分散加载文件来指定ARM连接器在生成映像文件时如何分配RO,RW,ZI等数据的存放地址。如果不用SCATTER文件指定,那么ARM连接器会按照默认的方式来生成映像文件,一般情况下我们是不需要使用分散加载文件的。

什么时候使用scatter file:
1、存在复杂的地址映射:例如代码和数据需要分开存放在多个区域。
2、存在多个存储器类型:包含Flash, ROM, SDRAM,快速SRAM。我们根据代码与数据的特性把他们发在不同的存储器中,比如中断处理部分放在快速SRAM内部来提高响应速度,而把不常用到的代 码放到速度比较慢的Flash内。
3、函数的地址固定定位:可以利用Scatter file实现把某个函数放在固定地址,而不管其应用程序是否已经改变或重新编译。
4、利用符号确定堆和堆栈。
5、内存映射的IO:利用scatter file可以实现把某个数据段放在精确的地址处。因此对于嵌入式系统来说scatter file是必不可少的,因为嵌入式系统采用了ROM, RAM和内存映射的IO。

【3.2】IAR中的stm32F407的.scf文件的一般格式如下:

  1. /*###ICF### Section handled by ICF editor, don't touch! ****/  
  2. /*-Editor annotation file-*/  
  3. /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */  
  4. /*-Specials-*/  
  5. define symbol __ICFEDIT_intvec_start__ = 0x08000000;/*中断向量表开始地址*/  
  6. /*-Memory Regions-*/  
  7. /*定义内部FLASH地址 */--/*定义内部RAM地址 */  
  8. define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;/*闪存起始地址*/  
  9. define symbol __ICFEDIT_region_ROM_end__   = 0x0800FFFF;/*闪存结束地址---flash大小64k*/  
  10. define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;/*SRAM起始地址*/  
  11. define symbol __ICFEDIT_region_RAM_end__   = 0x20004FFF;/*SRAM结束地址---SRAM大小20k*/  
  12. /*-Sizes-*//* 栈和堆大小*/  
  13. define symbol __ICFEDIT_size_cstack__ = 0x800; /*栈大小*/  
  14. define symbol __ICFEDIT_size_heap__   = 0x800;/*堆大小*/  
  15. /**** End of ICF editor section. ###ICF###*/  

  16. define memory mem with size = 4G;  
  17. define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];  
  18. define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];  

  19. define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };//CSTACK块属性(8字节对齐、大小__ICFEDIT_size_cstack__)  
  20. define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };  
  21. /* 下列语句定义所定义地址空间内可完成的操作类型*/  
  22. initialize by copy { readwrite };  
  23. do not initialize  { section .noinit };  

  24. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; //__ICFEDIT_intvec_start__赋值给.intvec标识符  

  25. place in ROM_region   { readonly };  
  26. place in RAM_region   { readwrite,  
  27.                         block CSTACK, block HEAP };  
复制代码

后续关于分散加载文件会有更加详细的说明;


(三)
由于自身能力有限,本文章存在相关表述问题,希望大家能够批评指正,相互交流,共同进步!

QQ联系方式:1030843709(泊叶)



收藏 评论0 发布时间:2021-12-7 11:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版