Cortex-M3

作者:dogsun88

一、进入异常之前处理器可能的状态有:

1、 handler

2、 线程,MSP

3、 线程,PSP

二、产生异常时:

1、 有一个压栈的过程,产生异常时使用PSP,就压入到PSP中,产生异常时使用MSP,就压入到MSP中

2、 会根据处理器的模式和使用的堆栈,设置LR的值(当然设置完的LR的值再压栈)

三、异常返回时:

根据LR的值,判读使用那个堆栈,然后再从相应的堆栈中POP数据到寄存器。

举例说明:

在利用OSStartHighRdy->OSPendSV->OSPendSV_nosave启动第一个线程时,在异常进入的时候,压栈到MSP(不会影响PSP的内容),在通过BX LR指令从异常返回之前,有一句ORR LR, LR, #0x04来设置LR的值,保证我们从异常返回时是从PSP中POP数据到寄存器里,而此时PSP的值是OSTCBHighRdy->OSTCBStkPtr,即任务创建时定义的堆栈数组,同时在OSTaskStkInit函数中对该任务数组初始化时,要保证其组织结构和异常产生时处理器自动压栈产生的栈的结构相同。

四、栈中的内容分析:

1、 变量

2、 调用函数时,如果子函数比较复杂,会由编译器自动的压入r4-r11, lr(压入多少寄存器,由子函数的复杂程度决定的)

3、 异常保存,压入栈的是r0-r3,r12,LR,PC,xSPR(硬件直接完成的)

4、 进程切换,所有寄存器全部压栈

由于异常死机了之后的具体操作:

产生异常时,两个值我们需要,一个是pc,一个是LR,通过LR找到栈, 再通过栈找到pc

1、 如果LR=0xFFFFFFF9说明产生异常的时候使用的是MSP,我们只需要读出当前sp的值,
sp += 0x1c;读出的内容就是产生异常时压入栈的PC的值,这个值跟反汇编代码对比,就能得到具体哪句话产生的异常。

2、 如果LR=0xFFFFFFFD明产生异常的时候使用的是PSP,我们需要读出PSP的值,不要直接来读sp的值,在keil集成开发环境中,调试时寄存器窗口有个Banked选项,会给出当前PSP的值,当然也可以在异常处理中加入两句话:

MRS R0,PSP
PUSH {R0}

我们就能在当前MSP中得到,我们PSP的值了,之后操作和上面一样,psp+=0x1c;读出的内容就是产生异常时压入栈的PC的值,这个值跟反汇编代码对比,就能得到具体哪句话产生的异常。

文章来源: ChinaUnix

围观 795

关于Cortex-M3的中断优先级的描述 

1、和之前的ARM7不同,Cortex-M3使用NVIC(嵌套向量中断管理器)来管理系统的中断。
 
2、每一个中断源的优先级由3个位来决定,这3个位就是中断优先级寄存器器里(PRIx)的INTn,这里的n 一般是A、B、C、D。 

3、每个中断源的优先级由2部分组成,一部分表示中断组别,一部分表示同组的优先级编号。组别优先级高的中断源,可以打断组别优先级低的中断处理,同一个组的中断源不能打断正在处理的中断,只能在进入中断处理时,同时发生的两个中断源进行判别优先级。 

4、我们把中断源的优先级组别和同组内的中断编号分别用抢占式优先级别和子优先级别来表示。他们的具体表现形式就是第2条提到的INTn。 

5、由于这INTn的3个位只能表示0-7 总共8个数字,所以在这3个位之外,系统安排了另一个寄存器来说明这3个位时如何使用的,这个寄存器就是APINT。APINT中的PRIGROUP位域就是对中断优先级的这3个位如何分配使用进行说明的,它是针对整个系统而言的,而不是针对某一个中断源而言的。 

INTn的3个位可以有4种组别管理模式,由APINT的PRIGROUP描述,换句话说PRIGROUP的值描述了如何使用这3个位。下面的表就列出了对应不同的PRIGROUP的值,如何去分析PRIX的INTn!

6、我们在设置系统的中断级别符合分组管理的时候调用IntPriorityGroupingSet(),这个函数修改的就是APINT寄存器中的PRIGROUP。 

7、我们针对每一中断源设置优先级,调用IntPrioritySet(),这个函数针对的就是PRIx寄存器中每个中断源对应的3个bits 即INTn。

8、举个例子说明,有两个中断源,A中断的中断优先级级置成INTA = b011, B中断的中断优先级设置成INTB = b001。单单依靠这两个设置我们是无法判断A,B是如何进行中断调度的,我们首先要看中断的组别管理是如何的。这里我们假设两种不同的组别管理方法,来说明如何分析中断的优先级管理。 

(1)假设我们设置PRIGROUP = 0x05,我们按下面来分析中断是如何调度的:通过查上面的表我们可以看出,INTn的优先级按照bxx.y来划分:

a. INTA的中断优先级就被划分为 INTA = b01.1 组优先级 = 01,子有限级 = 1 

b. INTB的中断有限级也被分为 INTB = b00.1  组优先级 = 00,子优先级 = 1 

由此可见,B的组优先级比A的优先级要高(注意,数字越小,级别越高),B的中断可以打断A的中断处理。 

(2)假设我们设置PRIGROUP = 0x06,我们按下面来分析中断是如何调度的:通过查上面的表我们可以看出,INTn的优先级按照bx.yy来划分 :

a. INTA的中断优先级被划分成INTA = b0.11.  

组优先级 = 0;子优先级  = 11。

b. INTB的优先级被划分为INTB = b0. 01   

组优先级 = 0;子优先级 = 01。

由此可见,A和B处于同一个组优先级,他们两个互相不能打断对方的中断处理。B中断的子优先级高,当两个中断同时发生时,会先进B中断处理,但如果A先发生,在未处理结束前,B是不能打算A进行处理的。
 
9、由第8项的分析可以看出,仅仅从中断优先级是不能判定中断源的相互关系的,还需要看中断优先级是如何划分的。这就是为什么有IntPrioritySet(..)和IntPriorityGroupingSet()这两个函数。

围观 482

在项目开发的过程中,发现程序总是死在判断DMA一次传输是否完成这个标志位上。进一步回退分析,发现是在I2C读的过程中,有使用到DMA去取外部I2C设备的data。

但是data并没有读完,Data为32bits,DMA在读到18bits时,就出现读不到data bit了。导致I2C硬件模块不能进一步动作,SCK一直被拉低,没有clock输出,SDA也是如此。

下面是通过示波器抓到的波形:

在上面的波形图中,绿色的是SCK,蓝色的是SDA。

在第一幅波形图中,有2段波形,第一段连续的I2C波形,经过确认I2C硬件和DMA配合是正常的。第二段则是有一段I2C波形,然后就SCK和SDA就都被拉低了。

将第一幅图的第2段波形放大,就是第二副图看到的情况。可以很明显的看到SCK输出有被其他因素打断。I2C吐出几个clock,被其他因素打断了,clock线即SCK被拉低一段时间,然后clock线再继续吐出几个clock。

直到I2C被频繁中断,clock吐不出来为止,SCK和SDA都被拉低,此时明显的I2C和DMA的配合过程被其他因素频繁的干扰打死了。

通过示波器抓到的波形验证了这一点,然后再来分析代码和串口输出,发现是外部GPIO一直有中断输入,Cortex-M3 MCU频繁的响应中断,导致I2C&DMA操作被打挂了。

有什么办法来解决这个问题?

方法就是在I2C和DMA操作的过程开始处关闭所有中断,而在操作结束的时候重新打开中断,以免I2C&DMA操作被其他中断打断。

ARM MDK编译环境自带的编译器ARMCC,含有内置的c函数,可供操作中断用:

__enable_irq();

__disable_irq();

不过debug发现这两个函数只会在privileged mode使用。也就是说需要Cortex-M3 MCU先进入privileged mode,才能调用这两个函数。

用什么方法让MCU从user mode切换到privileged mode呢?

exception handler!

可以用SVC啦,软件可以利用SVC制造一个exception,然后在exception handler中利用MCU的privileged mode来完成自己的任务。有点类似于linux里面的系统调用。

SVC exception可以调用SVC函数,而SVC函数可以传入参数,也可以返回参数。转为系统调用而设计。

举个例子,用户程序调用read()这个系统调用,read()会引发SVC exception,进而调用SVC函数,read()函数的参数传递给SVC函数,SVC在内核态执行硬件动作,并将SVC函数的返回结果,作为read()函数的返回,返回给用户程序。当然linux里面并不一定是SVC,这里只是做个类比。

也就是说SVC可以完成从用户态到内核态的转变,不让用户直接操作硬件。用户只需要记住系统调用API的名字和函数即可,而不用管硬件的具体实现。

所以这里我们就把I2C读的操作放在一个SVC函数里面去实现,并且在SVC函数的开始处调用__disable_irq();在函数的结束处,调用__enable_irq()。

经过验证,I2C&DMA操作再也不会被中断打断了。

参考资料:

1、http://www.keil.com/pack/doc/cmsis/Core/html/group___core___register__gr...

2、cortex-M3权威指南

文章来源: 博客园

围观 447

大部分采用Cortex-M3/M4 MCU的目标应用是便携式的,并且供电电源来自电池或能源收集系统,因此我们所探讨的大部分概念涉及如何减少系统整体能耗的技术。然而,在许多情况下,这些节能技术也是处理器应用设计的有力工具,可提供:

●更符合成本效益的解决方案

●更大的升级和采用新特性的设计冗余

●有助于产品在激烈竞争市场上脱颖而出的性能和特性

小知识:Cortex-M3对比Cortex-M4

Cortex-M3架构背后的指导思路是设计一种既要满足应用的成本效益又要提供高性能计算和控制1的处理器。类似的应用包括汽车车身系统、工业控制系统和无线网络/传感器产品等。M3系列为32位的ARM处理器架构引进了多项重要特性,包括:

●不可屏蔽式中断

●高度确定性、嵌套、向量式中断

●原子位操作

●可选的存储保护(MPU)

除了绝佳的计算性能,Cortex-M3处理器先进的中断结构还能确保系统迅速响应真实世界的事件,同时仍然提供极低的动态与静态功耗。

图1 ARM Cortex M3和M4对比

SWO接口节省I/O引脚并加速调试

除了传统的串行调试(Serial Wire Debug)功能之外,基于ARM Cortex-M的MCU还可以通过它的单引脚串行监视器输出(Serial Wire Viewer Output,SWO)3提供指令跟踪接口,如图2所示。这个接口可以直接把“printf格式的”调试信息传递给应用代码。SWO允许调试信息直接在任何标准的IDE中浏览。此外,这些信息也可以用独立的SWO监视器(例如,Segger的J-Link SWO Viewer软件4,或是Silicon Labs的energyAware Commander 4)进行浏览。由于SWO输出内建于内核硬件本身,因此它是Cortex-M内核与生俱来的优点。SWO不占用MCU的任何UART接口,这些接口它们可能早已被分配给了应用。

图2 专用ARM Cortex SWO接口节省I/O引脚并加速调试

基于SWO的调试还有一个重要的优势在于,它让微控制器在进入最低的休眠模式时,保持调试连接有效,而在大多数情况下,传统的调试连接这时是不能正常工作的。SWO的指令追踪还可以用于跟踪程序计数器,以帮忙IDE统计出程序各项功能所占用的时间。这些统计数字能够与电流测量结合起来,帮助开发人员对设计功耗进行微调。

目前一些供应商正在开始重新认识这项优点,而且有些厂商已经为了这个目的而把功耗模式和电流测量硬件纳入到本身的开发平台。例如,Silicon Labs的EFM32 Gecko MCU入门级和开发级工具包都包含功耗测量输出,并可搭配energyAware Profiler工具6中的程序代码追踪功能。图3显示了如何让设计人员精确定位到哪个程序功能块最耗费能源,并且能够快速调试其它与能源有关的问题。

图3 软硬件工具精确定位耗能最大的功能,无需示波器和万用表,快速排除问题

智能休眠节省每一微瓦

ARM Cortex-M处理器的Sleep-on-Exit(中断完成时直接进入休眠)是另一项“一箭双雕”的功能,可同时节省CPU周期和能耗。这点在由中断所驱动的应用中格外有用,因为处理器的大部分时间不是在执行中断处理,就是在中断事件之间休眠。在进入中断服务例程(ISR)时,MCU必须花费好几个指令周期把当前线程状态入栈,然后在退出中断处理返回时恢复原有线程状态,即“出栈”。当应用需要处理器在退出ISR后直接进入休眠状态时,传统MCU仍然必须恢复原先存储的状态信息,然后线程代码才能让MCU进入休眠状态。同样地,当下次的中断唤醒MCU时,它的状态必须再次入栈。

而当使能ARM Cortex-M微控制器上的Sleep-on-Exit功能后,MCU就会在中断处理完成后直接进入休眠状态,而不用先返回到原有线程上(见图4)。这会使处理器仍然保持在中断状态,因为消除了唤醒再入栈过程,因而节省下许多宝贵的机器周期。消除入栈出栈过程既节省了时间也节省了能耗,否则电能就会被不必要的指令周期白白消耗,也包括哪些传统MCU在休眠和唤醒之间管理堆栈的代码。而且,当处理器被中止调试请求(Halt Debug Request)唤醒时,出栈过程将会自动进行。

流程图


图4:ARM Cortex-M的Sleep-on-Exit功能通过避免不必要的代码执行和减少出栈入栈操作降低功耗

ARM Cortex-M4运行更快、休眠功耗更低

像许多MCU一样,Cortex-M3/4处理器通常能够采用高时钟速率的方法在中断驱动的应用中节省能耗。如果处理器大部分时间处于休眠状态,这种看似违背直觉但普遍采用的节能策略就会很好,因为运行时间减少所节省的能耗远远大于稍高的操作电流。简单来说,多花10%的电可以省掉 20%的时间,总体来说是节能了。

这种技术可以应用在任何Cortex-M系列的处理器上,而涉及密集运算任务的应用也能从Cortex-M4处理器的额外能力中受益。它的单周期DSP指令和可选的浮点加速器能大大减少诸如数字信号处理、过滤、分析或波形合成等功能所需要的执行周期数。

上面提及的节能特性也能带来其它优势。例如,在超音波/声学水表之类的应用中,它们必须在小电池供电下运行多年,需要MCU尽可能长的保持在休眠状态。除了有助于减少MCU唤醒时间之外,Cortex-4 DSP和浮点算术指令也能使用成熟的滤波功能从廉价声学传感器输出中获得所需的信息,从而避免采用昂贵的超声波流量传感器。在这个应用实例中,Wonder Gecko MCU的外设还能够作为模拟状态机提供额外的能量节省,它仅仅在需要时才唤醒Cortex-M4处理器。

虽然并不完备,但这些林林总总的秘诀与妙方应该能让各位产生好的思路,可以在下一次设计中充分利用Cortex-M系列中一些较不为人知的特性所带来的好处。为了发挥ARM Cortex-M系列的这些和其它重要功能,可参考本文末段的参考资料,它们提供了所需的更多细节。

文章来源: 畅学电子网

围观 465

作者:sunheshan

1、 异常

M3支持15个系统异常,240个外部异常IRQ,其中NMI,复位,hardfault三个异常的优先级固定不可更改且是负数,其余的都可编程。

M3的异常分为抢占优先级和子优先级。

2 、关于中断优先级

M3中,除了复位,NMI以及硬fault有固定的优先级,其他优先级都是可编程的。原则上,CM3支持3个固定的高优先级和多达256级的可编程优先级,并且支持128级抢占。但是,绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数会更少,如8级,16级,32级等。它们在设计时会裁掉表达优先级的几个低端有效位。

如使用3个位表示优先级则配置寄存器的结构如图所示:

在M3中,优先级分为两个部分,一个是抢占优先级优先级,一个是子优先级。在计算抢占优先级和子优先级的有效位数时,必须要知道:

1、芯片实际使用了多少位来表达优先级

2、优先级组是如何划分的。

举个例子,如果只使用3个位来表达优先级([7:5]),并且优先级组的值是5(从比特5处分组),则得到4级抢占优先级,且在每个抢占优先级的内部有2个子优先级,

当然也可设置全部是抢占优先级没有子优先级

在编写应用程序的时候,只需要系统所需要的中断分组和组内优先级即可,直接调用m3提供的API函数即可。

在CM3中,允许使用3个位到8个位来表达优先级。为了确定具体的位数,可以先往一个优先级寄存器中写0xFF,再读回来,读出多少个1,就表示使用多少个位来表达优先级。

关于中断配置基础

每个外部中断都在NVIC的下列寄存器中“挂号”:

1、使能与除能寄存器

2、悬起与“解悬”寄存器

3、优先级寄存器

4、活动状态寄存器

5、异常掩蔽寄存器(PRIMASK, FAULTMASK以及BASEPRI)

另外,下列寄存器也对中断处理有重大影响:

1、向量表偏移量寄存器

2、软件触发中断寄存器

3、优先级分组位段

其他异常配置寄存器

系统Handler控制及状态寄存器SHCSR用法fault,总线fault以及存储器管理fault都是特殊的异常,因此给它们开了小灶。它们的使能控制都是通过SHCSR来实现,各种faults的悬起状态和大多数系统异常的活动状态也都在该寄存器中。

中断控制及状态寄存器ICSR

在大多数情况下,它们对于应用软件都没有什么用处,只有悬起位对应用程序常常比较有参考价值。

异常屏蔽寄存器

PRIMASK用于除能在NMI和硬fault之外的所有异常,它有效地把当前优先级改为0(可编程优先级中的最高优先级)。该寄存器可以通过MRS和MSR以下例方式访问:

1、关中断

MOV R0, #1
MSR PRIMASK, R0

2、开中断

MOV R0, #0
MSR PRIMASK, R0

此外,还可以通过CPS指令快速完成上述功能:

CPSID i ;关中断
CPSIE i ;开中断

FAULTMASK更绝,它把当前优先级改为-1。这么一来,连硬fault都被掩蔽了。使用方案与PRIMASK的相似。但要注意的是,FAULTMASK会在异常退出时自动清零。

掩蔽寄存器虽然能一手遮天,却都动不了NMI,因为NMI是用在最危急的情况下的。因此系统为它开出单行道,无需挂号只是不要迟到。当NMI激活时,“谁都是省略号,唯独是你不得了,第一优先谁比你重要”!试想,如果NMI被连接到系统的掉电报警线上,且系统是体外循环机的电源管理器……如果因为中断被除能就视而不见,则会使体外循环机因断电而失能,体外循环序列可以被意外终止,病人的生命也将丢失。

Active状态寄存器

每个外部中断都有一个活动状态位。在处理器执行了其ISR的第一条指令后,它的活动位就被置1,并且直到ISR返回时才硬件清零。由于支持嵌套,允许高优先级异常抢占某个ISR。然而,哪怕中断被抢占,其活动状态也依然为1。

3、使用中断

对于应用程序存储在ROM中,不需要更改异常服务程序。

建立优先级组

为该中断指定优先级

使能该中断

4、 cm3.h中操作中断相关函数

__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) //---设置组优先级
__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) //---获得组优先级
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) //---使能中断
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) //---除能中断
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) //---获得被挂起的中断
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) //---挂起中断
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) //---清除挂起中断
__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) //---中断是否活动
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) //---设置中断优先级
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) //---获取中断优先级
__STATIC_INLINE void NVIC_SystemReset(void) //---NVIC 复位

5、 用户EFM32中断

(1)优先级数目

首先对于特定处理器,支持的外部中断数不一样,故在设置中断优先级时需要知道芯片实际使用了多少位来表达优先级。在EFM32中:__NVIC_PRIO_BITS定义efm32g280f128.h当中。

#define __NVIC_PRIO_BITS 3 /**< NVIC interrupt priority bits */

在cm3.h的优先级设置函数设置优先级语句为:

NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);

从cm3.h设置优先级函数可知芯片实际用了(8-__NVIC_PRIO_BITS)表达优先级。这个EFM32在startup.s提供的30中断向量数目符合。

(2)优先级组

优先级数目是定死了的,对于优先级组AIPCR[8:10]复位值为0,对于(8-__NVIC_PRIO_BITS)优先级数目来说就全部是抢占优先级而没有子优先级。

对于应用程序,可以根据工程需要对优先级组进行设定。

void NVIC_SetPriorityGrouping (uint32_t PriorityGroup)
PriorityGroup

有7-PriorityGroup位表示优先级组。如PriorityGroup为5,则[7:6]表示优先级抢占位段。

(3)开关可屏蔽中断

在core_cmFunc.h中定义了与PRIMASK中断操作相关的函数

__disable_irq(void);
__enable_irq(void);
__get_PRIMASK(void);
__set_PRIMASK(uint32_t priMask);

6、使用SVC

SVC指令带一个8位的立即数,可以视为是它的参数,被封装在指令本身中,如:

SVC 3 ;呼叫3号系统服务

SVC是用于呼叫OS所提供API的正道。用户程序只需知道传递给OS的参数,而不必知道各API函数的地址。

文章来源:CSDN

围观 1158

本文主要从M3和M4的MPU、DSP能力、debug调试和电源管理4个方面说明两者的区别。

1、内存保护单元MPU

与Cortex - M3的相同,MPU是一个Cortex - M4中用于内存保护的可选组件。处理器支持标准ARMv7内存保护系统结构模型。您可以使用在MPU执行 特权/访问 规则,或者独立的进程。这个MPU提供全面支持:

  • 保护区
  • 重叠保护区域,提升区域优先级(7 =最高优先级,0 =最低优先级)
  • 访问权限
  • 将存储器属性输出至系统
  • 2、DSP能力

    下图展示了处理器运行在相同的速度下Cortex - M3和Cortex - M4在数字信号处理能力方面的相对性能比较。
    在下面的数字,Y轴代表执行给出的计算用的相对的周期数。 因此,循环数越小,性能越好。以Cortex - M3作为参考,Cortex - M4的性能计算,性能比大概为其周期计数的倒数。举例说明,PID功能,Cortex - M4的周期数是与Cortex - M3的约0.7倍,因此相对性能是1/0.7,即1.4倍。

    Cortex - M系列16位循环计数功能

    Cortex - M系列32位循环计数功能

    这很清楚的表明,Cortex - M4在数字信号处理方面对比Cortex - M3的16位或32位操作有着很大的优势。
    Cortex-M4执行的所有的DSP指令集都可以在一个周期完成,Cortex - M3需要多个指令和多个周期才能完成的等效功能。即使是PID算法——通用DSP运算中最耗费资源的工作,Cortex - M4也能提供了一个1.4倍的性能得改善 。另一个例子,MP3解码在Cortex-M3需要20-25Mhz,而在Cortex-M4只需要10-12MHz。

    1) 32位乘法累加(MAC)

    32位乘法累加(MAC)包括新的指令集和针对Cortex - M4硬件执行单元的优化它是能够在单周期内完成一个 32 × 32 + 64 - > 64 的操作 或 两个16 × 16 的操作。如下表列出了这个单元的计算能力。

    2) SIMD

    Cortex - M4支持SIMD指令集,这在上一代的Cortex - M系列是不可用的。上述表中的指令,有的属于SIMD指令。与硬件乘法器一起工作(MAC),使所有这些指令都能在单个周期内执行。受益于SIMD指令的支持,Cortex - M4处理器是能在单周期完成高达32 × 32 + 64 - >64的运算,为其他任务释放处理器的带宽, 而不是被乘法和加法消耗运算资源。考虑以下复杂的算术运算,其中两个16 × 16乘法加上一个32位加法,被编译成由一个单一指令执行:SUM = SUM +(A* C)+(B *D)

    3) FPU

    FPU是Cortex - M4浮点运算的可选单元。因此它是一个专用于浮点任务的单元。这个单元通过硬件提升性能,能处理单精度浮点运算,并与IEEE 754标准 兼容。这完成了ARMv7 - M架构单精度变量的浮点扩展。FPU扩展了寄存器的程序模型与包含32个单精度寄存器的寄存器文件。这些可以被看作是:

  • 16个64位双字寄存器,D0 - D15
  • 32个32位单字寄存器,S0 - S31 该FPU提供了三种模式运作,以适应各种应用
  • 全兼容模式(在全兼容模式,FPU处理所有的操作都遵循IEEE754的硬件标准)
  • Flush-to-zero 冲洗到零模式(设置FZ位浮点状态和控制寄存器FPSCR [24]到flush-to-zero 模式。在此模式下,FPU 在运算中将所有不正常的输入操作数的算术CDP操作当做0.除了当从零操作数的结果是合适的情况。VABS,VNEG,VMOV 不会被当做算术CDP的运算,而且不受flush-to-zero 模式影响。结果是微小的,就像在IEEE 754 标准的描述的那样,在目标精度增加的幅度小于四舍五入后最低正常值,被零取代。IDC的标志位,FPSCR ,表示当输入Flush时变化。UFC标志位,FPSCR ,表示当Flush结束时变化)
  • 默认的NaN模式(DN位的设置,FPSCR ,会进入NaN的默认模式。在这种模式下,如对任何算术数据处理操作的结果,涉及一个输入NaN,或产生一个NaN结果,会返回默认的NaN。仅当VABS,VNEG,VMOV运算时,分数位增加保持。所有其他的CDP运算会忽略所有输入NaN的小数位的信息)
  • 下表显示的是FPU指令集


    3.debug调试

    与Cortex - M3的相同, Cortex - M4的设备是通过标准JTAG或串行线调试连接器调试。要连接到主机的接口,一个简单,标准化外部连接器是必要的。

    4. 电源

    1) 电源管理


    2) 功耗比较

    从图所示,很明显在功率效率方面Cortex - M4的性能大大优于表Cortex - M3。

    围观 920

    页面

    订阅 RSS - Cortex-M3