zynq7000 中断原理分析及IO中断解析

Zynq 7000 中断分析

文章目录

  • Zynq 7000 中断分析
    • GIC及中断机理
      • Crotex-A9常用汇编指令
      • Zynq中断控制
    • GPIO
      • 中断控制
        • 单IP双通道
        • 单IP多位
        • 双IP中断源

GIC及中断机理

Crotex-A9常用汇编指令

类型 指令 描述 备注
内部数据传输指令 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,=0xFFFFR0保存地址; 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

Zynq中断控制

zynq7000 中断原理分析及IO中断解析_第1张图片

INT_MASK,INT_DIS,INT_EN为一组,表示对对应位是否使能。

INT_TYPE ,INT_POLARITY,INT_ANY为一组,表示触发的方式,是电平还是边缘以及是否双边缘。

INT_STAT 读之可以知道对应位是否发生了中断,对应位写1表示清除中断(实际应用中要以注意中断撤掉或者被屏蔽)

三级跳转,以IRQ中断为例

  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 */
  1. 进入IRQ中断处理函数,此函数不是自定义的中断处理函数,而是GIC(中断控制器)提前注册的响应中断类型的函数,作用在于判断哪个中断号发生了IRQ中断,用以找到相应的用户处理函数
  2. 跳转至用户处理函数执行之
 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);
 }

GPIO

中断控制

单IP双通道

采用单个AXI GPIO IP核双通道, PL逻辑提供两路同步逻辑翻转输入

zynq7000 中断原理分析及IO中断解析_第2张图片

zynq7000 中断原理分析及IO中断解析_第3张图片

通道 结论
双通道 双通道 IP仅产生一次中断,中断状态寄存器两通道状态位都置1,在中断处理中读取之来判断通道

单IP多位

zynq7000 中断原理分析及IO中断解析_第4张图片

zynq7000 中断原理分析及IO中断解析_第5张图片

通道 结论
单通道 产生一次中断,中断状态寄存器置位响应通道,在中断处理中读取IO值判断

双IP中断源

采用两组AXI GPIO IP核, PL逻辑提供两路同步中断源

zynq7000 中断原理分析及IO中断解析_第6张图片

zynq7000 中断原理分析及IO中断解析_第7张图片

优先级 结论 延迟 描述
GPIO1 > GPIO2 ARM均可进行响应 时间不定(10us左右视具体情况而定) ARM对同时来到的中断源均可响应但存在延迟,优先响应高优先级
GPIO1 = GPIO2 ARM均可进行响应 时间不定(10us左右视具体情况而定) ARM对同时来到的中断源均可响应但存在延迟,存在固定顺序,影响因素未知

GPIO1 > GPIO2 | ARM均可进行响应 |时间不定(10us左右视具体情况而定)|ARM对同时来到的中断源均可响应但存在延迟,优先响应高优先级|
|GPIO1 = GPIO2|ARM均可进行响应|时间不定(10us左右视具体情况而定)|ARM对同时来到的中断源均可响应但存在延迟,存在固定顺序,影响因素未知|

你可能感兴趣的:(FPGA-ZYNQ,zynq)