具体看一下函数调用情况:
举例:
1在main.c中
micIrqFuncSet(Timer1_INT, 2, (unsigned int)IRQ_Timer1);
而micIrqFuncSet函数调用的是viccontrol.h中的函数
2在viccontrol.h中
__inline unsigned int micIrqFuncSet (unsigned int uiChannel,
unsigned int uiType,
unsigned int uiFuncAddr)
{
return swiHandle(0x100, uiChannel, uiType, uiFuncAddr);
}
这里采用的是inline函数,也就是说实际调用的是swiHandle函数
__swi(0x01) unsigned int swiHandle (int iHandle, unsigned int, unsigned int, unsigned int);
3在vicControl.s中
swihandle实际上是swi软件中断,有4个参数,分别传递给R0-R3。
补充:SWI 执行的流程是,先进入异常中断向量表,然后跳到向量地址处,接着一小段汇编操作,把功能号读入到一个寄存器中,然后 switch 判断这个功能号是多少,接着跳转到对应的终端服务程序,如果函数有参数,则根据ATPCS规则进行参数的传递;如只有一个参数,则用 R0 来传递,超过4个参数,超出的部分用堆栈来传递。
所以这里更加iHandle=0x100,于是根据swi中断向量表
vicControl
SUB R0, R0, #0x100
CMP R0, #0x12
LDRLO PC, [PC, R0, LSL #2]
MOVS PC, LR
vicControlFuncAdd
DCD SetmicIrqFunc ; 0
DCD ClrmicIrqFunc ; 1
DCD EnablemicIrq ; 2
DCD DisablemicIrq ; 3
DCD SetmicFiq ; 4
DCD ClrmicFiq ; 5
DCD Setsic1IrqFunc ; 6
DCD Clrsic1IrqFunc ; 7
DCD Enablesic1Irq ; 8
DCD Disablesic1Irq ; 9
DCD Setsic1Fiq ; 10
DCD Clrsic1Fiq ; 11
DCD Setsic2IrqFunc ; 12
DCD Clrsic2IrqFunc ; 13
DCD Enablesic2Irq ; 14
DCD Disablesic2Irq ; 15
DCD Setsic2Fiq ; 16
DCD Clrsic2Fiq ; 17
得知,跳转到SetmicIrqFunc 代码段执行。
4SetmicIrqFunc 代码段
SetmicIrqFunc
CMP R1, #32 ; if (通道号 >=32) return FALSE
MOVCS R0, #0
MOVCSS PC, LR
CMP R2, #4 ; if (触发类型 >=4) return FALSE
MOVCS R0, #0
MOVCSS PC, LR
CMP R3, #0 ; if (处理函数 ==0) return FALSE
MOVEQ R0, #0
MOVEQS PC, LR
MSR CPSR_c, #(NoFIQ | NoInt | SYS32Mode)
STMFD SP!, {R2, R3}
MOV R3, #1
MOV R3, R3, LSL R1
LDR R0, =MIC_ITR ; if (Enable) return FALSE
LDR R2, [R0]
ANDS R2, R2, R3
BNE SetmicIrqFunc_j
LDR R0, =VectStackSpace ; if (IRQ已经使能) return FALSE
LDR R2, [R0, R1, LSL #2]
CMP R2, #0
这里根据传递的R0-R3参数来设置中断控制寄存器。那么也就完成整个中断设置。
以上即为LPC3250中中断函数的调用情况。