如何在ADS调试中使用中断

  

    大家都知道ARM9产生中断的时候PC会自动跳转到0x18地址处执行中断处理代码,但是当FLASH等启动介质中没有预烧录代码会怎么样呢?ARM复位时从启动介质获取的代码为全F或者全0,而如果ADS调试将代码下载到外部RAM里边就会导致0x18地址没有中断处理代码,发生中断当然也就没有办法执行了,其实有几种处理方法:

1、使用ADS的分散加载机制。在下载映像时将带中断处理的代码下载到0地址开始的地方,使0x18地址有中断处理代码,而其它代码加载到外部RAM。

2、预烧录中断处理代码。就是将有中断处理的代码预先烧录到启动介质,当ARM复位的时候自动将代码读取到0地址,这样在调试过程也能很好的处理中断。

3、加载的镜像代码去改变0x18地址的数据。
代码如下:

_ISR_STARTADDRESS        EQU                0x33ffff00

        AREA StartupCode, CODE
ResetCode
        b .        ;ResetHandler
        b .        ;handler for Undefined mode
        b .        ;HandlerSWI
        b .        ;HandlerPabort
        b .        ;HandlerDabort
        b .
        b IsrIRQ        ;HandlerIRQ
        b .        ;HandlerFIQ
        b .;IsrIRQ;EnterPWDN
       
IsrIRQ
        sub        sp,sp,#4       ;reserved for PC
        stmfd        sp!,{r8-r9}

        ldr        r9,=INTOFFSET1
        cmp r9,#0
        ldrne        r8,=HandleEINT0
        bne %f0                                ;如果中断来自于INTOFFSET1跳转
       
        ldr r9,=INTOFFSET2
        ldr r8,=Handle2D
       
0        ldr        r9,[r9]
        add        r8,r8,r9,lsl #2
        ldr        r8,[r8]
        str        r8,[sp,#8]
        ldmfd        sp!,{r8-r9,pc}

        LTORG
       
CopyStartupCode
        adr        r0, ResetCode
        mov        r2, #0
        adr        r3, CopyStartupCode
0       
        ldmia        r0!, {r4-r7}
        stmia        r2!, {r4-r7}
        cmp        r0, r3
        bcc        %B0
       
        mov        pc,lr


;===============================================================================
        ALIGN

        AREA HandleAddr, DATA, READWRITE

        ^   _ISR_STARTADDRESS                ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset         #   4
HandleUndef         #   4
HandleSWI                #   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
HandleIRQ                #   4
HandleFIQ                #   4       


HandleEINT0                #   4
HandleEINT1                #   4
HandleEINT2                #   4
HandleEINT3                #   4
HandleEINT4_7        #   4
HandleEINT8_15        #   4
HandleReserved0        #   4               
HandlenBATT_FLT        #   4
HandleTICK                #   4
HandleWDT_AC97        #   4
HandleTIMER0         #   4
HandleTIMER1         #   4
HandleTIMER2         #   4
HandleTIMER3         #   4
HandleTIMER4         #   4
HandleUART2          #   4
;@0x33FF_FF60
HandleLCD                 #   4
HandleDMA                #   4
HandleUART3                #   4
HandleReserved2        #   4
HandleSDI1                #   4
HandleSDI0                #   4
HandleSPI0                #   4
HandleUART1                #   4
HandleNAND                #   4               
HandleUSBD                #   4
HandleUSBH                #   4
HandleIIC0                #   4
HandleUART0         #   4
HandleReserved3        #   4
HandleRTC                 #   4
HandleADC                 #   4
;@0x33FF_FFA0
Handle2D                #        4       
HandleReserve3        #        4
HandleReserve4        #        4
HandleReserve5        #        4
HandlePCM0                #        4
HandleReserve6        #        4
HandleI2S0                #        4       

在C文件中调用CopyStartupCode改变0地址开始的一段数据使0x18处能够处理中断。
中断函数初始化代码使用:
#define pISR_USBD                (*(unsigned *)(_ISR_STARTADDRESS+0x84))
pISR_USBD = (unsigned)ISR_USBD;       



其实三种方法中第一种和第三种都很简单,当初我竟然只用了第二种,为此还专门先写了段烧录ADS烧录NAND的代码,谁那个SJF用不起来,不过因为反正也要通过ADS烧录block0img和eboot也就无所谓了;第三种方法是后来根据EBOOT中USB中断初始化代码想到的;当初没有分散加载文件的方法还有一个原因是有一个重要的C函数,只要一使用分散加载调用就出错,查看Dissamemble发现使用分散加载时ADS Make出来的这个函数最后竟然没有mov pc,lr,搞不清楚它们之间有什么联系,改优化等级都没有用,彻底无奈,只好放弃使用分散加载。

转自:http://www.armce.com/bbs/thread-996-1-1.html 

作者:Veabol

原文地址:https://www.cnblogs.com/xfdarm/p/1626907.html