以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内初始化。

  1. 初始化地址寄存器
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:用于指示当前处理的数据块的偏移。

  1. 数据拷贝主循环
b LoopCopyDataInit  ; 跳转到循环条件检查
在进入拷贝主循环前,先跳转到循环条件检查部分。
  1. 数据拷贝过程
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,准备处理下一个数据单元。

  1. 循环条件检查
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函数的第一行,开始执行用户代码。

Flash和RAM之间的相关内容

以STM32为例的MCU启动过程的更多相关文章

  1. 关于linux的一点好奇心(一):linux启动过程

    一直很好奇,操作系统是如何工作的?我们知道平时编程,是如何让代码跑起来的,但那些都是比较高层次的东西.越往后,你会越觉得,像是空中楼阁,或者说只是有人帮你铺平了许多道理,而你却对此一无所知. 1. 操 ...

  2. STM32启动过程--启动文件--分析

    一.概述 1.说明 每一款芯片的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道.通过了解启动文件,我们可以体会到处理器的架构.指令集.中断向量安排等内容,是非常值得玩味的. ST ...

  3. STM32启动过程解读与跟踪验证

    经过查阅各种官方文献和对代码进行单步跟踪,详细地叙述了STM32加电启动的具体过程.对于关键性的语句都指明了出处.下面将学习成果分享给大家,由于笔者知识有限,不当之处敬请指出. 为了更好的说明问题,先 ...

  4. 专家揭秘:STM32启动过程全解

    电子发烧友网核心提示:本文主要阐述了STM32启动过程全面解析,包括启动过程的介绍.启动代码的陈列以及深入解析. 相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方 ...

  5. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(8)- 从Raw NAND启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Raw NAND启动. 前面铺垫了七篇启动系列文章,终于该讲具体Boot Device了,我们知道i. ...

  6. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(9)- KBOOT特性(IntegrityCheck)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT之完整性检测(Integrity Check)特性. Application完整性检测是非常 ...

  7. linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)

    转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...

  8. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(7)- 从SD/eMMC启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MXRTxxx系列MCU的SD/eMMC卡启动. 关于 i.MXRT 启动设备,痞子衡之前写过很多篇文章,都是关于串并行 NO ...

  9. Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)

    启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...

  10. Linux启动过程详解

    Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...

随机推荐

  1. Windows 提权-SeBackupPrivilege 特权

    本文通过 Google 翻译 Sebackupprivilege – Windows Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注 ...

  2. 面试题53 - I. 在排序数组中查找数字 I

    地址:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/ <?php /** 面试题53 ...

  3. Polar困难模式部分题解

    choose from pwn import *from LibcSearcher import *context.terminal = ["tmux","splitw& ...

  4. Note_Fem边界条件的处理和numpy实现的四种方法

    将单元刚度矩阵组装为全局刚度矩阵后,有: 此时的线性方程没有唯一解,\([K]\)是奇异矩阵,这是没有引入边界条件,消除刚体位移的原因. 边界条件分为两类:Forced and Geometric;对 ...

  5. @ComponentScan @MapperScan 拆分项目的时候,这两个注解很重要

    今天,在做项目拆分的时候遇到了个问题,就是将service和dao层拆完之后,项目启动不起开了,如图: 最终解决办法,在启动类上增加两个注解搞定: @ComponentScan(basePackage ...

  6. golang 使用goto进行多错误处理

    goto 语句介绍 在 Go 语言中,可以通过goto语句跳转到标签,进行代码间的无条件跳转.另外,goto语句在快速跳出循环.避免重复退出方面可以简化代码实现过程,但在结构化程序设计中一般不主张使用 ...

  7. jquery的radio的change事件

    一.用的jquery的radio的change事件:当元素的值发生改变时,会发生 change 事件,radio选择不同name值选项的时候恰巧是值发生改变 表单单选框 <input type= ...

  8. NumPy学习6

    今天学习 NumPy位运算 12, NumPy位运算NumPy 中提供了以下按位运算函数:numpy按位运算函数序号 函数 位运算符 描述说明1 bitwise_and & 计算数组元素之间的 ...

  9. windows下测试TCP/UDP端口连通性

    一.简介 最近调试项目的时候有需要测试UDP连接,所以顺便研究了一下. MaQaQ:省流,不介意下载工具的话就直接拉到最后看Advanced Port Scanner. 二.TCP 1.telnet( ...

  10. Linux下对LVM逻辑卷分区大小调整 [针对xfs和ext4文件系统]

    当我们在安装系统的时候,由于没有合理分配分区空间,在后续维护过程中,发现有些分区空间不够使用,而有的分区空间却有很多剩余空间.如果这些分区在装系统的时候使用了lvm(前提是这些分区要是lvm逻辑卷分区 ...