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

目录

  • 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.hqwc.cn/news/27657.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨网络的通信过程、路由的作用以及默认网关

如下网络拓扑图,交换机0所在的网段为192.168.1.0/24,交换机1所在网段为192.168.2.0/24,且各自有2台主机: 假设PC0(192.168.1.10/32)要跟PC4(192.168.2.11/32)通信,如何实…

Java版本电子招标采购系统源代码—企业战略布局下的采购寻源

智慧寻源 多策略、多场景寻源,多种看板让寻源过程全程可监控,根据不同采购场景,采取不同寻源策略, 实现采购寻源线上化管控;同时支持公域和私域寻源。 询价比价 全程线上询比价,信息公开透明,可…

matplotlib 3D

import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np# 创建一个三维坐标轴 fig plt.figure() ax fig.add_subplot(221, projection3d) xx fig.add_subplot(222) yy fig.add_subplot(223) xy fig.add_subplot(224)# 生成示例数据…

微服务组件Sentinel

什么是Sentinel Sentinel 是一种用于流量控制、熔断降级和系统负载保护的开源框架。它由阿里巴巴集团开发并开源,旨在帮助开发人员构建可靠和稳定的分布式系统。 Sentinel 提供了以下主要功能: 流量控制:Sentinel 可以通过限制请求的速率或…

缓存淘汰策略

LRU 与 LFU 缓存策略及其实现。 应用层缓存 鉴于磁盘和内存读写的差异性,DB 中低频写、高频读的数据适合放入内存中,直接供应用层读写。在项目中读取用户资料时就使用到了 LRU,而非放到 Redis 中。 缓存的 2 个基本实现 Set(key string, v…

【电路原理学习笔记】第4章:能量与功率:4.4 能量转换与电阻的电压降

第4章:能量与功率 4.4 能量转换与电阻的电压降 图4-11以电子作为电荷进行举例说明,电子从电池的负极流过电路,然后流回正极。当它们从负极出来时,电子具有最高的能量水平。电子流经过每个电阻,这些电阻连接在一起形成…

虚拟机(Ubuntu1804)相机与激光雷达联合标定实现过程记录

在智能小车录制的点云数据在rviz打开一定要修改Fixed Frame为laser_link,这样才能看到点云,注意此时用的是雷神激光雷达,话题名是lslidar_,可采用rostopic list查看具体名称 1、新建一个终端打开roscore roscore2、在文件夹libratia中新建一…

c++基础语法

c基础语法 c的关键字 asm 、do 、if、 return、 try、 continue、 auto、 double、 inline、 short、 typedef、 for、 bool、 dynamic_cast、 int、 signed 、typeid、 public、 break 、else 、long 、sizeof 、typename 、throw、 case、 enum 、mutable、 static、 union、…

C#(六十二)之泛型的约束

类型约束 基类约束有两个重要的目的。 1:它允许在泛型类中使用有约束指定的基类成员。 2:确保只能使用支持指定基类或派生类的类型实例。 约束是使用 where 上下文关键字指定的。 下表列出了五种类型的约束: 约束 说明 T:str…

SpringCloud集成Sleuth+Zipkin进行链路追踪

关于微服务链路追踪的一些概念:【分布式链路追踪】 文章目录 1、整合Seluth2、日志信息分析3、Zipkin介绍4、Zipkin服务端安装5、搭配Sleuth整合客户端Zipkin6、收集数据7、存储trace数据 1、整合Seluth Spring Cloud Sleuth是一个用于追踪的工具,它可以…

智能化升级:科智立RFID AGV地标传感器助力AGV小车升级改造

引言 在这个日新月异的信息化时代,各行各业都在不断进行升级改造,以求在激烈的市场竞争中立于不败之地。其中,智能化升级是提升企业核心竞争力的重要手段。本篇文章将以AGV小车的智能化升级为话题,深入探讨科智立RFID AGV地标传感…

从0到1:跑团小程序开发心得笔记

背景介绍 随着健康意识的兴起,越来越多的人选择加入跑步俱乐部,不仅体验到了运动的乐趣,也感受到了人生的不同色,那么通过小程序,把俱乐部搬到手机上,通过小程序了解俱乐部动态和运动常识,可以…