|
我试图将示例1改成在定时中断中实现LED的闪烁,可当我认为一切都完成的时候LED并没有按我的预想闪烁,是我中断处理代码有问题还是
定时器的设置有问题?由于定时器的配置拷贝自曾经成功运行过的项目中,所以我首先要解决的是在RealView中配置中断,我想这要从启动代
码开始,在研究RealView提供的启动代码的时候还是需要从网上找一些关于ARM7内核的相关文章,为了方便以后温习,我把这些相关内容整理
在一起。
一.
ARM7工作模式
实际上其它的ARM(如Cotex-M3)也可能与ARM7相同,有这些工作模式,但由于笔者还不了解其它型号的ARM内核这里只限定为ARM7.ARM7有7个
工作模式,分别如下:
1.用户模式(usr):正常运行的用户程序运行在此模式。
2.快速中断模式(fiq):快速中断程序运行在此模式。
3.外部中断模式(irq):通用中断程序运行在此模式。
4.管理模式(svc)
:复位或软件中断时进入,启动代码等运行于此模式。
5.数据访问终止模式(abt):当数据指令预取终止时进入此模式,可用于虚拟存储及存储保护等应用中。
6.系统模式(sys):在有操作系统的应用中用来运行操作系统的一些特权任务。
7.未定义指令中止模式(und):当未定义的指令执行时进入,可用于支持硬件协处理器的软件仿真。
注:用户模式以外的6个模式被称为特权模式,用户模式和系统模式以外的5种模式又被称为异常模式(Exception
Modes)。
ARM7在异常模式下的某些寄存器是相互独立的,如栈指针,各模式均有自己独立的栈指针。
| Sys&User |
Abt |
Und |
Svc |
IRQ |
FIQ |
APCS |
| R0 |
a1 |
| R1 |
a2 |
| R2 |
a3 |
| R3 |
a4 |
| R4 |
v1 |
| R5 |
v2 |
| R6 |
v3 |
| R7 |
v4 |
| R8 |
R8_fiq |
v5 |
| R9 |
R9_fiq |
v6 |
| R10 |
R10_fiq |
sl |
| R11 |
R11_fiq |
fp |
| R12 |
R12_fiq |
ip |
| R13 |
R13_abt |
R13_und |
R13_svc |
R13_irq |
R13_fiq |
sp |
| R14 |
R14_abt |
R14_und |
R14_svc |
R14_irq |
R14_fiq |
lr |
| R15/PC |
pc |
|
CPSR |
- |
|
- |
SPSR_abt |
SPSR_und |
SPSR_svc |
SPSR_irq |
SPSR_fiq |
- |
二.
CPSR寄存器
处理器的工作模式存储在CPSR(程序状态寄存器)低5位中,CPSR的各位及作用如下:
| 31 |
30 |
29 |
28 |
27~8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
| N |
Z |
C |
V |
保留 |
I |
F |
T |
M4 |
M3 |
M2 |
M1 |
M0 |
1.控制位
CPSR的低8位(包括I、F、T和M[4:0])称为控制位,当发生异常时这些位可以被改变。如果处理器运行于特权模式时,这些位也可以由
程序修改。
中断禁止位I、F:置1时,禁止IRQ中断和FIQ中断。
T标志位:该位反映处理器的运行状态。当该位为1时,程序运行于THUMB状态,否则运行于ARM状态。该信号反映在外部引脚TBIT上。
在程序中不得修改CPSR中的TBIT位,否则处理器工作状态不能确定。
运行模式位M[4:0]:这几位是模式位,这些位决定了处理器的运行模式。
2.标志位
N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。这与普通处理器的状态
寄存器的功能类似,这里不作祥述。
3.SPSR寄存器
处理器每一种异常模式下都有一个专用的物理状态寄存器,称为SPSR(备份程序状态寄存器)。当特定的异常中断发生时,这个寄存器用于存
放当前程序状态寄存器的内容。在异常中断程序退出时,可以用SPSR中保存的值来恢复CPSR。
三.MSR
指令
上面提到处理器的工作模式要么发生异常时自动被改变,要么在特权模式下由程序改变,那么在程序改变模式时用什么指令呢?下面是程序
状态寄存器传送指令MSR的介绍:
MSR 指令的格式:
MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数
MSR
指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态
寄存器中需要操作的位,32 位的程序状态寄存器可分为4个域:
位[31:24]为条件标志位域,用f 表示;
位[23:16]为状态位域,用s 表示;
位[15:8]为扩展位域,用x 表示;
位[7:0]为控制位域,用c 表示;
该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR 指令中指明将要操作的域。
指令示例:
MSR CPSR,R0 ;传送R0 的内容到CPSR
MSR SPSR,R0 ;传送R0 的内容到SPSR
MSR CPSR_c,R0 ;传送R0 的内容到SPSR,但仅仅修改CPSR 中的控制位域
有了以上的了解我们再来看一下RealView MDK-ARM 4.11内包含默认启动代码中的改变工作模式的代码段:
; Setup Stack for each mode 设置各模式下的栈指针
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode
and set its Stack Pointer 进入未定义指令模式并设置栈指针
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack
Pointer进入ABT式并设置栈指针
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack
Pointer进入FIQ模式并设置栈指针
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack
Pointer进入IRQ模式并设置栈指针
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its
Stack Pointer进入管理模式并设置栈指针
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode 进入用户模式
MSR CPSR_c, #Mode_USR
四.寄存器
ARM7有16个32位的寄存器(r0到r15)。r15充当程序寄存器PC,r14(link
register)存储子程序的返回地址,r13存储的是栈地址。
一些寄存器在异常发生时会产生新的instances,如r13,r14在进入IRQ处理器模式时变成r13_irq和r14_irq。
1.ARM7处理器共有37个寄存器,其中包括:
i. 31个通用寄存器,包括程序计数器(PC)在内。都是32位寄存器
ii. 6个状态寄存器,都是32位寄存器
2.通用寄存器可以分为3类:未备份寄存器(R0~R7)、备份寄存器(R8~R14)和程序计数器PC(R15)。对于每一个未备份寄存器来说,
在所有的处理器模式下指的都是同一个物理寄存器。对应备份寄存器R8~R12来说,每个寄存器对应两个不同的物理寄存器,这使得中断
处理非常简单。例如,仅仅使用R8~R14寄存器时,FIQ处理程序可以不必执行保存和恢复中断现场的指令,从而使中断处理过程非常迅速。
对于备份寄存器R13和R14来说,每个寄存器对应6个不同的物理寄存器,其中的一个是用户模式和系统模式共用的,另外的5个对应于其他
5种处理器模式。
3.每一种异常模式拥有自己的物理的R13。应用程序初始化该R13,使其指向该异常模式专用的栈地址。当进入异常模式时,可以将需要使
用的寄存器保存在R13所指的栈中;当退出异常处理程序时,将保存在R13所指的栈中的寄存器值弹出。这样就使异常处理程序不会破坏被
其中断程序的运行现场。
4.寄存器R14又被称为连接寄存器(Link Register,LR),在ARM体系中具有下面两种特殊的作用:
i.
每一种处理器模式自己的物理R14中存放当前子程序的返回地址。当通过BL或BLX指令调用子程序时,R14被设置成该子程序的返回
地址。在子程序中,当把R14的值复制到程序计数器PC中时,子程序即返回。
ii.
当异常中断发生时,该异常模式特定的物理R14被设置成该异常模式将要返回的地址,对于有些异常模式,R14的值可能与将返回
的地址有一个常数的偏移量。具体的返回方式与子程序返回方式基本相同。
芯艺设计室(http://www.chipart.cn) 2010.08.18 转载请注明出处!
|