类型 | 指令 | 描述 | 备注 |
---|---|---|---|
内部数据传输指令 | MOV R0 R1 |
R1 2 R0 | #0xFF:立即数:MOV R0, #0xFF |
内部数据传输指令 | MRS R0,SR |
SR 2 R0 | 读特殊寄存器: MRS R0, CRSR |
内部数据传输指令 | MSR SR R0 |
RO 2 SR | 写特殊寄存器: MSR CRSR,R0 |
存储器访问指令 | LDR Rd,[Rn ,#offset] |
从存储器Rn+offset处读取数据写至Rd | 存储加载数据到寄存器中,数据为立即数时: LDR R0,=0xFFFF ,从0Xffff地址取数; LDR R1,[R0] |
存储器访问指令 | STR Rd,[Rn,#offset] |
将Rd中的数据写入到Rn+offset的位置中 | LDR R0,=0xFFFF R0保存地址; LDR R1,=0x1234 R1保存数据; STR R1,[R0] 将R1中的值写入R0中的地址 |
堆栈指令 | PUSH |
将寄存器列表存入栈中 | 保护现场,即为将R0~R15寄存器值进行压栈; PUSH{R0~R3,R13} @将 R0~R3 和 R12 压栈 |
堆栈指令 | TMFD SP!, {reg list} |
将寄存器列表存入栈中 同Push | STMFD SP!,{R0~R3, R12} @R0~R3,R12 入栈 |
堆栈指令 | POP |
从栈中恢复寄存器列表 | 恢复现场,即为弹栈,从栈中回复寄存器列表 POP{LR} 注意堆栈模型 |
堆栈指令 | LDMFD SP!,{reg lsit} |
从栈中恢复寄存器列表 | 同上 |
跳转指令 | B |
跳转到lable | 如果跳转范围超过2KB可以制定B.W 指令以获取更大范围; B main 跳转至C函数main |
跳转指令 | BX |
间接跳转 | 跳转到Rm存放的地址处,并切换指令集 |
跳转指令 | BL |
跳转到lable并将返回地址保存在LR中 | 在跳转之前会在寄存器LR(R14)中保存PC寄存器值,意味着可以将PC值重新加载跳转至之前程序,中断的切换 |
跳转指令 | BLX |
跳转到Rm指定的地址,并将返回地址保存至LR | 示例如下 |
push {r0, r1} @保存 r0,r1
cps #0x13 @进入 SVC 模式,允许其他中断再次进去
bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
cps #0x12 @进入 IRQ 模式
pop {r0, r1}
str r0, [r1, #0X10] @中断执行完成,写 EOIR
INT_MASK,INT_DIS,INT_EN为一组,表示对对应位是否使能。
INT_TYPE ,INT_POLARITY,INT_ANY为一组,表示触发的方式,是电平还是边缘以及是否双边缘。
INT_STAT 读之可以知道对应位是否发生了中断,对应位写1表示清除中断(实际应用中要以注意中断撤掉或者被屏蔽)
三级跳转,以IRQ中断为例
15-IRQHandler:
保存完现场后执行33- bl IRQInterrupt
跳转至IRQ中断处理函数 .globl _vector_table
.section .vectors
_vector_table:
B _boot
B Undefined
B SVCHandler
B PrefetchAbortHandler
B DataAbortHandler
NOP /* Placeholder for address exception vector*/
B IRQHandler
B FIQHandler
IRQHandler: /* IRQ vector handler */
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code*/
#if FPU_HARD_FLOAT_ABI_ENABLED
vpush {d0-d7}
vpush {d16-d31}
vmrs r1, FPSCR
push {r1}
vmrs r1, FPEXC
push {r1}
#endif
#ifdef PROFILING
ldr r2, =prof_pc
subs r3, lr, #0
str r3, [r2]
#endif
bl IRQInterrupt /* IRQ vector */
#if FPU_HARD_FLOAT_ABI_ENABLED
pop {r1}
vmsr FPEXC, r1
pop {r1}
vmsr FPSCR, r1
vpop {d16-d31}
vpop {d0-d7}
#endif
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
void XScuGic_InterruptHandler(XScuGic *InstancePtr)
{
u32 InterruptID;
u32 IntIDFull;
XScuGic_VectorTableEntry *TablePtr;
IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET);
InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
if (XSCUGIC_MAX_NUM_INTR_INPUTS <= InterruptID) {
goto IntrExit;
}
TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]);
if (TablePtr != NULL) {
TablePtr->Handler(TablePtr->CallBackRef);
}
IntrExit:
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull);
}
采用单个AXI GPIO IP核双通道, PL逻辑提供两路同步逻辑翻转输入
通道 | 结论 |
---|---|
双通道 | 双通道 IP仅产生一次中断,中断状态寄存器两通道状态位都置1,在中断处理中读取之来判断通道 |
通道 | 结论 |
---|---|
单通道 | 产生一次中断,中断状态寄存器置位响应通道,在中断处理中读取IO值判断 |
采用两组AXI GPIO IP核, PL逻辑提供两路同步中断源
优先级 | 结论 | 延迟 | 描述 |
---|---|---|---|
GPIO1 > GPIO2 | ARM均可进行响应 | 时间不定(10us左右视具体情况而定) | ARM对同时来到的中断源均可响应但存在延迟,优先响应高优先级 |
GPIO1 = GPIO2 | ARM均可进行响应 | 时间不定(10us左右视具体情况而定) | ARM对同时来到的中断源均可响应但存在延迟,存在固定顺序,影响因素未知 |
GPIO1 > GPIO2 | ARM均可进行响应 |时间不定(10us左右视具体情况而定)|ARM对同时来到的中断源均可响应但存在延迟,优先响应高优先级|
|GPIO1 = GPIO2|ARM均可进行响应|时间不定(10us左右视具体情况而定)|ARM对同时来到的中断源均可响应但存在延迟,存在固定顺序,影响因素未知|