启动流程
📖 以从Flash启动为例,流程包括:
1️⃣ 初始化堆栈指针SP。
2️⃣ 将PC指针指向Reset_Handler。
3️⃣ 初始化中断向量表。
4️⃣ 配置系统时钟。
5️⃣ 调用C库函数_main,启动用户堆栈,最终进入main函数。
1. 初始化堆栈指针SP
首先初始化堆栈指针SP,就是栈顶的地址,用户只可以在.s文件中设置stack的大小,stack是编译器自动分配局部变量 函数调用形式参数的区域。
既然提到栈那么再聊聊内存的五大区域
栈:局部变量,函数的实际参数
堆:C中使用malloc开辟的区域
全局区(静态区):全局变量 和静态变量。其中初始化的数据放在data段 未初始化的束放在.bss段
常量区:存储常量数据,例如字符串常量
代码区:执行的代码
2. 初始化程序计数器指针PC
程序计数器指针PC就是复位中断服务函数地址Reset_Handler
3.初始化中断向量表
中断其实是一种异常,当内核响应了一个发生的异常后,对应的异常服务函数就会执行。中断向量表就是对每个异常排序,并且按照内核异常的顺序排列
4.配置系统时钟以及用户堆栈,最终进入main函数
Reset_Handle是上电后调用的第一个程序,调用 SystemInit
函数初始化系统时钟,然后调用 C 库函数 __main
,最终调用 main
函数去到 C 程序中。
SystemInit
是一个标准的库函数,主要作用是配置系统时钟。__main
是一个标准的 C 库函数,主要作用是初始化用户堆栈,并在函数的最后调用 main
函数去到 C 程序中。
参考https://blog.youkuaiyun.com/Teminator_/article/details/142333178