STM32F407汇编启动文件解析 (OTA 初始篇)

问题起源

在编写 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值