本文主要是介绍STM32系统启动文件分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
STM32启动代码分析(汇编代码)
启动代码的选择
- 根据自己芯片的选型不同,选择下面不同的启动文件,由于不同容量的启动文件里面所定义的外设中断向量地址在数量上不同,比如小容量的定义了USART1~3而大容量里面却是USART1~5,这样,所定义的4和5的串口中断机在向量表中找不到,会跳转到B. 处死循环。
startup_stm32f10x_ld.s
startup_stm32f10x_md.s
startup_stm32f10x_hd.s
其中,ld.s适用于小容量 产品;md.s适用于中等容量产品;hd适用于大容量产品;
这里的容量是指FLASH的大小.判断方法如下:
小容量:FLASH≤32K
中容量:64K≤FLASH≤128K
大容量:256K≤FLASH
启动代码源码注释分析(此处为V3.5.0版本固件)
因启动代码为汇编代码,所以下面代码中使用//双斜线做注释只是为了能更加清晰的阅读。
;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
;* File Name : startup_stm32f10x_hd.s
;* Author : MCD Application Team
;* Version : V3.5.0
;* Date : 11-March-2011
;* Description : STM32F10x High 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 and also configure the external
;* SRAM mounted on STM3210E-EVAL board to be used as data
;* memory (optional, to be enabled by user)
;* - 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>//栈大小定义,相当于C语言里的宏定义 1Kbyte
Stack_Size EQU 0x00000400//定义堆栈段,8字节对齐,注意,是可读写!!而我们的闪存flash是要擦除后才能写的,这就有问题了,
//说明我们的堆栈段不可能是安排在Flash闪存上的,那安排在哪呢?当然是内部20k的SRAM上啦!AREA STACK, NOINIT, READWRITE, ALIGN=3//stack_Mem为堆栈的底部,SPACE表示存储Stack_size个 分配单元
Stack_Mem SPACE Stack_Size//__initial_sp很显然表示的是栈顶地址
__initial_sp; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>//下面是在SRAM上分配堆空间,大小为512byte
Heap_Size EQU 0x00000200AREA HEAP, NOINIT, READWRITE, ALIGN=3//__heap_base和Heap_Mem为堆起始地址
__heap_base
Heap_Mem SPACE Heap_Size//__heap_limit为堆结束的地址
__heap_limit//8字节对齐,在keil中必须要这一条PRESERVE8//使用的是thumb指令集,但是cortex-m3是thumb-2版本,16位和32位的指令都有 THUMB; Vector Table Mapped to Address 0 at Reset
//只读代码段AREA RESET, DATA, READONLY//导出__Vectors中断向量表起始地址,相当于在此声明__Vectors为一个全局变量,别的文件时可以访问到的 EXPORT __VectorsEXPORT __Vectors_EndEXPORT __Vectors_Size//前面说过0x0地址必须放堆栈顶地址
__Vectors DCD __initial_sp ; Top of Stack//接下来是一些异常向量表,当发生该异常时,PC将会跳到这里执行DCD Reset_Handler ; Reset Handler( 0x0000 0004)DCD 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 InterruptsDCD 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 & ADC2DCD 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 suspendDCD TIM8_BRK_IRQHandler ; TIM8 BreakDCD TIM8_UP_IRQHandler ; TIM8 UpdateDCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and CommutationDCD TIM8_CC_IRQHandler ; TIM8 Capture CompareDCD ADC3_IRQHandler ; ADC3DCD FSMC_IRQHandler ; FSMCDCD SDIO_IRQHandler ; SDIODCD TIM5_IRQHandler ; TIM5DCD SPI3_IRQHandler ; SPI3DCD UART4_IRQHandler ; UART4DCD UART5_IRQHandler ; UART5DCD TIM6_IRQHandler ; TIM6DCD TIM7_IRQHandler ; TIM7DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End__Vectors_Size EQU __Vectors_End - __Vectors//声明代码段|.text|是约定的代码段名称AREA |.text|, CODE, READONLY; Reset handler
//中断异常向量的函数指针
Reset_Handler PROC//此处该符号[WEAK]表示如果外部有同名符号,外部该同名符号是优先使用的EXPORT Reset_Handler [WEAK]//这里先跳到SystemInit函数,进行系统时钟RCC初始化设置和Flash向量中断设置。
//__main标号起始不是我们C语言中的main函数,而是C/C++标准实时库函数里的一个初始化子程序__main的入口地址,
//该程序的一个主要作用是初始化堆栈(对于我们的程序来说是跳转到后面的_user_initial_stackheap标号处进行初
//始化堆栈),并初始化映象文件,最后跳转到C程序的main函数。IMPORT __mainIMPORT SystemInitLDR R0, =SystemInitBLX R0 LDR R0, =__mainBX R0ENDP; Dummy Exception Handlers (infinite loops which can be modified)
//下面就是其他向量的函数地址了,这里只是简单的死循环,不做任何处理,然而很有意思的是,他们都EXPORT…[WEAK]了,
//所以,当我们要设置该异常的中断向量函数时,以我们设置的同名标号为准,这就是我们经常在keil中写的各个外部中断
//的handler了,然而,当没有设置这个异常的中断函数就引发了该中断,程序就会死在中断函数入口了。
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]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_IRQHandlerB .ENDP// 字对齐(32位)ALIGN;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************IF :DEF:__MICROLIB
//导出栈顶,堆头和堆尾地址 EXPORT __initial_spEXPORT __heap_baseEXPORT __heap_limitELSEIMPORT __use_two_region_memory//一个小函数,我们前面提到在__main中会调用他来初始化堆栈 EXPORT __user_initial_stackheap__user_initial_stackheap//传入这些关于堆栈的地址,作为参数LDR R0, = Heap_MemLDR R1, =(Stack_Mem + Stack_Size)LDR R2, = (Heap_Mem + Heap_Size)LDR R3, = Stack_Mem//调回__mian中调用__user_initial_stackheap的地方去 BX LRALIGNENDIF//汇编结束END;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****
这篇关于STM32系统启动文件分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!