Hi everyone,
I’m working with Zynq7020 (ZC702 Board). I created a Vivado project where i generate interrupts from PL to PS. The following image shows that two debounced pushbuttons are connected to the line IRQ_F2P of Zynq7 Processing System.
I generated the bitstream, and created the platform in VITIS IDE 2024.2
Firstly I worked with a BAREMETAL platform, where I demonstrated that interrupts work. (So I figured out that the problem is not hardware!). The two interrupts line have the ID 61 and 62 respectively.
Then I generated a FREERTOS platform, but Interrupt doesn’t work anymore!
This is my code (to simplify, I’m only using interrupt from just one pushbutton).
/* ============================================================
* main.c — FreeRTOS + AXI GPIO interrupt — ZC702
* ============================================================ */
#include "FreeRTOS.h"
#include "task.h"
#include "xgpio.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "portmacro.h"
#include "xstatus.h"
#include "xil_exception.h"
#include "xil_types.h"
#define LED_BASE_ADDR XPAR_LED_19_BASEADDR
#define BTN1_BASE_ADDR XPAR_BUTTON_1_BASEADDR
#define BTN_1_INT_ID XPS_FPGA0_INT_ID //61
#define BTN_INT_MASK XGPIO_IR_CH1_MASK
#define GPIO_CHANNEL 1
XGpio LED_Inst;
XGpio BTN1_Inst;
static TaskHandle_t TaskLed = NULL;
static TaskHandle_t TaskHand = NULL;
static TaskHandle_t xHandle = NULL;
static void Task_Led (void *pvParameters);
static void Task_HAND (void *pvParameters);
static void BTN1_ISR (void *CallBackRef);
static void BTN1_Init (void);
//pushbutton 1 ISR
static void BTN1_ISR(void *CallBackRef)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
XGpio *GpioPtr = (XGpio *)CallBackRef;
XGpio_InterruptClear(GpioPtr, BTN_INT_MASK);
if (xHandle != NULL)
vTaskNotifyGiveFromISR(xHandle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
//pushbutton 1 initializiation
static void BTN1_Init(void)
{
XGpio_SetDataDirection(&BTN1_Inst, GPIO_CHANNEL, 0xFF);
XGpio_InterruptEnable(&BTN1_Inst, BTN_INT_MASK);
XGpio_InterruptGlobalEnable(&BTN1_Inst);
xPortInstallInterruptHandler(BTN_1_INT_ID,
(Xil_ExceptionHandler)BTN1_ISR,
(void *)&BTN1_Inst);
vPortEnableInterrupt(BTN_1_INT_ID);
}
int main(void)
{
int status;
status = XGpio_Initialize(&LED_Inst, LED_BASE_ADDR);
if (status != XST_SUCCESS) { xil_printf("LED INIT FAILED\n\r"); return XST_FAILURE; }
XGpio_SetDataDirection(&LED_Inst, GPIO_CHANNEL, 0x00);
xil_printf("LED INIT OK\n\r");
status = XGpio_Initialize(&BTN1_Inst, BTN1_BASE_ADDR);
if (status != XST_SUCCESS) { xil_printf("BTN1 INIT FAILED\n\r"); return XST_FAILURE; }
xil_printf("BTN1 INIT OK\n\r");
xTaskCreate(Task_Led, "Led", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &TaskLed);
xTaskCreate(Task_HAND, "HAND", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY + 2, &TaskHand);
vTaskStartScheduler();
for (;;);
return 0;
}
// TASK LED
static void Task_Led(void *pvParameters)
{
const TickType_t x1second = pdMS_TO_TICKS(1000);
uint8_t ledState = 0;
for (;;) {
ledState = (ledState == 0) ? 0x7F : 0x00;
XGpio_DiscreteWrite(&LED_Inst, GPIO_CHANNEL, ledState);
vTaskDelay(x1second);
}
}
// TASK HANDLER
static void Task_HAND(void *pvParameters)
{
xHandle = xTaskGetCurrentTaskHandle();
BTN1_Init();
xil_printf("Ready!, push BTN1\n\r");
for (;;) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
xil_printf("BTN1 pushed!\n\r");
}
}
VITIS 2024.2 IDE has the following parameters:
XPAR_XILTIMER_ENABLED = 1
SDT = 1
Moreover, I made another trying, where I handle an interrupt generated from the TTC 0, (using xPortInstallInterruptHandler) and it works.
But the xPortInstallInterruptHandler doesn’t work with interrupt from PL!!!
PS: before trying this code, I tried to use the function “XScuGic_Connect”, but it doesn’t work witth FREERTOS because the operating system itself initiliases the GIC.
Thank you in advance!
