xilinx zynq 7000 GPIO ISR、IRQ、vector table 实验

本文深入探讨了Zynq7010/7020处理器中GPIO中断、中断向量和GIC(Global Interrupt Controller)之间的交互机制。中断向量表用于跳转到特定的中断服务函数,而GIC负责中断信号的管理和分发。在中断发生时,GIC根据中断号通知CPU,CPU通过中断向量表执行相应的中断处理函数。代码示例展示了如何配置GPIO中断和GIC,实现中断处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上一篇 xilinx zynq 7010/7020 中断/中断向量/GIC向量/GPIO中断

在这里插入图片描述
中断向量表和中断ISR和GIC的关系如上图所示
这里是整个中断系统的重点。

ISR表示各个中断源中断发生后,中断服务函数的实例。通过中断号作为HandlerTable的索引值跳转到具体的中断服务函数。
中断服务函数中根据外设的MASK 和状态来判断具体是哪个部分发生了中断。

GIC的输入是各个中断源的中断线,通过中断号来记录是哪个中断源发生了中断,这里是记录。
中断发生后,GIC根据配置把中断信号,给到对应的CPU,CPU接收到了中断后,由硬件进行中断跳转,跳转到VectorTable对应的中断服务函数。以GPIO为例,GIC会触发CPU 的IRQ中断,CPU就会通过VextorTABLE中IRQ中断的入口跳转到XScuGic_InterruptHandler.
所有的IRQ中断都会进入到XScuGic_InterruptHandler函数,XScuGic_InterruptHandler函数根据GIC中记录的中断号来判断,是哪个中断源发生了中断,进行软件跳转到ISR #n。这里和MCU (ARM cortex M3,M4)内核的中断有非常大的区别。
理清楚上面的关系后,就不难理解代码。代码中有多个函数的配置和关联,本质上就是上图信息流的配置。

代码如下,适配的是xilinx 官方zc702开发板 。SW13作为输入,LED DS11作为输出显示。

#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
#include <xil_printf.h>


#define INT_GPIO_KEY (14)
#define INT_GPIO_LED (8)
#define INTC_DEVICE_ID		0
#define XPS_GPIO_INT_ID			52U
#define GPIO_DEVICE_ID  	XPAR_XGPIOPS_0_DEVICE_ID
#define GPIO_BANK	XGPIOPS_BANK0  /* Bank 0 of the GPIO Device */

XGpioPs IntGpio;
XScuGic IntGIC; /* The Instance of the Interrupt Controller Driver */

/****************************************************************************/
/**
* This function is the user layer callback function for the bank 0 interrupts of
* the GPIO device. It checks if all the switches have been pressed to stop the
* interrupt processing and exit from the example.
*
* @param	CallBackRef is a pointer to the upper layer callback reference.
* @param	Status is the Interrupt status of the GPIO bank.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
	XGpioPs *Gpio = (XGpioPs *)CallBackRef;
	u32 DataRead;

	/* Push the switch button */
	DataRead = XGpioPs_ReadPin(Gpio, INT_GPIO_KEY);
	XGpioPs_WritePin(Gpio, INT_GPIO_LED, DataRead);

}

int main(void)
{
	 int Status;
	 XGpioPs_Config *ConfigPtr;
	 XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
     
	 print("GPIO Interrupt test \r\n");

    /*initial GPIO */
	 ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	 Status = XGpioPs_CfgInitialize(&IntGpio, ConfigPtr,ConfigPtr->BaseAddr);

	 if (Status != XST_SUCCESS) {
	     return XST_FAILURE;
	 }
	 
    /*config GPIO output LED */
	 XGpioPs_SetDirectionPin(&IntGpio, INT_GPIO_LED, 1);
	 XGpioPs_SetOutputEnablePin(&IntGpio, INT_GPIO_LED, 1);

	/*config Input Button*/
	 XGpioPs_SetDirectionPin(&IntGpio, INT_GPIO_KEY, 0x0);
	
    /*initial GIC */
	 IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	 if (NULL == IntcConfig) {
		return XST_FAILURE;
	 }
	 
     Status = XScuGic_CfgInitialize(&IntGIC, IntcConfig,IntcConfig->CpuBaseAddress);
	 if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	 }

	 /*config IRQ*/
	 /*
	 * Connect the interrupt controller interrupt handler to the hardware
	 * interrupt handling logic in the processor.
	 */
	 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
				&IntGIC);
     /*
	 * Connect the device driver handler that will be called when an
	 * interrupt for the device occurs, the handler defined above performs
	 * the specific interrupt processing for the device.
	 */
	 Status = XScuGic_Connect(&IntGIC, XPS_GPIO_INT_ID,
				(Xil_ExceptionHandler)XGpioPs_IntrHandler,
				(void *)&IntGpio);
	if (Status != XST_SUCCESS) {
		return Status;
	}
	
	/* Enable falling edge interrupts for all the pins in bank 0. */
	XGpioPs_SetIntrType(&IntGpio, GPIO_BANK, 0x00, 0xFFFFFFFF, 0x00);

	/* Set the handler for gpio interrupts. */
	XGpioPs_SetCallbackHandler(&IntGpio, (void *)&IntGpio, IntrHandler);


	/* Enable the GPIO interrupts of Bank 0. */
	XGpioPs_IntrEnable(&IntGpio, GPIO_BANK, (1 << INT_GPIO_KEY));


	/* Enable the interrupt for the GPIO device. */
	XScuGic_Enable(&IntGIC, XPS_GPIO_INT_ID);


	/* Enable interrupts in the Processor. */
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);				 
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值