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

news2024/11/27 12:32:00

目录

  • 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_Init
    main.o(i.main) refers to sys.o(i.sys_stm32_clock_init) for sys_stm32_clock_init
    main.o(i.main) refers to delay.o(i.delay_init) for delay_init
    main.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   PROC
                EXPORT  Reset_Handler   [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR   R0, =SystemInit
                BLX   R0               
                LDR   R0, =__main
                BX      R0
                ENDP

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 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 detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                DCD     ADC3_IRQHandler            ; ADC3
                DCD     FSMC_IRQHandler            ; FSMC
                DCD     SDIO_IRQHandler            ; SDIO
                DCD     TIM5_IRQHandler            ; TIM5
                DCD     SPI3_IRQHandler            ; SPI3
                DCD     UART4_IRQHandler           ; UART4
                DCD     UART5_IRQHandler           ; UART5
                DCD     TIM6_IRQHandler            ; TIM6
                DCD     TIM7_IRQHandler            ; TIM7
                DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

                AREA    |.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.coloradmin.cn/o/764254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MybatisPLus3-Activerecord

不用注入数据层对象&#xff0c;就可以实现对数据的访问和操作 具体步骤 1.实体类继承Model<实体类名> 2.mapper接口继承BaseMapper<类名> 3.通过实例化实体对象&#xff0c;就可以通过对象调用CRUD的方法 增 删除/修改/查找的方式都和上面一样

《TCP IP网络编程》第六章

《TCP IP网络编程》第六章&#xff1a;基于 UDP 的服务端/客户端 UDP 套接字的特点&#xff1a; 通过寄信来说明 UDP 的工作原理&#xff0c;这是讲解 UDP 时使用的传统示例&#xff0c;它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址&#xff0c;之后…

力扣142. 环形链表 II

题目 给定一个链表的头节点head&#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回null。 链接&#xff1a;142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 题解 方法一&#xff1a;设置两个指针&#xff0c;一个指针指向链表头结点&#…

重生之我要学C++第一课

时隔三月&#xff0c;继C语言之后&#xff0c;博主学成C归来&#xff0c;欲重开博客&#xff0c;与诸位分享经验&#xff0c;共同学习&#xff0c;今天就开始我们的c第一课——入门篇。 既然要开始学习c&#xff0c;就要了解 什么是c&#xff1a; C 语言是结构化和模块化的语言…

Vue2 ➔ Vue3 都做了哪些改变?

不是吧&#xff0c;兄弟&#xff0c;Vue3 都出来多久了&#xff0c;你还对这个感兴趣&#xff0c;说&#xff01;是不是没好好卷&#xff1f;&#x1f60f; 俺也一样 &#x1f602;&#xff0c;Vue3 出来之后只是简单了解了一下&#xff0c;然后还是转头一直在写 Vue2。当然&a…

如何升级iOS17/iPadOS17公测版?iOS17公测版升级教程

苹果官方发布了iOS 17/iPadOS 17系统首个公测版更新&#xff0c;其版本号及更新内容与iOS 17 beta 3一致&#xff0c;版本号为21A5277j。 对于想升级iOS 17/iPadOS 17 公测版的用户&#xff0c;可以参考本教程进行操作。 升级注意事项&#xff1a; 1. 为防止意外情况&#xf…

AlignPS中的TOIM损失

本文介绍了CVPR2021行人重识别领域中一篇名为AlignPS论文中的TOIM损失函数 论文链接&#xff1a;https://arxiv.org/abs/2109.00211 代码链接&#xff1a;GitHub - daodaofr/AlignPS: Code for CVPR 2021 paper: Anchor-Free Person Search TOIM TOIM Loss OIM Loss Trip…

【STM32零基础入门教程02】STM32环境获取及搭建

(14条消息) 【STM32零基础入门教程01】STM32入门基础知识_小超电子笔记的博客-CSDN博客 工欲善其事必先利其器&#xff0c;在上一章了解完STM32的一些基础知识之后&#xff0c;我们需要对使用的环境进行获取和安装。 一、MDK&#xff08;KEIL&#xff09;的获取 Keil是一种…

CCF 202209-2 何以包邮? (01背包动态规划练习)

一、先温习一下01背包问题 有N件物品和一个容量为V的背包。第i件物品的体积是c[i]&#xff0c;价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 条件汇总 -------- 背包限制容量&#xff1a;Z 此时背包容量&#xff1a;C 物品&#xff1a;1 , i ... …

WSA - root,frida与ida测试

本文旨在配置windows subsystem for android(win安卓子系统)来作为win在开启了hyper-v的情况下的一种轻量的安卓模拟器方案。使用MagiskOnWsa设置root权限&#xff0c;最终使其正常与开发环境、frida、ida打通。 1. Root的WSA 常用的Wsa版本在目前是没有默认root的。在物理机…

matlab滤波器设计-IIR滤波器的设计与仿真

matlab滤波器设计-IIR滤波器的设计与仿真 1 引言 在现代通信系统中&#xff0c;由于信号中经常混有各种复杂成分&#xff0c;所以很多信号的处理和分析都是基于滤波器而进行的。但是&#xff0c;传统的数字滤波器的设计使用繁琐的公式计算&#xff0c;改变参数后需要重新计…

【Matlab】智能优化算法_猎豹优化算法CO)

【Matlab】智能优化算法_猎豹优化算法CO 1.背景介绍2.数学模型2.1 搜索策略2.2 坐等策略2.3 攻击策略2.4 假设 3.文件结构4.伪代码5.详细代码及注释5.1 CO.m5.2 CO_VectorBased.m5.3 Get_Functions_details.m 6.运行结果7.参考文献 1.背景介绍 猎豹&#xff08;Achinonyx jubat…

Kubernetes部署服务到集群中的指定节点

# kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready master 25h v1.17.3 k8s-node2 Ready <none> 25h v1.17.3 集群只有两个节点&#xff0c;这里打算将应用部署在k8s-node2节点上&#xff0c;需要先记下这个节点的…

【3】Vite Vue3 用户、角色、岗位选择组件封装

在当今前端开发的领域里&#xff0c;快速、高效的项目构建工具以及使用最新技术栈是非常关键的。ViteVue3 组合为一体的项目实战示例专栏将带领你深入了解和掌握这一最新的前端开发工具和框架。 作为下一代前端构建工具&#xff0c;Vite 在开发中的启动速度和热重载方面具有突…

攻不下dfs不参加比赛(十三)

标题 为什么练dfs题目为什么练dfs 相信学过数据结构的朋友都知道dfs(深度优先搜索)是里面相当重要的一种搜索算法,可能直接说大家感受不到有条件的大家可以去看看一些算法比赛。这些比赛中每一届或多或少都会牵扯到dfs,可能提到dfs大家都知道但是我们为了避免眼高手低有的东…

24 - 数组和广义表 - 二维数组

前面我们学习了一维数组、今天来看看二维数组,比一维数组更加复杂! 数组的特点 存储的空间连续 存储类型相同 可以使用地址+偏移快速访问 二维数组定义 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,语法格式如下: 类型说明符 数组名[常量表达式][常量表达…

977.有序数组的平方

977.有序数组的平方 1.暴力排序 这道题最直观的方法在于&#xff0c;将数组中的每个数平方之后&#xff0c;排个序 public int[] sortedSquares(int[] nums) {int[]ans new int[nums.length];for(int i0;i<nums.length;i){ans[i] nums[i]*nums[i];} Arrays.sort(ans);ret…

人工智能LLM模型:奖励模型的训练、PPO 强化学习的训练、RLHF

人工智能LLM模型&#xff1a;奖励模型的训练、PPO 强化学习的训练 1.奖励模型的训练 1.1大语言模型中奖励模型的概念 在大语言模型完成 SFT 监督微调后&#xff0c;下一阶段是构建一个奖励模型来对问答对作出得分评价。奖励模型源于强化学习中的奖励函数&#xff0c;能对当前…

高通芯片android进入EDL模式 下载 热启动 串口指令

参考&#xff1a;高通方案的Android设备几种开机模式的进入与退出_edl模式怎么退出_Rookie20190715的博客-CSDN博客 切换为EDL模式 向串口发送 4b 65 01 00 54 0f 7e 或者adb reboot edl

Ceph的安装部署

文章目录 一、存储基础1.1 单机存储设备1.2 单机存储的问题1.3分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二、Ceph 简介2.1 Ceph 优势2.2 Ceph 架构2.3 Ceph 核心组件2.4 Pool、PG 和 OSD 的关系&#xff1a;2.5 OSD 存储后端2.6 Ceph 数据的存储过程2.7 Ceph 版本…