Using Interrupts in Embedded Systems

October 16, 2015


Taking the Xilinx Zedboard as an example, we need to do a few things to enable interrupts through the GIC:

  1. XScuGic_CfgInitialize(). The device ID should be defined in "xparameters.h".

  2. Xil_ExceptionInit(). This is to initialize the exception vector table.

  3. Xil_ExceptionRegisterHandler(). We can register the XScuGic_InterruptHandler as we like.

  4. Xil_ExceptionEnable(). We need to enable interrupts on the Zedboard.

From here, the GIC is ready to call ISRs for whichever device sets their interrupt flag. We need to figure out the interrupt ID of the accelerator and register that to the GIC. To enable interrupts for a device:

  1. Configure the device for interrupts. This might involve setting a bit to allow interrupts in the device. Most Xilinx 3rd-party libraries have functions written for this.

  2. Register an interrupt handler to the GIC. After this, the GIC should know what ISR to call when the interrupt has fired. This is done with XScuGic_Connect().

  3. Enable interrupts for that specific device using XScuGic_Enable(). The second parameters for XScuGic_Connect() and XScuGic_Enable() must match.

From there you should be good to go. If you don't register a handler to the GIC for a device that has interrupts enabled, then it will call the default handler, StubHandler(), found in "xscugic.c", which will do nothing except increment the UnhandledInterrupts variable in the

XScuGic data structure. If that structure has not been properly initialized, the program will probably go into an infinite loop.


Sometimes we want to build FreeRTOS instead of bare-metal. Xilinx SDK projects define the interrupt vector table as part of the BSP. This makes it difficult to install the FreeRTOS handlers using the methods described on the page about running FreeRTOS on ARM Cortex-A embedded processors. Therefore, to use interrupts in FreeRTOS, in most cases we have to define its own interrupt vector table in "FreeRTOS_asm_vectors.S". The vector table defined by the BSP is replaced by the freertos_vector_table defined in "FreeRTOS_asm_vectors.S" at run time by calling the function vPortInstallFreeRTOSVectorTable(). This function is usually directly called in "main.c" during initialization.