如何在ADS调试中使用中断
作者:veabol
大家都知道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,搞不清楚它们之间有什么联系,改优化等级都没有用,彻底无奈,只好放弃使用分散加载。 |