问题起源
在编写 STM32 OTA 程序过程中对 FLASH第一个字存放栈顶地址和第二个字存放中断向量表实现比较疑惑,不太确定是在程序的哪个阶段固定这两个地址到了FLASH中,查询资料后发现原来就在启动文件中。
之前工作写应用都是从自定义的main函数开始思考流程,虽然一直知道有启动文件,但是是因为汇编语言编写,所以没有深入了解,这次借此机会把启动文件的流程和具体功能过一遍。
下方代码后都附有具体的注释,实际会汇编指令不多,具体功能都在下方有解释。
代码分析
;*******************************************************************************
;* File Name : startup_stm32f407xx.s
;* Author : MCD Application Team
;* Description : STM32F407xx devices vector table for MDK-ARM toolchain.
设备向量表用于MDK-ARM编译工具链
;* This module performs:
这个模块执行
;* - Set the initial SP 设置最初的堆栈指针
;* - Set the initial PC == Reset_Handler 设置程序计数器值为 复位中断处理函数
;* - Set the vector table entries with the exceptions ISR address 设置向量表入口为异常中断地址?
;* - Branches to __main in the C library (which eventually
;* calls main()). 运行至在C库中的__main函数(最终调用main())。
;* After Reset the CortexM4 processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main. 重置后,CortexM4处理器处于线程模式,优先级为特权,堆栈设置为Main。
;********************************栈空间设置 在内存中************************************************
Stack_Size EQU 0x400 ;定义栈空间大小为0x400个字节,即1Kbyte。等价于: C中#define Stack_Size 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size ;伪指令AREA,表示开辟一段大小为Stack_Size的内存空间作为栈。 READWRITE 表示在内存中
__initial_sp ;标号__initial_sp,表示栈空间顶地址。
;***********************************堆空间设置 在内存中*********************************************
Heap_Size EQU 0x200 ;定义堆空间大小为0x400个字节,也为1Kbyte。
AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;伪指令AREA,READWRITE表示在内存中
__heap_base ;标号__heap_base,表示堆空间起始地址。
Heap_Mem SPACE Heap_Size ;开辟一段大小为Heap_Size的内存空间作为堆。
__heap_limit ;标号__heap_limit,表示堆空间结束地址。
PRESERVE8 ;告诉编译器以8字节对齐。
THUMB ;告诉编译器使用THUMB指令集。
;***********************************对断向量表设置 在FLASH中*********************************************
; Vector Table Mapped to Address 0 at Reset ;
;定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000)
AREA RESET, DATA, READONLY ;READONLY代表在CODE区,也就是FLASH区
EXPORT __Vectors ;将标号__Vectors声明为全局标号,这样外部文件就可以使用这个标号。类似于C中的extern
EXPORT __Vectors_End ;同上
EXPORT __Vectors_Size ;同上
;重要:以下为建立中断向量表,也就是上电首先将这几个地址放置到FLASH开始的位置,这里就是为什么说 FLASH第一个字存放栈顶地址,第二个字存放复位中断函数的由来!
__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 detection
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
DCD FLASH_IRQHandler ; FLASH
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line0
DCD EXTI1_IRQHandler ; EXTI Line1
DCD EXTI2_IRQHandler ; EXTI Line2
DCD EXTI3_IRQHandler ; EXTI Line3
DCD EXTI4_IRQHandler ; EXTI Line4
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0
DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1
DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2
DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3
DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4
DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5
DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6
DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s
DCD CAN1_TX_IRQHandler ; CAN1 TX
DCD CAN1_RX0_IRQHandler ; CAN1 RX0
D

最低0.47元/天 解锁文章
1056

被折叠的 条评论
为什么被折叠?



