【10】STM32·HAL库开发-MAP文件解析 | STM32启动过程

news/2025/2/12 16:18:06/

目录

  • 1,MAP文件浅析(了解)
    • 1.1MAP文件概念和作用
    • 1.2MAP文件组成
    • 1.3MAP文件实操
  • 2.STM32启动过程(了解)
    • 2.1STM32启动模式(F1/F4/F7/H7)(也称自举模式)
      • 2.1.1STM32启动模式(F1/F4)
      • 2.1.2STM32启动模式(F7)
      • 2.1.3STM32启动模式(H7)
    • 2.2STM32启动过程(以内部FLASH启动为例)
      • 2.2.1启动文件介绍
      • 2.2.2Reset_Handler函数介绍
      • 2.2.2堆栈简介
    • 2.3STM32启动过程图解
  • 3,总结(了解)

该篇文章参考资料为:
STM32 MAP文件浅析.pdf
STM32 启动文件浅析.pdf
Cortex-M3权威指南(中文).pdf

1,MAP文件浅析(了解)

  MDK编译会产生一些中间文件,在之前新建MDK工程时使其输出到了【Output】文件夹,总共有11种,如下表所示:
在这里插入图片描述

1.1MAP文件概念和作用

MAP文件是MDK编译代码后,产生的集程序、数据及IO空间的一种映射列表文件。简单说就是包括了:各种.c文件、函数、符号等的地址、大小、引用关系等信息,用于分析各.c文件占用FLASH 和 RAM的大小,方便优化代码

1.2MAP文件组成

组成部分简介
程序段交叉引用关系描述各文件之间函数调用关系
删除映像未使用的程序段描述工程中未用到而被删除的冗余程序段(函数/数据)(比如说定义了变量temp,但是后面并没有使用temp,MAP文件将变量temp删除,生成一个被删除的列表,也可以是函数,表示未被是使用。)
映像符号表描述各符号(程序段/数据)在存储器中的地址、类型、大小等
映像内存分布图描述各个程序段(函数)在存储器中的地址及占用大小
映像组件大小给出整个映像代码(.o)占用空间汇总信息

1.3MAP文件实操

学会分析:哪个.c占用flash 和ram比较大,以便针对性的优化。(以【09】STM32·HAL库-新建HAL库版本MDK工程 | 下载STM32固件库文章中创建工程为例。

  在【LIsting】选项卡中,可以配置MAP文件产生文件,如果要产生MAP文件需要勾选【Linker Listng: …\Output\f103.map】,具体内容由下方勾选框决定,默认全部勾选
在这里插入图片描述
  在【C/C++】选项卡中,勾选【One ELF Section per Function】,可以将冗余的程序段删除。
在这里插入图片描述
  可以在工程中【Output】文件夹可以找到MAP文件,另一种就是在MDK中双击工程名可以打开MAP文件,此处MAP文件能打开,前提是编译工程0错误,否则可能产生的文件不完整。
在这里插入图片描述
在这里插入图片描述
  “i.main”表示main函数的入口地址,调用了stm32f1xx_hal.o中的"i.HALL_Init"入口地址,也就是HAL_Init函数。

	main.o(i.main) refers to stm32f1xx_hal.o(i.HAL_Init) for HAL_Initmain.o(i.main) refers to sys.o(i.sys_stm32_clock_init) for sys_stm32_clock_initmain.o(i.main) refers to delay.o(i.delay_init) for delay_initmain.o(i.main) refers to main.o(i.led_init) for led_init

  与main函数中代码相对应。

    HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */led_init();                         /* LED初始化 */

  以下部分是未使用的程序段组成的列表。
在这里插入图片描述
  映像符号表显示的内容是局部、全局变量或函数地址、类型、大小等,改变函数为static数据类型,可以改变其在局部或全局的位置。
在这里插入图片描述
  映像内存分布图可以查看程序段在存储器的地址及占用大小。
在这里插入图片描述
  映像组件文件,可以查看用户程序文件的占用空间信息。Code是代码占用空间量,data是编译器数据(不用管),R0 Data是只读,RW Data是可读可写,delay.o是delay.c产生的文件,占用FLASH是Code+R0 Data+RW Data,放到SRAM上是RW Data ZI Data
在这里插入图片描述

2.STM32启动过程(了解)

2.1STM32启动模式(F1/F4/F7/H7)(也称自举模式)

M3/M4/M7等内核复位后,做的第一件事:
1,从地址 0x0000 0000 处取出堆栈指针 MSP 的初始值,该值就是栈顶地址:
2,从地址 0x0000 0004 (STM32为32位单片机,4个字节)处取出程序计数器指针 PC 的初始值,该值是复位向量。
在这里插入图片描述
  芯片厂商可以会把0x0000 0000和0x0000 0004地址映射到其它的地址,根据映射地址的来源将启动分为几种模式。

2.1.1STM32启动模式(F1/F4)

  在系统复位后,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。从系统存储器启动时,系统存储器中存放的是ST的Bootloader程序,Bootloader程序可以引导我们用其他方式下载程序。内置SRAM起始地址也就是块2地址。
在这里插入图片描述
  F4系列不仅可以从内置SRAM启动,还可以从外部SRAM启动,如果要使用FSMC重映射到外部的SRAM:可以通过配置SYSCFG_MEMRMP寄存器。无法下载程序时可以尝试解决方法:BOOT0接3.3V,按复位,然后再下载。

2.1.2STM32启动模式(F7)

  与F1、F4系列相同,F7系列在系统复位后,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存;不同的是在F7系列中只有一个BOOT引脚,接GND为0,接3.3V为1,启动地址由“启动地址选项字节”决定,BOOT_ADD0和BOOT_ADD1位域由FLASH_OPTCR1寄存器决定,由于寄存器设置的是29:14位,该寄存器一共是32位,所以造成寄存器值和启动地址不一致,如果将寄存器值放到32位中对应的值就是启动地址

在这里插入图片描述
  F7系列可以从ITCM或者AXIM都访问到FLASH。允许将自举存储器地址配置为从 0x0000 0000 到 0x2004 FFFF 的任意地址(16KB的整数倍,最小操作位为14,214/1024=16kb。无法下载程序时可以尝试解决方法:BOOT接3.3V,按复位,然后再下载。

2.1.3STM32启动模式(H7)

  在系统复位后,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。
在这里插入图片描述
在这里插入图片描述
  选项字节允许将自举存储器地址配置为从 0x0000 0000 到 0x3FFF 0000 的任意地址,其中低16位只能为0,无论BOOT引脚高低电平,只能设置高16位。无法下载程序解决方法:B0接3.3,按复位,然后再下载。

2.2STM32启动过程(以内部FLASH启动为例)

  在地址0x0800 0000获取栈顶指针MSP的值,在地址0x0800 0004获取中断向量表中的复位向量,也就是中断复位函数名,也是该函数的首地址,该函数被定义在启动文件中,执行完以上两步后,到达main函数,执行用户程序。
在这里插入图片描述

2.2.1启动文件介绍

  **参考资料:**STM32 启动文件浅析.pdf

1,初始化MSP:从0X0800 0000获取,因为从FLASH开始启动
2,初始化PC:从0X0800 0004获取;
3,设置堆栈大小:Heap_Size(堆)、Stack_Size(栈),通过着两个宏来设置堆栈大小
4,初始化中断向量表:__Vectors定义;
5,调用初始化函数:可选的,如调用: SystemInit函数;
6,调用__main:标准C库函数,执行一系列设置,最终调用main函数。用户编写了main函数,编译器会自动定义__main函数

2.2.2Reset_Handler函数介绍

  复位中断函数Reset_Handler被定义在启动文件中,启动文件后缀是“.s”,是汇编语言文件。Reset_Handler函数源码如下:

Reset_Handler   PROCEXPORT  Reset_Handler   [WEAK]IMPORT  __mainIMPORT  SystemInitLDR   R0, =SystemInitBLX   R0               LDR   R0, =__mainBX      R0ENDP

EXPORT:标明全局属性,可被外部调用
IMPORT:声明来自外部文件,类extern
PROC:定义子程序
ENDP:表示子程序结束
WEAK:弱定义,允许用户在其他地方重新定义Reset_Handler函数,那么此处的函数将失效。在HAL库版本中,SystemInit函数在system_stm32f1xx.c中定义,而在寄存器中没有定义所以用分号“;”进行注释掉三行代码。
调用__main,完成一系列操作后,就会执行用户的main函数。
如果外部没有:SystemInit函数,则会报错!

2.2.2堆栈简介

在这里插入图片描述
  函数局部变量较多,嵌套关系复杂时,需加大栈大小(Stack_Size),超过栈的定义大小时会溢出,在启动文件startup_stm32f103xe.s中,栈大小被设置成如下所示。也就是1KB的大小,堆被设置成512B的大小。

Stack_Size      EQU     0x00000400
...
Heap_Size       EQU     0x00000200

  中断向量表如下所示,其中__initial_sp为栈顶指针,STM32复位后第一件事是让MSP指针取中断向量表栈顶地址,依次偏移4字节,可以得到复位中断向量地址等,中断向量表中只是列出了中断处理函数的首地址,在其他处定义

__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 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     RTC_Alarm_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 - __VectorsAREA    |.text|, CODE, READONLY

2.3STM32启动过程图解

  以下信息是正点原子HAL库跑马灯实验仿真得到的数据图,其中堆是0x200大小,大小是0x20000388减去0x20000188,MSP指针自动对值进行加1处理,其实堆空间是到0x20000387,同理栈大小是0x400,但是是向下生长。内核从FLASH启动,首先从0x0800,0000获取MSP堆栈指针初始值(也就是栈顶地址__initial_sp),然后从0x0800,0000获取PC指针初始值(也就是复位中断服务函数首地址),这两个地址通过MAP文件得到,

在这里插入图片描述

3,总结(了解)

在这里插入图片描述


http://www.ppmy.cn/news/940333.html

相关文章

MySQL-DQL-小结

基本查询 条件查询 分组查询 排序查询 分页查询

LAZYSYSADMIN1靶机详解

LAZYSYSADMIN1靶机复盘 一个五分钟就能结束的靶机,非常快。 下载地址:https://download.vulnhub.com/lazysysadmin/Lazysysadmin.zip nmap对这个ip进行单独扫描后发现开启的服务挺多。 就直接枚举了一下这个服务器的内容,发现了一个用户名…

提升按钮效力:七大基本原则全面解析

按钮是交互设计中的基本元素。他们在用户和系统之间扮演重要角色。在本文中,我们将一起思考创建有效按钮所需了解的七个基本原则。 ⬇⬇⬇点击获取更多设计资源 https://js.design/community?categorydesign&sourcecsdn&planbbqcsdn768 让按钮看起来像按…

win10 下Adobe Reader XI闪退问题解决

win10 下Adobe Reader XI闪退问题解决 控制面板→系统安全→防火墙和系统保护→点击“高级设置”→点击“出站规则”→点击“新建规则”→要创建的规则类型“程序”,下一步→此程序路径,默认路径是“C:\Program Files (x86)\Adobe\Reader 11.0\Reader\A…

解决Adobe Reader XI打开就后崩溃问题

2020年2月后在使用Adobe Reader XI后,打开一段时间后会自动卡死后关闭,通过网上查询,发现可能是Adobe搞得鬼。后来发现这些办法可以解决特此记录。 在电脑的host中加入127.0.0.1 acroipm.adobe.com搜索“防火墙和系统保护”→找到并点击“高…

ABAP-接口-tcode:SPROXY-tcode:SXI_MONITOR

SPROXY - ABAP Proxy Generation 查询对象名称激活(服务接口名称) 发送:SI_xxxx_In 接受:SI_xxxx_Out SXI_MONITOR - XI: Message Monitoring 查询接口日志 发送者-接口名称:SI_xxxx_In 接受者-接口名称:…

茜在人名可以读xi吗_茜读xi还是qian?

01 茜可以读xi,也可以读qian,通常用于外国女子名字译音时多读xī,而qin多用于中国名。茜,本义是草名即“茜草”读音为qin时,指茜草,在古汉语中也指“深红”。读xī时,多为音译用字,多…

解决Adobe Acrobat XI pro 开启十几秒自动闪退

解决Adobe Acrobat XI pro 开启十几秒自动闪退 Adobe ReaderXI自动关闭问题: 左下角菜单打开后搜索“防火墙和系统保护”→找到并点击“高级设置”→点击“出站规则”→点击“新建规则”→要创建的规则类型“程序”,下一步→此程序路径,默认…