首先给出一些定义:

//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. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=armv7 armv7s)

    In Build Settings are: Architectures: Starndard (armv7, armv7s) Base SDK: Latest iOS (iOS 6.0) Build ...

  2. css包含块containing block

    <css权威指南>P167: The Containing Block Every element is laid out with respect to its containing b ...

  3. kafka集群搭建与apiclient创建

    曾经的消息队列(activeMQ)对于大数据吞吐率不行,但kafka非常好的攻克了此类问题.而且以集群的方式进行扩展.可谓相当强大: 集群搭建方式很轻量级.仅仅需将tar包复制到server,解压,改 ...

  4. Oracle数据库 ORA-01555 快照过旧 (undo表空间:撤销表空间)

    UNDO表空间用于存放UNDO数据,当执行DML操作时,oracle会将这些操作的旧数据写入到UNDO段,以保证可以回滚或者一致读等,而临时表空间主要用来做查询和存放一些缓冲区数据.你听说UNDO也是 ...

  5. Oracle闪回操作

    Oracle闪回操作 1. 记录当前时间或SCN 在数据库变动前记录时间或SCN SQL> select  to_char(sysdate,'YYYY-MM-DD HH24:mi:ss') fr ...

  6. CSS了一个浮动导航条

    绝对浏览器窗口定位positio:FIXED: 下拉后出现返回顶部按钮 图片是我们美工给做的.55*55px,中间缝隙3px. css: html,body { height:100%}html,bo ...

  7. mysql数据迁移

    使用mysqldump mysqldump -host=host1 -uroot -p123456 -opt sourceDb| mysql -host=host2 -uroot -p123 -C t ...

  8. Asp.net 网站发布之文件系统方式

    1.选中项目右键→发布方式选[文件系统]→点击发布 2.打开[Internet 信息服务(IIS)管理器] 默认网站(Default Web Site)→添加应用程序 填写[别名],[物理路径]选择上 ...

  9. javascript实现的功能--二级联动

    <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" ...

  10. 设计模式的PHP实现示例(转)

    symfony2 很多设计模式思想,下面的资料会有点帮助:http://www.open-open.com/lib/view/open1414996676559.html 阅读目录 Creationa ...