intmain(void){int Status;/*
* Setup an assert call back to get some info if we assert.
*/Xil_AssertSetCallback(AssertPrint);xil_printf("GIC Example Test\r\n");/*
* Run the Gic example , specify the Device ID generated in xparameters.h
*/
Status =ScuGicExample(INTC_DEVICE_ID);if(Status != XST_SUCCESS){xil_printf("GIC Example Test Failed\r\n");return XST_FAILURE;}xil_printf("Successfully ran GIC Example Test\r\n");return XST_SUCCESS;}
示例代码的主体在于ScuGicExample的函数体。其具体实现如下:
/*****************************************************************************//**
*
* This function is an example of how to use the interrupt controller driver
* (XScuGic) and the hardware device. This function is designed to
* work without any hardware devices to cause interrupts. It may not return
* if the interrupt controller is not properly connected to the processor in
* either software or hardware.
*
* This function relies on the fact that the interrupt controller hardware
* has come out of the reset state such that it will allow interrupts to be
* simulated by the software.
*
* @param DeviceId is Device ID of the Interrupt Controller Device,
* typically XPAR_<INTC_instance>_DEVICE_ID value from
* xparameters.h
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note None.
*
******************************************************************************/intScuGicExample(u16 DeviceId){int Status;#ifdefined(VERSAL_NET)
u32 CoreId, ClusterId;#endif/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
GicConfig =XScuGic_LookupConfig(DeviceId);if(NULL== GicConfig){return XST_FAILURE;}
Status =XScuGic_CfgInitialize(&InterruptController, GicConfig,
GicConfig->CpuBaseAddress);if(Status != XST_SUCCESS){return XST_FAILURE;}/*
* Perform a self-test to ensure that the hardware was built
* correctly
*/
Status =XScuGic_SelfTest(&InterruptController);if(Status != XST_SUCCESS){return XST_FAILURE;}/*
* Setup the Interrupt System
*/
Status =SetUpInterruptSystem(&InterruptController);if(Status != XST_SUCCESS){return XST_FAILURE;}/*
* Connect a device driver handler that will be called when an
* interrupt for the device occurs, the device driver handler performs
* the specific interrupt processing for the device
*/
Status =XScuGic_Connect(&InterruptController, INTC_DEVICE_INT_ID,(Xil_ExceptionHandler)DeviceDriverHandler,(void*)&InterruptController);if(Status != XST_SUCCESS){return XST_FAILURE;}/*
* Enable the interrupt for the device and then cause (simulate) an
* interrupt so the handlers will be called
*/XScuGic_Enable(&InterruptController, INTC_DEVICE_INT_ID);/*
* Simulate the Interrupt
*/#ifdefined(VERSAL_NET)
CoreId =XGetCoreId();
ClusterId =XGetClusterId();#ifdefined(ARMR52)
CoreId =(1<< CoreId);#endif
Status =XScuGic_SoftwareIntr(&InterruptController,
INTC_DEVICE_INT_ID,((ClusterId << XSCUGIC_CLUSTERID_SHIFT )| CoreId));#else
Status =XScuGic_SoftwareIntr(&InterruptController,
INTC_DEVICE_INT_ID,
XSCUGIC_SPI_CPU_MASK);#endifif(Status != XST_SUCCESS){return XST_FAILURE;}/*
* Wait for the interrupt to be processed, if the interrupt does not
* occur return failure after timeout.
*/
Status =Xil_WaitForEventSet(XSCUGIC_SW_TIMEOUT_VAL,1,&InterruptProcessed);if(Status != XST_SUCCESS){return XST_FAILURE;}return XST_SUCCESS;}
结合上述两段主要代码,我们就可以基本梳理出SGI的基本使用流程与方法。
// DeviceId定义(映射)#defineINTC_DEVICE_IDXPAR_SCUGIC_0_DEVICE_ID// GIC对象创建
XScuGic InterruptController;// GIC配置对象创建static XScuGic_Config *GicConfig;// 绑定Device
GicConfig =XScuGic_LookupConfig(DeviceId);// 初始化SGI
Status =XScuGic_CfgInitialize(&InterruptController,
GicConfig,GicConfig->CpuBaseAddress);// 寄存器句柄创建并使能Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler) XScuGic_InterruptHandler,
InterruptController);Xil_ExceptionEnable();// 连接SGI到设备
Status =XScuGic_Connect(&InterruptController, INTC_DEVICE_INT_ID,(Xil_ExceptionHandler)DeviceDriverHandler,(void*)&InterruptController);// 使能SGIXScuGic_Enable(&InterruptController, INTC_DEVICE_INT_ID);// 等待中断返回结果,若超时返回ERROR
Status =Xil_WaitForEventSet(XSCUGIC_SW_TIMEOUT_VAL,1,&InterruptProcessed);