ARM启动一般从0x00000000开始启动,当然也有可能从SD、其他的地址(M3默认0x80000000),那么A9默认从0开始,打开vector_asm.s汇编代码如下所示:
.org 0
.text
.arm
.global _boot
.global _freertos_vector_table
.global _vector_table
.global FIQInterrupt
.global DataAbortInterrupt
.global PrefetchAbortInterrupt
.global vPortInstallFreeRTOSVectorTable
.extern FreeRTOS_IRQ_Handler
.extern FreeRTOS_SWI_Handler
.section .vectors
_vector_table:
_freertos_vector_table:
B _boot
B FreeRTOS_Undefined
ldr pc, _swi
B FreeRTOS_PrefetchAbortHandler
B FreeRTOS_DataAbortHandler
NOP /* Placeholder for address exception vector*/
LDR PC, _irq
B FreeRTOS_FIQHandler
_irq: .word FreeRTOS_IRQ_Handler
_swi: .word FreeRTOS_SWI_Handler
.align 4
FreeRTOS_FIQHandler: /* FIQ vector handler */
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */
FIQLoop:
blx FIQInterrupt /* FIQ vector */
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
.align 4
FreeRTOS_Undefined: /* Undefined handler */
b .
.align 4
FreeRTOS_DataAbortHandler: /* Data Abort handler */
#ifdef CONFIG_ARM_ERRATA_775420
dsb
#endif
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */
blx DataAbortInterrupt /*DataAbortInterrupt :call C function here */
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
.align 4
FreeRTOS_PrefetchAbortHandler: /* Prefetch Abort handler */
#ifdef CONFIG_ARM_ERRATA_775420
dsb
#endif
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */
blx PrefetchAbortInterrupt /* PrefetchAbortInterrupt: call C function here */
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
上电第一段代码boot,设置堆栈、始终,cache,外设等等,最终跳到Main中执行。
-swi软中断,主要用于系统调用的实现,如A9下swi 3,转换为机器码位0x0000003,通过机器码便可以获得指令数进行操作。
FIQ与IRQ主要是通过数组的形式保存了中断向量的处理函数以及ID,来实现的,比如FIQ
.align 4
FreeRTOS_FIQHandler: /* FIQ vector handler */
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */
FIQLoop:
blx FIQInterrupt /* FIQ vector */
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
在FIQ内部:
{
XExc_VectorTable[XIL_EXCEPTION_ID_FIQ_INT].Handler(XExc_VectorTable[
XIL_EXCEPTION_ID_FIQ_INT].Data);
}
IRQ实现也是如此