STM32 标准库V3.5启动文件startup_stm32f10xxx.s分析

2024-05-18 18:32

本文主要是介绍STM32 标准库V3.5启动文件startup_stm32f10xxx.s分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


layout: post
tags: [STM32]
comments: true

文章目录

    • layout: post tags: [STM32] comments: true
    • 前言
    • 分析startup_stm32f10x_md.s
      • 汇编指令
        • EQU
        • AREA
        • SPACE
        • DCD
        • PROC
        • LDR
        • 常见的转移指令
      • 源码分析

前言

这里以stm32f103为硬件平台,搭建了stm32f1系列的标准库,版本是V3.5,在路径标准库的源码路径下Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup包含了各个编译器或者说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_limitPRESERVE8THUMB; Vector Table Mapped to Address 0 at Reset
;向量表映射到地址0x00000000AREA    RESET, DATA, READONLYEXPORT  __Vectors       ;导出__Vectors符号,用于外部文件的使用EXPORT  __Vectors_End   ;导出向量表的结束地址EXPORT  __Vectors_Size  ;导出向量表的大小;使用DCD为__initial_sp以及异常地址分配内存空间,存到向量表中
__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler; External Interrupts; 外设的中断地址DCD     WWDG_IRQHandler            ; Window WatchdogDCD     PVD_IRQHandler             ; PVD through EXTI Line detectDCD     TAMPER_IRQHandler          ; TamperDCD     RTC_IRQHandler             ; RTCDCD     FLASH_IRQHandler           ; FlashDCD     RCC_IRQHandler             ; RCCDCD     EXTI0_IRQHandler           ; EXTI Line 0DCD     EXTI1_IRQHandler           ; EXTI Line 1DCD     EXTI2_IRQHandler           ; EXTI Line 2DCD     EXTI3_IRQHandler           ; EXTI Line 3DCD     EXTI4_IRQHandler           ; EXTI Line 4DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7DCD     ADC1_2_IRQHandler          ; ADC1_2DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TXDCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1DCD     CAN1_SCE_IRQHandler        ; CAN1 SCEDCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5DCD     TIM1_BRK_IRQHandler        ; TIM1 BreakDCD     TIM1_UP_IRQHandler         ; TIM1 UpdateDCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and CommutationDCD     TIM1_CC_IRQHandler         ; TIM1 Capture CompareDCD     TIM2_IRQHandler            ; TIM2DCD     TIM3_IRQHandler            ; TIM3DCD     TIM4_IRQHandler            ; TIM4DCD     I2C1_EV_IRQHandler         ; I2C1 EventDCD     I2C1_ER_IRQHandler         ; I2C1 ErrorDCD     I2C2_EV_IRQHandler         ; I2C2 EventDCD     I2C2_ER_IRQHandler         ; I2C2 ErrorDCD     SPI1_IRQHandler            ; SPI1DCD     SPI2_IRQHandler            ; SPI2DCD     USART1_IRQHandler          ; USART1DCD     USART2_IRQHandler          ; USART2DCD     USART3_IRQHandler          ; USART3DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI LineDCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
__Vectors_End__Vectors_Size  EQU  __Vectors_End - __Vectors  ;   计算向量表大小AREA    |.text|, CODE, READONLY ;   分配代码段,只读; Reset handler
Reset_Handler    PROCEXPORT  Reset_Handler             [WEAK]IMPORT  __mainIMPORT  SystemInitLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP; Dummy Exception Handlers (infinite loops which can be modified)
; [WEAK]指令会优先使用外部的链接符号,但是没有原型,编译器也不会出现报错
NMI_Handler     PROCEXPORT  NMI_Handler                [WEAK]B       .ENDP
HardFault_Handler\PROCEXPORT  HardFault_Handler          [WEAK]B       .ENDP
MemManage_Handler\PROCEXPORT  MemManage_Handler          [WEAK]B       .ENDP
BusFault_Handler\PROCEXPORT  BusFault_Handler           [WEAK]B       .ENDP
UsageFault_Handler\PROCEXPORT  UsageFault_Handler         [WEAK]B       .ENDP
SVC_Handler     PROCEXPORT  SVC_Handler                [WEAK]B       .ENDP
DebugMon_Handler\PROCEXPORT  DebugMon_Handler           [WEAK]B       .ENDP
PendSV_Handler  PROCEXPORT  PendSV_Handler             [WEAK]B       .ENDP
SysTick_Handler PROCEXPORT  SysTick_Handler            [WEAK]B       .ENDPDefault_Handler PROCEXPORT  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_IRQHandlerB       .ENDPALIGN;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************IF      :DEF:__MICROLIB           EXPORT  __initial_spEXPORT  __heap_baseEXPORT  __heap_limitELSEIMPORT  __use_two_region_memoryEXPORT  __user_initial_stackheap__user_initial_stackheapLDR     R0, =  Heap_MemLDR     R1, =(Stack_Mem + Stack_Size)LDR     R2, = (Heap_Mem +  Heap_Size)LDR     R3, = Stack_MemBX      LRALIGNENDIFEND;******************* (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函数;

这篇关于STM32 标准库V3.5启动文件startup_stm32f10xxx.s分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/995647

相关文章

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛