ARM单片机的详细启动流程
一、ARM架构
- ARM Cortex_M3内核中提供了多个复位信号,厂商设计MCU时一般只使用以下三个复位信号,其他复位信号在MCU内部实现(如看门狗复位信号、软件复位:软件服务只能复位内核,内核以外不受影响)。
复位信号 | 描述 |
---|---|
(外部)上电复位 | 器件上电时需要把复位信号设置为有效,把处理器核心和调试系统一起复位 |
(外部)系统复位 | 只影响处理器核心、NVIC。不复位调试系统 |
(外部)测试复位 | 只复位调试系统 |
2.中断向量表
-
中断向量表为存储中断服务程序入口地址的表格。该物理地址中存放着各种中断服务程序的入口地址。
-
中断向量表的起始地址为0,因此地址为0处必须包含一张向量表,用于初始时的异常分配。
异常向量标的部分截图:从图中可以看出向量表的标号为0的地址存放的不是复位后的地址而是主堆栈指针的值。系统会将这个值取出赋值给MSP指针。
二、MCU的初始次上电
- 1.产生上电复位信号:上电第一时刻产生一个上电复位状体,等待时钟信号稳定后退出复位状态。上电复位不是中断,不会进入某个中断中。
- 2.堆栈初始化:退出复位转态,之后的第一件事就是读取下列两个32位整数值:
- 从地址为0x0000_0000处(中断向量为0的地址)取出MSP的初始值。为什么第一步要初始化堆栈,因为后面的复位中断服务函数的调用和其他特权服务函数的执行都需要使用堆栈。
- 从地址为0x0000_0004处(中断向量为4的地址) 取出PC的初始值——这个值是复位向量,这个地址所指向复位中断函数的的入口地址。
- 进入复位中断服务程序:
-
- 裸机的中断服务程序:在裸机程序中只是用一个SP指针(MSP),下图是裸机的复位中断服务函数,直接对系统进行初始化后,跳转到main中运行。
- 裸机的中断服务程序:在裸机程序中只是用一个SP指针(MSP),下图是裸机的复位中断服务函数,直接对系统进行初始化后,跳转到main中运行。
-
- 带操作系统的中断复位服务程序:与裸机复位不同的是带操作系统的复位中断服务程序还会对操作系内核的东西进行初始化。
-
- 跳转到main应用程序:在完成复位中断服务函数后,就会跳到main里面去执行程序了。
三、双堆栈的使用
- 一般来说,操作系统为了避免出现应用程序恶意修改内存,都会使用算堆栈(MSP和PSP)。由于从向量表中取出0号向量,仅初始化了MSP。对于PSP指针的初始化(或修改)需要在PendSV中断服务函数中对各个线程的PSP指针进行保护和更新。