以STM32为例的MCU启动过程

以STM32为例的MCU启动过程

在面试的时候,好多位面试官问过这个问题,即从上电后,到第一行main函数语句的执行,软件部分都在做什么。这次看了微控制器是如何启动的? |STM32 为例演示微控制器的启动这个视频后,觉得很好,顺便整理下。

0x00000004 Reset Handler

处理器复位时,从中断向量表0x00000004位置读取Reset Handler的入口。
初始化SP,并且获取Reset Handler的入口地址,判断当前的Boot配置。如果0x1F开头则代表是SRAM引导或Bootloader引导;如果是0x08开头则代表是从Flash引导。如果从Flash里面引导,则执行ApplicationStart
image

alt text

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之间的相关内容

posted @   青灰色的风  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示