首先给出一些定义:

//2440addr.inc

INTOFFSET    EQU  0x4a000014    ;Interruot request source offset

//option.inc

_ISR_STARTADDRESS    EQU 0x33ffff00

//2440init.s

         MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,# ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does t push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND

下面进入正题:

//2440init.s

    PRESERVE8
AREA RESET,CODE,READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
ResetEntry
b ResetHandler ;0x0
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
b EnterPWDN ; Must be @0x20. ... HandlerIRQ HANDLER HandleIRQ ... .............
; Setup IRQ handler//建立中断表
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there isn t 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0] ................
^ _ISR_STARTADDRESS ;0x33ffff00
HandleReset #
HandleUndef #
HandleSWI #
HandlePabort #
HandleDabort #
HandleReserved #
HandleIRQ #
HandleFIQ # ;0x33ffff1C
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 # ;0x33ffff20
HandleEINT1 #
HandleEINT2 #
.................................
HandleUART1        #   4            ;0x33ffff7C
.................................

uart是一个外部中断,走的是FIQ.

外部中断 --> b    HandlerFIQ ;

  看代码发现HandlerFIQ在init.s中进行了宏定义,展开之后得到:

//展开宏 HandlerIRQ  HANDLER  HandleIRQ
HandlerIRQ
sub sp,sp,# ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does t push because it return to original address)
ldr r0,=$HandleIRQ ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

  可以看到,HandlerIRQ是一个标准的中断处理过程(正因如此使用了宏进行封装): 首先保存现场,然后跳转到HandleIRQ,从HandleIRQ回来之后恢复现场.

  HandleIRQ其实是一个函数指针,它可以在程序中被我们指向某一个处理函数. 这里我们指向了IsrIRQ. 在IsrIRQ里,我们读取INTOFFSET寄存器的值,加上外部中断的起始值HandleEINT0,这样我们就获得了世纪的中断入口HandleUART1. 通过ldmfd sp!,{r8-r9,pc},我们跳转进入了HandleUART1对应的实际的中断处理函数(见后面的分析).

//2440init.s
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-
r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2 ;//r8=r8+(r9*4)
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}

  上面说到,"通过ldmfd sp!,{r8-r9,pc},我们跳转进入了HandleUART1对应的实际的中断处理函数." 怎么跳转的呢,在代码里,我们又实现并绑定了HandleUART1的处理函数Uart1_TxRxInt:

//2440addr.h
#define pISR_UART1 (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
//2440lib.c
pISR_UART1=(unsigned)Uart1_TxRxInt;
extern unsigned char UartBuf1[]; void __irq Uart0_TxRxInt(void)//这里只处理了接收中断
{
unsigned char *pbuf = UartBuf1;
if(rSUBSRCPND & BIT_SUB_RXD0) //接收中断
{
rINTSUBMSK |= BIT_SUB_RXD0; while((rUFSTAT0&0x3f))
{
*pbuf++ = rURXH0;
}
*pbuf = '\0'; rINTSUBMSK &= ~BIT_SUB_RXD0;
rSRCPND |= BIT_UART0;
rINTPND |= BIT_UART0;
rINTSUBMSK &= ~(BIT_SUB_TXD0);
}
}

ARM异常---一个Uart中断的触发处理过程:的更多相关文章

  1. ARM异常---一个DataAbort的触发过程:

    一个DataAbort异常的触发过程://////////////////////////////xxxx.inc_STACK_BASEADDRESS EQU 0x33ff8000_MMUTT_STA ...

  2. ARM异常中断处理

    ARM异常中断处理 在ARM体系中,通常有以下3种方式控制程序的执行流程: 在正常程序执行过程中,每执行一条ARM指令,程序计数器寄存器(PC)的值加4个字节:每执行一条Thumb指令,程序计数器寄存 ...

  3. 【ARM】arm异常中断处理知识点

    ARM处理器7种类型异常 按优先级从高到低的排列如下: 复位异常(Reset) 数据异常(Date Abort) 快速中断异常(FIQ) 外部中断异常(IRQ) 预取异常(Prefetch Abort ...

  4. stm32 uart 中断 蜜汁bug

    在项目中,使用stm32f103,配置uart1接收RXNE中断,使用DMA来进行UART1的发送. 初始化代码如下: void uart_init(u32 bound) { GPIO_InitTyp ...

  5. 基于ZYNQ 的UART中断实验之串口写数据到DDR3中

    1.参考 UG585 网络笔记 2.理论知识 参见上一次实验:基于ZYNQ 的UART中断实验 3.实验目的 练习使用UART的中断实验,并将接收到的数据写入到DDR3中. 4.实验过程 建立工程,设 ...

  6. c语言编写51单片机中断程序,执行过程是怎样的?

    Q:c语言编写51单片机中断程序,执行过程是怎样的? 例如程序:#include<reg52.h>  void main(void)  {   EA=1;      //开放总中断   E ...

  7. windows 系统中打开一个数字证书所经历的过程

         今天在使用Outlook express调试CSP程序时,发现数字证书总是加载不上(提示该数字证书已经被破坏),使用断点进去跟踪一下,发现在CSP程序中调用CPVerifySignature ...

  8. 一个简单的CS系统打包过程图文版

    一个简单的CS系统打包过程图文版 1.     打包内容 1.1.  此次打包的要求和特点 主工程是一个CS系统: 此CS系统运行的先决条件是要有.Net Framework 3.5: 主工程安装完成 ...

  9. Atitit. 软件开发中的管理哲学--一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向

    Atitit. 软件开发中的管理哲学--一个伟大的事业必然是过程导向为主    过程导向 vs 结果导向 1. 一个伟大的事业必然是过程导向为主 1 1.1. 过程的执行情况(有明确的执行手册及标准) ...

随机推荐

  1. IOS 特定于设备的开发:获取和使用设备姿势(通过手机方向控制3d物体显示)

    利用设备的机载陀螺仪可以实现,当你旋转手机屏幕时,里面的画面不会随着视图更新而移动,以平衡物理运动. 下面例子利用少量简单的几何变换执行该操作.他建立一个运动管理器,订阅设备运动更新,然后基于运动管理 ...

  2. why-and-howto-calculate-your-events-per-second

    http://eromang.zataz.com/2011/04/12/why-and-howto-calculate-your-events-per-second/

  3. Windows 键盘快捷键

    Windows 键盘快捷键 标签页和窗口快捷键 Ctrl+N 打开新窗口. Ctrl+T 打开新标签页. Ctrl+Shift+N 在隐身模式下打开新窗口. 按 Ctrl+O,然后选择文件. 通过 G ...

  4. 在CI框架下执行存储的方法

    我直接把代码摆在这里分享哈 <?php /** * * Created by JetBrains PhpStorm. * User: lsl * Date: 14-1-8 * Time: 下午2 ...

  5. Cocos2d-x lua游戏开发之安装Lua到mac系统

    注意:mac ox .lua version :5.15 下载lua官网的lua, 注意:最好是5.15下面.5.2的lua不支持table的getn()方法,这让我情何以堪.(获取table长度.相 ...

  6. ANDROID对文件的操作介绍

    1. Android遵循MVC设计思想: M(业务层):service V:视图(main.xml). C:Activity 2.使用文件如何对数据进行存储 Activity提供了openFileOu ...

  7. ios7高级

    1.实现控制器和视图. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1     ...

  8. iOS开发笔记 基于wsdl2objc调用asp.net WebService

    1.准备 先下载待会要用到的工具 WSDL2ObjC-0.6.zip WSDL2ObjC-0.7-pre1.zip 我用的是WSDL2ObjC-0.6.zip 1.1搭建asp.net WebServ ...

  9. Stack(栈)

    Stack(栈)是一种后进先出的数据结构,下面介绍一下栈的具体运用: 一.Stack 中的 empty 函数 stack<int> s( 5 , 10) ; s.empty()  ;   ...

  10. servlet三种实现方式之三通过继承HttpServlet开发servlet

    servlet有三种实现方式: 1.实现servlet接口 2.继承GenericServlet 3.通过继承HttpServlet开发servlet 第三种: import java.io.*; i ...