zoukankan      html  css  js  c++  java
  • STM32启动文件详解及SystemInit函数分析(转)

    ;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000
    ;然后在RAM中分配变量使用的堆
    ;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x0800_0000,该中断向量表就从这个起始地址开始分配
    ;分配完成后,再定义和实现相应的中断函数,
    ;所有的中断函数全部带有[weak]特性,即弱定义,如果编译器发现在别处文件中定义了同名函数,在链接时用别处的地址进行链接。
    ;中断函数仅仅实现了Reset_Handler,其他要么是死循环,要么仅仅定义了函数名称
    
    ;STM32被设置为从内部FLASH启动时(这也是最常见的一种情况),当STM32遇到复位信号后,
    ;从0x0800_0000处取出栈顶地址存放于MSP寄存器,从0x0800_0004处取出复位中断服务入口地址放入PC寄存器,
    ;继而执行复位中断服务程序Reset_Handler,
    ;Reset_Handler仅仅执行了两个函数调用,一个是SystemInit,另一个__main,
    ;SystemInit定义在system_stm32f10x.c中,主要初始化了STM的时钟系统:HSI,HSE,LSI,LSE,PLL,SYSCLK,USBCLK,APECLK等等.
    ;__main函数由编译器生成,负责初始化栈、堆等,并在最后跳转到用户自定义的main()函数,来到C的世界。
    
    
    Stack_Size      EQU     0x00000400  ;//定义堆栈大小
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3  ;//定义一个数据段 按8字节对齐    ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0
    Stack_Mem       SPACE   Stack_Size    ;//保留Stack_Size大小的堆栈空间 分 配连续 Stack_Size 字节的存储单元并初始化为 0
    __initial_sp  ;//标号,代表堆栈顶部地址,后面有用
                                                      
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    Heap_Size       EQU     0x00000200    ;//定义堆空间大小
                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3  ;//定义一个数据段,8字节对齐
    __heap_base      ;//标号,代表堆末底部地址,后面有用
    Heap_Mem        SPACE   Heap_Size     ;//保留Heap_Size的堆空间  
    __heap_limit     ;//标号,代表堆界限地址,后面有用
        ;PRESERVE8 指令指定当前文件保持堆栈八字节对齐。 它设置 PRES8 编译属性以通知链接器。
        ;链接器检查要求堆栈八字节对齐的任何代码是否仅由保持堆栈八字节对齐的代码直接或间接地调用。
                    PRESERVE8 ;//指示编译器8字节对齐
                    THUMB   ;//指示编译器以后的指令为THUMB指令 
    
    ;中断向量表定义
    ; Vector Table Mapped to Address 0 at Reset
                    AREA    RESET, DATA, READONLY   ;//定义只读数据段,其实放在CODE区,位于0地址
                    EXPORT  __Vectors    ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用
                    EXPORT  __Vectors_End
                    EXPORT  __Vectors_Size
    __Vectors       DCD     __initial_sp               ; Top of Stack  ;给__initial_sp分配4字节32位的地址0x0
                    DCD     Reset_Handler              ; Reset Handler ; 给标号Reset Handler分配地址为0x00000004
                    DCD     NMI_Handler                ; NMI Handler ; 给标号NMI Handler分配地址0x00000008
                    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
                    ; External Interrupts
                    DCD     WWDG_IRQHandler            ; Window Watchdog
                    DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                    DCD     TAMPER_IRQHandler          ; Tamper
                    DCD     RTC_IRQHandler             ; RTC
                    DCD     FLASH_IRQHandler           ; Flash
                    DCD     RCC_IRQHandler             ; RCC
                    DCD     EXTI0_IRQHandler           ; EXTI Line 0
                    DCD     EXTI1_IRQHandler           ; EXTI Line 1
                    DCD     EXTI2_IRQHandler           ; EXTI Line 2
                    DCD     EXTI3_IRQHandler           ; EXTI Line 3
                    DCD     EXTI4_IRQHandler           ; EXTI Line 4
                    DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                    DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                    DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                    DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                    DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                    DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                    DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                    DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                    DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                    DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                    DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                    DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                    DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                    DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                    DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                    DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                    DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                    DCD     TIM2_IRQHandler            ; TIM2
                    DCD     TIM3_IRQHandler            ; TIM3
                    DCD     TIM4_IRQHandler            ; TIM4
                    DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                    DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                    DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                    DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                    DCD     SPI1_IRQHandler            ; SPI1
                    DCD     SPI2_IRQHandler            ; SPI2
                    DCD     USART1_IRQHandler          ; USART1
                    DCD     USART2_IRQHandler          ; USART2
                    DCD     USART3_IRQHandler          ; USART3
                    DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                    DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                    DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                    DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                    DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                    DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                    DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                    DCD     ADC3_IRQHandler            ; ADC3
                    DCD     FSMC_IRQHandler            ; FSMC
                    DCD     SDIO_IRQHandler            ; SDIO
                    DCD     TIM5_IRQHandler            ; TIM5
                    DCD     SPI3_IRQHandler            ; SPI3
                    DCD     UART4_IRQHandler           ; UART4
                    DCD     UART5_IRQHandler           ; UART5
                    DCD     TIM6_IRQHandler            ; TIM6
                    DCD     TIM7_IRQHandler            ; TIM7
                    DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                    DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                    DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                    DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
    __Vectors_End
    __Vectors_Size  EQU  __Vectors_End - __Vectors
                    AREA    |.text|, CODE, READONLY ;代码段定义
    
    ; Reset Handler
    ;利用PROC、ENDP这一对伪指令把程序段分为若干个过程,使程序的结构加清晰
    Reset_Handler   PROC   ;过程的开始 
                    EXPORT  Reset_Handler             [WEAK];[WEAK] 弱定义,意思是如果在别处也定义该标号(函数),在链接时用别处的地址。
                  ;如果没有其它定方定义,编译器也不报错,以此处地址进行链接。
                  ;EXPORT提示编译器该标号可以为外部文件引用。
                    IMPORT  __main    ;通知编译器要使用的标号在其他文件
                    IMPORT  SystemInit
                    LDR     R0, =SystemInit
                    BLX     R0          ;BX是ARM指令集和THUMB指令集之间程序的跳转     
                    LDR     R0, =__main ;使用“=”表示LDR目前是伪指令不是标准指令。这里是把__main的地址给RO。
                    BX      R0   ;BX是ARM指令集和THUMB指令集之间程序的跳转
                    ENDP     ;过程的结束
                    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    NMI_Handler     PROC
                    EXPORT  NMI_Handler                [WEAK]
                    B       .      ;原地跳转(即无限循环),
                    ENDP
    HardFault_Handler
                    PROC
                    EXPORT  HardFault_Handler          [WEAK]
                    B       .
                    ENDP
    MemManage_Handler
                    PROC
                    EXPORT  MemManage_Handler          [WEAK]
                    B       .
                    ENDP
    BusFault_Handler
                    PROC
                    EXPORT  BusFault_Handler           [WEAK]
                    B       .
                    ENDP
    UsageFault_Handler
                    PROC
                    EXPORT  UsageFault_Handler         [WEAK]
                    B       .
                    ENDP
    SVC_Handler     PROC
                    EXPORT  SVC_Handler                [WEAK]
                    B       .
                    ENDP
    DebugMon_Handler
                    PROC
                    EXPORT  DebugMon_Handler           [WEAK]
                    B       .
                    ENDP
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler             [WEAK]
                    B       .
                    ENDP
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler            [WEAK]
                    B       .
                    ENDP
    Default_Handler PROC
                    EXPORT  WWDG_IRQHandler            [WEAK]
                    EXPORT  PVD_IRQHandler             [WEAK]
                    EXPORT  TAMPER_IRQHandler          [WEAK]
                    EXPORT  RTC_IRQHandler             [WEAK]
                    EXPORT  FLASH_IRQHandler           [WEAK]
                    EXPORT  RCC_IRQHandler             [WEAK]
                    EXPORT  EXTI0_IRQHandler           [WEAK]
                    EXPORT  EXTI1_IRQHandler           [WEAK]
                    EXPORT  EXTI2_IRQHandler           [WEAK]
                    EXPORT  EXTI3_IRQHandler           [WEAK]
                    EXPORT  EXTI4_IRQHandler           [WEAK]
                    EXPORT  DMA1_Channel1_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel2_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel3_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel4_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel5_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel6_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel7_IRQHandler   [WEAK]
                    EXPORT  ADC1_2_IRQHandler          [WEAK]
                    EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]
                    EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]
                    EXPORT  CAN1_RX1_IRQHandler        [WEAK]
                    EXPORT  CAN1_SCE_IRQHandler        [WEAK]
                    EXPORT  EXTI9_5_IRQHandler         [WEAK]
                    EXPORT  TIM1_BRK_IRQHandler        [WEAK]
                    EXPORT  TIM1_UP_IRQHandler         [WEAK]
                    EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]
                    EXPORT  TIM1_CC_IRQHandler         [WEAK]
                    EXPORT  TIM2_IRQHandler            [WEAK]
                    EXPORT  TIM3_IRQHandler            [WEAK]
                    EXPORT  TIM4_IRQHandler            [WEAK]
                    EXPORT  I2C1_EV_IRQHandler         [WEAK]
                    EXPORT  I2C1_ER_IRQHandler         [WEAK]
                    EXPORT  I2C2_EV_IRQHandler         [WEAK]
                    EXPORT  I2C2_ER_IRQHandler         [WEAK]
                    EXPORT  SPI1_IRQHandler            [WEAK]
                    EXPORT  SPI2_IRQHandler            [WEAK]
                    EXPORT  USART1_IRQHandler          [WEAK]
                    EXPORT  USART2_IRQHandler          [WEAK]
                    EXPORT  USART3_IRQHandler          [WEAK]
                    EXPORT  EXTI15_10_IRQHandler       [WEAK]
                    EXPORT  RTCAlarm_IRQHandler        [WEAK]
                    EXPORT  USBWakeUp_IRQHandler       [WEAK]
                    EXPORT  TIM8_BRK_IRQHandler        [WEAK]
                    EXPORT  TIM8_UP_IRQHandler         [WEAK]
                    EXPORT  TIM8_TRG_COM_IRQHandler    [WEAK]
                    EXPORT  TIM8_CC_IRQHandler         [WEAK]
                    EXPORT  ADC3_IRQHandler            [WEAK]
                    EXPORT  FSMC_IRQHandler            [WEAK]
                    EXPORT  SDIO_IRQHandler            [WEAK]
                    EXPORT  TIM5_IRQHandler            [WEAK]
                    EXPORT  SPI3_IRQHandler            [WEAK]
                    EXPORT  UART4_IRQHandler           [WEAK]
                    EXPORT  UART5_IRQHandler           [WEAK]
                    EXPORT  TIM6_IRQHandler            [WEAK]
                    EXPORT  TIM7_IRQHandler            [WEAK]
                    EXPORT  DMA2_Channel1_IRQHandler   [WEAK]
                    EXPORT  DMA2_Channel2_IRQHandler   [WEAK]
                    EXPORT  DMA2_Channel3_IRQHandler   [WEAK]
                    EXPORT  DMA2_Channel4_5_IRQHandler [WEAK]
    WWDG_IRQHandler
    PVD_IRQHandler
    TAMPER_IRQHandler
    RTC_IRQHandler
    FLASH_IRQHandler
    RCC_IRQHandler
    EXTI0_IRQHandler
    EXTI1_IRQHandler
    EXTI2_IRQHandler
    EXTI3_IRQHandler
    EXTI4_IRQHandler
    DMA1_Channel1_IRQHandler
    DMA1_Channel2_IRQHandler
    DMA1_Channel3_IRQHandler
    DMA1_Channel4_IRQHandler
    DMA1_Channel5_IRQHandler
    DMA1_Channel6_IRQHandler
    DMA1_Channel7_IRQHandler
    ADC1_2_IRQHandler
    USB_HP_CAN1_TX_IRQHandler
    USB_LP_CAN1_RX0_IRQHandler
    CAN1_RX1_IRQHandler
    CAN1_SCE_IRQHandler
    EXTI9_5_IRQHandler
    TIM1_BRK_IRQHandler
    TIM1_UP_IRQHandler
    TIM1_TRG_COM_IRQHandler
    TIM1_CC_IRQHandler
    TIM2_IRQHandler
    TIM3_IRQHandler
    TIM4_IRQHandler
    I2C1_EV_IRQHandler
    I2C1_ER_IRQHandler
    I2C2_EV_IRQHandler
    I2C2_ER_IRQHandler
    SPI1_IRQHandler
    SPI2_IRQHandler
    USART1_IRQHandler
    USART2_IRQHandler
    USART3_IRQHandler
    EXTI15_10_IRQHandler
    RTCAlarm_IRQHandler
    USBWakeUp_IRQHandler
    TIM8_BRK_IRQHandler
    TIM8_UP_IRQHandler
    TIM8_TRG_COM_IRQHandler
    TIM8_CC_IRQHandler
    ADC3_IRQHandler
    FSMC_IRQHandler
    SDIO_IRQHandler
    TIM5_IRQHandler
    SPI3_IRQHandler
    UART4_IRQHandler
    UART5_IRQHandler
    TIM6_IRQHandler
    TIM7_IRQHandler
    DMA2_Channel1_IRQHandler
    DMA2_Channel2_IRQHandler
    DMA2_Channel3_IRQHandler
    DMA2_Channel4_5_IRQHandler
                    B       .
                    ENDP
                    ALIGN ;填充字节使地址对齐
    ;*******************************************************************************
    ; User Stack and Heap initialization
    ;*******************************************************************************
    ;堆和栈的初始化
                     IF      :DEF:__MICROLIB ;“DEF”的用法——:DEF:X 就是说X定义了则为真,否则为假
                           ;如果定义了MICORLIB,
                     EXPORT  __initial_sp  ;则将栈顶地址,
                     EXPORT  __heap_base  ;堆起始地址赋予全局属性,
                     EXPORT  __heap_limit  ;堆末端界限地址赋予全局属性,使外部程序可调用
                    
                     ELSE  ;如果没定义__MICROLIB,则使用默认的C运行时库
                    
                     IMPORT  __use_two_region_memory  ;;通知编译器要使用的标号在其他文件__use_two_region_memory    
                     EXPORT  __user_initial_stackheap ;声明全局标号__user_initial_stackheap,这样外程序也可调用此标号
                 ;则进行堆栈和堆的赋值,在__main函数执行过程中调用
    
        ;如果使用默认的C库,程序启动过程中就不会执行该标号下的代码
    __user_initial_stackheap     ;标号__user_initial_stackheap,表示用户堆栈初始化程序入口
            ;//则进行堆栈和堆的赋值,在__main函数执行过程中调用。
                     LDR     R0, =  Heap_Mem     ;保存堆始地址
                     LDR     R1, =(Stack_Mem + Stack_Size) ;保存栈的大小
                     LDR     R2, = (Heap_Mem +  Heap_Size)  ;保存堆的大小
                     LDR     R3, = Stack_Mem    ;保存栈顶指针
                     BX      LR
                     ALIGN  ;填充字节使地址对齐
    
                     ENDIF
         
                     END

  • 相关阅读:
    每天一道LeetCode--141.Linked List Cycle(链表环问题)
    每天一道LeetCode--119.Pascal's Triangle II(杨辉三角)
    每天一道LeetCode--118. Pascal's Triangle(杨辉三角)
    CF1277D Let's Play the Words?
    CF1281B Azamon Web Services
    CF1197D Yet Another Subarray Problem
    CF1237D Balanced Playlist
    CF1239A Ivan the Fool and the Probability Theory
    CF1223D Sequence Sorting
    CF1228D Complete Tripartite
  • 原文地址:https://www.cnblogs.com/Zoran-/p/5819221.html
Copyright © 2011-2022 走看看