最近学了一系列的中断程序,就复习下顺便撸一篇文来分享下学习。以外部中断为例(之前单片机用的最多的)
1. ARM 工作模式
ARM体系结构(除了Cortex之外支持7种工作模式),取决于程序状态寄存器中低5位的值(在第二部分会详细讲到)
• User (usr): The normal ARM program execution state
(用户模式:ARM程序的正常执行状态)
• FIQ (fiq): Designed to support a data transfer or channel process
(快速中断模式:处理高速中断用于高速数据传输或通道传输)
• IRQ (irq): Used for general-purpose interrupt handling
(外部中断模式:用于普通的中断处理)
• Supervisor (svc): Protected mode for the operating system
(管理模式:操作系统的保护模式,处理软中断SWI)
• Abort mode (abt): Entered after a data or instruction prefetch abort
(中止模式:处理存储器故障,实现虚拟存储器与存储器保护)
• System (sys): A privileged user mode for the operating system
(系统模式:运行特权级的操作系统任务)
• Undefined (und): Entered when an undefined instruction is executed
(未定义指令模式:处理未定义的指令,在执行未定义的指令时输入)
2. ARM处理器的寄存器组织
ARM处理器共有37个寄存器,包括31个通用寄存器(包括PC)和六个状态寄存器。如下图所示:
其中黑色带角标的我们可以这么理解:
由于任何工作状态出现异常,跳到其他的模式。以中断为例,需要保护现场,即将把r0 - r14全部保护起来,所以为了减少保护的寄存器,通过硬件操作在中断发生的时候把黑色角标对应的值传入,等待模式变回去的时候再提取表出来,达到恢复现场的功能。
所以对于快中断模式来说有很多的banked register,这是为了达到它的快速性,不用那么多数据搬来搬去。
对于程序状态寄存器(CPSR)也同理,在出现不用的模式切换的时候需要把CPSR值传入SPSR进行现场保护。
Program Status Register Format (PSR):
• N(符号标志):N = 1表示运算结果为负数,N = 0表示运算结果为正数
• Z(全0标志):运算结果为0时 Z = 1
• C(进借位标志):加法进位:C = 1; 减法借位: C = 1
• V(溢出标志):加减法运算结果有溢出时V = 1
• I(中断禁止控制位):I = 1表示禁止外部IRQ中断,I = 0表示允许外部IRQ中断
• F(快速中断禁止控制位):F = 1表示禁止FIQ中断,F = 0表示允许FIQ中断
• T(ARM与Thumb指令集之间的切换):T = 1表示执行Thumb指令,T = 0表示执行ARM指令
• M0-M4(模式选择位):其模式选择如下表所示:
PSR中的其余位是保留的。在更改PSR的标志或控制位时,必须确保这些未使用的位没有被更改。另外,程序不应该依赖于包含特定值的它们,因为在将来的处理器中,它们可能读取为1或0。(不管就行)
3. ARM处理器的异常及其相应过程
当程序的正常流必须暂时停止时,就会出现异常,例如为了从外设提供中断服务。在处理异常之前,必须保留当前处理器的状态,以便在处理程序例程完成后恢复原始程序。
有可能同时出现几个例外情况。如果发生这种情况,它们将按照固定的顺序被处理,在第四部分中通过优先级寄存器进行处理。
I. 初始化异常
主要是对与异常有关的寄存器进行操作。不同的异常配置不同的寄存器。
II. 进入异常的操作(硬件自动操作)
STEP1: 将下一条指令的地址保存在相应的链接寄存器中。
如果从ARM状态输入了异常,那么下一条指令的PC地址将被复制到Link Register(lr寄存器)(R14)。偏移量取决于中断的类型。
这样程序在从异常返回时从正确的位置恢复。这意味着异常处理程序不需要确定异常的状态。
STEP2: 将CPSR复制到对应的SPSR
STEP3: 将CPSR MODE位设置为对应异常的值
STEP4: PC值调至对应异常的程序位置执行(异常向量表 Exception Vectors )
所以按照这个表在程序的开头应该包含(以U-boot的start.S为例):
.globl _start
_start: b reset // 0x00
ldr pc, _undefined_instruction // 0x04
ldr pc, _software_interrupt // 0x08
ldr pc, _prefetch_abort // 0x0c
ldr pc, _data_abort // 0x10
ldr pc, _not_used // 0x14
ldr pc, _irq // 0x18
ldr pc, _fiq // 0x1c
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
III. 进入中断
* 在中断向量表中可以发现,Reset中使用的是b进行跳转,但是其他模式的跳转指令使用ldr,并且通过配合.word进行配合来做到PC跳转作用。其中差别在于b跳转是一个绝对跳转,在代码重定位之后,应该执行SDRAM中的程序而不是NOR FLASH中的。所以利用链接地址的办法,读SDRAM中执行中断函数的地址进行跳转,从而实现执行中断函数。
在中断函数中应该不用多说,就是那三步 :
保存现场
执行异常
恢复现场
IV. 跳出异常的操作
STEP1: 将LR中的值移动到PC。(下一条指令)
STEP2: 将SPSR复制回CPSR。
STEP3: 清除中断标志位。
4. ARM外部中断程序编写过程
I. 初始化外部中断
第一部分:中断初始化
首先先看中断源是如何进入CPU进行工作的,以芯片手册中中断流程图图为例进行讲解
Setp 1: 打开CPSR中 中断总开关
mrs r0, cpsr
bic r0, r0, #0xf //将模式设置为user模式
bic r0, r0, (1<<7) //外部中断IRQ打开
msr cpsr, r0 //user模式
ldr sp, =0x33f00000 //设置user的栈(没啥用只是和以后的中断地址做比较)
Step 2:SOURCE PENDING (SRCPND)REGISTER
用途:在中断完成之后将其对应为设置为1,进入中断再请求
这里将的是外部中断,所以并没有SUB-SOURCE,所以Sources直接从输入到寄存器SRCPND,他的作用为:指示中断请求状态,所以应该设置相应的位为“1”进入请求状态。
Step 3: INTERRUPT MODE (INTMOD) REGISTER
用途:将中断设置为快速中断模式
这个寄存器由32位组成,每个位与一个中断源相关。如果一个特定的位设置为1,则在FIQ(快速中断)模式下处理相应的中断。否则,它被处理在IRQ模式(正常中断)。由于我们很少使用到快中断模式,所以按照初始值设置为0x0000000就OK。
Step 4: INTERRUPT MASK (INTMSK) REGISTER
用途:屏蔽/打开中断请求
这个寄存器也有32位,每个位与一个中断源相关。如果一个特定的位被设置为1,CPU就不会为来自相应中断源的中断请求提供服务(注意,在该寄存器置1时,SRCPND寄存器的相应位也被设置为1),如果掩码位为0,则中断请求可以被服务。所以SRCPND不用进行初始化。
综上所述。在中断初始化函数中需要以下代码:
void init_EINT(void)
{
INTMSK &= ~((1<<0) | (1<<2) | (1<<5));
// 按键对应的中断: 中断 0 2 11 19 ->对应的位为:0 2 5
}
第二部分:外部中断IO口初始化(简化)
Step 1: LED初始化
由于led的程序之前写过,所以对于LED的初始化不做赘述。
Step2 : 按键初始化
寄存器1:GPxCON --------------------设置为中断模式
寄存器2:EXTINTx---------------------设置为双边触发
寄存器3:EINTMASK -----------------设置对应中断使能
void init_key(void)
{
GPFCON &= ~((3<<0) | (3<<4));
GPFCON |= ((2<<0) | (2<<4));
GPGCON &= ~((3<<6) | (3<<22));
GPGCON |= ((2<<6) | (2<<22));
EXTINT0 |= (7<<0) | (7<<8);
EXTINT1 |= (7<<12);
EXTINT2 |= (7<<12);
EINTMASK &= ~((1<<11) | (1<<19));
}
II. 进入中断
按照中断向量表我们编写中断函数irq:
do_irq:
/* 执行到这里之前:
* 1. lr_und保存有被中断模式中的下一条即将执行的指令的地址
* 2. SPSR_irq保存有被中断模式的CPSR
* 3. CPSR中的M4-M0被设置为10010, 进入到irq模式
* 4. 跳到0x18的地方执行程序
*/
// 1.保护现场
ldr sp, =0x33d00000
/* 在irq异常处理函数中有可能会修改r0-r12, 所以先保存 */
/* lr-4 是异常处理完后的返回地址, 也要保存 */
sub lr, lr, #4
stmdb sp!, {r0-r12, lr}
// 2.处理中断函数
bl Find_interrupt_source
/* 3.恢复现场 */
ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */
中断函数编写要点:
通过INTOFFSET、INTPEND和EINTPEND寄存器读出中断源
在中断发生完之后,要进行清中断(至顶向下清)
INTOFFSET和INTPEND是一样的,但是只能访问到一条线上的中断源(比如说EINT4-7 EINT8-23),这样在EINTPEND能够判断在具体是哪个中断。
故外部中断函数模板为:
void hand_irq_fun(void)
{
int bit = INTOFFSET;
if(bit == * || bit == *) // 目标中断位 (可不写)
irq_fun(bit);
SRCPND = (1< void irq_fun(int bit) { unsigned int val = EINTPEND; ....... }
上一篇:11.S3C2440 中断实验(一)und和swi实验
下一篇:一起学mini2440裸机开发(二)--MDK自带的S3C2440.s分析
推荐阅读最新更新时间:2024-11-11 10:26
推荐帖子
- 温度监测报警器电路
- 本帖最后由jameswangsynnex于2015-3-319:57编辑本例介绍的温度监测报警器,具有“高”、“中”、“低”3档温度指示,能在温度偏高或偏低时发出报警信号,可用于大棚、温室等需要温度监控的场合。该温度监测报警器电路由温度检N/指示电路和声音报警电路组成,如图所示。 元器件选择R1~R4选用1/4W金属膜电阻器或碳膜电阻器。RP选用合成膜电阻器或可变电阻器。RT选用负温度系数热敏电阻器。VD1~VD3均选用IN4148型硅开关二极管。VL1
- 探路者 移动便携
- 有关台达伺服接送脉冲频率的问题,请高手指点???
- 我在使用台达伺服的时候遇到一个问题:我的脉冲输出频率大约为0.45M的时候,也就是450K的时候,我的机械会产生顿挫。我的怀疑是台达伺服的脉冲接收频率不高导致。请高手指点一下:台达伺服的最高接收脉冲频率是多少?松下的是500K。有关台达伺服接送脉冲频率的问题,请高手指点???
- eeleader-mcu 工控电子
- 用5509a做电话测试。振铃,忙音
- 新手最近在用dsp5509a的板子做两电话通信实验,一直不明白,那个dtmf到底用程序怎么实现拨号,呼叫,振铃。。。用5509a做电话测试。振铃,忙音
- zilongang DSP 与 ARM 处理器
- AD奇怪的线。怎么都删除不了,求教
- 请问一下各位,途中的那条细线怎么删除,这个是运行了规则检查后就出现的,怎么都删除不掉呢?AD奇怪的线。怎么都删除不了,求教线没有连接完或者在白线处有残余线点,,,放大检查在报告--板子信息--报告--最后一个RoutingInformation报告看到Routingcompletion是否为100%边线有的是PCB库中不小心画上的,需要先找到是在哪个元件中,然后在元件的属性中,将LockPrimitives的勾去掉,就可以删除了。
- zqdl8 PCB设计
- 关于PLL配置寄存器的两个问题
- 华大单片机PLL控制寄存器(PLL_CR),如下图所示,请教两个问题1、(1)处已经指定的输入时钟,那PLL的时钟频率就已经由XTH或RCH输入的时钟决定了,为什么(2)处还要进行选择2、(4)处已经决定了PLL的输出时钟,为什么(3)处还要选择关于PLL配置寄存器的两个问题本振由晶体/RC/外部时钟频率决定,PLL输入配置须与之相适应,然后根据需要选择其它输出频率,自然需要对PLL的倍频数和输出范围进行配置了。想理
- 深圳小花 单片机
- 【2024 DigiKey 创意大赛】二月柳絮大作战项目-08项目演示效果
- 系统组成:花粉检测:PM2.5烟雾检测:因为项目出点问题,耽搁几天,虽然效果和预期有点差异,但基本功能都已经实现【2024DigiKey创意大赛】二月柳絮大作战项目-08项目演示效果
- Maker_kun DigiKey得捷技术专区
设计资源 培训 开发板 精华推荐
- NFC_校园卡_齐鲁师范学院_物电学院
- LTC3126HFE 汽车和光伏供电 5V USB 电源的典型应用电路
- ADAU1592 D类音频功率放大器的典型单声道应用电路
- LTC3615HUF-1 双路 3A 同步降压型 DC/DC 转换器用于 DDR 存储器终端的典型应用
- FAN251030GEVB:FAN251030GEVB,带 PMBUS 的 35A 同步降压稳压器
- LT6656BIS6-5、5V 低功率 ADC 电压基准的典型应用
- TND330/D、16W、12V 交流转直流单路输出电源参考设计
- 【征集令】智慧加湿器
- 使用 ROHM Semiconductor 的 BD46442 的参考设计
- EFM32GG-STK3700、EFM32 Giant Gecko MCU 入门套件