开始在EBOOT中使用USB的时候很奇怪中断响应。因为在EBOOT和STEPLDR中都没有看到有对中断向量表部分的处理。那么这个中断是怎么触发?
最后在USB.C中的Isr_Init找到这句话:
pISR =(unsigned)(0xEA000000)+(((unsigned)IsrHandler - (0x80000000 + 0x18 + 0x8) )>>2);
这个实现了将USB的handler交给中断向量部分的处理,很简洁,下面分析这句话:
0xEA00000000 是机械码,将汇编中的无条件跳转指令 b
(unsigned)IsrHandler 是汇编中的ISR处理程序的首地址。
0x80000000 是MMU以后的映射的首地址。
0x18是中断向量表中的ISR部分的地址偏移量。
0x8 是进行ARM的三级流水的补偿。
((unsigned)IsrHandler - (0x80000000 + 0x18 + 0x8) )的意思就是计算ISRHandle函数相对于首地址的偏移地址。>>2是取Word对齐。
(unsigned)(0xEA000000)+(((unsigned)IsrHandler - (0x80000000 + 0x18 + 0x8) )>>2)就是一个机械码。EAXXXXXX,跳转到相对于首地址的ISRHandle位置。
而pISR的宏定义为#define pISR (*(volatile unsigned *)(0x30000000+0x18)) // Virtual Address 0x0 is mapped to 0x30000000, ISR Address is VA 0x18
意思就是指向中断向量表中ISR地址。
所以
pISR =(unsigned)(0xEA000000)+(((unsigned)IsrHandler - (0x80000000 + 0x18 + 0x8) )>>2);
就是将IsrHandle的程序指向到中断向量表中的ISR。
当有USB的中断发生时,会先进入到IsrHandler程序进行判断。然后再这段汇编中跳转到IsrUsbd中进行对USB的各种中断处理。
在其中还有一点疑惑。
1. pISR是一个指向函数/地址的指针。而等式后面是一个机械码。相当于将一个这个机械码写到某个地址上面。不知道这样是否ok@