Cortex-M0

作者:Founder_U

一、 NVIC和系统控制块特性

1. 灵活的中断管理:使能/禁止中断,优先级配置

2. 硬件嵌套中断支持

3. 向量化的异常入口

4. 中断屏蔽

5. NVIC寄存器的起始地址:0xE000E100, 对其访问必须是每次32bit

6. SCB的起始地址: 0xE000E010,也是每次32bit访问。

二. 中断使能和清除使能

1. 中断寄存器是可编程的,用于控制中断请求(异常编号16以上)的使能(SETENA)和禁止(CLRENA), 如下所示:

2. 使能/禁止 中断的代码:

1). C代码:

*(volatile unsigned long) (0xE000E100) = 0x4 ; //使能#2中断
*(volatile unsigned long) (0xE000E180) = 0x4 ; //禁止#2中断

2). 汇编代码:

LDR R0, =0xE000E100 ; //SETEAN寄存器的地址
MOVS R1, #04 ; //设置#2中断
STR R1, [R0] ; //使能中断#2

3). CMSIS标准设备驱动函数:

void NVIC_EnableIRQ(IRQn_Type_IRQn); //使能中断#IRQn;
void NVIC_DisableIRQ(IRQn_Type_IRQn); //禁止中断#IRQn;

三. 中断挂起和清除挂起:

1. 可以通过操作中断挂起(SETPEND)和清除挂起(CLRPEND),这两个寄存器来访问和修改中断挂起状态。

2.挂起/清除挂起的代码:

1). C代码:

*(volatile unsigned long)(0xE000E100) = 0x4 ; //使能中断#2
*(volatile unsigned long)(0xE000E200) = 0x4 ; // 挂起中断#2
*(volatile unsigned long)(0xE000E280) = 0x4 ; // 清除中断#2的挂起状态

2). 汇编代码:

LDR R0, =0xE000E100 ; //设置使能中断寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //使能#2中断
LDR R0, =0xE000E200 ; //设置挂起中断寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //挂起#2中断
LDR R0, =0xE000E280 ; //设置清除中断挂起寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //清除#2的挂起状态

3). CMSIS标准设备驱动函数:

void NVIC_SetPendingIRQ(IRQn_Type_IRQn) ; //设置一个中断挂起
void NVIC_ClearPendingIRQ(IRQn_Type_IRQn); //清除中断挂起
void NVIC_GetPendingIRQ(IRQn_Type_IRQn) ; //读取中断挂起状态

四. 中断优先级:(0xE000E400~0xE000E41C)

1. 每个外部中断都有一个对应的中断有先级寄存器,每个优先级都是只有一个字节且只有最高2Bit有效;

2. NVIC支持字传输,所以每次访问都会涉及4个中断优先级寄存器。

3. 设置中断优先级代码:(先读一个字,再修改对应字节,最后整个字写回)

1). C代码:

unsigned long temp; //定义一个临时变量
temp = *(volatile unsigned long)(0xE000E400); //读取IRP0值
temp &= (0xFF00FFFF |(0xC0 << 16)); //修改中断#2优先级为0xC0
*(volatile unsigned long)(0xE000E400) = temp; //设置IPR0

2). 汇编代码:

LDR R0, =0xE000E100 ; //设置使能中断寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //使能#2中断
LDR R0, =0xE000E200 ; //设置挂起中断寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //挂起#2中断
LDR R0, =0xE000E280 ; //设置清除中断挂起寄存器地址
MOVS R1, #0x4 ; //中断#2
STR R1, [R0] ; //清除#2的挂起状态

3). CMSIS标准设备驱动函数:

void NVIC_SetPriority(IRQn_Type_IRQn, uint32_t priority) ; //设置中断优先级
uint32_t NVIC_GetPriority(IRQn_Type_IRQn); //读取中断优先级

这里的priority是0,1,2,3.函数内部会自动移位到对应的优先级最高2位:

void NVIC_SetPriority(2, 3) ; //设置#2中断的优先级为0xC0

五. 异常屏蔽寄存器(PRIMASK)

1.对时间敏感的应用,需要用PRIMASK来屏蔽掉除NMI和硬件错误异常以外的其他所有中断和异常。

2.PRIMASK只有1Bit有效,默认为0,为1时起屏蔽作用。

3.操作PRIMASK的代码:

1). 汇编代码:

MOVS R0, #1 ;
MSR PRIMASK, R0 ; //使用MSR指令设置PRIMASK值

2). CPS指令:

CPSIE i ; //清除PRIMASK值
CPSID i ; //设置PRIMASK值

3). CMSIS标准设备驱动函数:

void _enable_irq(void) ; //清除PRIMASK值
void _disable_irq(void) ; //设置PRIMASK值

六. 中断输入和挂起行为

1. Cortex-M0允许电平触发和脉冲触发两种方式;

2. 每个外部中断请求都会对应一个挂起状态寄存器,且只有1bit,当开始处理这个异常时,硬件会自动清除挂起状态;

3. 大多数外设都是使用电平触发,当执行中断服务程序并且清除外设中断信号之前,该信号一直为高:

4. 使用脉冲触发中断时,至少持续1个时钟周期:

七. 中断等待 (中断确认 –> 中断服务处理开始执行)

1. Cortex-M0中断默认等待的时间为16个时钟周期;

2. 中断等待的条件:

1). 改中断使能并且没有被PRIMASK屏蔽掉;

2). 存储器系统没有任何等待。

3. IRQLATENCY的8位信号可以控制中断等待:设置为0,则以最快速度响应中断。

八. 系统异常的控制寄存器(SHPR2,SHPR3)

1. Cortex-M0处理器只有SVC、PendSV和SysTick 3个与OS相关的系统异常才具有可编程的优先级

2. 符合CMSIS的设备驱动,可使用如下方式访问:

3. 中断控制状态寄存器(ICSR, 0xE000ED04):
P139, 表9.6

4. 符合CMSIS的设备驱动,可使用 "SCB -> ICRS" 来访问。

九. 系统控制寄存器(0xE000E000~0xE000EFFF)

1. SCS包括NVIC、调试控制、SysTick定时器;

2. CPU ID基址寄存器(0xE000ED00),只读,包含处理器ID信息,"SCB -> CPUID" 访问;

3. 应用中断和复位控制寄存器(AIRCR, 0xE000ED0C):

1). 用于应用程序请求系统复位,识别系统的大小端,以及清除所有的异常活动状态:

2). CMSIS 设备驱动,可以使用 "SCB -> AIRCR" 来访问;

3). CMSIS 设备驱动, 请求系统复位的函数:

Void NVIC_SystemReset(void);

十. 配置和控制寄存器(CCR, 0xE000ED14)

1. CCR 只读, 决定了栈的双字节对齐设置和非对称访问的处理;

2. CMSIS 设备驱动,可以使用 "SCB -> CCR" 来访问;

文章来源:极客头条

围观 874

作者:Founder_U

1、异常类型及编号

Cortex-M0的每个异常源都有一个单独的编号:

1~15内部系统异常:Reset(1), NMI(2), H/W Error(3), SVC(11), PndSV(14), SysTick(15)其他编号未用;

16~47外部中断:IRQ#0~IRQ#31。

2、异常优先级 (Cortex-M0 支持7个)

1). Cortex-M0 支持3个固定的最高优先级(Reset(-3), NMI(-2), H/W Error(-1))和4个可编程优先级;

2). 可编程寄存器有8bit宽,但只有Bit7和Bit6可配置,其余Bits为0. (优先级由高到低:0x00,0x40,0x80,0xC0);

3). 如果两个同时发生的异常的优先级相同,则先执行异常编号小的。(IRQ#0,IRQ#1 则先执行IRQ#0)

3、向量表(异常处理所需的起始地址信息)

异常向量的地址为异常编号乘以4(Reset向量的地址为:1*4=0x00000004),其他向量地址如下图所示:

4、EXC_RETURN(32Bits)

该值用于异常返回机制,下图是其位域的含义:

3个合法值:

0xFFFFFFF1 返回处理模式(嵌套异常发生的情况)

0xFFFFFFF9 返回线程模式并在返回中使用主栈(MSP);

0xFFFFFFFD 返回线程模式并在返回中使用进程栈(PSP);

5、异常的流程

接受异常请求:

1) 中断和SysTick中断使能;

2) 未被NMI屏蔽掉;

3) 异常优先级大于当前执行的异常优先级。

压栈及相关寄存器更新:

1) 压栈并更新栈指针(8个registers被压栈:R0~R3, R12, R14/LR, R15/PC, xPSR);

2) 取出异常向量写入PC中;

3) 3个寄存器更新(LR<–EXC_RETURN, IPSR<–异常编号, NVIC<– 对应的中断控制和状态)

执行异常处理:

1) 自动定位异常向量,并处理;

2) 利用EXC_TURN的值来触发异常返回机制。

异常退出:

1) 寄存器出栈;

2) 恢复返回地址,并执行异常前程序。

6、3种主要的异常及其机制:(单异常,末尾连锁,延迟到达)

1)单异常

2)末尾连锁

3)延迟到达

文章来源:极客头条

围观 801

一、故障处理

故障是异常的一个子集,见第2-19页的异常处理模型。在NMI或HardFault异常处理时发生的故障将会引起HardFault异常或导致锁定(Lockup)。故障包含:•执行一条SVC指令,该指令的优先级高于或等于SVCall。•缺少调试器连接时,执行BKPT指令。

• 在加载或存储数据时,系统产生总线错误。

• 执行XN存储区的指令。

• 执行来自系统已产生总线故障的地址位置的指令。

• 取向量时系统产生总线错误。

• 执行一条未定义的指令。

• T位已清为0,处理器不在Thumb状态时执行指令。

• 试图读取或保存数据到未对齐的地址。

注意:只有Reset和NMI能抢占具有固定优先级的HardFault异常。而HardFault异常则能抢占除Reset、NMI或另一个HardFault异常之外的所有异常。

1、锁定(Lock up)

以下这些情况处理器会进入锁定状态:执行NMI或HardFault异常处理时发生故障;或在使用MSP异常返回时,还没有从堆栈恢复PSR寄存器的值系统就产生总线错误。当处理器处于锁定状态时,不能执行任何指令。处理器将保持锁定状态直到以下情况之一发生:

• 处理器被复位;

• 调试器中止处理器运行;

• 发生NMI异常,并且当前锁定是处于HardFault异常处理中。

注意:如果锁定状态出现在NMI异常处理中,后续的NMI异常不能导致处理器离开锁定状态。

二、功耗管理

Cortex-M0处理器的睡眠模式可减少功耗,睡眠模式是在处理器实现时定义的,可以是以下的一种或两种:•停止处理器时钟的睡眠模式。

• 深度睡眠模式,停止系统时钟,并关掉PLL和flash存储器。

如果处理器实现了两种睡眠模式,则能提供不同级别的节能,SCR寄存器的SLEEPDEEP位用于选择睡眠模式,见下文的系统控制寄存器。关于深度睡眠模式的更多信息见处理器提供商所提供的资料。本节将描述进入睡眠模式的机制,以及从睡眠模式唤醒的条件。

1、进入睡眠模式

本节描述使处理器进入睡眠模式的软件机制。

系统可能产生伪唤醒事件,例如,一个调试操作可唤醒处理器。因此软件在此事件后,必须能重新让处理器进入睡眠模式。为了把处理器置回睡眠模式,程序可能需要一个空闲循环。

等待中断指令

等待中断指令WFI,能使处理器立即进入睡眠模式,当处理器执行一条WFI指令时,它停止执行指令,并进入睡眠模式,见第3-60页的WFI以获取更多的信息。

等待事件指令

等待事件指令,WFE,根据条件让处理器进入睡眠模式,条件是根据1位事件寄存器的值。当处理器执行一条WFE指令时,它检查事件寄存器的值:

0 处理器停止执行指令,进入睡眠模式。

1 处理器将寄存器该位的值置为0,并继续执行指令,不进入睡眠模式。

如果事件寄存器的值为1,表明处理器在执行WFE指令时不能进入睡眠模式。典型的情况:这是由于一个外部事件信号的要求,或在多处理器系统中的另一个处理器执行了一条SEV指令。软件不能直接访问这个寄存器。

异常退出时睡眠(sleep-on-exit)

如果SCR寄存器的SLEEPONEXIT位置为1,则当处理器完成执行一个异常处理并返回Thread模式时,处理器立即进入睡眠状态,这一机制用于仅仅需要处理器在中断发生时才运行的应用中。

2、从睡眠模式唤醒

唤醒处理器的条件依赖于导致处理器进入睡眠模式的机制。从WFI或sleep-on-exit产生的睡眠中唤醒正常情况下,处理器只在检测到具有足够优先级的异常,并进入异常时才会唤醒。

处理器唤醒后,在执行中断处理之前,某些嵌入式系统可能必须执行系统恢复任务。这通过置PRIMASK位为1来实现。如果一个有中断到达,该中断被允许,并比当前异常的优先级高,则处理器唤醒,但直到PRIMASK位置为0,处理器才执行中断处理。

从WFE产生的睡眠中唤醒

如果出现以下情况,处理器将被唤醒:

• 处理器检测到一个足够高优先级的异常而进入异常。

• 处理器检测到一个外部事件信。

• 在多处理器系统中的另一个处理器执行了一条SEV指令。

另外,如果SCR寄存器的SEVONPEND位置为1,任何一个新的挂起的中断都能触发一个事件并唤醒处理器,哪怕该中断是禁止的或没有足够的优先级而不能进入异常。关于SCR的更多信息见第4-16页的系统控制寄存器。

3、可选的唤醒中断控制器

处理器可能包含了一个唤醒中断控制器(WIC),WIC是一个可选的外设,能检测中断并将处理器从深度睡眠模式唤醒。仅当SCR寄存器的DEEPSLEEP位置1时,WIC才被允许。

WIC是不可编程的,也没有任何寄存器或用户接口,完全通过硬件信号工作。

当WIC被允许,处理器进入深度睡眠模式时,系统功耗管理单元能关闭Cortex-M0处理器大部分组成部分的功耗。但同时也有一个副作用,就是停止了系统滴答定时器。当WIC接收到一个中断时,它需要花费几个时钟周期唤醒处理器,并恢复处理器的状态,而后处理器才能处理中断。这意味着在深度睡眠模式下,中断延时增加了。

4、外部事件信号

处理器可能包含一个外部事件信号,处理器外设使用此信号与处理器联络,用于处理器从WFE状态唤醒;或将内部的WFE事件寄存器置为1,以表示处理器在执行下一个WFE指令后不能进入深度睡眠模式。

5、功耗管理编程

ISO/IEC语言没有直接产生WFI、WFE和SEV指令,CMSIS为这些指令提供以下内部函数:

void WFE(void)//WaitforEvent

void WFI(void)//WaitforInterrupt

void SEV(void)//SendEvent

围观 1093

本节主要介绍Cortex-M0的异常处理模型。

1、异常的状态

每个异常都处于以下状态之一:

未激活(Inactive)

异常没有被激活也没有被挂起。

挂起(Pending)

异常正等待被处理器服务。

来自外设或软件的中断请求,能让相应中断变为挂起状态。

激活(Active)

异常正在被处理器服务,并且服务尚未结束。

注意:一个异常处理能中断另一个异常处理,在这种情况下,两个异常都处于激活态。

激活且挂起(Active and pending)

异常正在被处理器服务时,又出现了来自同一异常源的异常。

2、异常类型

异常的类型有:

Reset

复位(Reset)由加电或热复位引起,异常模型把复位当作一个特殊形式的异常。当复位信号有效时,无论指令执行到什么位置,处理器都停止当前的指令。复位信号失效之后,从复位异常规定的入口地址处开始执行,按Thread模式工作。

NMI

不可屏蔽中断(NMI)可由外设引起或软件触发,NMI是除Reset之外,最高优先级的异常,NMI被永久允许,拥有固定的优先级-2。

NMI不能被:

• 任何别的异常屏蔽或阻止。

• 除复位之外的任何异常抢占。

HardFault

硬故障(HardFault)是指在正常情况或异常处理时出现错误(error)所引起的一种异常,硬故障有固定的优先级-1,表明硬故障比任何一个可以配置优先级的异常的优先级都高。

SVCall

超级管理员调用(SuperVisorCall,SVC)是一种由SVC指令触发的异常,在操作系统环境下,应用程序能使用SVC指令访问操作系统内核或设备驱动程序。

PendSV

PendSV是一种中断驱动的请求,用于面向系统级服务。在操作系统环境下,当没有别的异常激活时,使用PendSV进行上下文切换。

SysTick

如果处理器实现系统滴答定时器,那么SysTick是由系统滴答定时器计数到0时所产生的一种异常。软件也能产生SysTick异常,在操作系统环境下,处理器能使用这一异常作为系统滴答计时。

中断(IRQ)

中断(IRQ)是由外设或软件请求而产生的异常,所有的中断对指令的执行是异步进行的。在计算机系统中,外设通过中断与处理器通信。

表1、不同类型异常的优先级

a、为简化软件层,CMSIS仅使用IRQ号,因此采用负数作为异常的编号,IPSR返回异常编号,详见第2-7页的中断程序状态寄存器。

b、有关更多的信息,请看中断向量表。

c、如果处理器没有系统滴答定时器,则异常15保留。

d、IRQ中断号是在处理器实现时定义的,范围是1-32。未实现的IRQ异常编号被保留,例如,如果某处理器仅实现一个IRQ,则异常号17及以上的编号均被保留。

e、见下文的中断优先级寄存器。

f、增长步长为4。

对于异步异常,除Reset外,处理器在异常被触发到异常开始被处理的这段时间内,仍能继续执行指令。
特权软件可以禁止表1中所列出的具有可配置优先级的异常。

3、异常处理

处理器使用以下方式处理异常:

ISRs

中断服务子程序(ISRs)处理IRQ中断异常。

Fault handler

故障处理程序(Faulthandler)处理硬故障。

System handlers

系统处理程序(System handlers)处理系统异常:NMI,PendSV,SVCallSysTick和硬故障。

4、异常向量表

异常向量表包含堆栈指针的复位值,以及起始地址。堆栈指针的复位值和起始地址一起被称为异常向量,用于所有异常处理。图2列出了异常向量表中的异常向量的次序。每一个向量的最低位必须为1,表明异常处理是用Thumb代码实现的。

图2向量表

向量表起始地址固定于0x00000000。

5、异常优先级

如上文中的表1所示,所有的异常都有一个优先级。

• 优先级数值越小,优先级越高。

• 除Reset,HardFault和NMI之外,其余所有异常都能配置其优先级。

如果软件没有配置优先级,那么所有可配置优先级的异常的优先级为0。

注意:可配置优先级的数值范围是0-192,步长为64。Reset、HardFault和NMI是具有负数值的固定优先级异常,比其它异常具有更高的优先级。

给IRQ[0]分配一个较大的优先级数值,而给IRQ[1]分配一个较小的优先级数值,就意味着IRQ[1]比IRQ[0]的优先级高,如果IRQ[1]和IRQ[0]都被触发,则IRQ[1]比IRQ[0]先执行。

如果多个挂起的异常具有同等的优先级,那么具有较小异常号的异常优先执行。例如,如果IRQ[0]和IRQ[1]具有相同的优先级,且都挂起,则IRQ[0]比IRQ[1]优先执行。

当处理器在执行一个异常处理时,如果有更高优先级的异常发生,则该异常可以被抢占。如果发生的异常与正在执行的异常具有相同的优先级,则不管其异常号为多少,正在执行的异常都不会被抢占,而新发生的异常的状态变为挂起。

6、异常处理的进入与返回

描述异常处理的一些术语:

抢占(Preemption)

当处理器在执行一个异常处理时,另一个异常处理可以抢占这个正在被执行的异常处理,只要其优先级比正在被处理的异常优先级高。

一个异常处理抢占另一个异常处理,被称为异常嵌套。

返回(Return)

当没有以下情况时,异常处理结束之后就异常返回:

• 没有挂起的异常需要服务。

• 所完成的异常处理不是一个迟到异常。

处理器从堆栈弹出数据,现场恢复到中断发生之前的状态。

尾链(Tail-chaining)

该机制加速了异常服务。当一个异常处理刚好完成时,若此时有一个挂起的异常满足进入执行的条件,则从堆栈弹出数据的操作就跳过,直接转到这个新的异常处理。

迟到(Late-arriving)

该机制加速抢占。当一个异常处理正在保存状态时,如果出现了一个更高优先级的异常,则处理器切换去执行这个更高优先级的异常,为新异常初始化预取向量。迟到异常并不影响向量的保存,因为两个异常需要保存的状态是一致的。在迟到异常返回时,正常的尾链规则依然有效。

异常进入

有一个具有足够高优先级的挂起异常,以及以下条件之一,则可以进入异常:

• 处理器处于Thread模式。

• 新的异常比正在处理的异常具有更高的优先级。这种情况下,新异常抢占正在执行的异常。

当一个异常抢占另一个异常时,将出现异常嵌套。

足够高优先级的含义是,该异常比屏蔽寄存器的任一有限集的优先级都高,见第2-8页的异常屏蔽寄存器。而比有限集的优先级低的异常就挂起,不执行。当处理器处理一个异常时,除非该异常是一个尾链或迟到的异常,处理器把信息压入当前堆栈,这一操作称为入栈,而这个8字的数据结构被称为一个堆栈帧,堆栈帧包含如下的信息:

入栈后,堆栈指针指向帧的最低地址,堆栈帧是双字地址对齐的。

地址,该地址值保存在堆栈帧信息的PC中,因此被中断程序能恢复现场。处理器从向量表中读取异常处理程序的起始地址,当保护现场的入栈操作完成后,处理器开始执行异常处理程序。与此同时,处理器会将一个EXC_RETURN值写到LR寄存器,这能指明与堆栈信息帧相应的堆栈指针,以及进入异常之前处理器所处的操作模式。

如果在进入异常时没有发生更高优先级的异常,则处理器开始执行该异常处理,并自动把该异常的状态由挂起修改为激活。

如果在进入异常时发生了另一个更高优先级的异常,则处理器将执行高优先级的异常处理,先前的异常的挂起状态保持不变,这属于迟到异常的情况。

异常返回

当处理器处于Handler模式,且执行以下之一指令将PC的值置为EXC_RETURN的值,则发生异常返回:

• 执行POP指令,加载PC寄存器。

• 执行BX指令(任何寄存器均可)。

在异常进入时,处理器把EXC_RETURN的值保存到LR寄存器。处理器根据此数值来决定异常处理完成时的动作。EXC_RETURN值的[31:4]位是0xFFFFFFF,当处理器加载的值与之匹配时,处理器将检测到这不是一个正常的分支操作,而是异常结束。因此,处理器将开始异常返回操作。

EXC_RETURN值的[3:0]位指出所需的返回堆栈以及处理器模式,如表2所示。

表2、异常返回行为

围观 674

本文将描述Cortex-M0设备的内存映射和内存访问行为。该处理器有一个固定的存储映射,它可以提供高达4GB的可寻址内存。存储映射图如下:

该处理器为处理器核外设寄存器保留了PPB地址范围,关于Cortex-M0处理器以及核外设的内容见《Cortex-M0处理器及其特性》

1、存储区、类型和属性

存储映射被分成多个区,每个区都有其存储类型,有些区还有附加属性。存储类型及附加属性决定了如何访问该存储区。

储存类型是下列几种:

普通型(Normal)

为了提高效率、或执行预测读,处理器可以对该类型存储器的存取操作进行重排序。

设备型(Device)

该类型存储器与设备型或强顺序型存储器之间的存取操作,处理器将保持其顺序。

强顺序型(Strongly-ordered)

任何与该类型存储器相关的存取操作,处理器将保持其顺序。

对于设备型和强顺序型存储器的不同顺序要求,意味着存储系统可以将一个写操作缓存到一个设备型存储器中,但是不能缓存到一个强顺序型的存储器中。附加属性有:

可共享(ShaSharreableeable)

对于可共享的存储区,在多总线主设备系统中,存储系统可提供主设备之间的数据同步,例如某个带有DMA控制器的处理器。

强顺序型存储器都具有可共享属性。

如果多个总线主设备访问一个不可分享的存储区域,必须通过软件来保证多个总线主设备之间的数据一致性。

注意:仅当处理器在共享存储器的多处理器系统中时,该属性才有关系。

不可执行(XN)

处理器将阻止不可执行存储区指令的执行。如果从一个不可执行存储区取指令并执行,将会产生一个硬故障。

2、存储系统的访问顺序

对于多数显式的存取指令所产生的存储器访问,存储系统不能保证指令的顺序与实际操作的顺序是一致的,而且对指令的重排序并不会影响到指令序列的行为结果。通常,如果正确的程序执行要求两次内存访问必须按程序的顺序来完成,那么软件必须在内存访问指令之间插入一个存储隔离指令,相关内容见第2-16页存储访问的软件排序。

然而,存储系统能够保证访问设备和强顺序存储区的顺序。对于两个存储访问指令A1和A2,如果A1在A2程序之前发生,则存储访问顺序是:

其中:

- 表示存储系统不能保证访问的顺序。

< 表示按照程序的顺序访问,也就是说A1始终在A2前被执行。

3、存储访问行为

对内存映射中每个区的访问行为是:

表1、存储访问行为

a、关于存储区、类型和附加属性,可见上文。

其中Code、SRAM和externalRAM区可以存放程序。

关于Cache和可共享存储区的访问限制

当一个系统包含Cache或可共享存储区时,一些存储区有额外的访问限制,有些区被再次细分,如表2所示:

表2、存储区的可共享性和缓存策略


a、更多关于存储区、类型和属性的内容见上文。

b、WT=写通方式,没有写分配。WBWA=写回方式,写分配。更多内容见词汇表(Glossary)。

4、软件对存储访问排序

指令在程序中的顺序并不能始终够保证相应存储操作处理的顺序。这是由于:•处理器可对一些存储访问进行重排列,以提高效率,只要不影响指令顺序的行为。

• 内存映射中的存储器或设备可能有不同的等待状态。

• 有一些存储访问被缓冲或是预测执行的。

上文中存储系统内存访问顺序的内容描述了存储系统如何保证存储访问顺序的情况。此外,如果存储访问的顺序很重要,那么软件必须包括存储隔离指令来保证所希望的顺序。处理器提供以下存储隔离指令:

DMB

数据存储隔离指令,确保DMB之前所有显式存储访问完成之后,其后的存储访问才可以开始执行。DMB的内容见下文。

DSB

数据同步隔离指令,当DSB之前所有的显式存储访问完成之后,其后的指令才可以开始执行。见下文的DSB指令。

ISB

在ISB后续的指令被取之前,处理器的流水线必须被清空。见下文的ISB指令。

存储隔离指令的实例:

向量表

如果程序改变向量表中的一个入口地址,而后允许相应的异常发生,就需要在操作中使用一条DMB指令。这能确保能在异常被允许后就立即执行时,处理器将使用新的异常向量。

自修改代码

如果一个程序包含有自修改代码,那么在代码修改之后应使用一个ISB指令。这能确保接下来的指令使用更新后的程序。

内存映射切换

如果系统包含一个内存映射切换机制,那么在切换了内存映射之后应使用一个DSB指令。这保证接下来的指令使用更新过的内存映射。

访问强顺序存储区,例如系统控制时钟,就不需要使用DMB指令。

5、存储系统的端格式

处理器把存储系统当作一个从0开始向上增长编号的字节集合。例如0-3字节存放第一个字,4-7字节存放第二个字。内存字节顺序是在实现时定义的,下面小节的内容描述了可能的实现方案:

• 字节不变的大端格式,见下文。

• 字节不变的大端格式,见下文。

参见下文应用中断和复位控制寄存器(ApplicationInterruptandResetControlRegister)的内容,阅读AIRCRENDIANNESS位域的内容来找到所实现的端格式。

字节不变大端格式

在字节不变大端格式中,处理器在存储器的最低地址存储字的最高字节,而字的最低字节被存放在最高地址。例如:

小端格式

在小端格式中,处理器在存储器的最低地址存放字的最低字节,而字的最高字节被存放在最高地址。例如

围观 600

本节描述Cortex-M0编程模型。除了内核的各个寄存器之外,还包含处理器操作模式和堆栈的介绍。

1、处理器工作模式

处理器工作模式有:

Thrread模式

用于执行应用程序,在处理器复位时,进入Thread模式。

Handler模式

用于异常处理,处理器执行完所有异常程序后,返回到Thread模式。

2、堆栈

处理器使用满递减堆栈,也就是说栈顶指针指向最后入栈的数据。处理器的压栈操作为:栈顶指针自动递减,再存入新的数据。处理器的堆栈有主堆栈(mainstack)和进程堆栈(processstack),它们的栈顶指针相互独立,见下文介绍的堆栈指针SP。

在Thread模式中,由CONTROL寄存器来决定使用主堆栈还是进程堆栈。而在Handler模式通常使用主堆栈。处理器工作模式与栈选择之间的关系如下表1所示:

表1:处理器工作模式和堆栈选择之间的关系

3、内核寄存器组

处理器的内核寄存器如下:

表2、内核寄存器组总览

注:

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的位分布是:

通过MRS/MSR指令,可以单独访问这3个PSR,也可以组合访问(2或3个组合)。

例如:

• 在MRS指令使用PSR,读取全部寄存器的值。

• 在MSR指令使用APSR,将值写入APSR。PSR的组合及属性如下表3所示:

表3、PSR寄存器的组合

注:

a、处理器忽略对寄存器IPSR相应位的写操作。

b、读取EPSR相应的位,返回0,并忽略对其写操作。

应用程序状态寄存器

根据指令的执行情况,APSR保存条件标志的当前状态,参见上文中的表2、其位域分配如表4所示:

表4、APSR位域分配

中断程序状态寄存器

中断程序状态寄存器IPSR保存了当前ISR的异常号,参见上文中的表2,其位域分配如下表5所示:

表5、IPSR位域分配

a、如果处理器中没有SysTick定时器,系统异常号15保留

b、外部中断号n是在实现处理器时定义的,范围为1-32。

执行程序状态寄存器

EPSR包含Thumb状态位。

参见上文表2,其位域分配如下表6所列:

表6、EPSR位域分配

应用程序直接使用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,位域分配如下图所示:

表7、PRIMASK寄存器位域分配

控制寄存器(CONTROL)

控制寄存器CONTROL用于选择在Thread模式下当前使用哪个堆栈指针。该寄存器的描述见上文中的表2,其位域分配如下:

表8、CONTROL寄存器位域分配

在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定义的短名,少部分情况下有别于其它文档中用到的短名。

围观 437

本文将简要地介绍Cortex-M0处理器及其特性:

Cortex-M0处理器及其核外设

Cortex™-M0处理器是用于嵌入式应用设计的入门级ARM Cortex 32位的处理器。它为开发者提供以下好处:

• 简单易用的编程模型;

• 高效的低功耗操作模式;

• 高代码密度;

• 可确定的、高效的中断处理;

• 向上兼容Cortex-M 处理器系列其他处理器。

图1-1 Cortex-M0 处理器的实现

Cortex-M0处理器内置的高效处理器核,为3段流水线的冯诺依曼结构,适用于高要求的嵌入式应用。该处理器在低功耗和面积方面进行了高度优化,通过高效的指令集来实现超低功耗,该处理器还提供以下高端处理硬件:

• 单周期乘法器,以实现高性能的优化;

• 32周期乘法器,以实现面积的优化。

Cortex-M0处理器基于ARMv6-M架构,使用ARMv6-M Thumb® 指令集,包含Thumb-2技术。该处理器拥有32位处理器的高性能,又比8位、16位处理器有着更好的代码密度。

Cortex-M0内置一个紧密连接的可配置的内嵌向量中断控制器(Nested Vectored InterruptController,NVIC),提供工业领先的中断性能。该NVIC:

• 包含一个不可屏蔽中断(NMI)

• 提供:

— 零偏差的中断选项;

— 四个中断优先级。

NVIC与处理器核紧密连接,可实现中断服务程序(ISR)的高速执行,可大大降低中断延迟。其超低的中断延迟是通过硬件实现寄存器堆栈、寄存器批量存取操作的复位和放弃来实现的。中断处理程序不需要任何汇编封装代码,去掉了ISR的所有多余的代码开销。当从一个ISR切换到另外一个ISR时,尾链(Tailchaining)优化也大大减少了时间开销。

为了实现低功耗设计,NVIC还带有随眠模式。还可以选择随眠模式支持深度随眠模式,可让整个处理器快速掉电。

1、 系统级接口

Cortex-M0处理器采用单一的AMBA®技术系统级接口,实现高速低延迟的内存访问。

2、 可选的集成可配置调试方案

Cortex-M0可实现完整的硬件调试解决方案,可选择多个硬件断点和观测点。

JTAG或SWD接口是适用于微控制器和小封装处理器的理想调试端口,通过这两种接口可以为Cortex-M0处理器提供高的系统可视性。MCU提供商可以决定其处理器调试方案的具体实现。

3、 Cortex-M0处理器特性

• 32位性能、高代码密度;

• 工具及二进制代码向上兼容其他Cortex-M系列处理器;

• 集成了低功耗随眠模式;

• 快速代码执行允许慢的处理器时钟或增加随眠模式时间;

• 硬件乘法器;

• 零偏差中断处理;

• 强大的调试能力。

4、 Cortex-M0核外设

Cortex-M0 核外设有:

NVIC 内嵌中断控制器,支持低延迟中断处理。

SystemControl Block

系统控制块(SCB)是处理器的编程模型接口。它提供系统实现信息和系统控制,包括配置、控制和系统异常报告。

Optional systemtimer

可选的系统计时器SysTick, 是一个24位的向下计时器。若选用它,则可以作为实时操作系统(RTOS)的滴答计时器或一个简易计数器。

围观 562

最近在关注Cortex-M处理器,针对目前进入大众视野的M0、M3、M4做了如下简单对比,内容来自ARM等官网,这里仅仅是整理了下,看起来更直观点,

Cortex-M 系列针对成本和功耗敏感的 MCU 和终端应用(如智能测量、人机接口设备、汽车和工业控制系统、大型家用电器、消费性产品和医疗器械)的混合信号设备进行过优化。.

一、比较 Cortex-M 处理器

1

Cortex-M 系列处理器都是二进制向上兼容的,这使得软件重用以及从一个

2

Cortex-M 处理器无缝发展到另一个成为可能。

M Cortex-M 技术

3

CMSIS

ARM Cortex 微控制器软件接口标准 (CMSIS) 是 Cortex-M 处理器系列的与供应商无关的硬件抽象层。 使用 CMSIS,可以为接口外设、实时操作系统和中间件实现一致且简单的软件接口,从而简化软件的重用、缩短新微控制器开发人员的学习过程,并缩短新产品的上市时间。

深入:嵌套矢量中断控制器 (NVIC)

NVIC 是 Cortex-M 处理器不可或缺的部分,它为处理器提供了卓越的中断处理能力。 Cortex-M 处理器使用一个矢量表,其中包含要为特定中断处理程序执行的函数的地址。接受中断时,处理器会从该矢量表中提取地址。

为了减少门数并增强系统灵活性,Cortex-M 处理器使用一个基于堆栈的异常模型。出现异常时,系统会将关键通用寄存器推送到堆栈上。完成入栈和指令提取后,将执行中断服务例程或故障处理程序,然后自动还原寄存器以使中断的程序恢复正常执行。使用此方法,便无需编写汇编器包装器了(而这是对基于 C 语言的传统中断服务例程执行堆栈操作所必需的),从而使得应用程序的开发变得非常容易。NVIC 支持中断嵌套(入栈),从而允许通过运用较高的优先级来较早地为某个中断提供服务。

在硬件中完成对中断的响应

Cortex-M 系列处理器的中断响应是从发出中断信号到执行中断服务例程的周期数。它包括:

● 检测中断
● 背对背或迟到中断的最佳处理(参见下文)
● 提取矢量地址
● 将易损坏的寄存器入栈跳转到中断处理程序

4

5

这些任务在硬件中执行,并且包含在为 Cortex-M 处理器报出的中断响应周期时间中。在其他许多体系结构中,这些任务必须在软件的中断处理程序中执行,从而引起延迟并使得过程十分复杂。

NVIC 中的尾链

在背对背中断的情况下,传统系统会重复完整的状态保存和还原周期两次,从而导致更高的延迟。Cortex-M 处理器通过在 NVIC 硬件中实现尾链技术简化了活动中断和挂起的中断之间的转换。处理器状态会在比软件实现时间更少的周期内自动保存在中断条目上并在中断退出时还原,从而显著提升低 MHz 系统的性能。

NVIC 对迟到的较高优先级中断的响应

如果在为上一个中断执行堆栈推送期间较高优先级的中断迟到,NVIC 会立即提取新的矢量地址来为挂起的中断提供服务,如上所示。Cortex-M NVIC 对这些可能性提供具有确定性的响应并支持迟到和抢占。

NVIC 进行的堆栈弹出抢占

6

同样,如果异常到达,NVIC 将放弃堆栈弹出并立即为新的中断提供服务,如上所示。通过抢占并切换到第二个中断而不完成状态还原和保存,NVIC 以具有确定性的方式实现了缩短延迟。

二、为什么选择 1、为什么选择Cortex-M0

能耗最低的最小 ARM 处理器

Cortex-M0 的代码密度和能效优势意味着它是各种应用中 8/16 位设备的自然高性价比换代产品,同时保留与功能丰富的 Cortex-M3 处理器的工具和二进制向上兼容性。 超低的能耗
Cortex-M0 处理器在不到 12 K 门的面积内能耗仅有 85 µW/MHz(0.085 毫瓦),所凭借的是作为低能耗技术的领导者和创建超低能耗设备的主要推动者的无与伦比的 ARM 专门技术。

简单

指令只有 56 个,这样您便可以快速掌握整个 Cortex-M0 指令集(如果需要);但其 C 语言友好体系结构意味着这并不是必需的。可供选择的具有完全确定性的指令和中断计时使得计算响应时间十分容易。

优化的连接性

设计为支持低能耗连接,如 Bluetooth Low Energy (BLE)、IEEE 802.15 和 Z-wave,特别是在这样的模拟设备中:这些模拟设备正在增加其数字功能,以有效地预处理和传输数据。

2、为什么选择Cortex-M3

提供更高的性能和更丰富的功能

于 2004 年引进、最近通过新技术进行了更新并更新了可配置性的 Cortex-M3,是专门针对微控制器应用开发的主流 ARM 处理器。

性能和能效

具有高性能和低动态能耗,Cortex-M3 处理器提供领先的功效:在 90nmG 基础上为 12.5 DMIPS/mW。将集成的睡眠模式与可选的状态保留功能相结合,Cortex-M3 处理器确保对于同时需要低能耗和出色性能的应用不存在折衷。

全功能

该处理器执行 Thumb-2 指令集以获得最佳性能和代码大小,包括硬件除法、单周期乘法和位字段操作。Cortex-M3 NVIC 在设计时是高度可配置的,最多可提供 240 个具有单独优先级、动态重设优先级功能和集成系统时钟的系统中断。

丰富的连接

7

功能和性能的组合使基于 Cortex-M3 的设备可以有效处理多个 I/O 通道和协议标准,如 USB OTG (On-The-Go)。

3、为什么选择Cortex-M4 ®

目标用用:专门面向电动机控制、汽车、电源管理、嵌入式音频和工业自动化市场的新兴类别的灵活解决方案。

曾获大奖的高能效数字信号控制

Cortex-M4 提供了无可比拟的功能,以将 32 位控制与领先的数字信号处理技术集成来满足需要很高能效级别的市场。

易于使用的技术

Cortex-M4 通过一系列出色的软件工具和 Cortex 微控制器软件接口标准 (CMSIS) 使信号处理算法开发变得十分容易。

三、规范

1、M0

ARM Cortex-M0 处理器执行 Thumb 指令集,包括少量使用 Thumb-2 技术的 32 位指令。这是 ARM Cortex-M3 和 ARM Cortex-M4 支持的指令集的二进制向上可兼容子集。

2、

8

M3

9

内核面积、频率范围和功耗取决于工艺、库和优化。上面引用的数字是使用通用 TSMC 工艺技术和 ARM 物理 IP 标准单元库和 RAM 的合成核心的说明。面积数字包括
CM3Core、嵌套向量中断控制器 (NVIC) 和总线矩阵,但不包括可选组件(包括内存保护单元、嵌入式跟踪宏单元、断点单元、数据检测点单元和跟踪端口接口单元)。

速度优化的实现是指为了实现目标频率性能而做出的库选择、合成流决策和折衷。面积优化的实现是指为了实现目标面积密度而做出的库选择、合成流决策和折衷。

3、M4

10

11

12

内核面积、频率范围和功耗取决于工艺、库和优化。上面引用的数字是使用低功耗工艺技术和 ARM 物理 IP 标准单元库和 RAM 的合成内核的说明。面积数字包括中央内核(包括 DSP 扩展、嵌套矢量中断控制器 (NVIC) 和总线矩阵),但不包括可选组件

13

(包括内存保护单元、嵌入式跟踪宏单元、断点单元、数据检测点单元和 Trace Port Interface Unit。

速度优化的实现是指为了实现目标频率性能而做出的库选择、合成流决策和折衷。面积优化的实现是指为了实现目标面积密度而做出的库选择、合成流决策和折衷。

以下的一点为M4页面特有的介绍:

系统 IP

系统 IP 组件对于在芯片上构建复杂的系统至关重要,通过利用系统 IP 组件,开发人员可以显著缩短开发和验证周期,从而节省成本并缩短产品的上市时间。

14

来源:百度文库

围观 619

页面

订阅 RSS - Cortex-M0