`
pleasetojava
  • 浏览: 732984 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

中断分析以及程序设计

阅读更多

在设计涉及到外中断的时候,比如按键中断就要研究一下怎么编了:

这里对EINT4567研究:

首先ARM芯片要中断设置要是能中断向量,然后当有IRQ中断来之后,CPU自动的到0x18地址处取指。0x18处的指令呢是CPU根据中断源算好的(比如:中断EINT4567来了,那么0x18处的指令就是跳转到地址0x30处)。然后就执行“ldr pc,=HandlerEINT4567”这条指令。这条指令的执行结果就是跳转到 “HandlerEINT4567 HANDLER HandleEINT4567”处执行。这条是宏指令,你可以看一下宏定义。执行结果就是跳转到HandleEINT4567处执行。
那么HandleEINT4567处又是什么指令呢?这就要联系44b.h文件的#define pISR_EINT4567 (*(unsigned *)(_ISR_STARTADDRESS+0x74))定义看了。HandleEINT4567处的地址就是“_ISR_STARTADDRESS+0x74”。到此还不知道这个地址对应的指令是什么。
这时候就要去看Target.c文件的中断初始化了,其中pISR_EINT4567= (unsigned) OSEINT4567ISR;这条语句就解释了中断去向何处。 OSEINT4567ISR就是在OS_CPU_A.s里面定义的中断处理程序了。
一、 关于44B0中断系统。
44B0中断系统中有两张中断转移表,经过二重转移才跳到中断处理程序。第一张中断向量表由硬件决定,所在区域为ROM(flash),地址空间从0X00开始,其中0X00-0X1C为异常向量入口地址,0X20-0XC0为中断向量入口地址。另一张中断向量表在RAM中,可以随便改,其位置在程序连接后才定。
二、 如何从第一张中断向量表跳到第二张中断向量表。
由于RAM放在地址空间的高端(距离中断向量超过了32M),故在第一张中断向量表对应位置上写上
ldr PC,# interrupt_service
如:ldr PC,=HandlerEINT4567
三、如何在启动程序中设置异常向量,中断向量表。如何把C语言中的一个中断函数对应到汇编的中断向量表中,示意图及举例如下:
#define _ISR_STARTADDRESS 0xc7fff00 //GCS6:16M bit DRAM/SDRAM
#define pISR_EINT4567 (*(unsigned *)(_ISR_STARTADDRESS+0x74))
.macro HANDLER HandleLabel
sub sp, sp, #4
stmfd sp!, {r0}
ldr r0,=\HandleLabel
ldr r0, [r0]
str r0, [sp,# 4]
ldmfd sp!, {r0,pc}
.endm
.text
ENTRY:
b ResetHandler ……
VECTOR_BRANCH:
ldr pc,=HandlerEINT0 ……
ldr pc,=HandlerEINT4567 /* 0x30 */
HandlerEINT4567:HANDLER HandleEINT4567
.equ HandleEINT4567, _ISR_STARTADDRESS+4*29

把C语言中的一个中断函数对应到汇编的中断向量表中
pISR_EINT4567 = (int)Eint4567Isr;
其实异常向量就是中断向量,ARM7的内核实际上只有8个(1个保留)异常向量,对于众多的中断源,ARM7的内核是通过IRQ、FRQ的软件查询中断状态寄存器的位来获得ISR的起始地址。而44B0为了克服这种方式所带来的中断延迟,就加入了更多的中断向量表(0x20到0xc0),要使用这种方式,必须在中断控制寄存器中设置每个中断源的方式为IRQ方式,且使用向量中断。
S3C44B0X的中断控制器有30个中断源。S3C44B0X支持新的中断处理模式称为(vectored interrupt mode),在多个中段请求发生时,由硬件优先级逻辑确定应该有哪个中断得到服务,同时硬件逻辑使中断相量表的跳转指令加载到(0X18或0X1C)位置,在该位置执行跳转指令使程序跳到相应的中断服务线程,因此相对与传统的ARM的软件方法能够大大减少中断进入延时。有两种类型的中断模式,FIQ (快速中断)和IRQ.所有的中断源在中断请求时应该确定使用的
中断模式。在网络上广为流传的44b0开发板例程中,大部分使用的都是IRQ中断模式(请查阅
寄存器rINTCON)。
一般来讲,使用44b0开发板进行调试时,无需更改44b.h,44blib.h,def.h,option.h,44binit.s,44blib.c,44blib_a.s,memcfg.s,option.s等程序,甚至无需看懂,即可编程使用44b0开发板。如前所述,硬件逻辑使中断相量表的跳转指令加载到(0X18或0X1C)位置,在该位置执行跳转指令使程序跳到相应的中断服务线程,用户只需定义相应的中断服务程序即可。中断向量表的定义如下
(节选,请看44b.h)
/* ISR */
#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))
#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))
#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))
#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))
#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))
#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))
#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))
#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))
.........................................
#define pISR_EINT4567 (*(unsigned *)(_ISR_STARTADDRESS+0x74))
#define pISR_EINT3 (*(unsigned *)(_ISR_STARTADDRESS+0x78))
#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x80))
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x84))
用户定义相应的中断服务程序,可以参考该语句,
pISR_EINT4567=(unsigned)Key_Int;;//将外部中断4567产生的中断,指向函数Key_Init
当然,用户也可以根据自己的爱好,任意改变函数名,
pISR_EINT4567=(unsigned)MyCat; //函数名由用户定义
最好在程序开头声明一下,
void __irq Mycat(void);;;
显然,至此可以基本理解44b0的中断,是如何与程序中的中断服务子程序联系起来的了。中断的硬件逻辑,将检测到的中断,以某种方式指向中断服务程序的地址,该地址在头文件中以宏定义的形式出现。用户在自己的程序中,将中断服务子程序的地址付给该指针,从而将其联系起来。
ARM7TDMI在矢量模式下,当从0X18地址处取指令时候,中断控制器会在数据总线上加载分支指令,这些分支指令使程序计数器能够对应到每一个中断源的向量地址。这些跳转到每一个中断源向量地址的分支指令由中断控制器产生。
例如:假设EINT0是IRQ中断,EINT0的向量地址为:0X20(见向量表),那么中断控制器必须产生0X18---0X20的分支指令。 中断控制器产生的机器码为: 0XEA000000。在各个中断源对应的中断向量地址中,存放着跳转到相应中断服务程序的程序代码。在相应向量地址处分支指令的机器代码如下计算:
矢量中断模式的机器指令代码=0XEA000000+((<目标地址>-<向量地址>-0X8)>>2)
机器代码一般由反汇编后自动产生。
结合这些,再看看程序中的代码。在无矢量中断模式,通过分析IISPR/FISPR寄存器,IRQ/FIQ处理器将移动PC到相应的ISR。HandleXXX地址包含每个响应的ISR程序的起始地址。(见 44binit.S 文件)
编译器它自动有设置的(初始化的伪编译宏),
|Image$$RO$$Limit|:表示RO区末地址后面的地址,即RW数据源的起始地址
|Image$$RW$$Base|:RW区在RAM里的执行区起始地址,也就是编译器选项RW_Base指定的地址
|Image$$ZI$$Base|:ZI区在RAM里面的起始地址
|Image$$ZI$$Limit|:ZI区在RAM里面的结束地址后面的一个地址
程序先把ROM里|Image$$RO$$Limt|开始的RW初始数据拷贝到RAM里面|Image$$RW$$Base|开始的地址,当RAM这边的目标地址到达|Image$$ZI$$Base|后就表示RW区的结束和ZI区的开始,接下去就对这片ZI区进行清零操作,直到遇到结束地址|Image$$ZI$$Limit|

下面举例一个实际的程序设计方法:

ARM44B0实验:外部中断测试实验


一、实验预备知识

实现外部中断编程的一般步骤:

(1)I/O口设置

rPCONG=0xff00;/0xffff;keyint 4~7

rPUNPG=0x00; 采用内部上拉。

(2)外部中断触发模式设置:

rEXTINT=0x22222222; //Falling edge mode

rEXTINT=0x4444444;//Rising edge mode

rEXTINT=0x777777;//Both Edge trigger mode

rEXTINT=0x0;// Low level trigger mode

(2) EXINT reg 设置

将EXINT 4~7设置为IRQ mode

rINTCON=0x5;
rINTMOD=0x0; //All=IRQ mode

修改中断处理指针

pISR_EINT4567=(unsigned)Key_Int;

开启中断

rINTMSK=~(BIT_GLOBAL|BIT_EINT4567); //start INT

中断测试程序编写:

oid Key_Init(void)
{
rINTCON=0x5;
rINTMOD=0x0; //All=IRQ mode
// rEXTINT=0x22222222; //Falling edge mode
rEXTINT=0x0; //"0" level mode
rPCONG=0xffff; //EINT7~0
rPUPG=0x0; //pull up enable
pISR_EINT4567=(unsigned)Key_Int;
rINTMSK=~(BIT_GLOBAL|BIT_EINT4567); //start INT
}

编写好了,编写中断处理程序:

oid __irq Key_Int(void)
{

which_int=rEXTINTPND;//识别是那个中断
rEXTINTPND=0xf; //clear EXTINTPND reg.
rI_ISPC=BIT_EINT4567; //clear pending_bit
……(处理模块)
}

本次实验任务:按键中断,并使相应LED亮起来,按EXINT4则第一个LED亮,依次类推。

处理程序

switch(which_int)
{
case 1:
Uart_Printf("EINT4 had been occured...\n");
Led_Display(1);
which_int=0;
break;
case 2:
Uart_Printf("EINT5 had been occured...\n");
Led_Display(2);
which_int=0;
break;
case 4:
Uart_Printf("EINT6 had been occured...\n");
Led_Display(4);
which_int=0;
break;
case 8:
Uart_Printf("EINT7 had been occured...\n");
Led_Display(0);
which_int=0;
break;
default :
break;
}
//注意理解上面程序。

实验结果:

***********************************************************************

FS44B0X

FS44B0X key1 key2 key3 key4!EINT4 had been occured...
EINT4 had been occured...
EINT4 had been occured...
EINT4 had been occured...
EINT4 had been occured...
EINT4 had been occured...
EINT4 had been occured...

*********************************************************************************
开发板上LED的闪亮随按键依次变化。

实验例程序附录如下:

#i nclude "option.h"
#i nclude "def.h"
#i nclude "44b.h"
#i nclude "44blib.h"

volatile char which_int=0;

void __irq Key_Int(void)
{

which_int=rEXTINTPND;
rEXTINTPND=0xf; //clear EXTINTPND reg.
rI_ISPC=BIT_EINT4567; //clear pending_bit
switch(which_int)
{
case 1:
Uart_Printf("EINT4 had been occured...\n");
Led_Display(1);
which_int=0;
break;
case 2:
Uart_Printf("EINT5 had been occured...\n");
Led_Display(2);
which_int=0;
break;
case 4:
Uart_Printf("EINT6 had been occured...\n");
Led_Display(4);
which_int=0;
break;
case 8:
Uart_Printf("EINT7 had been occured...\n");
Led_Display(0);
which_int=0;
break;
default :
break;
}

}
void Key_Init(void)
{
rINTCON=0x5;
rINTMOD=0x0; //All=IRQ mode
// rEXTINT=0x22222222; //Falling edge mode
rEXTINT=0x0; //"0" level mode
rPCONG=0xffff; //EINT7~0
rPUPG=0x0; //pull up enable
pISR_EINT4567=(unsigned)Key_Int;
rINTMSK=~(BIT_GLOBAL|BIT_EINT4567); //start INT
}

void Main(void)
{
rSYSCFG=CACHECFG; // Using 8KB Cache//

Port_Init();
Uart_Init(0,57600);
Delay(10);
Uart_Select(0); //Select UART0
Led_Display(0x07);

Uart_Printf("\nFS44B0X");
Uart_Printf("\n按键中断演示程序");
Uart_Printf("\n按FS44B0X开发板上的按键 key1 key2 key3 key4!");

Key_Init();
while(1);

}

注意:处理程序随便放那个函数里都可以。


分享到:
评论

相关推荐

    BIOS和DOS中断调用应用程序设计

    在这个主题中,“BIOS和DOS中断调用应用程序设计”主要关注如何利用这些系统提供的中断服务来编写能够控制屏幕输出、移动光标以及插入字符的简单字处理程序。以下将详细阐述这两个关键概念及其在程序设计中的应用。 ...

    51单片机外部中断实验程序的设计与分析.pdf

    本文将探讨51单片机的外部中断实验程序设计,并分析其中涉及到的关键知识点。 首先,51单片机具有两个外部中断源,它们分别是INT0和INT1。这两个中断源具有固定的入口地址,分别为0003H和0013H。在51单片机的硬件...

    DSP的中断程序

    在本文中,我们将深入探讨DSP中断系统的工作原理、中断程序的配置与实现,以及如何通过键盘来触发中断并观察其效果。 首先,我们要理解中断的基本概念。中断是一种异步通信方式,当处理器接收到外部硬件设备或内部...

    实验报告6中断及服务程序设计.doc

    实验报告“中断及服务程序设计”探讨了单片机中断系统的工作原理以及中断优先级的管理,主要通过实例展示了如何设计中断服务程序,并利用定时器0和定时器1来实现不同优先级的中断处理。实验中,使用了PC机和Wave6000...

    中断服务程序举例2013-11-29.7z

    此外,"中断服务程序举例.docx"文件可能是对这些ASM程序的详细解释和分析,可能包括中断服务程序的设计思路、执行流程图以及实际应用中的注意事项。 总的来说,中断服务程序是实现系统实时性和响应性的关键技术。...

    TMS320F2812中断系统分析及其C语言编程

    TMS320F2812的中断系统设计灵活且强大,通过合理配置和编程,可以显著提升系统的实时性能和可靠性。本文通过对F2812中断机制的深入分析和C语言编程示例的展示,为开发者提供了实用的指导和参考。

    飞思卡尔定时中断程序

    #### 四、定时中断程序设计流程 1. **初始化定时器**: - 设置工作模式:选择定时器的工作模式(自由运行、模模式等)。 - 设置预分频器:根据所需的时间间隔调整预分频器值。 - 设置比较寄存器:配置匹配中断时...

    汇编语言子程序及中断实验四

    本实验的目的是为了学习和掌握子程序和中断服务子程序的设计和实现方式,以及中断向量表结构和中断服务程序链的实现。通过本实验,我们可以更好地理解计算机系统的工作机理,并掌握编程的基本技能。 实现方法: 1....

    单片机利用中断延时程序

    3. 中断服务程序设计:在中断服务程序中更新定时器值,确保中断不会立即再次触发。 4. 保护和恢复现场:在进入中断前保存CPU状态,在中断退出前恢复,以防止主程序的运行受到影响。 5. 关闭中断:在延时结束后,关闭...

    中断检测和中断设计程序.zip_中断检测程序_中断滤按

    这个名为"中断检测和中断设计程序.zip"的压缩包包含了与中断相关的源代码和配置文件,主要涉及中断检测和中断滤波两个关键概念。 中断检测是指处理器监测并响应来自外部或内部硬件设备的中断请求的过程。在这个程序...

    外部中断参考C语言程序

    2. **中断初始化**:在程序开始运行时,需要对中断进行初始化,包括开启中断控制器,设置中断优先级,以及注册ISR。这可以通过调用特定的库函数实现。 3. **中断服务例程(ISR)**:ISR是响应中断的代码段,应设计...

    西门子200 PLC 中断程序做流量累计 程序

    在这个特定的程序设计场景中,我们要利用中断程序来实现流量累计的功能。中断程序是一种在特定事件发生时被调用的程序段,它可以实时响应系统中的特定输入信号,如时间、计数器或输入端口状态的变化,以完成特定任务...

    linux下中断处理程序示例,含驱动和应用程序

    在文件`irq-test.tar`中的应用程序可能展示了如何在用户空间调用这些接口,以及如何处理中断返回的结果。 总的来说,这个示例涵盖了从驱动开发到应用程序的完整中断处理流程,是学习Linux中断系统和驱动开发的宝贵...

    中断应用程序设计(汇编).doc

    【中断应用程序设计(汇编)】 在计算机编程中,中断是一种重要的机制,它允许操作系统和其他硬件设备暂停当前执行的程序,以便处理紧急事件或服务请求。汇编语言是低级编程语言,通常用于编写与硬件交互密切的程序...

    基于ARM Cortex-M4的MQX中断机制分析与中断程序框架设计.pdf

    提出的原则不仅提高了程序设计的灵活性,也使得软件更加容易适应不同的硬件环境和应用需求。 通过上述知识点,可以看出文章的研究对于嵌入式系统开发者具有很高的参考价值,特别是在需要高性能和快速响应的实时系统...

    汇编语言实验8-中断程序设计[参考].pdf

    【汇编语言中断程序设计详解】 中断是计算机系统中一种重要的机制,用于处理突发事件或请求。在汇编语言编程中,理解和掌握中断处理是至关重要的。本实验旨在帮助学生熟悉中断的类型、处理过程以及如何设计中断程序...

    Linux内核中断分析

    ### Linux内核中断分析 #### 重要性及作用 中断系统是计算机系统中不可或缺的关键组件,在整个系统的运行中扮演着至关重要的角色。特别是在Linux操作系统中,中断机制的高效性和灵活性对于提升系统的整体性能至关...

    s3c6410裸机中断程序

    总结,S3C6410的中断处理涉及硬件层面的中断源、中断控制器以及软件层面的中断程序设计和管理。掌握中断机制和编写裸机中断程序是嵌入式开发的关键技能,这有助于实现高效、可靠的嵌入式系统。通过详细阅读和分析...

    基于ARM9芯片S3C2410异常中断程序设计.pdf

    随后,详细分析了S3C2410芯片上的异常中断处理流程,并给出了具体的程序设计示例。 #### 中断与异常基础 在计算机体系结构中,中断和异常通常被用来处理系统中的突发状况或外部事件。异常通常是指由于内部错误或非...

    中断处理 课程设计

    中断处理不仅是计算机操作系统中的核心机制之一,也是实现多道程序设计、任务调度和系统管理的重要基础。通过实际的课程设计,学生们可以更深刻地理解中断及其处理程序的作用和重要性。在本文中,我们将详细介绍一个...

Global site tag (gtag.js) - Google Analytics