![kelly的头像 kelly的头像](https://cdn.eetrend.com/files/styles/picture200/public/pictures/picture-233-1470101630.jpg?itok=1zaKJM2x)
本节描述Cortex-M0编程模型。除了内核的各个寄存器之外,还包含处理器操作模式和堆栈的介绍。
1、处理器工作模式
处理器工作模式有:
Thrread模式
用于执行应用程序,在处理器复位时,进入Thread模式。
Handler模式
用于异常处理,处理器执行完所有异常程序后,返回到Thread模式。
2、堆栈
处理器使用满递减堆栈,也就是说栈顶指针指向最后入栈的数据。处理器的压栈操作为:栈顶指针自动递减,再存入新的数据。处理器的堆栈有主堆栈(mainstack)和进程堆栈(processstack),它们的栈顶指针相互独立,见下文介绍的堆栈指针SP。
在Thread模式中,由CONTROL寄存器来决定使用主堆栈还是进程堆栈。而在Handler模式通常使用主堆栈。处理器工作模式与栈选择之间的关系如下表1所示:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7547-1.jpg)
3、内核寄存器组
处理器的内核寄存器如下:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7548-2.jpg)
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7549-3.jpg)
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7550-4.jpg)
注:
a、在Thread模式和Handler模式下运行程序时,为存取访问类型,调试访问模式下可以不同。
b、第24位为T-bit,从复位向量表的bit[0]处加载。
通用寄存器组
R0-R12都是32位通用寄存器,用于数据操作。
堆栈指针
R13(SP)是堆栈指针寄存器。在Thread模式下,由CONTROL寄存器的bit[1]来选择使用MSP还是PSP。
• 0=主堆栈指针MSP,复位值。
• 1=进程堆栈指针PSP。
复位时,处理器从地址0x00000000处加载MSP的值。
链接寄存器
R14(LR)是链接寄存器,当子程序调用、函数调用以及异常处理时时,由R14存储返回地址。复位时,LR的值未知。
程序计数寄存器
R15(PC)是程序计数寄存器,指向当前程序的地址。复位时,从向量表(地址:0x00000004)中加载PC的值。Bit[0]的值被加载到EPSR的T-bit中,且必须为1。
程序状态寄存器
程序状态寄存器PSR包括:
• 应用程序状态寄存器APSR。
• 中断状态寄存器IPSR。
• 运行状态寄存器EPSR。
这些寄存器处于32位PSR寄存器相互独立的位域中。PSR的位分布是:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7551-5.jpg)
通过MRS/MSR指令,可以单独访问这3个PSR,也可以组合访问(2或3个组合)。
例如:
• 在MRS指令使用PSR,读取全部寄存器的值。
• 在MSR指令使用APSR,将值写入APSR。PSR的组合及属性如下表3所示:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7552-6.jpg)
注:
a、处理器忽略对寄存器IPSR相应位的写操作。
b、读取EPSR相应的位,返回0,并忽略对其写操作。
应用程序状态寄存器
根据指令的执行情况,APSR保存条件标志的当前状态,参见上文中的表2、其位域分配如表4所示:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7554-7.jpg)
中断程序状态寄存器
中断程序状态寄存器IPSR保存了当前ISR的异常号,参见上文中的表2,其位域分配如下表5所示:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7555-8.jpg)
a、如果处理器中没有SysTick定时器,系统异常号15保留
b、外部中断号n是在实现处理器时定义的,范围为1-32。
执行程序状态寄存器
EPSR包含Thumb状态位。
参见上文表2,其位域分配如下表6所列:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7556-9.jpg)
应用程序直接使用MRS指令读取EPSR的值时,通常得到的返回值是0。如果企图使用MSR指令向EPSR写数据,其结果是写操作被忽略。但是Fault处理能够检测被压栈的EPSR值,从而断定出错误原由。可参见下文异常入口与异常返回小节。可通过以下3种方法将EPSR的Tbit值为清为0:
• 指令BLX、BX和POP{PC}
• 异常返回时,从堆栈恢复xPSR的值;
• 异常处理入口向量值的[0]位为0。
当T位为0时,执行一条指令将导致硬故障或者锁定。参见下文有关锁定的介绍。
可中断重启动的指令
在LDM或STM指令执行过程中如果发生中断,处理器将放弃批量读取或批量存放操作;如果乘法指令采用32周期实现,在乘法指令执行过程中如果发生中断,处理器也将放弃该指令。
在中断服务结束之后,处理器将重新执行被放弃的指令。
异常屏蔽寄存器
异常屏蔽寄存器用于屏蔽所有的处理器异常处理,对于时序要求非常严格的代码序列,有时需要屏蔽异常的发生。
除了可以通过使用MRS和MSR指令访问PRIMASK寄存器之外,还可以使用专用的CPS指令来进行设置。
优先级屏蔽寄存器
PRIMASK寄存器阻止所有可配置优先级的异常的激活。该寄存器的描述见上文中的表2,位域分配如下图所示:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7557-10.jpg)
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7558-11.jpg)
控制寄存器(CONTROL)
控制寄存器CONTROL用于选择在Thread模式下当前使用哪个堆栈指针。该寄存器的描述见上文中的表2,其位域分配如下:
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7559-12.jpg)
![](http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002389-7560-13.jpg)
在Handler模式下总是使用MSP,因此处理器忽略对CONTROL的写操作。但是可以在异常进入和异常返回时更新CONTROL寄存器。
在操作系统环境中,ARM建议任务运行在Thread模式下并使用进程栈,而内核和异常处理使用主堆栈。
默认情况下,Thread模式下使用MSP,如果想要改成PSP,可以通过指令MSR将CONTROL置1。
注意:
如果要改变堆栈指针,就必须在MSR指令之后立即使用ISB指令。这样可以保证在ISB执行完以后,其它指令能够使用新的堆栈。
4、异常和中断
Cortex-M0支持外部中断和系统异常。处理器和NVIC按照优先次序处理所有异常。一个中断或异常可以打断正常的软件执行顺序,处理器在Handler模式下可以执行除重启之外的所有系统异常。
NVIC寄存器控制中断处理,见下文详细介绍。
5、数据类型
Cortex-M0处理器:
• 支持的数据类型有:
—32-bit,字;
—16-bit,半字;
—8-bit,字节。
• 依据处理器的具体实现,Cortex-M0处理器可以按照大端格式或小端格式对数据进行存取访问。指令存储和PrivatePeripheralBus(PPB)总线访问通常用的是小端格式。
6、Cortex微处理器软件接口标准CMSIS
ARM为Cortex-M0处理器的编程提供了Cortex微控制器软件接口标准CMSIS,CMSIS集成部分设备的驱动库,对于Cortex-M0处理器来说,CMSIS定义了:
• 一个通用的方法:
—访问外设寄存器;
—定义异常向量。
• 以下的名字
—内核的外部寄存器;
—内核的异常向量。
• 为RTOS内核提供一个与处理器独立的接口。
CMSIS既包括了Cortex-M0处理器内部外设的地址定义、数据结构,也包括了一些可选的中间件接口,包括TCP/IP协议栈和Flash文件系统等。
由于CMSIS允许模板代码复用并且可以整合不同提供商的中间件,从而简化了软件开发过程。软件提供商还能添加自己的外设定义和相关函数来扩展CMSIS。
本文档包含CMSIS定义的寄存器名字,同时简单介绍了CMSIS中有关处理器核和核外设的函数。
注意:本文档用到的寄存器名字是CMSIS定义的短名,少部分情况下有别于其它文档中用到的短名。