您好、专家!
我们在使用 AM5728时遇到了一个问题、某个版本的应用程序会在几个小时内使流水线停顿、经过我们自己的分析后、这与中断处理有很大关系。
以下是 SDK 提供的中断处理代码
IRQHandler: STMFD r13!, {r0-r3, r12, r14} @ Save context in IRQ stack FMRX r0, FPEXC @ Check Neon/VFP Enable bit UBFX r0, r0, #30, #1 @ Bit 30 extract for check CMP r0, #0 @ Compare for zero BEQ vfp_disabled_irq_save @ VFP bit is not enabled MRS r12, spsr @ Copy spsr VMRS r1, FPSCR @ Copy fpscr VMRS r2, FPEXC @ Copy fpexc STMFD r13!, {r1-r2, r12} @ Save spsr, fpscr and fpexc VSTMDB r13!, {d0-d7} @ Save D0-D7 Neon/VFP registers VSTMDB r13!, {d16-d31} @ Save D16-D31 Neon/VFP registers vfp_disabled_irq_save: LDR r1, =addrIar @ Load global variable addrIar address into r1 LDR r0, [r1] @ Load IAR address into r0 LDR r1, [r0] @ Get the Active IRQ MOV r2, r1 @ save active IRQ in r2 AND r1, r1, #IAR_INT_ID_MASK @ Mask the Active IRQ number SUB r1, r1, #PPI_SGI_MASK @ Get Shared pheriperal int number LDR r3, =fnRAMVectors @ Load the base of the vector table LDR r0, =argArray @ Load base of argument LDR r0, [r0, r1, lsl #2] @ Load argument STMFD r13!, {r2} @ Save active IRO in stack ADD r14, pc, #0 @ Save return address in LR LDR pc, [r3, r1, lsl #2] @ Jump to the ISR LDMFD r13!, {r2} @ Get active IRO from stack LDR r1, =addrEoi @ Load global variable addrEoi address into r1 LDR r3, [r1] @ Acknowledge the current IRQ STR r2, [r3] DMB @ Barrier to complete the data write FMRX r0, FPEXC @ Check Neon/VFP Enable bit UBFX r0, r0, #30, #1 @ Bit 30 extract for check CMP r0, #0 @ Compare for zero BEQ vfp_disabled_irq_restore @ VFP bit is not enabled VLDMIA r13!, {d16-d31} @ Restore D16-D31 Neon/VFP registers VLDMIA r13!, {d0-d7} @ Restore D0-D7 Neon/VFP registers LDMFD r13!, {r1-r2, r12} @ Get fpscr, fpexc and spsr MSR spsr, r12 @ Restore spsr VMSR fpscr, r1 @ Restore fpscr VMSR fpexc, r2 @ Restore fpexc vfp_disabled_irq_restore: LDMFD r13!, {r0-r3, r12, r14} @ Restore registers from IRQ stack SUBS pc, r14, #0x4 @ Return to program before IRQ
在此基础上、我实现了在双线程之间来回切换的功能、以下代码是我自己修改过的中断处理汇编代码
hi_pCurrentTaskStructConst: .word hi_pCurrentTaskStruct Hanix_IRQHandler: SUB lr, lr, #4 SRSDB sp!, #MODE_SYS //保存状态寄存器的值到系统模式下的栈中 MSR cpsr_c, #MODE_SYS|0x80 PUSH {R0-R12, R14} FMRX r0, FPEXC @ Check Neon/VFP Enable bit UBFX r0, r0, #30, #1 @ Bit 30 extract for check CMP r0, #0 @ Compare for zero BEQ check_hanix_task @ VFP bit is not enabled VMRS r1, FPSCR @ Copy fpscr VMRS r2, FPEXC @ Copy fpexc STMFD r13!, {r1-r2} @ Save fpscr and fpexc VSTMDB r13!, {d0-d7} @ Save D0-D7 Neon/VFP registers VSTMDB r13!, {d16-d31} @ Save D16-D31 Neon/VFP registers check_hanix_task: LDR R0, hi_pCurrentTaskStructConst LDR R1, [R0] STR SP, [R1] vfp_disabled_irq_save: LDR r1, =addrIar @ Load global variable addrIar address into r1 LDR r0, [r1] @ Load IAR address into r0 LDR r1, [r0] @ Get the Active IRQ MOV r2, r1 @ save active IRQ in r2 AND r1, r1, #IAR_INT_ID_MASK @ Mask the Active IRQ number SUB r1, r1, #PPI_SGI_MASK @ Get Shared pheriperal int number LDR r3, =fnRAMVectors @ Load the base of the vector table LDR r0, =argArray @ Load base of argument LDR r0, [r0, r1, lsl #2] @ Load argument STMFD r13!, {r2} @ Save active IRO in stack ADD r14, pc, #0 @ Save return address in LR LDR pc, [r3, r1, lsl #2] @ Jump to the ISR LDMFD r13!, {r2} @ Get active IRO from stack LDR r1, =addrEoi @ Load global variable addrEoi address into r1 LDR r3, [r1] @ Acknowledge the current IRQ STR r2, [r3] DSB ISB /* Set the SP to point to the stack of the task being restored. */ LDR R0, hi_pCurrentTaskStructConst LDR R1, [R0] LDR SP, [R1] check_neon: FMRX r0, FPEXC @ Check Neon/VFP Enable bit UBFX r0, r0, #30, #1 @ Bit 30 extract for check CMP r0, #0 @ Compare for zero BEQ vfp_disabled_irq_restore @ VFP bit is not enabled VLDMIA r13!, {d16-d31} @ Restore D16-D31 Neon/VFP registers VLDMIA r13!, {d0-d7} @ Restore D0-D7 Neon/VFP registers LDMFD r13!, {r1-r2} @ Get fpscr, fpexc and spsr VMSR fpscr, r1 @ Restore fpscr VMSR fpexc, r2 @ Restore fpexc vfp_disabled_irq_restore: POP {R0-R12, R14} RFEIA sp!
当 CPU 管线被暂停时、使用 xds200仿真器连接至 AM5728、并显示以下消息:
ERROR-1323@0x8024F858该地址的反汇编代码如下所示:
我猜应该是 CPU 正在执行 DSB 命令、这个命令还没有完成。我想问我修改的中断汇编代码是否有问题吗? 何时会发生这种情况?