首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

底层中止调试-开中断,程序就飞-这是为什么?(与wince无关)

2013-01-01 
底层中断调试--开中断,程序就飞--这是为什么??--(与wince无关)程序运行在Supervisor Mode下,当程序做完初

底层中断调试--开中断,程序就飞--这是为什么??--(与wince无关)
程序运行在Supervisor Mode下,当程序做完初始化、中断向量表初始化以后。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
这是一段宏指令,用于下面的程序调用。
MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
subsp,sp,#4        ;decrement sp(to store jump address)
stmfdsp!,{r0-r1}        ;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,#4]      ;store the contents(ISR) of HandleXXX to stack
ldmfd   sp!,{r0-r1,pc}     ;POP the work register and pc(jump to ISR)
MEND


LTORG   
HandlerIRQ      HANDLER AddrIRQ  调用上面的宏,令HandlerIRQ 的内容存放AddrIRQ(0x33ffff18)的地址
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
bResetHandler  程序的第一条指令,地址为0
省略
bHandlerIRQ程序的irq指令,地址为0x18,为了让程序跳入AddrIRQ(0x33ffff18)的地址里面存放的中断向量影射函数地址IsrIRQ(0x30000190),
                                    程序应该跳转到IsrIRQ  处执行。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
获得中断类型,依据中断类型查找向量表(见最后),pc跳转到向量表对应的中断服务首地址

IsrIRQ  
subsp,sp,#4       ;reserved for PC
stmfdsp!,{r8-r9}   

ldrr9,=INTOFFSET
ldrr9,[r9]依据中断类型
ldrr8,=HandleEINT0
addr8,r8,r9,lsl #2
ldrr8,[r8]查找向量表
strr8,[sp,#8]
ldmfdsp!,{r8-r9,pc}pc跳转到向量表对应的中断服务首地址
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
ResetHandler(程序真正开始执行的地方)
     。。。。。。。初始化一些东西
     blInitStacks //各个模式下的堆栈初始化,最后初始化管理模式下的堆栈,[color=#FF0000]并且令管理模式下允许接收irq中断

  ; Setup IRQ handler设置中断向量表查询入口地址
ldrr0,=HandleIRQ    HandleIRQ =0x33ffff18   
ldrr1,=IsrIRQ        IsrIRQ=0x30000190  
strr1,[r0]         意图想在中断来临的时候,程序自动从0x33ffff18 读出0x30000190,并跳转到0x30000190处执行查询中断向量表[/color]
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
AREA RamData, DATA, READWRITE  中断向量表

        ^   _ISR_STARTADDRESS(ISR_STARTADDRESS==0x33ffff00)
HandleReset #   4
HandleUndef #   4
HandleSWI   #   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
AddrIRQ   #   4
HandleFIQ   #   4

;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.


;IntVectorTable
HandleEINT0   #   4
HandleEINT1   #   4
HandleEINT2   #   4
HandleEINT3   #   4
HandleEINT4_7#   4
HandleEINT8_23#   4
HandleRSV6#   4
HandleBATFLT   #   4
HandleTICK   #   4
HandleWDT#   4
HandleTIMER0 #   4
HandleTIMER1 #   4
HandleTIMER2 #   4
HandleTIMER3 #   4
HandleTIMER4 #   4
HandleUART2  #   4
HandleLCD #   4
HandleDMA0#   4
HandleDMA1#   4
HandleDMA2#   4
HandleDMA3#   4
HandleMMC#   4
HandleSPI0#   4
HandleUART1#   4
HandleRSV24#   4
HandleUSBD#   4     HandleUSBD=0x33ffff84
HandleUSBH#   4
HandleIIC   #   4
HandleUART0 #   4
HandleSPI1 #   4
HandleRTC #   4
HandleADC #   4
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
void Isr_Init(void)
 pISR_USBD =(unsigned)IsrUsbd;//c代码中将中断服务程序首地址写入向量表。在0x33ffff84里写入函数IsrUsbd的地址0x30002294
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
void ConfigUsbd(void)配置usbd设备
{
    ReconfigUsbd();   
    rINTMSK&=~(BIT_USBD); 配置完成后,程序只要一开中断(0x4a000008里面写入0xfdffffff),中断来临时,程序立即进入中断模式,但是程序却跑飞了。
}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


[解决办法]

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
ldr r8,[r8]查找向量表
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}pc跳转到向量表对应的中断服务首地址


原來的返回位址呢?? ISR 結束後要去哪??

Paul, Chao @ Techware

[解决办法]
学习来了
[解决办法]
uping
[解决办法]
你这是ADS 下的代码吧?

看了一下,和我的没有差别啊。是不是你写的中断函数有问题。
其余的和我一摸一样。
[解决办法]
哦,我准备买RVDS

现在很多人还停留在ADS上的

楼主一味求新,就注定孤独单干了。那玩意没有使用过。
[解决办法]
开了MMU吗,一般调试器不支持中断跳转的,可以通过MMU处理后支持调试器。
[解决办法]
这个肯定不是,ARM中断产生后,会自动跳转到对应的中断地址,比如复位时跳到0,ISR 跳到 ISR 异常入口,当中断产生时,代码不是直接跳到中断程序中,而是进行了一次类似复位的操作,然后根据对应的中断异常再执行处理。
所以一般仿真器是不会自动找到中断程序的,一般的做法是在启动代码初始化完成,并且使能中断前,用MMU把你代码的ResetHandle地址映射到0地址,这样仿真器就能找到中断函数入口而不会跑飞。
还有一种可能就是你对中断的堆栈没有进行正确的初始化。
[解决办法]

引用:
引用:


开了MMU吗,一般调试器不支持中断跳转的,可以通过MMU处理后支持调试器。 
 
我对mmu不是很熟,ads里面调用了这个,我在keil里面同样调用了这个: 
MMU_EnableICache 
  mrc p15,0,r0,c1,c0,0 
  orr r0,r0,#R1_I 
  mcr p15,0,r0,c1,c0,0 
  MOV_PC_LR



我晕,估计是你MMU使用不当造成

这是使能指令cache

cache和MMU不是一回事啊。
[解决办法]
MMU的一个重要作用就是方便系统管理内存,在bootloader阶段可以不开。

启动了MMU,可以一个物理地址对应多个虚拟地址,这就是为什么有wince最大的物理内存在512M,但是虚拟内存可以高达2G以上的原因。

这样做的好处很明显的,可以提高效率。

热点排行