赞
踩
目录
Zynq 中的中断可以分为以下几种类型:
软件中断(Software Generated Interrupt, SGI):由软件触发,通常用于CPU之间的通信。
私有外设中断(Private Peripheral Interrupt, PPI):与每个CPU相关的中断,如定时器和看门狗。
共享外设中断(Shared Peripheral Interrupt, SPI):由多个设备共享,可以被路由到任何一个CPU。
中断控制器(GIC)是Zynq中管理中断的核心组件,负责中断的使能、屏蔽、优先级设置以及将中断信号发送到CPU1。
本文展示是一个中断处理示例,记录如何在PS(处理系统)和PL(可编程逻辑)之间使用GPIO(通用输入输出)和中断。
系统中断由多个系统元素生成,并通过GIC代理(GICPx_IRQ 寄存器)广播到GICs、PMU以及PL中的输出信号。
我们重点关注PL中的输出信号:
UG1085: System Interrupts
Datasheet 中的描述的两组中断寄存器,对于到 Zynq 配置页面示意图如下:
如果查看 "xparameters.h" 文件,可以看到 IRQ 对应的中断号:
//AXI GPIO 中断号 121
#define AXI_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR
代码的主要功能包括:
- #include "stdio.h"
- #include "xparameters.h"
- #include "xgpiops.h"
- #include "xgpio.h"
- #include "sleep.h"
- #include "xil_exception.h"
- #include "xscugic.h"
-
- #define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
- #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
- #define AXI_GPIO_DEVICE_ID XPAR_GPIO_0_DEVICE_ID
-
- //AXI GPIO 中断号 121
- #define AXI_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR
- //AXI GPIO 通道
- #define GPIO_CHANNEL1 1
-
- #define MIO7_LED 7
- #define MIO36_KEY 36
-
- static void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpio *AXI_Gpio,
- u16 AXI_GpioIntrId);
- static void IntrHandler();
-
- XGpioPs Gpio; /* The driver instance for GPIO Device. */
- XScuGic Intc; /* The Instance of the Interrupt Controller Driver */
- XGpio AXI_Gpio; /* The Instance of the GPIO Driver */
-
- static XGpioPs_Config *ConfigPtr;
- static XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
-
- int main() {
-
- u32 keyval;
-
- printf("AXI GPIO INTERRUPT TEST!\n\r");
-
- //由 ID 查找 PS 端器件,并初始化
- ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
- XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
- //PS 端 GPIO 方向设置, 0 - Input, 1 - Output
- XGpioPs_SetDirectionPin(&Gpio, MIO7_LED, 1);
- XGpioPs_SetDirectionPin(&Gpio, MIO36_KEY, 0);
- //PS 端设置输出使能,0 - Disable, 1 - Enable
- XGpioPs_SetOutputEnablePin(&Gpio, MIO7_LED, 1);
-
- //由 ID 查找 PL 端器件,并初始化
- XGpio_Initialize(&AXI_Gpio, AXI_GPIO_DEVICE_ID);
- //PL 端 GPIO 方向设置, 0 - Output, 1 - Input
- XGpio_SetDataDirection(&AXI_Gpio, GPIO_CHANNEL1, 0x00000001);
-
- //设置中断系统
- SetupInterruptSystem(&Intc, &AXI_Gpio, AXI_GPIO_INTERRUPT_ID);
-
- while(1){
- keyval = XGpioPs_ReadPin(&Gpio, MIO36_KEY);
- XGpioPs_WritePin(&Gpio, MIO7_LED, ~keyval);
- }
-
- return 0;
- }
-
- static void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpio *AXI_Gpio,
- u16 AXI_GpioIntrId)
- {
- //根据GIC器件ID,查找器件的配置信息,并初始化
- IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
- XScuGic_CfgInitialize(GicInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress);
-
- //初始化ARM处理器异常句柄
- Xil_ExceptionInit();
- //注册IRQ异常处理程序
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
- (Xil_ExceptionHandler)XScuGic_InterruptHandler,
- GicInstancePtr);
- //使能处理器中断
- Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
-
- //关联中断处理函数
- XScuGic_Connect(GicInstancePtr, AXI_GpioIntrId,
- (Xil_ExceptionHandler)IntrHandler,
- (void *)AXI_Gpio);
- //使能GIC器件中断
- XScuGic_Enable(GicInstancePtr, AXI_GpioIntrId);
-
- //0xA0:中断源的优先级, 0x01:中断类型为高电平有效,电平敏感类型
- XScuGic_SetPriorityTriggerType(GicInstancePtr, AXI_GpioIntrId, 0xA0, 0x01);
-
- //全局中断使能
- XGpio_InterruptGlobalEnable(AXI_Gpio);
- //通道中的信号对应的中断使能
- XGpio_InterruptEnable(AXI_Gpio, 0x00000001);
- }
-
- void IntrHandler() {
- if (XGpio_DiscreteRead(&AXI_Gpio, GPIO_CHANNEL1) == 0x00000000){
- printf("AXI interrupt detected!\n\r");
- }
- XGpio_InterruptClear(&AXI_Gpio, 0x00000001);
- }

为了直观地理解代码的结构和功能,参照图片进行理解:
在本文中,我们探讨了Zynq平台上中断的概念和分类,包括软件中断、私有外设中断和共享外设中断。我们还介绍了中断控制器(GIC)的作用,它是中断管理的核心。通过一个实际的示例,我们展示了如何在处理系统(PS)和可编程逻辑(PL)之间使用通用输入输出(GPIO)来处理中断。示例代码包括初始化GPIO设备、设置中断系统和定义中断处理函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。