首页 > 其他分享 >简单讲解一下STM32的启动过程

简单讲解一下STM32的启动过程

时间:2024-07-23 11:55:24浏览次数:17  
标签:__ 文件 启动 跳转 MSP STM32 地址 讲解 main

启动模式

首先我们先看一下启动模式

第一个为内部 FLASH 启动方式      当芯片上电后采样到 BOOT0 引脚为低电平时, 0x00000000 和 0x00000004 地址被映射到 内部 FLASH 的首地址 0x08000000 和 0x08000004 。因此,内核离开复位状态后,读取内部 FLASH 117 的 0x08000000 地址空间存储的内容,赋值给栈指针 MSP ,作为栈顶地址,再读取内部 FLASH 的 0x08000004 地址空间存储的内容,赋值给程序指针 PC ,作为将要执行的第一条指令所在的 地址。完成这两个操作后,内核就可以开始从 PC 指向的地址中读取指令执行了。 第二种为内部 SRAM 启动方式        类似于内部 Flash ,当芯片上电后采样到 BOOT0 和 BOOT1 引脚均为高电平时,地址0x00000000 和 0x00000004 被映射到内部 SRAM 的首地址 0x20000000 和 0x20000004。 在实际应用中,由启动文件 决定0x00000000 和 0x00000004 地址存储什么内容,链接时,由分散加载文件 (sct) 决定这些内容的绝 对地址,即分配到内部 FLASH 还是内部 SRAM 。 第三种系统存储器启动方式用到的较少,用于更新和修复功能,这个我感觉初学者不用考虑。

启动流程

    RESET->获取MSP值,获取PC值->Reset_Handler

在cortex-M3权威指南中是这样讲的:

下面两个图片可以先不看

现在讲一下MSP和SP是什么

MSP是复位向量的第一个字(32位)包含堆栈指针(MSP - Main Stack Pointer)的初始值。处理器将该值加载到堆栈指针寄存器(SP)中。简单地说,就是一会要分配的栈的起始地址。因为 CM3 使用的是向下生长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加 1。 举例来说,如果你的栈区域在 0x20000388‐0x20000787 之间,那么 MSP 的初始值就必须是0x20000788。

PC: 复位向量的第二个字包含程序计数器(PC - Program Counter)的初始值,即复位向量。处理器将该值加载到程序计数器寄存器(PC)中。 简单的说就是指向并调用Reset_Handler函数

Reset_Handler: 一个特殊的函数,由启动文件(通常是startup_stm32xxx.s)提供。Reset_Handler 会执行一些处理器的基本初始化,然后跳转到 main 函数。

启动文件解析

参考正点原子的STM32启动浅析,启动文件的关键步骤如下

现在来看一下startup_stm32f103xb.s

栈空间的开辟,大小为Stack_Size,这里就是0x400 堆空间的开辟,和栈一样,堆大小为0X200, PRESERVE8 :指示编译器按照 8 字节对齐。 THUMB :指示编译器之后的指令为 THUMB 指令。

中断向量定义表

    前几段声明了__Vectors(向量起始地址)、__Vectors_End (向量结束地址)和 __Vectors_Size (向量大小)三个标号具有全局性(EXPORT),可被外部的文件使用。

  61行注释说了这一个是,栈顶指针,这里如果是在内部FLASH运行,就是0x08000000。DCD表示以四字节对齐分配内存,那么下个地址是 0x0800 0004,存放的是 Reset_Handler 中断函数入口地址。这里也说明函数其实就是一个地址。这里截图不完整,在ST公司的参考手册9.1.2中断和异常向量中有完整的向量表。

122-124行是计算范围

126行是定义一个段命为.text,只读的代码段,在 CODE 区。

129行之后就是程序的实现了

第一个就是Reset_Handler

首先利用 PROC 、 ENDP 这一对伪指令把程序段分为若干个过程,使程序的结构加清晰。 首先用EXPORT将其设置为全局属性 这样外部文件就可以调用此复位中断服务。WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用外部定义的标号,如果外部文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。 就是你可以用这个,如果你自己想自己定义也可以,定义后以你自己定义的为主。 131 行和 132 行 IMPORT 表示该标号来自外部文件。这里表示 SystemInit 和__main 这
两个函数均来自外部的文件。
133 行 LDR 表示从存储器中加载字到一个存储器中。SystemInit 是一个标准的库函数,
在 system_stm32f1xx.c 文件中定义,主要作用是配置系统时钟、还有就是初始化 FSMC/FMC
总线上外挂的 SRAM(可选),前面说配置外部 SRAM 作为数据存储器(可选)就是这个。
134 行 BLX 表示跳转到由寄存器给出的地址,并根据寄存器的 LSE 确定处理器的状态,
还要把跳转前的下条指令地址保存到 LR。
135 行把__main 的地址给 R0。__main 是一个标准的 C 库函数,主要作用是初始化用
户堆栈和变量等,最终调用 main 函数去到 C 的世界。这就是为什么我们写的程序都有一
个 main 函数的原因,如果不调用__main,那么程序最终就不会调用我们 C 文件里面的
main,也就无法正常运行。__main和main不是一个东西
136 行 BX 表示跳转到由寄存器/标号给出的地址,不用返回。这里表示切换到__main
地址,最终调用 main 函数,不返回,进入 C 的世界。
137 行 ENDP 表示子程序结束

上面就是中断服务程序的声明了B 指令是跳转到一个标号,这里跳转到一个‘.’,表示无限循环。

都有WEAK声明。所以真正的中断服务函数需要我们在外部实现。  

最后面就是用户堆栈的初始化,堆是从低到高生长,栈是从高到低生长,是两个互相独立的数据段,并且不能交叉使用。这里就不做详细分析了。

标签:__,文件,启动,跳转,MSP,STM32,地址,讲解,main
From: https://blog.csdn.net/p18440/article/details/140629962

相关文章

  • VS2022无法启动程序
    win11专业版23h2在安装VS2022时会遇到以下问题以下就是正确的操作方法1.首先打开VS022的install 2.点击修改 3.选择单个组件 4.找到Windows11SDK(10.0.26100.0)安装好之后就可以正常的编写c/c++代码了 ......
  • 源神,启动!马斯克开源史上最大模型Grok,参数高达3140亿,可商用!
    马斯克真不愧是源神,自开源X的推荐算法以及特斯拉智能驾驶算法后,又说到做到,开源旗下大模型Grok!代码和模型权重已上线GitHub。官方信息显示,此次开源的Grok-1是一个3140亿参数的混合专家模型,远超OpenAIGPT-3.5的1750亿。,就是说,这是当前开源模型中参数量最大的一个,遵照Apache......
  • 如何在启动时设置 Raspberry Pi 上的显示环境变量?
    我有一个RaspberryPi4,显示屏为1280x800,没有键盘或鼠标。我通过WiFi远程ssh进入它,并对它进行编码以显示图像,最终无需我ssh进入它。我安装了feh并在python脚本中使用它来显示图像:importsubprocessimage=subprocess.Popen(["feh","--hide-pointer","-x","-q"......
  • STM32&定时器(超明白超细致超核心)
    可以说,STM32的定时器是32这块芯片中功能最多,结构最复杂,内容涉及最多的外设之一了。从学习形式来看,可以归纳为两个层面:原理层和软件层。那么由于内容太多,我也按照这个架构来逐一进行讲解。目录一:定时器架构与原理1.时基2.计数方式3.定时器的架构二.定时器功能1.基础溢出......
  • java毕业设计-基于springboot+vue的校园二手交易系统,基于java的校园二手交易系统,基于j
    文章目录前言演示视频项目背景项目架构和内容获取(文末获取)具体实现截图前台功能管理后台技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站前言博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • VScode利用EIDE和cortex-debug进行stm32开发(也适用51)
    文章目录前言必要准备第一步:安装vscode插件——EIDEEIDE是什么EIDE的下载**EIDE的配置(重点)**EIDE功能的简单介绍1.项目的建立:新建项目或者导入项目2.为项目选择[芯片支持包](https://em-ide.com/zh-cn/docs/modules/chip_pkg)(不是必须)3.构建配置4.[烧录配置](https://e......
  • Python学习-九大数据类型整合,详细讲解
    目录1.int(整型)2.float(浮点型)3.Bool(布尔类型)4.Str(字符串类型)5.None(空值)6.List(列表)7.Tuple(元组)8.Dict(字典)9.Set(集合)(字典,列表,元组,字符串知识点可能不全,可以参考本人之前发的博客进行学习,加油。)1.int(整型)特点和用途:1.可以表示正整数、负整数......
  • Python学习—函数篇 面面俱到,细致讲解
    目录1.函数目的2.函数定义3.函数的调用4.函数的形参,实参5.函数的返回值1.返回一个值2.返回多个值3.没有返回值4.返回None6.函数的参数类型1.必需参数2.关键字参数3.默认参数4.可变参数5.关键字可变参数7.匿名函数基本语法示例1.函数目的在编程中,定......
  • 视频汇聚平台EasyCVR启动出现报错“cannot open shared object file”的原因排查与解
    安防视频监控EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。EasyCVR平台支持多种视频流的外部分发,如RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、WebRTC、fmp4等,这为其在各种复杂环境下的部署提供了便利。有用......
  • 《文明6》找不到d3d12.dll怎样处理?文明6游戏启动d3d12.dll丢失解决之道
    在尽情畅玩SidMeier’sCivilizationVI(文明6)这款广受欢迎的策略游戏过程中,部分玩家或许会在启动游戏时碰到提示“d3d12.dll文件丢失”的状况,这给游戏的正常运行带来了严重阻碍。d3d12.dll作为Direct3D12API的核心动态链接库文件,在游戏内的图形渲染与输出方面起着关键作用。本......