今天看了2103的VIC和启动代码部分,感受颇多,记录自己的心得!哈哈!
一、向量控制器
1、将外部中断0设置非向量中断
VICDefVectAddr=(int)IRQ_Eint0;//设置中断服务程序地址
EXINT=0x01; //清除EXINT0中断标志
VICIntEnable=1<<0x0e; //使能ENIT0中断
2、将外部中断0设置为向量中断
VICIntSelect=0x00000000; //设置所有中断分配为IRQ中断
VICVectCntl0=0x20|0x0e; //分配外部中断0到向量中断0
VICVectAddr0=(uint32)IRQ_Eint0; //设置中断服务程序地址
EXTINT=0X01; //清除EINT0中断标志
VICIntEnable=1<<0x0e; //使能EINT0中断
3、多个中断设置(假设UART0和SPI0产生中断请求,它们被分配为向量IRQ,而UART1和I2C产生非向量IRQ)
VICIntSelect=0x00000000; //中断请求分配为IRQ中断
VICIntEnable=0x000006c0; //使能对应的中断
VICDefVectAddr=0x... //
VICVectAddr0=0x... //
VICVectAddr1=0x... //
VICVectCntl0=0x00000026; //这里就相当于前面 VICVectCntl0=0x20|0x06 使通道号位6的中断源使能 //为优先级0,其实就是UART0
VICVectCntl1=0x0000002A; //VICVectCntl0=0x20|0x0A 同理,使SPI0为次高优先级
在任何IRQ请求产生之后,微控制器跳转到0x00000018执行代码。
4、只有MSR可以直接设置状态寄存器cpsr和spsr
二、引脚连接模块
PINSEL0=PINSEL0&0XFFFFFFFC; //设置p0.0为GPIO,其他功能不可用
PINSEL0=(PINSEL0&0XFFFFFFFC)|0x01;//设置p0.0为TxD0,其他功能不可用
三、启动代码
Startup.s文件
开始有个地方不是很明白,到网上找了些资料才明白过来了,其实是arm的三级流水线的作用,现在把不懂得代码贴上:
///
SoftwareInterrupt
CMP R0,#4 //判断传过来的参数是否大于4
LDRLO PC,[PC,R0,LSL #2] //小于4(参数正确),PC = PC + R0*4进行查表
MOVS PC,LR //大于或者等于4,则返回
SwiFunction
DCD IRQDisable
DCD IRQEnable
DCD FIQDisable
DCD FIQDEnable
IRQDisable
IRQDisable实现部分
IRQEnable
IRQEnable实现部分
FIQDisable
FIQDisable实现部分
FIQDEnable
FIQDEnable实现部分
//
开始我对LDRLO PC,[PC,R0,LSL #2] //小于4(参数正确),进行查表 这句话不理解,看到下面这段话才恍然大悟。
在ARM体系结构中,当正确读取了PC的值时,该值为当前指令地址值加8字节,也就是说,对于ARM指令集来说,读出的PC值指向当前指令的下两条指令的地址,本例中就是指向SwiFunction 表头DCD function0 这个地址,在该地址中保存了异常处理子分支function0的入口地址。所以,当进入SWI异常处理子程序SoftwareInterrupt时,如果R0=0,执行LDRLO PC, [PC, R0, LSL #2]语句后,PC的内容即为function0的入口地址,即程序跳转到了function0执行。在本例中,因为R0=1,所以,实际程序是跳转到了function1执行。R0左移2位(LDRLO PC, [PC, R0, LSL #2]),即R0*4,是因为ARM指令是字(4个字节)对齐的DCD function0等伪指令也是按4字节对齐的。