zoukankan      html  css  js  c++  java
  • STM32 标准库V3.5启动文件startup_stm32f10xxx.s分析


    layout: post
    tags: [STM32]
    comments: true

    前言

    这里以stm32f103为硬件平台,搭建了stm32f1系列的标准库,版本是V3.5,在路径标准库的源码路径下LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartup包含了各个编译器或者说IDE的启动文件:
    这些IDE分别是armgcc_ride7,iar,TrueSTUDIO,不过这不是关注的重点,本文主要分析startup_stm32f10x_md.s

    分析startup_stm32f10x_md.s

    首先看一下arm文件夹下的文件,具体如下;

    -ar---        2011/3/10     10:52          15766 startup_stm32f10x_cl.s
    -ar---        2011/3/10     10:52          15503 startup_stm32f10x_hd.s
    -ar---        2011/3/10     10:52          15692 startup_stm32f10x_hd_vl.s
    -ar---        2011/3/10     10:52          12376 startup_stm32f10x_ld.s
    -ar---        2011/3/10     10:52          13656 startup_stm32f10x_ld_vl.s
    -ar---        2011/3/10     10:52          12765 startup_stm32f10x_md.s
    -ar---        2011/3/10     10:51          14073 startup_stm32f10x_md_vl.s
    -ar---        2011/3/10     10:51          15955 startup_stm32f10x_xl.s
    

    这里可以看到文件最终加以区分的是xl,md_vl,md等等,这些需要根据芯片具体的容量不同进行选择;
    下面看一下startup_stm32f10x_md.s的汇编代码另外一般用户的代码都是从main()函数开始的,但是在此之前,则有启动代码初始化化硬件环境,然后跳转到 c runtime lib__main中,进行运行环境的初始化,包括栈,堆等等,最终跳转到用户的main函数中。这里没有找到c runtime lib的源码,着实有点遗憾。

    在分析源码之前,有必要对部分汇编指令进行简单的了解,这里参考了《Cortex_M3权威指南》

    汇编指令

    EQU

    将一个变量赋值,例如:Stack_Size EQU 0x00000400|

    AREA

    用于定义一个代码段或数据段,具体用法如:AREA 段名称 {,参数1} {,参数2}...

    SPACE

    用于申请一片内存空间但不赋初值,例如:Stack_Mem SPACE 0x00000400,分配1024字节的内存控制,感觉相当于mallocStack_Mem应该会该内存空间的首地址;

    DCD

    用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化

    PROC

    该伪指令用于定义子程序,位置在子程序的开始处,它和ENDP分别表示子程序定义的开始和结束两者必须成对出现;

    LDR

    从存储器中加载字到一个寄存器中,Load Data to Register

    常见的转移指令

    • B Label 跳转到 Label 处对应的地址
    • BX reg 跳转到由寄存器 reg 给出的地址
    • BL Label 跳转到 Label 对应的地址,并且把跳转前的下条指令地址保存到 LR
    • BLX reg 跳转到由寄存器 reg 给出的地址,并根据 REG 的 LSB 切换处理器状态,还要把转移前的下条指令地址保存到 LR

    LR(Link Register),连接寄存器的英文缩写,在ARM体系结构中LR的特殊用途有两种:
    一是用来保存子程序返回地址;
    二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。

    源码分析

    下面参考一下startup_stm32f10x_md.s的源码,进行分析一下。

    ;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
    ;* File Name          : startup_stm32f10x_md.s
    ;* Author             : MCD Application Team
    ;* Version            : V3.5.0
    ;* Date               : 11-March-2011
    ;* Description        : STM32F10x Medium Density Devices vector table for MDK-ARM 
    ;*                      toolchain.  
    ;*                      This module performs:
    ;*                      - Set the initial SP
    ;*                      - Set the initial PC == Reset_Handler
    ;*                      - Set the vector table entries with the exceptions ISR address
    ;*                      - Configure the clock system
    ;*                      - Branches to __main in the C library (which eventually
    ;*                        calls main()).
    ;*                      After Reset the CortexM3 processor is in Thread mode,
    ;*                      priority is Privileged, and the Stack is set to Main.
    ;* <<< Use Configuration Wizard in Context Menu >>>   
    ;*******************************************************************************
    ; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
    ; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
    ; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
    ; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
    ; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
    ; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
    ;*******************************************************************************
    
    ; Amount of memory (in bytes) allocated for Stack
    ; Tailor this value to your application needs
    ; <h> Stack Configuration
    ;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    Stack_Size      EQU     0x00000400  ;栈空间 1024 Bytes,1K的空间
    
                    ;分配数据段,命名为`STACK`,数据段未初始化,可以读写
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3   ;
    Stack_Mem       SPACE   Stack_Size
    __initial_sp
    
    
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Heap_Size       EQU     0x00000200  ;堆空间的配置,512 字节的空间
    
                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3
    __heap_base
    Heap_Mem        SPACE   Heap_Size   ;分配堆空间为 512字节
    __heap_limit
    
                    PRESERVE8
                    THUMB
    
    ; Vector Table Mapped to Address 0 at Reset
    ;向量表映射到地址0x00000000
                    AREA    RESET, DATA, READONLY
                    EXPORT  __Vectors       ;导出__Vectors符号,用于外部文件的使用
                    EXPORT  __Vectors_End   ;导出向量表的结束地址
                    EXPORT  __Vectors_Size  ;导出向量表的大小
    
    ;使用DCD为__initial_sp以及异常地址分配内存空间,存到向量表中
    __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
    
                    ; 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_2
                    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
    __Vectors_End
    
    __Vectors_Size  EQU  __Vectors_End - __Vectors  ;   计算向量表大小
    
                    AREA    |.text|, CODE, READONLY ;   分配代码段,只读
    
    ; Reset handler
    Reset_Handler    PROC
                     EXPORT  Reset_Handler             [WEAK]
         IMPORT  __main
         IMPORT  SystemInit
                     LDR     R0, =SystemInit
                     BLX     R0
                     LDR     R0, =__main
                     BX      R0
                     ENDP
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    ; [WEAK]指令会优先使用外部的链接符号,但是没有原型,编译器也不会出现报错
    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]
    
    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
    
                    B       .
    
                    ENDP
    
                    ALIGN
    
    ;*******************************************************************************
    ; User Stack and Heap initialization
    ;*******************************************************************************
                     IF      :DEF:__MICROLIB           
                    
                     EXPORT  __initial_sp
                     EXPORT  __heap_base
                     EXPORT  __heap_limit
                    
                     ELSE
                    
                     IMPORT  __use_two_region_memory
                     EXPORT  __user_initial_stackheap
                     
    __user_initial_stackheap
    
                     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
    
    ;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****
    
    

    主要做了这几个事情:

    1. 初始化堆栈内存空间;
    2. 设置PC寄存器的地址指向Reset_Handler,即上电便运行复位程序;
    3. 设置向量表,中断服务程序入口地址;
    4. 配置系统时钟, SystemInitmain函数运行前就已经运行了;
    5. 运行外部的函数,LDR R0, =__main,将__main地址装载到R0寄存器并运行,__main在C库中,会初始化程序的C运行环境,最终调用用户的main函数;
  • 相关阅读:
    httpcontext in asp.net unit test
    initialize or clean up your unittest within .net unit test
    Load a script file in sencha, supports both asynchronous and synchronous approaches
    classes system in sencha touch
    ASP.NET MVC got 405 error on HTTP DELETE request
    how to run demo city bars using sencha architect
    sencha touch mvc
    sencha touch json store
    sencha touch jsonp
    51Nod 1344:走格子(贪心)
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783374.html
Copyright © 2011-2022 走看看