对ZYNQ设备GPIO中断函数的详解 (一)
简言:同别的文章一样,各大厂商,正点原子,米联客,威视瑞等等,都对GPIO中断有了很实际应用的讲解。但是却没有找到类似与AXI时序那样,再进一步深入的讲解。也许是因为这个没有那么重要。但是对我来说,我时长认为,真正有价值的,不在于广度而在于深度,不在于复杂,而在于细节。同时我还是相信,别希望有很多人会这样。于是便有意借此机会,研究GPIO中断函数相关。本文是讲解PL发送中断,PS端接收的情况。当然,情形对应的是最简单的按键触发LED亮灭。
/*
1 GPIO初始化
*/
//1.1查找GPIO设备
XGpioPs_LookupConfig();
//1.2初始化GPIO设备
XGpioPs_CfgInitialize();
//1.3将中断对应的GPIO设置为输入
XGpioPs_SetDirectionPin(Gpio, Input_Pin, 0x0);
/*
2 GPIO 中断初始化
*/
//2.0.兼容性
Xil_ExceptionInit();
//2.1.查找GIC设备
XScuGic_LookupConfig();
//2.2.初始化GIC设备
XScuGic_CfgInitialize();
//2.3.将中断处理handler与处理器硬件中断处理逻辑相关联
Xil_ExceptionRegisterHandler();
//2.4.连接设备驱动程序处理程序,该设备驱动程序处理程序在设备中断
//发生时将被调用,上面定义的处理程序对设备执行特定的中断处理。
XScuGic_Connect();
//2.5.使能bank 0中所有引脚的下降沿中断
XGpioPs_SetIntrType();
//2.6.设置gpio中断的处理程序。其中IntrHandler为中断处理函数
XGpioPs_SetCallbackHandler();
//2.7.启用GPIO设备的中断。
XScuGic_Enable();
//2.8.在处理器中启用中断。
Xil_ExceptionEnableMask();
/*
3.对于输出GPIO,要使能输出,并设定输出的值
*/
//3.1使能输出
XGpioPs_SetOutputEnablePin();
//设定输出的值
XGpioPs_WritePin();
上面是官方历程“xgpiops_intr_example.c”工程文件中提炼出的整个PL端GPIO初始化,中断初始化所需要调用的函数,以及流程。下面我们依次进行说明。
1. GPIO初始化相关函数
1.1 函数XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId)
1.1.1XGpioPs_Config结构
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Register base address */
} XGpioPs_Config;
同时为了方便,我同时说,DeviceId是唯一的设备ID为2个字节,u32BaseAddr是设备的基地址为4个字节。即该结构体一共是6个字节。
1.1.2 XPAR_XGPIOPS_NUM_INSTANCES
#define XPAR_XGPIOPS_NUM_INSTANCES 1 这个是该参量的宏定义
1.1.3 XGpioPs_ConfigTable变量
XGpioPs_ConfigTable变量是1.1.1中所述XGpioPs_Config类型的。
XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES] =
{
{
XPAR_PS7_GPIO_0_DEVICE_ID,
XPAR_PS7_GPIO_0_BASEADDR
}
};
其中XPAR_XGPIOPS_NUM_INSTANCES是在1.1.2节中定义,值为1。
其中我们XGpioPs_Config结构体中
1.1.4 XPAR_PS7_GPIO_0_DEVICE_ID
#define XPAR_PS7_GPIO_0_DEVICE_ID 0
默认是第一个ID 0,这个在对于其他设备来说,