ARM核心启动流程

ARM核心启动流程

ARMv7-M Essentials 1

Link: https://www.bilibili.com/video/BV1tTVPz3EdA/?spm_id_from=333.1387.favlist.content.click&vd_source=e742ab928a70238934780b04b84d177d

1. 框图

电源引脚上电–> 复位 –> Boot ROM –> 根据VectorTable偏移0地址的内存地址设置MSP –> 将M核心的PC寄存器设置为VectorTable的偏移4字节即复位向量 –> 之后就可以依次执行指令了!

Note: 中断向量表Vector Table:

  • 中断向量表中每个元素都是4个Bytes;
  • 每个元素用于指示MCU中的一个有效存储空间;代表一个内存地址或者函数地址;

从上图的方框可以看到,VectorTable的内容:

  1. 第一个元素是MSP的初始值;MSP指的是栈顶指针(Main Stack Pointer), 用于指示内存中某个具体地址;
  2. 往后的元素都是函数地址;最重要的是第二个,复位向量;它指示每次MCU复位后执行的第一条用户指令;

2. 示例工程

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// main.c

#include"stm32f10x.h"
#include <stdint.h>
#define CODE_ADDR_START Ox00000000
#define CODE_ADDR_END 0x1FFFFFFF
#define SRAM_ADDR_START Ox20000000
#define SRAM_ADDR_END 0x3FFFFFFF
#define SCB_CPUID_ADDR OxE000ED00
uint32_t example_function(void)
{
return 0;
}

uint32_t example_value = 0x12345678;
int main(void)
{
//get the address of the example function
uint32_t function_addr=(uint32_t)&example_function;
if (function_addr <CODE_ADDR_START I1 function_addr > CODE_ADDR_END)
{
while(1);
}
// get the address of the example value
uint32_t value_addr = (uint32_t)&example_value;
if (value_addr < SRAM_ADDR_START 11 value_addr > SRAM_ADDR_END)
{
while(1);
}
}

中断向量表

  • _estack:即栈顶指针MSP;
  • Reset_Handler: 即复位向量;

当工程进入调试模式时可以看到,

  1. PC寄存器指向main()中的第一个指令地址;
  2. M核心的MSP寄存器指向RAM中的某个地址;
  3. 使用gdb的monitor system_reset指令触发复位,观察PC和MSP两个寄存器的地址:
    • PC:0x8000088c –> 即 Reset_Handler;
    • MSP: 0x20002000 –> 即map中的一致;
作者

Gavin

发布于

2025-05-10

更新于

2025-05-10

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×