Cortex-M0

NASA成功发射SpaceX CRS-10货运飞船进行第十次国际空间站商业货运任务。SpaceX CRS-10搭载了一个电子辐射效应实验,关键是该实验由美国Vorago公司的ARM架构抗辐射MCU进行控制。2016年,NASA宣布将选择ARM Cortex-A53处理器构建下一代空间电子产品平台,计划于2020年发射。可见,ARM技术在航天工业中势头越来越猛。此次搭载实验是由美国空军实验室和NASA联合支持,标志着基于ARM的耐极端环境抗辐射微处理器首次部署于空间系统。

抗辐射存储器实验

空间环境下,存储器暴露于高能质子和辐射粒子的辐射环境下,当这些粒子轰击存储器或其他微电路时将导致存储器位信息错误,这将导致电子设备故障或危及任务。

为解决这一问题,研究人员设计了抗辐射电子存储器实验——RHEME(监测空间存储器),RHEME将持续一年监测空间粒子辐射对存储器的影响。该实验采用了VORAGO公司基于ARM Cortex-M0的抗辐射微控制器进行控制。该微控制器采用VORAGO HARDSIL®工艺制造,抗辐射且耐受极端温度环境。实验结果将有助于空间用存储器的错误检测、纠正和消除。该实验是挑战空间环境、实现下一代空间计算的重要一步。

ARM芯片空间发展前景

一直以来,空间电子系统基于FPGA高度定制,且不重复利用。但随着太空探测的不断发展和运载火箭再次利用成为可能,电子系统需要变的可扩展、经济、可靠。而标准化的ARM架构正好具有这种灵活性。

该实验将改变空间抗辐射系统的设计方法,加快芯片的设计,允许基于MCU的电子设备集成于飞行器中的关键控制和安全功能系统,且成本更低。

VORAGO公司市场主管表示:空间计算应用,尤其是小型卫星平台的设计人员越来越倾向于选择抗辐射微控制器。ARM技术具有低功耗的特点,能够适应广泛的生态系统,且尺寸很小,这对于太阳能供电、受尺寸严格限制的飞行器而言非常重要。该实验将为未来芯片的发展提供关键数据。

这些辐射效应也可能发生在近地飞行的设备。例如,已开发了许多ARM CPU用于“关键任务”的功能安全应用。在这些应用中,需要检测和消除辐射效应,保证设备可控,这对于保护人们和地球环境至关重要。

围观 608

前几天刚好同事问起在Cortex-M上延时不准的问题,在网上也没找到比较满意的答案,干脆自己对这个问题做一个总结。

根据我们的经验,最容易想到的大概通过计算指令周期来解决。该思路在Cortex上并不是很适用:一方面MCU从Flash取指是有延时的,另一方面Cortex的指令集不是固定周期的,特别从M3加入分支预测后,分支指令在Cortex-M不同型号上的结果都不相同。因此除了指令周期外,我们需要考虑的东西还有很多,才能得到正确的结果。

不带分支预测器的情况

仍然先从不带分支预测器的Cortex-M0开始,通过计算指令周期延时的实现代码如下:

void delay_us(us) {
delay_ntimes((us * sysclk - 8) / 4);
}
__asm void delay_ntimes(unsigned int n)
{
L1
SUBS R0, #1
BCS L1
BX LR
}

从这段代码可发现两个主要问题:

一、delay_us里的公式是怎么来的:

假如想延时us微秒,系统时钟为48MHz,即sysclk=48,那么周期数period_count满足以下公式:

period_count = us * sysclk;

然后再delay_ntimes这个函数,又能推出period_count还满足以下公式(见第二个问题的分析):

period_count = 8 + 4 n

于是:

n = (us sysclk - 8 ) / 4;

这就解决了第一个问题,需要注意的是:该公式忽略了跳转到delay_us和(us * sysclk -8 )/4的几个固定周期。

二、delay_ntimes的周期数怎么算:

它的周期数满足以下公式:

period_count = 8 + 4 * n;

这个要根据指令集的周期数来确定,请看下表:

先考虑n为0的情况,

SUBS为1周期+BCS为1周期+BX为3周期+外层调用delay_times(相当于BLX指令)的3周期=8周期。
当n不为0时,将再执行n次SUBS和BCS执行,SUBS仍为1周期,BCS有跳转3周期,所以是4n个周期,因此该函数的执行周期数为:

period_count=8+4n;

好了,在了解了原理之后,是时候到真正的板子上去测试了。

然而在MCU上的实测结果却不如预期,延时5MS,实测为7.5MS;延时10MS,实测15MS。为什么会出现这样的现象?

这个跟MCU的设计有关。一般代码都放在FLASH上,MCU中Cortex核要从FLASH上先取出指令,然后才能将指令放到指令流水线上执行。而上面的分析忽略了Cortex核从FLASH取出指令的时间,因此实测值与理论值分析不一致。

不同的MCU从FLASH读取指令的时间消耗各不相同,因此需要根据不同MCU去调整公式,这是一个比较繁琐的过程,比如这款MCU,将公式修改为(us * sysclk - 8) / 6就得到了正确结果。

另外一个做法是不修改公式,将延时代码放到RAM中,许多MCU从RAM取出指令没有等待周期。使用该方法再次测试,延时结果与理论计算一致。

但值得注意的是,不是所有MCU都满足RAM取值零等待周期的条件,因此一定要做测试。

读者若对MCU如何从FLASH读取指令感兴趣,参考资料[4]的分析是比较清楚的。

带分支预测器的情况

将上面的代码放到Cortex-M3和Cortex-M4的芯片上测试,测试结果是错误的,不论在FLASH还是在RAM中,这个是由于Cortex-M3,Cortex-M4上的指令流水线带有分支预测器引起的。

要了解分支预测器,就不得不提指令流水线。Cortex-M3是三级流水线:取指,解码,执行。但是没找到CORTEX方面较好的图,以下讨论就基于下图的4级流水线,该图多了一步:写回。这并不影响我们的讨论。

(该图引用自参考资料[1])

假设一条指令从执行开始到执行结束需要4个时钟周期,在没有流水线的情况下,需要等待第一条指令执行结束,才能取第二条指令,这时两条指令就用了8个周期,效率是很低的。

引入4级流水线将指令拆成4个步骤:取指、解码、执行、写回。当第一条指令处于解码时,同时对第二条指令取指;对第一条指令执行时,同时对第二条指令解码,对第三条指令取指;对第一条指令写回时,同时对第二条执行,第三条解码,第四条取指;如此这般。最终达到的效果就如上图所示,只有第一条指令需要4个周期,其他后续的指令都只需要1个周期,极大地提高了处理效率。

流水线的高效率是基于指令顺序执行的前提,在执行跳转指令时,流水线将被清空,又回到了上图中的第一步,跳转后的第一条指令要执行仍然需要4周期。因此如果程序频繁跳转,流水线的作用就大打折扣。

为了解决这个问题,就引入了分支预测器:它会提前检测到跳转指令,并根据预判结果取指。如果预判结果是不跳转,就按顺序取下一条指令;如果预判结果是跳转,就从跳转的目的地址取下一条指令。假如预测对了,那么流水线就不会被清空,仍然可以一条指令1个周期;如果预测错了,下一条指令仍然要4周期。从这里看出,分支预测器对于提高流水线效率是有帮助的。值得一提的是,预判对了能减少指令延迟,但是否是零延迟取决于MCU的设计;预判错了清空流水线也未必是唯一的做法,同样取决于MCU的设计。

回到Cortex-M3的延时问题,网络上找到的资料提到分支预测器将延迟减小到1个周期,没有找到更详细的说明。那么理论上计算公式就应该调整为(us * sysclk - 8) / 3,在两款Cortex-M3和两款Cortex-M4上测试,测试结果与理论值一致。

微秒级精确延时的其他方法

对于Cortex而微秒级延时最通用的方法,大概便是通过比较SysTick的SYST_CVR寄存器来做延时,理论误差在1us内(基于48MHz主频)。以下为实现代码:

/*
* 使用SysTick的CVR实现微秒级精确延时,一般SysTick周期设置为10MS,因此该方法适用于10MS以内的延时
*/
void delay_us(int us) {
unsigned t1, t2, count, delta, sysclk;
sysclk = 48;//假设为48MHz主频

t1 = SYST_CVR;
while (1) {
t2 = SYST_CVR;
delta = t2 if (delta >= us * sysclk)
break;
}
}

其他补充点

1、本文假设在延时过程中没有产生任何中断,如果有中断产生,将影响延时精确性。

2、这部分的内容属于计算机体系结构。

3、以上测试时间范围在[0,10MS),该范围之外未详细测试,建议采用其他方法。

4、覆盖测试的MCU:1款Cortex-M0,2款Cortex-M3,2款Cortex-M4。

5、在我测试的两款Cortex-M3 MCU上,将代码都放RAM上,测试结果比放在FLASH差,而在Cortex-M4 MCU上,测试结果都一样,目前没有找到合理的解释。

参考资料

1、浅谈分支预测、流水线与条件转移

2、Cortex-M0指令集

3、CPU性能衡量参数-主频,MIPS,CPI,时钟周期,机器周期,指令周期

4、Cortex-M3的周期判断的依据是什么

5、计算机体系结构——流水线中的相关——延迟分支方法

文章来源:博客园

(直接点击图片可进入调查页面)

开发板测评图片
围观 428

作者:Founder_U

1. Cortex-M0 的两种总线协议:

1)AHB_Lite 系统总线协议:32位地址线,高速高性能访问(Flash, SRAM,总线桥,外部存储器接口)

2)APB 外设总线协议: 32位, 外设等较慢设备通讯(I/O,Timer, UART, Watch Dog。)

系统总线和外设总线是相互分离的,两种总线通过总线桥连接通讯,时钟频率控制不同,可能有多个外设总线段,并且每个段运行在不同的时钟频率下。有些高速外设是直接连接在AHB_Lite系统总线上的。

2. 存储器映射(4GB地址空间)

Cortex-M0(+)处理器的4G存储空间从架构上被分为多个区域。总的被分成8个大部分,每个部分512M。

Cortex-M0处理器架构定义的存储器映射

虽然映射已经被架构预先定义,但是实际分配却是很灵活的。

存储器设计的一个例子:

3. 程序存储器(Flash),Bootloader和存储器重映射

1)程序存储器一般使用片上Flash,不过也可以使用外部或其他类型存储器设备(EEPROM)

2)Flash存储器一般是从地址0开始,当Reset 后,会首先访问0地址的向量表,取得MSP的初始值和复位向量。

3)Bootloader 是位于芯片上的一小段加载引导程序,与用户应用程序是分开的。

4)存储器重映射:系统总线的一种存储器映射切换特性。Bootloader执行时会设置硬件寄存器来控制重映射。常见的处理方式是通过地址别名被重映射到地址的开头。

5)Bootloader其他特性:硬件初始化(时钟,PLL设置),多种启动配置,固件保护,Flash擦除工具。

6)SRAM重映射到地址0,code可以被复制到SRAM并以最快速度执行,可以避免取向量的等待时间。

4. 数据存储器(SRAM)

1) Cortex-M0数据存储:数据(全局变量、静态变量、数据结构)、栈存储(临时数据、局部变量、函数调用参数传递和异常处理的寄存器备份)和堆存储(C函数自动分配存储区域:alloc()、malloc()) 。

2)没有OS,就之后使用一个栈(MSP),数据存储分配如下:

SRAM常见数据存储使用示例

5. 支持小端和大端

1)Cortex-M0支持大端和小端两种存储,都支持字节(8bit)、半字(16bit)和字(32bit)传输, 存储器会根据传输大小和地址的最低两位选择数据链路。

2)大端模式:字节不变模式(BE8)和字不变模式(BE32), 字数据最低字节会保存在24到31位;

3)小端模式:字数据最低字节会保存在0到7位;

4) 多数情况下,连接到APB的外设应该用字传输,因为APB协议没有定义传输宽度信号,都被默认为字大小,因此,通过APB访问的外设寄存器通常被声明为”volatile unsigned integer“。

5)Thumb指令只能产生对齐访问(字对齐,半字对齐,字节对齐),传输地址只能是传输大小的整数倍。

6) C程序直接操作一个指针或用汇编,可进行非对齐传输。

6. 存储器属性

存储器访问属性:可执行(Executable),可缓冲(Bufferable),可缓存(Cacheable),可共享(Shareable)。

文章来源:极客头条

围观 450

作者: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 *(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" 来访问;

文章来源:极客头条

围观 583

作者: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

执行异常处理:

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

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

异常退出:

1) 寄存器出栈;

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

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

1)单异常

2)末尾连锁

3)延迟到达

文章来源:极客头条

围观 603

一、故障处理

故障是异常的一个子集,见第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

围观 554

本节主要介绍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、异常返回行为

围观 334

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

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

1、存储区、类型和属性

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

储存类型是下列几种:

普通型(Normal)

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

设备型(Device)

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

强顺序型(Strongly-ordered)

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

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

可共享(ShaSharreableeable)

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

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

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

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

不可执行(XN)

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

2、存储系统的访问顺序

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

然而,存储系统能够保证访问设备和强顺序存储区的顺序。对于两个存储访问指令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位域的内容来找到所实现的端格式。

字节不变大端格式

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

小端格式

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

围观 537

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

围观 346

本文将简要地介绍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)的滴答计时器或一个简易计数器。

围观 447

页面

订阅 RSS - Cortex-M0