void HardFault_Handler(void)
__disable_irq();
__set_MSP(__Vectors);
LEDS_SETUP();
register int count;
for (count = 0; count < 5; count++)
LedRunningOn();
Delay_ms(250);
LedRunningOff();
LedConnectedOn();
Delay_ms(250);
LedConnectedOff();
Delay_ms(1000);
NVIC_SystemReset();
ARM 一直支持两种形式相对独立的指令集
32位的ARM指令集。对应的处理状态:ARM状态。
16位的Thumb指令集。对应处理器状态:Thumb状态。
程序执行的过程中,处理器可以动态的在两个指令集之间切换。
AHB 先进高性能总线
AHB‐AP AHB访问端口
AMBA 先进单片机总线架构
APB 先进外设总线
ARM ARM ARM架构参考手册
ASIC 行业领域专用集成电路
ATB 先进跟踪总线
BE8 字节不变式大端模式
CPI 每条指令的周期数
CPU 中央处理单元
DAP 调试访问端口
DSP 数字信号处理器/数字信号处理
DWT 数据观察点及跟踪
ETM 嵌入式跟踪宏单元
FPB 闪存地址重载及断点
FSR Fault状态寄存器
HTM CoreSight AHB跟踪宏单元
ICE 在线仿真器
IDE 集成开发环境
IRQ 中断请求(通常是指外部中断的请求)
ISA 指令系统架构
ISR 中断服务例程
ITM 指令跟踪宏单元
JTAG 连结点测试行动组(一个关于测试和调试接口的标准)
JTAG‐DP JTAG调试端口
LR 连接寄存器
LSB 最低有效位
LSU 加载/存储单元
MCU 微控制器单元(俗称单片机)
MMU 存储器管理单元
MPU 存储器保护单元
MSB 最高有效位
MSP 主堆栈指针
NMI 不可屏蔽中断
NVIC 嵌套向量中断控制器
OS 操作系统
PC 程序计数器
PSP 进程堆栈指针
PPB 私有外设总线
1. R0-R12:通用寄存器
R0‐R12都是32位通用寄存器,用于数据操作。但是注意:绝大多数16位Thumb指令只能访问R0‐R7,而32位Thumb‐2指令可以访问所有寄存器。
Banked R13: 两个堆栈指针
Cortex‐M3拥有两个堆栈指针,然而它们是banked,因此任一时刻只能使用其中的一个。
主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)
进程堆栈指针(PSP):由用户的应用程序代码使用。
堆栈指针的最低两位永远是0,这意味着堆栈总是4字节对齐的。
在ARM编程领域中,凡是打断程序顺序执行的事件,都被称为异常(exception)。除了外部中断外,当有指令执行了“非法操作”,或者访问被禁的内存区间,因各种错误产生的fault,以及不可屏蔽中断发生时,都会打断程序的执行,这些情况统称为异常。在不严格的上下文中,异常与中断也可以混用。另外,程序代码也可以主动请求进入异常状态的(常用于系统调用)。
R14:连接寄存器
当呼叫一个子程序时,由R14存储返回地址 不像大多数其它处理器,ARM为了减少访问内存的次数(访问内存的操作往往要3个以上指令周期,带MMU和cache的就更加不确定了),把返回地址直接存储在寄存器中。这样足以使很多只有1级子程序调用的代码无需访问内存(堆栈内存),从而提高了子程序调用的效率。如果多于1级,则需要把前一级的R14值压到堆栈里。在ARM上编程时,应尽量只使用寄存器保存中间结果,迫不得以时才访问内存。
在RISC处理器中,为了强调访内操作越过了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。
R15:程序计数寄存器
指向当前的程序地址。如果修改它的值,就能改变程序的执行流(很多高级技巧就在这里面——译注)。
特殊功能寄存器
Cortex‐M3还在内核水平上搭载了若干特殊功能寄存器,包括
程序状态字寄存器组(PSRs)
中断屏蔽寄存器组(PRIMASK,FAULTMASK, BASEPRI)
控制寄存器(CONTROL)
来自于ARM Cortex-M3 权威指南
为了使代码更加的清爽,Cortex-M3在进入异常服务例程时,自动压栈了R0-R3、R12、LR、PSR和PC,并且返回时自动的弹出它们,即加速了中断的响应,也不在需要汇编语言代码了;
在内核水平上支持节能模式(SLEEPING和SLEEPDEEP位),通过使用等待中断指令(“WFI”)和等待事件指令(“WFE”),内核可以进入睡眠模式,并以不听的方式唤醒。
R15程序计数器,在汇编代码中一般都叫它的外号“PC”。因为CM3内部采用指令流水线,读取PC时返回的值是当前指令的地址+4。
如果向PC中写数据,就会引起一次程序的分支(但是不更新LR寄存器)。CM3中的指令至少是半字节对其的,所以PC得LSB总是读回0。然而在分支时无论是直接写PC值还是使用分支指令都必须保证加载到PC的值是奇数(LSB ==1),用以表明这是在Thumb状态下执行。倘若写成了0,则视为企图装入ARM状态模式,CM3将会产生一个fault异常。
在Thumb-2指令集中,有些操作既可以由16位指令完成,也可以由32位指令完成,如:R0 = R0 +1,在UAL下,汇编器能够决定使用哪个,也可以自己指定使用暗种 汇编指令;
使用.W和.N表示32位指令还是16位指令,如:
ADDS R0, #1; 汇编器为了节省空间使用16位指令
ADDS.N R0, #1; 指定使用16位指令(N == Narrow)
ADDS.W R0, #1; 指定使用32位指令(W == Wide)
ARM 指令集中的跳转指令可以完成从当前指令向前或向后的 32MB 的地址空间的跳转,包括以下 4 条指令:
(1) B 跳转指令
(2) BL 带返回的跳转指令
(3) BLX 带返回和状态切换的跳转指令
(4) BX 带状态切换的跳转指令
1、 B 指令
B 指令的格式为:
B{条件} 目标地址
B 指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继
续执行。注意存储在跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB 的地址空间)。以下指令:
B Label ;程序无条件跳转到标号 Label 处执行
CMP R1 ,# 0 ;当 CPSR 寄存器中的 Z 条件码置位时,程序跳转到标号 Label 处执行
BEQ Label
2、 BL 指令
BL 指令的格式为:
BL{条件} 目标地址
BL 是另一个跳转指令,但跳转之前,会在寄存器R14 中保存PC 的当前内容,因此,可以通过将R14 的内容重新加载到PC 中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。以下指令:
BL Label ;当程序无条件跳转到标号 Label 处执行时,同时将当前的 PC 值保存到 R14 中
3、 BLX 指令
BLX 指令的格式为:
BLX 目标地址
BLX 指令从ARM 指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM 状态切换到Thumb 状态,该指令同时将PC 的当前内容保存到寄存器R14 中。因此,当子程序使用Thumb 指令集,而调用者使用ARM 指令集时,可以通过BLX 指令实现子程序的调用和处理器工作状态的切换。
同时,子程序的返回可以通过将寄存器R14 值复制到PC 中来完成。
4、 BX 指令
BX 指令的格式为:
BX{条件} 目标地址
BX 指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM 指令,也可以是Thumb指令。
LDMIA指令 与之对应的指令是STMIA指令
LDM是多寄存器存取的意思,IA表示数据传输后地址增加(increase after);(IB:increase before, DA: decrease after, DB: decrease before)
后面参数以“,”分隔,第一个参数是首地址;第二个参数是寄存器列表,并以“{}”括起来。
具体的例子:
LDMIA R0!, {R1-R4}
R0表示要操作的存储空间首地址,要操作的数据个数由寄存器列表决定,现在是R1到R4,共4个数据(每个数据是32bits的)
具体:地址为R0的存储空间中的数据赋值给R1
地址为R0+4的存储空间中的数据赋值给R2
地址为R0+8的存储空间中的数据赋值给R3
地址为R0+12的存储空间中的数据赋值给R4
MRS,状态寄存器传送至通用寄存器类指令
功能:将状态寄存器的内容传送至通用寄存器。
MRS{<条件码>}Rd,CPSR}SPSR
Rd 目标寄存器,Rd不允许R15。
R=0 将CPSR中的内容传送目的寄存器。
R=1 将SPSR中的内容传送至目的寄存器。
MRS与MSR配合使用,作为更新PSR的读-修改-写序列的一部分。例如:改变处理器或清除标志Q。注意:当处理器在用户模式或系统模式下,一定不能试图访问SPSR
这条指令不影响条件码标志。
MRS R0,CRSR ;将CPSR中的内容传送至R0
MRS R3,SPSR ;将SPSR中的内容传送至R3
MSR,通用寄存器传送至状态寄存器传送指令
功能:将通用寄存器的内容传送至状态寄存器。
MSR{<条件码>CPSR_f|SPSR_f,<#immed_8r>
MSR{<条件码>CPSR_<field>|SPSR_<field>,Rm
<field>字段可以是以下之一或多种:(位从右到左)
C:控制域屏蔽字段(PSR中的第0位到第7位);
X:扩展域屏蔽字段(PSR中的第8位到第15位);
S:状态域屏蔽字段(PSR中的第16位到第32位);
F:标志域屏蔽字段(PSR中的第24位到第31位)。
immed_8r 值数字常量的表达式。常量必须对应8位位图。该位图在32位字中循环移位偶数数位。
Rm 源寄存器。
CM3中隔离指令的来历
举例来说,如果可以在运行时更改存储器的映射关系或者内存保护区的设置,(通过写 MPU 的寄存 器),就必须在更改之后立即补上一条 DSB 指令(数据同步指令)。因为对 MPU 的写操作很可能会被放 到一个写缓冲中。写缓冲是为了提高存储器的总体访问效率而设的,但它也有副作用,其中之一,就是 会导致写内存的指令被延迟几个周期执行,因此对存储器的设置不能即刻生效,这会导致紧临着的下一 条指令仍然使用旧的存储器设置——但程序员的本意显然是使用新的存储器设置。这种紊乱危象是后患 无穷的,常会破坏未知地址的数据,有时也会产生非法地址访问 fault。紊乱危象还有其它的表现形式, 后续章节会一一介绍。CM3 提供隔离指令族,就是要消灭这些紊乱危象(在有些讲解计算机体系体系结 构的书中,这类紊乱危象也被称为“存储器相关”——译注)
指令名
DMB
数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作
都执行完毕后,才提交(commit)在它后面的存储器访问操作。
数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作
都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)
指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执
行完毕之后,才执行它后面的指令。
ARM初探–aliasalias是为老函数,取一个新的名字! attribute关键字来描述函数,变量和数据类型的属性,用于编译器对源代码的优化#include &amp;amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;amp;gt; int __Hard_Fualt() { printf(&amp;amp;amp;amp;amp;amp;amp;quot;my
Cortex-M3只使用Thumb-2指令集。这是个了不起的突破,因为它允许32位指令和16位指令水乳交融,代码密度与处理性能两手抓,两手都硬。而且虽然它很强大,却依然易于使用。
在过去,做ARM开发必须处理好两个状态。这两个状态是井水不犯河水的,它们是:32位的ARM状态和16位的Thumb状态。当处理器在ARM状态下时,所有的指令均是32位的(哪怕只是个”NOP”指令),此时性能相当高。而在T...
ARM汇编(适用于ARM realview工具链 DS-5 Keil微控制器开发套件)指令格式如下:
label
mnemonic operand1,operand2, … ;注释
label(标号)表示地址位置,是可选的。有些指令的前面可能会有标号,这样就可以通过这个标号得到指令的地址。标号也可以用于表示数据地址。例如,可以在程序内的查找表处放一个标号。mnemonic为助记符,也就是指令的名称,其后跟着的是多个操作数。
对于在ARM汇编器中编写的数据处理指令,第一个操
1.大部分算术运算和逻辑运算指令都是单周期的,例如加法、减法、位级运算和移位
2.乘法指令根据操作数位数的不同,从2-5个周期都有可能。
3.无条件跳转语句和跳转语句成功跳转,需要重新填充流水线,因此至少需要3个周期
4.跳过条件不满足的指令只需要花1个周期
(以上周期应该是指各指令包含的机器周期数)
时钟周期: 振荡周期,即CPU主频。
机器周期:又称CPU周期,完...
转自:http://www.elecfans.com/emb/arm/2009071678028.html
ARM7具有3级流水线结构(取指、译码、执行),对大多数指令来说每条流水线的处理都是单周期的,不过某些情况下,取指和执行的周期数会延长,导致流水线进入stall状态,指令执行时间超过1个周期。
经过在LPC213x/214x(NXP ARM7TDMI-S)上的试验,得出各类指令的执行周期数如下:
1、大部分算术运算和逻辑运算指令都是单周期的(乘法例外)。
2、STR指令需要增加1个总线周期。如...
- `标号`:可选,**必须顶格**写,作用是让汇编器计算程序转移的地址(可以是C函数名)
- `cond`:可选,即指令执行条件,如果不写则使用默认条件`AL`(无条件执行)。
- `S`:可选,表示指令执行后,会修改PSR寄存器
- `操作码`:即**指令助记符**,前面**必须至少有一个空格**
- `操作数`:第1个操作数一般为本指令的执行结果存储处。形成操作数的有效地址的方法称为操作数的寻址
IPC ( Instruction Per Clock) 即CPU 每一时钟周期内所执行的指令多少
HPC ( High Performance Computing) 高性能计算机群
基本上一条指令一个周期。
访问内存的操作往往要 3个以上指令周期,带MMU和cache的就更加不确定了。
arm 每一条指令不仅执行时间固定,其指令长度也是固定的
周期:就是时间,完成一次任务的时间
指令周期 :CPU从内存取出一条指令并...
处理器使用的是ARMv6-M Thumb指令集,包括大量的32位的使用Thumb-2技术的指令。表7-22列出了Cortex-M0指令和它们的周期数。周期计数以零等待状态的系统为基准。
表7-22 Cortex-M0指令和它们的周期数