2.1 ARM Cortex-M4F处理器简介

在1.1.2节中介绍嵌入式系统发展简史时,已经简要介绍了ARM。本节以MSP432系列MCU阐述嵌入式应用,该系列的内核这里使用内核(Core)一词,而不用CPU,原因在于ARM中使用内核术语涵盖了CPU功能,它比CPU功能可扩充一些。一般情况下,可以认为两个术语概念等同。使用32位ARM Cortex-M4F处理器(简称CM4F),它是ARM大家族中重要一员。

2010年ARM公司发布Cortex-M4处理器,浮点单元(FPU)作为内核的可选模块,如果Cortex-M4内核包含FPU,则称它为Cortex-M4F。Cortex-M4与ARM在2005年发布的Cortex-M3处理器都基于ARMv7-M架构,从功能上来看可以认为Cortex-M4是Cortex-M3加上DSP指令与可选的FPU,所以它们有以下共同点。

(1)32位处理器,内部寄存器、数据总线都为32位。

(2)采用Thumb 2技术同时支持16位与32位指令。

(3)哈佛总线结构Cortex-M3/M4采用哈佛结构,而Cortex-M0+采用的是冯•诺依曼结构。区别在于它们是不是具有独立的程序指令存储空间和数据存储地址空间,如果有,就是哈佛结构,如果没有就是冯•诺依曼结构。而具有独立的地址空间也就意味着在地址总线和控制总线上至少要有一种总线必须是独立的,这样才能保证地址空间的独立性。,使用统一存储空间编址,32位寻址,最多支持4GB存储空间;三级流水线设计。

(4)片上接口基于高级微控制器总线架构(Advanced Microcontroller Bus Architecture,AMBA)技术,能进行高吞吐量的流水线总线操作。

(5)集成NVIC(嵌套向量中断控制器),根据不同的芯片设计,支持8~256个中断优先级,最多240个中断请求。

(6)可选的MPU(存储器保护单元)具有存储器保护特性,如访问权限控制,提供时钟、主栈指针、线程栈指针等操作系统特性。

(7)具有多种低功耗特性和休眠模式。

Cortex-M3和Cortex-M4处理器都提供了数据操作指令、转移指令、存储器数据传送指令等基本指令,这些基本指令将在2.2节详细介绍;此外Cortex-M4还支持SIMD(单指令多数据)、快速MAC和乘法、饱和运算等DSP相关指令;Cortex-M4F还支持单精度的浮点指令。

相比其他架构的32位微控制器,Cortex-M4有较高的性能与较低的功耗,具有优秀的能耗效率,Cortex-M3和Cortex-M4处理器性能可达到3 CoreMark/MHz、1.25DMIPS/MHz(基于Dhrystone2.1平台Dhrystone是测量处理器运算能力的最常见基准程序之一,常用于处理器的整型运算性能的测量。);Cortex-M3和Cortex-M4处理器还进行了低功耗的优化。由于采用了Thumb ISA(指令架构),在Cortex-M3和Cortex-M4处理器上编程可以获得较高的代码密度。

Cortex-M3和Cortex-M4处理器易于使用,它们采用的架构针对C语言编译器进行了优化,可以使用标准的ANSI C完成绝大多数的编程代码;Cortex-M3和Cortex-M4处理器还提供程序运行暂停、单步调试、捕获程序流、数据变动等调试手段,使代码调试更加方便。

Cortex-M3和Cortex-M4处理器具有的高性能与低功耗可广泛应用于微控制器、汽车、数据通信、工业控制、消费电子、片上系统、混合信号设计等方面。

MSP432是TI(德州仪器)生产的基于Cortex-M4F处理器的微控制器,凭借32位的48 MHz Cortex-M4F内核可提供更高性能,同时源于MSP的低功耗基因,MSP432微控制器被设计成超低功耗的通用型微控制器,在工作模式下功耗为95μA/MHz,而待机时功耗仅为850nA/MHz,这其中还包括了RTC的功耗。

2.1.1 ARM Cortex-M4F处理器内部结构概要

Cortex-M4F处理器组件结构如图2-1所示。

1. M4F内核

ARM Cortex-M4F是一种低功耗、高性能、高速度的处理器,尤其是在ARMv7-M架构中,支持Thumb指令集,同时采用Thumb 2技术Thumb是ARM架构中的一种16位指令集,而Thumb 2则是16/32位混合指令集。,且拥有符合IEEE 754标准的单精度浮点单元(FPU)。其硬件方面支持除法指令,并且有着中断处理程序和线程两种模式。32位的ARM Cortex-M4F有着指令和调试两种状态。在一些汇编指令,如LDM、STM、PUSH和POP中断和持续都支持。在处理中断方面,M4F具有着自动保存处理器状态和恢复低延迟中断。Cortex-M4F处理器可提供更高性能,如定点运算的速度是M3内核的2倍,而浮点运算速度比M3内核快10倍以上,同时功耗只有M3内核的一半此性能评估出自http://www.ti.com.cn/cn/lit/ml/zhct281b/zhct281b.pdf.

图2-1 ARM Cortex-M4F处理器结构

2. 嵌套向量中断控制器

嵌套向量中断控制器(Nested Vectored Interrupt Controller,NVIC)是一个在Cortex-M4F中内建的中断控制器。在MSP432系列芯片中,配置的中断源数目为64个,优先等级可配置范围为0~7,其中0等级对应最高中断优先级。更细化的是,对优先级进行分组,这样中断在选择时可以选择抢占和非抢占级别。对于Cortex-M4F处理器而言,通过在NVIC中实现中断尾链和迟到功能,意味着两个相邻的中断不用再处理状态保存和恢复。处理器自动保存中断入口,并自动恢复,没有指令开销,在超低功耗睡眠模式下可唤醒中断控制器。NVIC还采用了向量中断的机制,在中断发生时,它会自动取出对应的服务例程入口地址,并且直接调用,无须软件判定中断源,缩短中断延时。为优化低功耗设计,NVIC嵌套中断控制器还集成一个可选WIC(唤醒中断控制器),在睡眠模式或深度睡眠模式下,芯片可快速进入超低功耗状态,且只能被WIC唤醒源唤醒。Cortex-M4F的构件中,还包含一个24位倒计时定时器SysTick,即使系统在睡眠模式下也能工作,是作为嵌套向量中断控制器(NVIC)的一部分实现的,若用作实时操作系统RTOS的时钟,将给RTOS在同类内核芯片间移植带来便利。

3. 存储器保护单元

存储器保护单元(Memory Protection Unit,MPU)是指可以对一个选定的内存单元进行保护。它将存储器划分为8个子区域,该子区域的优先级均是可自定义的。处理器可以使指定的区域禁用和使能。

4. 调试访问接口

ARM Cortex-M4F处理器可以对存储器和寄存器进行调试访问,具有SWD或JTAG调试访问接口,或者两种都包括。Flash修补和断点单元(Flash Patch and Breakpoint,FPB)用于实现硬件断点和代码修补,数据观察点和触发单元(Data Watchpoint and Trace,DWT)用于实现观察点、触发资源和系统分析,指令跟踪宏单元(Instrumentation Trace Macrocell,ITM)用于提供对printf()类型调试的支持,跟踪端口接口单元(Trace Port Interface Unit,TPIU)用来连接跟踪端口分析仪,包括单线输出模式。

5. 总线接口

ARM Cortex-M4F处理器提供先进的高性能总线(AHB-Lite)接口,其中包括4个接口:I-code存储器接口、D-code存储器接口、系统接口和基于高性能外设总线(ASB)的外部专用外设总线(PPB)。位段的操作可以细化到原子位段的读写操作。对内存的访问是对齐的,并且在写数据时采用写缓冲区的方式。

6. 浮点运算单元

处理器可以处理单精度32位指令数据,结合了乘法和累积指令用来提高计算的精度。此外,硬件能够进行加减法、乘除法及平方根等运算操作,同时也支持所有的IEEE数据四舍五入模式。拥有32个专用32位单精度寄存器,也可作为16个双字寄存器寻址,并且通过采用解耦三级流水线来加快处理器运行速度。

2.1.2 ARM Cortex-M4F处理器存储器映像

ARM Cortex-M4F处理器直接寻址空间为4GB,地址范围为0x0000_0000~0xFFFF_FFFF。这里所说的存储器映像是指,把4GB空间当作存储器分成若干区间,都可安排一些怎样的实际物理资源。ARM定出的条条框框是粗线条的,它依然允许芯片制造商灵活地分配存储器空间,以制造出各具特色的MCU产品。

图2-2所示为CM4F的存储器空间地址映像。CM4F的存储器系统支持小端配置和大端配置小端格式:字的低字节存储在低地址中,字的高字节存储在高地址中。大端格式:字的低字节存储在高地址中,字的高字节存储在低地址中。,一般具体某款芯片在出厂时已经被厂商定义过,如MSP432采用小端格式参见《MSP432参考手册》第1章,该章表1-1给出了MSP432系列的内核可选配置。

图2-2 CM4F的存储器空间地址映像

2.1.3 ARM Cortex-M4F处理器的寄存器

CM4F处理器的寄存器包含用于数据处理与控制寄存器、特殊功能寄存器与浮点寄存器。数据处理与控制寄存器在Cortex-M系列处理器中定义与使用基本相同,包括R0~R15,如图2-3所示。其中,R13作为堆栈指针SP。SP实质上有两个(MSP与PSP),但在同一时刻只能看到一个,这就是所谓的“banked”寄存器。特殊功能寄存器有预定义的功能,而且必须通过专用的指令来访问,在Cortex-M系列处理器中M0与M0+的特殊功能寄存器数量与功能相同,M3与M4较M0与M0+多了3个用于异常或中断屏蔽的寄存器,且在某些寄存器上的预定义不尽相同。在Cortex-M系列处理器中,浮点寄存器只存在于CM4F中。

图2-3 Cortex-M4F处理器的寄存器组

1. 数据处理与控制寄存器

1)通用寄存器R0~R12

R0~R12是最具“通用目的”的32位通用寄存器,用于数据操作。大部分能够访问通用寄存器的指令都可以访问R0~R12。其中,低位寄存器(R0~R7)能够被所有访问通用寄存器的指令访问;高位寄存器(R8~R12)能够被所有32位通用寄存器指令访问,而不能被所有的16位指令访问。

2)堆栈指针R13

R13被用作堆栈指针(SP)。堆栈指针用于访问堆栈,因为SP忽略写入到[1:0]位(即最低两位永远是0),则堆栈是按照字对齐的(4个字节对齐)。主堆栈指针SP_main是复位后默认使用的堆栈指针,用于操作系统内核及异常处理例程(包括中断服务例程)。“Handler”模式总是使用主堆栈指针(MSP),有时也可以配置成“Thread”模式来使用MSP或进程堆栈指针(PSP)。

3)连接寄存器R14

R14为子程序连接寄存器(LR)。当分支和链接(BL)或分支和链接执行交换(BLX)指令被执行后,LR从PC获取返回地址;LR也可以被用于异常返回。在其他情况下,可以将R14作为通用寄存器来使用。

4)程序计数寄存器R15

R15是程序计数寄存器(PC),指向当前的程序地址。复位时,处理器将复位向量值的加载PC,其中复位向量的地址为0x0000_0004。如果修改它的值,就能改变程序的执行流。该寄存器的[0]位若为0,则指令总是按照字对齐或半字对齐。PC寄存器可以以特权或非特权模式进行访问。

2. 特殊功能寄存器

1)程序状态字寄存器(xPSR)

程序状态字寄存器在内部分为3个子寄存器:APSR、IPSR、EPSR。这3个子寄存器既可以单独访问,也可以2个或3个组合到一起访问,使用三合一方式访问时,把该寄存器称为xPSR,各个寄存器组合名称与读写类型如表2-1所示。其中,xPSR、IPSR和EPSR寄存器只能在特权模式下被访问,而APSR寄存器能在特权或非特权模式下被访问,具体描述详见《CM4用户指南》。

表2-1 各寄存器的组合名称及读写类型

① 处理器忽略了写入IPSR位。

② EPSR位的读数归零,并且处理器忽略写入这些位。

程序状态字的各数据位预定义如表2-2所示。

表2-2 程序状态字的各数据位预定义

(1)应用程序状态寄存器(APSR):显示算术运算单元ALU状态位的一些信息。

负标志N:若结果最高位为1,相当于有符号运算中结果为负,则置1,否则清0。

零标志Z:若结果为0,则置1,否则清0。

进位标志C:若有最高位的进位(减法为借位),则置1,否则清0。

溢出标志V:若溢出,则置1,否则清0。

以上各数据位在Cortex-M系列处理器中M0、M0+、M3、M4的定义是一样的,它们在条件转移指令中被用到。复位之后的数据位是随机的。

饱和饱和就是在信号处理中信号的幅度超出了允许的输出范围,如果只是简单地将数据的最高位去掉,就会引起很大的畸变。例如,将32位有符号数0x00010000饱和为16位数,结果为0x7FFF,Q位为1,这时如果只是简单地将高位去掉,则结果为0x0000,就会引起很大的信号畸变。标志位Q:在实现DSP扩展的处理器中,如果在运算中出现饱和处理器就将该位置1。将该位设置为1称为饱和,该位只在Cortex-M3、Cortex-M4中存在。

大于或等于标志位GE:仅用于DSP扩展,SIMD指令更新这些标志用以指明结果来自操作的单个字节或半字,软件可以使用这些标志控制稍后的SEL指令。该位只在Cortex-M4中存在,更多信息请参考《ARMv7-M参考手册》。

(2)中断程序状态寄存器(IPSR):只能被MRS指令读写,每次异常完成之后,处理器会实时更新IPSR内的异常号。在进程模式下(可以理解为处于无操作系统的主循环中,或者有操作系统情况下的某一任务程序中),值为0;在Handler模式(处理异常的模式,简单地理解为中断状态)下,存放当前的异常号;复位之后,寄存器被自动清零。复位异常号是一个暂时值,复位时是不可见的。在Cortex-M系列处理器中,M0和M0+的异常号占用0~5位、M3、M4使用0~8位,这与处理器所能支持的异常或中断数量有关

(3)执行程序状态寄存器(EPSR):T标志位指示当前运行的是否是Thumb指令,该位是不能被软件读取的。运行复位向量对应的代码时置1。如果该位为0,会发生硬件异常,进入硬件中断服务例程。在Cortex-M系列处理器中该位的定义是相同的。

ICI/IT标志位存在于Cortex-M3与Cortex-M4中,该位指示异常可继续指令状态或保存的IT状态。该位的更多信息请参考《ARMv7-M参考手册》。

2)中断屏蔽寄存器(PRIMASK)

中断屏蔽寄存器的D31~D1位保留,只有D0位(记为PM)有意义。当该位被置位时,除不可屏蔽中断和硬件错误之外的所有中断都会被屏蔽。使用特殊指令(如MSR、MRS)可以访问该寄存器,此外还有一条特殊指令也能访问它,其命名为改变处理器状态CPS,但是该指令只有在实时任务时才会用到。执行汇编指令“CPSID i”,则将D0位置1(关总中断);执行汇编指令“CPSIE i”,则将D0位清0(开总中断),其中i代表IRQ中断。IRQ是Interrupt Request(非内核中断请求)的缩写。

3)错误屏蔽寄存器(FAULTMASK)

FAULTMASK寄存器与PRIMASK寄存器的区别在于,它能够屏蔽优先级更高的硬件错误(HardFault)异常。错误屏蔽寄存器D31~D1位保留,只有D0位有意义。当该位被置位时,除不可屏蔽中断(NMI)之外的所有中断都会被屏蔽,也就是说,硬件错误(HardFault)异常也会被屏蔽。该寄存器只能在特权模式下访问,使用特殊指令(如MSR、MRS)可以访问该寄存器,此外还有一条特殊指令也能访问它,其命名为改变处理器状态CPS,但是该指令只有在实时任务时才会用到。执行汇编指令“CPSID F”,则将D0位置1(关总中断);执行汇编指令“CPSIE F”,则将D0位清0(开总中断),其中F代表FAULTMASK。在退出异常处理时FAULTMASK会被自动清除,但从不可屏蔽中断(NMI)中退出除外,复位时被清除。FAULTMASK寄存器存在于Cortex-M3与Cortex-M4处理器中。

4)基本优先级屏蔽寄存器(BASEPRI)

基本优先级屏蔽寄存器(BASEPRI)提供了一种更加灵活的中断屏蔽机制,通过设置该寄存器可以屏蔽特定优先级的中断,当该寄存器设置为一个非零值时,所有优先级值大于或等于(中断的优先级是数值越大优先级越低)该值的中断都会被屏蔽,当该寄存器为零时不起作用。寄存器只能在特权模式下访问。复位时,基本优先级屏蔽寄存器被清除。

基本优先级屏蔽寄存器(BASEPRI)的宽度与在芯片设计时实际实现的优先数量有关,通常BASEPRI的宽度为3~8位二进制,占用D0~D7位,当不足8位时高位有效。例如,当BASEPRI的宽度为3位时,D7、D6、D5有效,BASEPRI设置值可为0xE0、0xC0、0xA0、0x80、0x60、0x40、0x20、0x00(共8个)。BASEPRI寄存器存在于Cortex-M3与Cortex-M4处理器中。

BASEPRI还有另一种访问方式,就是通过名称BASEPRI_MAX,它们在物理上是同一个寄存器,但访问方式有些不同,使用BASEPRI_MAX访问时,只能接收大于当前内容的值。例如,假设BASEPRI_MAX原有的值为0x40,下面指令中的0x80不会被接收。

要设置为更小的优先级可以使用BASEPRI寄存器。

5)控制寄存器(CONTROL)

Cortex-M0、Cortex-M3、Cortex-M4处理器内核中的控制寄存器(CONTROL)的D31~D2位保留,D1、D0位含义如下。

D1(SPSEL)——堆栈指针选择位。若SPSEL=0,使用主堆栈指针MSP为当前堆栈指针(复位后默认值);若SPSEL=1,在线程模式下,使用线程堆栈PSP指针为当前堆栈指针。特权、线程模式下,软件可以更新SPSEL位;在Handler模式下,写该位无效。复位后,控制寄存器清零,非特权访问无效。可用MRS指令读该寄存器,用MSR指令写该寄存器。

D0(nPRIV)——如果权限扩展,在线程模式下定义执行特权。若nPRIV=0,线程模式下可以特权访问;若nPRIV=1,线程模式下无特权访问。在Handler模式下,总是特权访问。

Cortex-M4F中除了以上D1、D0位外,还定义了D2位,D2(FPCA)浮点上下文活跃位。FPCA会在执行浮点指令时自动置位,当FPCA=1且发生了异常时,处理器的异常处理机制就认为当前上下文使用了浮点指令,这时就需要保存浮点寄存器,浮点寄存器的保存方式分多种,详细内容请参考《CM3/4权威指南》《ARMv7-M参考手册》。处理器硬件会在异常入口处清除FPCA位。

3. 浮点寄存器

浮点控制寄存器只在Cortex-M4F处理器中存在,其中包含了用于浮点数据处理与控制的寄存器,这里只进行简单的介绍,详细内容请参考《CM3/4权威指南》《ARMv7-M参考手册》。此外浮点单元还有一些不在内核中,通过存储器映射的寄存器有协处理器访问控制寄存器(CPACR)。需要注意的是,为降低功耗浮点单元默认是被禁用的,如果需使用浮点运算,就要通过设置CPACR来启用浮点单元。

1)S0~S31和D0~D15

S0~S31都是32位寄存器,每个寄存器都可用来存放单精度浮点数,它们两两组合可用来存放双精度浮点数,两两组合成双精度寄存器时可用D0~D15来访问,如D0是由S0和S1组合而成。注意,Cortex-M4F的浮点运算单元只能进行单精度浮点运算,不支持双精度浮点运算,但可以对双精度浮点数进行传输操作。

2)浮点状态控制寄存器(FPSCR)

浮点状态控制寄存器提供了浮点系统的应用程序级控制,其中包括浮点运算结果的状态信息与定义一些浮点运算的动作。浮点状态控制寄存器在系统复位时状态是未知的,各数据位的预定义如表2-3所示,其各位含义为:负标志N、零标志Z、进位/借位标志C、溢出标志V、交替半精度控制位AHP、默认NaN模式控制位DN、清零模式控制位FZ、舍入模式控制位RMode、输入非正常累积异常位IDC、不精确累积异常位IXC、下溢累积异常位UFC、溢出累积异常位OFC、被零除累积异常位DZC、非法操作累积异常位IOC。

表2-3 FPSCR浮点状态控制寄存器各数据位预定义