1 复位类型
- 上电复位:复位微控制器中的所有部分,其中包括处理器、调试支持部件和外设等。
- 系统复位:只会复位处理器和外设,不包括处理器的调试支持部件。
- 处理器复位:只复位处理器。
系统复位与处理器复位不会复位调试部件,因此可以保持MCU与调试器间的连接,调试器也可以通过系统控制块(SCB)的寄存器产生系统复位或处理器复位。
2 复位信号
2.1 内核复位寄存器
Application interrupt and reset control register SCB->AIRCR
(地址0xE000ED0C)可控制复位信号:
MDK Debug中相关配置:
- HW RESET:翻转DAPLink的nSRST/nRESET引脚(一般也会接到MCU reset脚)来复位MCU
- VECTRESET:除了调试逻辑之外的所有角落,但是它不会影响到CM7处理器外部的任何电路,所以MCU上的片上外设和其它电路都不受影响。
- SYSRESETREQ:复位整个芯片,调试debug一般勾选此项
2.2 STM32硬件复位
CM3单片机对复位电路有特定要求,一般复位信号只需用到1~2个,STM32中的复位信号如下图所示:
- NRST:上电复位引脚
- NJTRST:JTAG/SW接口的调试器复位引脚
3 复位序列
在复位后以及处理器开始执行程序前,CM处理器会先从片内Flash中读取前两个字:
- 从第一个地址处取出MSP的初始值。
- 从第二个地址处取出复位向量地址(32位),其LSB必须为1,因为要将该值赋给PC,PC的LSB为1表示
Thumb
状态。
MSP的设置是非常有必须的,因为复位时有可能产生NMI
和HardFault
异常,异常处理前将处理器状态压栈时需要栈存储和MSP。
因为CM3使用的是向下生长的满栈,所以MSP的初始值必须是堆栈内存的末地址加1。如:堆栈区域在0x20007C00-0x20007FFF,则MSP初始值必须为0x20008000。
向量表在MSP之后初始化,其地址的LSB必须为1(奇数),下图中用0x101来表达复位向量(Reset_Handler
)地址0x100。当0x100处的指令得到执行后,就正式开始了程序的执行。
注意:对于多数C开发环境,C启动代码会在进入主程序main()前更新MSP的数值。通过这两次对栈的设置,具有外部存储器的微控制器可以将外部存储器用作栈。例如,启动时栈可能位于片上SRAM,在复位处理中初始化外部存储器后执行C启动代码,此时会将栈设置为外部存储器。
4 STM32的复位序列
4.1 启动文件
;1-配置栈
Stack_Size EQU 0x00000400 ;1KB
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;分配栈空间 不初始化 可读写 2^3字节对齐
Stack_Mem SPACE Stack_Size
__initial_sp ;栈顶地址
;2-配置堆
Heap_Size EQU 0x00000200 ;512Byte
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8 ;当前堆栈以8字节对齐
THUMB ;表示后面指令兼容THUMB指令集(16bit) 现在cortex-M系列使用THUMB-2指令集(32bit)
;3-初始化中断向量表
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack 栈顶指针
DCD Reset_Handler ; Reset Handler 复位中断
DCD NMI_Handler ; NMI Handler 不可屏蔽中断
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
......
AREA RESET, DATA, READONLY
中定义的RESET段会通过以下MDK默认的分散加载文件加载到芯片Flash起始地址0x08000000
开始位置
LR_IROM1 0x08000000 0x00040000 { ; load region size_region
ER_IROM1 0x08000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections) ; 主要作用COPY RW区到RAM,然后再RW区后面创建ZI区。
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x0000C000 { ; RW data
.ANY (+RW +ZI)
}
}
4.2 反汇编验证
RESET
段起始地址即为Flash首地址0x08000000
,第一个地址存放的即为MSP初值,第二地址为Reset_Handler
地址(LSB为1),后面的地址分别为NMI_Handler、HardFault_Handler等中断向量的地址,其LSB也均为1。
程序会跳到0x08000145 - 1 = 0x08000144
的位置执行:
参考:
END