【STM32】单片机启动文件分析 01

这篇具有很好参考价值的文章主要介绍了【STM32】单片机启动文件分析 01。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

启动文件

启动文件由汇编语言写成,时单片机上电之后执行的第一个文件。也就是从上电到mian函数中间的一段过程。

bootloader

bootloader也可以叫启动文件,每种MCU都有对应的启动文件。但开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main函数开始进行应用程序的设计即可。

启动文件是使用汇编指令写的,所以在看启动文件之前大家需要先了解一下汇编指令,常用的汇编指令如下:

常见指令

指令 含义
EQU 给数字常量取一个符号名,类似于define
AREA 汇编一个新的代码或者数据段
SPACE 分配内存空间
PRESERVE8 当前文件堆栈需要按8字节对齐
EXPORT 声明一个符号具有全局属性,可以被外部文件调用
DCD 以word为单位分配内存,要求4byte对齐,并且要求初始化这些内存
PROC 定义子程序,与ENDP一同使用表示程序结束
WEAK 弱定义,如果外部文件声明了一个标号,则优先使用外部文件定义的标号,如果外部文件也没有定义,也不会出错。这个是编译器指令,不属于arm的指令。
IMPORT 声明标号来自外部文件,类似于extern
B 跳转到一个标号
ALIGN 编译器对数据或者内存进行对齐,一般跟一个立即数。缺省表示4字节对齐,这个是编译器指令,不属于arm的指令。
END 到达文件末尾文件结束
IF,ELSE,ENDIF 条件语句类似于if else
LDR(load) LDR R0,[R1] 假设R1的值是x,读取地址x上的数据(4个字节)。保存到R0中。
STR(store) STR R0,[R1] 假设R1的值是x,把R0的值写到地址x(4个字节)。
MOV:移动 MOV R0, R1:把R1的值赋给R0. MOV R0, #0x100 R0=0x100

启动文件做了什么

1.设置堆栈指针 SP = _initial_sp
2.设置PC指针 = Reset_Handler
3.配置系统时钟
4.配置外部 SRAM 用于程序变量等数据存储(可选)
5.调用C库的 _main 函数,最终调用main函数

这边我们举个例子来具体说明启动文件具体的执行

开辟栈

Stack_Size      EQU     0x00001800	

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件

EQU 是伪指令。伪指令的意思是指这个 “指令” 并不会生产二进制程序代码,也不会引起变量空间分配。
ARER :汇编一个新的代码或者数据段
STACK : 表示这个段的名字,可以任意命名。
NOINIT: 表示此数据段不需要填入初始数据。
READWRITE:表示此段可读可写。
ALIGN=3: 表示首地址按照2的3次方对齐,所以栈空间是8字节对齐的
SPACE 给 STACK 段分配 Stack_Size 的空间。

__initial_sp只是一个标号,标号主要用于表示一片内存空间的某个位置,等价于C语言中的“地址”概念。地址仅仅表示存储空间的位置。此处的 __initial_sp 紧接着 SPACE 语句放置,表示了栈顶地址。

开辟堆空间

堆和栈的属性都是 READWRITE 可读写,可读写段保存于 SRAM区,即地址0x2000 0000 地址后

; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000000

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件

中断向量表部分

PRESERVE8:指定当前文件的堆栈按照8 字节对齐。
THUMB :表示后面指令兼容THUMB 指令。

                PRESERVE8
                THUMB


; Vector Table Mapped to Address 0 at Reset

                AREA    DEFVECT, DATA, READONLY
                EXPORT  __Vectors

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler

stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
上图中的 AREA 定义了一段名为 RESET 的 READONLY 只读数据段,只读属性保存在 Flash 区(如果STM32从Flash启动,则此中断向量表的地址为0x0800 0000)
EXPORT 指令,使得标号可以被外部文件调用,对应的有个 IMPORT 指令,指示后续符号是在外部文件定义的,外部文件的函数供汇编文件调用
标号__Vectors,表示中断向量表入口地址
标号 __Vectors_End,表示中断向量表的结束地址
标号__Vectors_Size,表示中断向量表的大号

开始建立中断向量表:

stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
中间中断向量省略。。。。。。。
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
DCD指令作用是开辟一段空间,其意义等价于 C 语言中的地址符 “&” 。
中断向量表的建立类似于使用C语言定义了一个指针数组,其每一个成员都是一个函数指针,分别指向各个中断服务函数。

; Vector Table Mapped to Address 0 at Reset

                AREA    DEFVECT, DATA, READONLY
                EXPORT  __Vectors				

__Vectors       DCD     __initial_sp              ; Top of Stack	//分配4字节的空间
                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     DMACERR0_IRQHandler       ; 0,   DMAC Error Count Interrupt
                DCD     DMACTC0_IRQHandler        ; 1,   DMAC Terminal Count Interrupt
                DCD     DMACERR1_IRQHandler       ; 2,   DMAC Error Count Interrupt
                DCD     DMACTC1_IRQHandler        ; 3,   DMAC Terminal Count Interrupt
                DCD     DMACERR2_IRQHandler       ; 4,   DMAC Error Count Interrupt
                DCD  

Reset_Handler 系统启动

系统上电或者复位后首先执行的代码就是复位中断服务函数 Reset_Handler:也是中断向量表的第一个函数。
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
图中的 Reset_Handler 中断服务函数使用了WEAK申明,说明我们在外部可以自定义 Reset_Handler 函数
PROC、ENDP这一对伪指令把程序分为若干个过程,是程序结构更加清晰
LDR R0,[R1]:假设R1的值是x,读取地址x上的数据(4个字节)。保存到R0中。这里是读取SystemInit函数地址,存入R0.

调用SystemInit函数。这个函数里面开启了外部晶振设置了PLL除能了所有中断设置了时钟

_main 标号表示 C/C++标准实时库函数里的一个初始化子程序 _main的入口地址。该程序的一个主要作用是初始化堆栈(跳转_user_initial_stackheap标号进行初始化堆栈),并初始化映像文件,最后跳转到C程序中的main函数。这也正解释了为什么所有的C程序必须有一个main函数作为程序的起点,因为这是由C/C++标准实时库所规定的。

; Reset Handler

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  boot_init
                IMPORT  boot_entry
                LDR     R0, =boot_init
                BLX     R0
				LDR     R0, =0x1008DFFC		;ブートプログラム破損検知状態格納アドレスに"0"を設定
				LDR     R1, =0x00000000
				STR     R1, [R0]
                LDR     R0, =boot_entry
                BX      R0
                ENDP

LDR R0, =0x1008DFFC:仍然是LDR,但是里面有个等号,这是一条伪指令,伪指令就是并不存在这么一条指令,它最终会被拆分成几条真正的RAM指令。执行结果是R0=0x1008DFFC

STR R1, [R0]:假设R1的值是x,把R0的值写到地址x(4个字节)。这里是把R0, =0x1008DFFC的地址写到R1 (R1, =0x00000000)

中断服务程序

stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC
                EXPORT  NMI_Handler               [WEAK]
                B       .
                ENDP

中间中断服务程序省略。。。。。。。
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
中间中断服务程序省略。。。。。。。
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件
当CPU检查到某个中断产生时,硬件会根据我们提供的中断号自动跳转到向量表中与这个中断号对应的这个中断服务函数的入口地址。

上面的这些不管是系统的中断服务程序还是外设的中断服务程序,都是_WEAK申明,其实我们写中断服务函数的时候,都会自己实现,比如F1中,我们在stm32f1xx_it.c文件中实现使用到的中断服务函数:
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件

在工作中遇到一个第二次Reset_Handler2的例子
                ALIGN

                AREA    boot_program_2, CODE, READONLY

; Reset Handler2

Reset_Handler2  PROC
                EXPORT  Reset_Handler2             [WEAK]
                IMPORT  boot_init
                IMPORT  boot_entry
                LDR     R0, =boot_init
                BLX     R0				
				LDR     R0, =0x1008DFFC		;ブートプログラム破損検知状態格納アドレスに"1"を設定
				LDR     R1, =0x00000001
				STR     R1, [R0]
                LDR     R0, =boot_entry
                BX      R0
                ENDP

AREA boot_program_2, CODE, READONLY开辟一段数据空间名叫boot_program_2的readonly的代码段

初始化堆栈

文件最后就是堆栈的初始化工作:
stm32启动文件详解,STM32,单片机,stm32,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-801894.html

到了这里,关于【STM32】单片机启动文件分析 01的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【32单片机学习】(11)STM32启动过程详解

    目录 前言 一、系统架构 二、启动配置 三、启动流程 1.首先复位MCU,获取栈顶指针MSP和PC指针的内容 2.根据PC的值找到复位中断处理函数Reset_Handler 1.进入中断处理函数Reset_Handler 2.进入SystemInit函数 3._main函数 3.进入main函数 总结          通过查阅官方手册和对实际代码进行

    2024年02月08日
    浏览(35)
  • GD32单片机和STM32单片机的对比分析

    GD32单片机和STM32单片机都是基于Arm Cortex-M3/M4内核的32位通用微控制器,广泛应用于各种嵌入式系统和物联网领域。两者之间有很多相似之处,但也有一些不同之处,本文将从以下几个方面对比分析两者的特点、优势和开发成本。 GD32单片机采用的是二代的M3/M4内核,而STM32单片

    2024年02月16日
    浏览(49)
  • STM32+ESP-01s+EMQX实现单片机MQTT协议传输数据上云(二)STM32F103与ESP-01s的Usart通信,实现STM32连接上网上云

    单片机:STM32F103c8t6 WiFi模块:ESP8266-01s EMQX:自身服务器上搭载emq服务器或者借用emqx window 版本  USB TO TTL模块:CH340 因为CH340不能给ESP-01s供3.3V的电,所以测试时需要外加供电           本章中涉及到的技术原理主要为ESP01S wfi模块的AT指令通信,我在上一篇文章给大家提到了

    2024年02月16日
    浏览(46)
  • STM32单片机Flash不擦除直写案例分析

    产品跳闸前需保存致使产品动作的故障类型和具体的故障分析数据,并在产品二次上电后读取故障类型,进行相应指示;之后清除故障类型的相关Flash,但故障分析数据仍保存,以便后续读出分析。然而,Flash扇区擦除时间较长,会影响程序正常运行、判断。 Flash的编程原理都

    2024年02月16日
    浏览(43)
  • GC9A01-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)

           不久前我们收到用户反馈问题中,多次反馈各种不同型号的屏幕驱动不起来,从0开始编写代码花费大量时间,也有不少初次学习驱动屏幕代码编写经验过少等问题,为此我们决定以文章的形式发布到CSDN来分享相应的一些经验以及收集整理好的资料,希望可以帮助用

    2024年01月25日
    浏览(33)
  • K_A23_001 基于STM32等单片机AT指令驱动ESP-01/ESP-01S实现手机遥控点灯

    其他资料目录 直戳跳转 单片机型号 测试条件 模块名称 代码功能 STC89C52RC 晶振11.0592M ESP-01/ESP-01S模块 STC89C52RC驱动ESP-01/ESP-01S模块 实现手机遥控点灯 STM32F103C8T6(标准库) 晶振8M/系统时钟72M ESP-01/ESP-01S模块 STM32F103C8T6驱动ESP-01/ESP-01S模块 实现手机遥控点灯 ESP-01/ESP-01S模块 引脚

    2024年01月21日
    浏览(32)
  • STM32单片机的 Hard-Fault 硬件错误问题追踪与分析

    目录 1、了解STM32的寄存器组 1.1、Cortex-M3的通用寄存器组 1.1.1、通用目的寄存器 R0-R7 1.1.2、通用目的寄存器 R8-R12 1.1.3、R13 — 堆栈指针(SP) 1.1.4、R14 — 连接寄存器(LR) 1.1.5、R15 — 程序计数器(PC) 1.2、Cortex‐M3 的特殊功能寄存器 1.2.1、xPSR — 状态寄存器 1.2.2、中断屏蔽寄

    2024年02月13日
    浏览(34)
  • 物联网选题分享 - 便携式STM32的红外信号分析仪 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(44)
  • STM32单片机(一)STM32简介

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(51)
  • STM32单片机(二)STM32环境搭建

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包