单片机启动

1.基础

堆就会向下增长(向低地址扩展),而栈向上增长(向高地址扩展)。

栈从高地址开始,向低地址方向增长(压栈操作地址递减)

堆从低地址的末尾开始,向高地址方向增长

2.大致流程

  1. 硬件复位:触发处理器启动序列

  2. 内核初始化:设置堆栈指针、程序计数器

  3. 内存初始化:.data段复制、.bss段清零

  4. 系统初始化:时钟、中断控制器、外设

  5. 运行时环境:C++全局构造、C库初始化

  6. 操作系统初始化:RTOS内核启动(如使用)

  7. main函数执行:应用代码开始运行

3.栈的角度看MCU启动

上电之后,cpu会从0x00000000地址开始取指令

由boot决定在哪进行(flash、sram、系统存储器),一般是从flash进行,即从0x08000000开始

随后从0x08000000开始取第一个4B指令(0x08000000~0x08000003),这里面存的是栈指针MSP(也是主栈,使用的是单片机的栈)

这个指针MSP是栈顶指针,最开始指向栈的底部(高地址),在.s文件中会定义单片机栈的大小和堆大小,然后在栈运行指令时MSP会向低地址移动

0x08000004~0x08000007这里装的是复位函数的地址,pc指向这个复位函数地址,然后执行复位函数(在栈中执行,MSP向下移动)在MSP向下移动的过程,会有一个重定位过程,这里会把flash中的.rwdata段的数据拷贝到sram中的.data段,随后继续初始化,将sram的bss初始化为0

单片机分为MSP主栈和PSP从栈

在bss段中分配了freertos的堆栈空间,创建的所有的任务以及其TCP、堆、栈、队列、信号量等均分配到这里面

这里PSP专门来处理freertos的栈

操作中断用的一定是MSP,而任务切换是在pendSV中断进行的,将PSP指针指向新任务的栈中