注意:本文中关于复位和复位序列的叙述只适用于Cortex-M3和Cortex-M4(F)(同样适用于Cortex-M0内核处理器),而Cortex-M7内核的复位序列与其有点不一样。详情请参考相关内核处理器的权威指南或技术参考手册(TRM)。
一、复位的种类
STMF427/STM32429总共有3种复位:系统复位、电源复位 及 备份域复位。在分别介绍这3种复位之前,先来详细了解下什么是备份域,如图1所示:
由图1可以看出,备份域中包括:
● 低速外部(LSE)振荡器
● 低功耗(LP)备份调压器
● 实时时钟(RTC)
● 4K字节的备份SRAM
● 20个32位RTC备份寄存器(RTC_BKPxR,x=0,1,2……18,19)
关于备份域的操作说明:
● 只有当电源VDD断电的时候,模拟开关才会连接到VBAT,由VBAT对备份域供电;
● RTC备份寄存器可在VDD电源断电时通过VBAT保持上电状态,并且其不会在系统复位或电源复位时复位,也不会在器件从待机模式唤醒时复位;
● 4K字节的备份SRAM在使能低功耗备份调压器时(此低功耗调压器由PWR_CSR寄存器的BRE位控制),即使处于待机模式或VBAT模式,备份SRAM中的内容也能保留。若VBAT一直存在,备份SRAM就如同内部EEPROM一样,不会因VDD断电而丢失数据。
● 发生入侵事件时(即引起备份域复位的方式),将复位所有的备份寄存器(RTC_BKPxR)。
1、系统复位
除了时钟控制寄存器CSR中的复位标志和备份域中的寄存器以外,系统复位会将其它所有的寄存器(处理器内核寄存器和外设寄存器)复位成默认的复位值。
引起系统复位的方式有:
(1)NRST引脚低电平(外部复位);
(2)窗口看门狗计数结束(WWDG复位);
(3)独立看门狗计数结束(IWDG复位);
(4)软件复位(SW复位);
关于软件复位请参考《Cortex-M3 and Cortex-M4权威指南》9.6节。
(5)低功耗管理复位。
引起低功耗管理复位的方式有:
● 进入待机模式时产生的复位。
此复位的使能方式是清零用户选项字节中的 nRST_STDBY 位。使能后,只要成功执行进入待机模式序列,器件就将复位,而非进入待机模式。
● 进入停机模式时产生的复位。
此复位的使能方式是清零用户选项字节中的 nRST_STOP 位。使能后,只要成功执行进入停止模式序列,器件就将复位,而非进入停止模式。
2、电源复位
除了备份域内的寄存器以外,电源复位会将其它全部寄存器(处理器内核寄存器和外设寄存器)复位成默认的复位值。
引起电源复位的方式有:
(1)上电/掉电复位(POR/PDR复位)或欠压(BOR)复位;
(2)退出待机模式时。
注意:图3是系统复位和电源复位的电路原理图。备份域复位有两个特定的复位方式,这两种复位方式仅仅会引起备份域的复位。平时,我们所说的“复位”指的是系统复位或电源复位,这两种复位可以使所有的SRAM区的数据复位为复位值(除备份域以外)。
3、备份域复位
备份域复位会将所有 RTC 寄存器和 RCC_BDCR 寄存器复位为各自的复位值。不过,BKPSRAM 不受此复位影响。BKPSRAM的唯一复位方式是通过Flash接口将Flash保护等级从 1 切换到 0。
引起备份域复位的方式有:
(1)软件复位;
通过将 RCC 备份域控制寄存器 (RCC_BDCR) 中的 BDRST 位置 1 触发复位。
(2)电源VDD和VBAT都已经掉电后,其中任何一个又再上电。
二、向量表的定义
异常(Exception)就是引起程序流发生改变的事件。当异常发生时,处理器就会暂停当前的任务,转而去执行exception handler,并且在处理完异常服务程序后复原到原来的程序流处继续执行。
中断是异常事件的一种,它通常由外设、外部输入产生,某些情况下也可能由软件触发。
异常向量在异常向量表中。由图2可知,编号为1-15的异常是系统异常,编号16及其以上的异常是中断。
有时需要修改启动文件中的向量表,以满足应用程序的需要。关于对向量表的修改请查看启动文件一文(待续)。
三、复位序列
如图4所示,在退出复位后,处理器会从存储器中读取两个字(注意:矩形框中的数值是存储器单元的地址),然后再去执行程序:
● 初始主堆栈指针值(MSP): 从存储器地址0x00000000取堆栈指针初始值,也是内核寄存器R13的初始值;
● 复位向量值:从存储器地址0x00000004取复位向量 (程序执行的起始地址,LSB的值应该置1,以表明是Thumb状态)。
对于Cortex-M3和Cortex-M4,MSP的初始值位于存储器映射的开始处,后面紧跟着就是向量表(在程序的执行过程中,向量表可以被重新分配到另外一个地址处)。值得注意的是,向量表的内容为地址,而非跳转指令。
图5是复位后,初始堆栈指针和初始程序计数器的变化示例。
● 由于Cortex-M3和Cortex-M4内核的栈操作为满递减(即堆栈指针指向栈顶元素,并且堆栈由高地址向低地址生长),所以,SP的初始值应该指向栈顶元素上面的存储单元。注意:堆栈指针始终都是指向入栈的最后一个字节的存储单元,而不是提前指向下一个即将入栈的数据单元处;
● 初始化堆栈指针SP之后,接着就是向量表的第一个向量,即复位向量;
● 向量表中的向量值的最低位应该设置为1,以表明是Thumb代码。由于这个原因,图5中复位向量为0x00000101,而启动代码是从地址0x00000100开始的。处理器读取复位向量的值后就进入启动代码(Boot Code)中开始执行程序。