以STM32为例的MCU启动过程
以STM32为例的MCU启动过程
在面试的时候,好多位面试官问过这个问题,即从上电后,到第一行main
函数语句的执行,软件部分都在做什么。这次看了微控制器是如何启动的? |STM32 为例演示微控制器的启动这个视频后,觉得很好,顺便整理下。
0x00000004 Reset Handler
处理器复位时,从中断向量表0x00000004
位置读取Reset Handler
的入口。
初始化SP,并且获取Reset Handler
的入口地址,判断当前的Boot配置。如果0x1F
开头则代表是SRAM引导或Bootloader引导;如果是0x08
开头则代表是从Flash引导。如果从Flash里面引导,则执行ApplicationStart
。
C Runtime Init
简单来说,就是将Flash里.data段拷贝到SRAM中,.bss段的内容在RAM内初始化。
- 初始化地址寄存器
ldr r0, =sdata ; 将 .data 段的起始地址(SRAM 中)加载到 R0 中
ldr r1, =edata ; 将 .data 段的结束地址加载到 R1 中
ldr r2, =sidata ; 将 .data 段在 Flash 中的起始地址加载到 R2 中
movs r3, #0 ; 初始化偏移量 R3 为 0
R0:SRAM 中 .data 段的起始地址。
R1:SRAM 中 .data 段的结束地址。
R2:Flash 中 .data 段初始值的起始地址。
R3:用于指示当前处理的数据块的偏移。
- 数据拷贝主循环
b LoopCopyDataInit ; 跳转到循环条件检查
在进入拷贝主循环前,先跳转到循环条件检查部分。
- 数据拷贝过程
CopyDataInit:
ldr r4, [r2, r3] ; 从 Flash 的 sidata 段中加载一个 4 字节值到 R4
str r4, [r0, r3] ; 将 R4 的值存入 SRAM 的 .data 段
adds r3, r3, #4 ; 偏移量增加 4 字节(指向下一个数据单元)
从 Flash 中 .data 段的初始值区域读取一个数据单元(4 字节)。
将该数据单元写入到 SRAM 中对应的 .data 段。
偏移量加 4,准备处理下一个数据单元。
- 循环条件检查
LoopCopyDataInit:
adds r4, r0, r3 ; 将当前拷贝目标地址 (R0 + R3) 存入 R4
cmp r4, r1 ; 比较目标地址是否到达 .data 段的结束地址
bcc CopyDataInit ; 如果目标地址小于结束地址,则继续拷贝
adds r4, r0, r3:当前的拷贝目标地址 = 起始地址 + 偏移量。
cmp r4, r1:判断当前目标地址是否已经超出 .data 段的结束地址。
bcc CopyDataInit(Branch if Carry Clear):如果目标地址尚未到达结束地址,继续拷贝。
SystemInit
跳转到该函数,做时钟等外设或其他配置的初始化。
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
}
libc_init_array
调用构造函数,主要与C++相关。
main
跳转到main函数的第一行,开始执行用户代码。
以STM32为例的MCU启动过程的更多相关文章
- 关于linux的一点好奇心(一):linux启动过程
一直很好奇,操作系统是如何工作的?我们知道平时编程,是如何让代码跑起来的,但那些都是比较高层次的东西.越往后,你会越觉得,像是空中楼阁,或者说只是有人帮你铺平了许多道理,而你却对此一无所知. 1. 操 ...
- STM32启动过程--启动文件--分析
一.概述 1.说明 每一款芯片的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道.通过了解启动文件,我们可以体会到处理器的架构.指令集.中断向量安排等内容,是非常值得玩味的. ST ...
- STM32启动过程解读与跟踪验证
经过查阅各种官方文献和对代码进行单步跟踪,详细地叙述了STM32加电启动的具体过程.对于关键性的语句都指明了出处.下面将学习成果分享给大家,由于笔者知识有限,不当之处敬请指出. 为了更好的说明问题,先 ...
- 专家揭秘:STM32启动过程全解
电子发烧友网核心提示:本文主要阐述了STM32启动过程全面解析,包括启动过程的介绍.启动代码的陈列以及深入解析. 相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方 ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(8)- 从Raw NAND启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Raw NAND启动. 前面铺垫了七篇启动系列文章,终于该讲具体Boot Device了,我们知道i. ...
- 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(9)- KBOOT特性(IntegrityCheck)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT之完整性检测(Integrity Check)特性. Application完整性检测是非常 ...
- linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)
转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...
- 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(7)- 从SD/eMMC启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MXRTxxx系列MCU的SD/eMMC卡启动. 关于 i.MXRT 启动设备,痞子衡之前写过很多篇文章,都是关于串并行 NO ...
- Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)
启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...
- Linux启动过程详解
Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...
随机推荐
- 2024.11.12随笔&联考总结
前言 心情不好,因为考试时 T2T3 全看错题了,导致 T2 没做出来,T3 一份没得.然后下午打球眼镜架子坏了,回机房才发现被高二的盒了. 但还是稍微写一下总结吧. 总结 感觉我今天做题状态还行,思 ...
- GUI图形界面编程(Java)
GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1.简介 Gui的核心技术:Swing.AWT 2.AWT 2.1.AWT介绍 1.包含了很多类和接 ...
- 有限元方法[Matlab]-笔记
<-- 访问笔记代码仓库 --> << MATLAB Codes for Finite Element Analysis - Solids and Structures (Fe ...
- 【Linux】1.1 Linux课程介绍
Linux课程介绍 1. 学习方向 linux运维工程师: 维护linux的服务器(一般大型企业) linux嵌入式工程师: linux做驱动开发,或者linux的嵌入式 linux下开发项目 2. ...
- python环境配置命令
在Python中,创建新的环境通常指的是创建一个隔离的Python环境,以便在该环境中安装和管理不同版本的库,而不会影响到系统中其他Python环境的库.这通常用于解决不同项目之间的依赖冲突.下面是一 ...
- PriorityQueue作用和源码
一.PriorityQueue作用和源码 PriorityQueue跟前几个阻塞队列不一样,并没有实现BlockingQueue接口,只是实现了Queue接口,Queue接口中定义了几组放数据和取数据 ...
- @PathVaribale
/** * @pathVaribale * 作用: 用于获取url 中的占位符的值. * 例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符. * url 支持占位符是 ...
- vue属性/子属性监听watch的几种方法
特殊字符法 特殊字符+deep法 直接deep法 常规法 直接用如下代码示例吧: data(){ return { goBackHeader:'添加排班', scheduleForm:{ schedu ...
- jwt的个人理解
概念: jwt全名json web token,是一种web登录验证和授权技术 官网debug:#debug 应用场景: 授权这是使用JWT最常见的场景.一旦用户登录,每个后续请求将包括JWT,允许用 ...
- 自定义控件,重写 TextBox 实例
项目中可能会遇到重写控件的情况,特此记录下: 1 <Window x:Class="WpfApp6.MainWindow" 2 xmlns="http://sche ...