最近学了一系列的中断程序,就复习下顺便撸一篇文来分享下学习。以外部中断为例(之前单片机用的最多的)
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分析
推荐阅读
史海拾趣
随着技术的不断进步,伊士曼柯达公司不断推出新的产品和服务,以满足市场的多样化需求。在20世纪初,柯达已成为全球最大的胶卷供应商,并占据了美国摄影市场的绝大部分份额。此外,公司还积极向国际市场扩张,通过设立分支机构和办事处,将产品销往全球各地。这一时期,柯达不仅凭借其优质的产品赢得了广泛的客户基础,还树立了良好的品牌形象。
随着业务的不断扩展,Antex在1980年决定将工厂从东京都大田区羽田迁至茨城县高萩市。这一搬迁不仅为公司提供了更广阔的发展空间,也标志着Antex开始向着全球化布局迈进。此后,公司积极寻求国际合作,与全球各地的供应商和客户建立了紧密的合作关系。
近年来,创客文化在全球范围内兴起,Global Specialties迅速抓住了这一趋势。公司推出了一系列创客/DIY产品,包括各种模块化的电子元件和工具,旨在帮助创客们实现他们的创意和想法。通过举办线上线下的创客活动,Global Specialties不仅促进了创客之间的交流与合作,还进一步扩大了自己的品牌影响力。
为了进一步扩大市场份额,Global Specialties积极实施全球化战略。公司通过与国际分销商和代理商的合作,将产品销往全球各地。同时,公司还参加了多个国际性的电子展会和论坛,与来自世界各地的客户和合作伙伴进行交流和合作。这些举措不仅提升了Global Specialties的品牌知名度,还为公司带来了更多的国际合作机会和客户资源。通过这些努力,Global Specialties逐渐发展成为一家具有全球影响力的电子测试与测量公司。
在环保和可持续发展成为全球共识的背景下,AMP积极响应号召,将绿色发展理念融入企业的日常运营中。公司采用环保材料和工艺,减少生产过程中的污染排放。同时,AMP还积极推动循环经济的发展,努力实现资源的有效利用和废弃物的减量化处理。
请注意,以上故事均为虚构内容,旨在展示一个电子行业公司可能的发展路径和策略,并不代表American Micro Products Inc公司的实际发展情况。如需了解该公司的真实故事和发展历程,建议查阅相关新闻报道、公司年报或行业研究报告等权威资料。
自上世纪80年代起,Beckhoff便将基于PC的自动化新技术作为公司的发展理念。通过不断研发和创新,公司成功地将工业PC、现场总线模块、驱动产品和控制软件等整合为一套完整的、相互兼容的控制系统。这一创新为工控领域带来了革命性的变革,使得工业自动化系统更加开放、灵活和高效。
EDA技术的概念及范范畴 EDA技术是在电子CAD技术基础上发展起来的计算机软件系统,是指以计算机为工作平台,融合了应用电子技术、计算机技术、信息处理及智能化技术的最新成果,进行电子产品的自动设计。 利用EDA工具,电子设计师可以 ...… 查看全部问答∨ |
|
我刚刚接触dsp,有很多指令不懂,我用的芯片是f2812. 试着打开了f2812的串口测试程序。发现工程里有很多头文件(如DSP28_Device.h),他们都是自己写的吗,还是ti文件夹里默认有的?我搜索了一下ti的文件夹,也没有这些头文件啊? 还有,有很多指 ...… 查看全部问答∨ |
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay (uchar x) { uchar i,j; //¶¨Òå2¸öÎÞ·ûºÅÕûÐ ...… 查看全部问答∨ |
uboot编译突然出现has EABI version 5, but target u-boot has EABI version 0错误 S5pv210 uboot 编译很久了,最近增加了一些gui 的功能,但是编译居然出现如下错误,why?! /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-ld: error: Source object /usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4 ...… 查看全部问答∨ |
我不知道F2PI,Fsignal1,fstepsignal1这样的名字代表什么,导致程序看不懂啊,求解答歇歇啦~~~~~ 比如说:#define FIRNUMBER 25 #define SIGNAL1F 1000 #define SIGNAL2F 4500 #define SAMPLEF 10000 #define PI 3.1415926 除了 ...… 查看全部问答∨ |
我使用RT-thread1.2.2版本的源代码,是从官网的百度网盘中下载的.我把源代码打开后找到bsp文件夹,发现里面有stm32f40x的移植工程,于是惊喜万分,没有做任何修改就把工程下载到了我自己的stm32f407 开发板上,led显示的状态正常,可就是串口发回来的数据 ...… 查看全部问答∨ |
看EVM板上没加散热片但是 TMS320C6678的功率要比6472大很多 6472的评估板上6472加了散热片 但是6678的反而没加想问问做个6678的硬件设计的人 这片子需要加散热片么? 告诉运行的时候温度可以达到多少呢? 谢谢 … 查看全部问答∨ |