I am currently testing interrupts using FreeRTOS with Xilinx’s Vitis. I have created an interrupt handler and it should execute when triggered. However, once the handler is activated, all tasks are executed once and do not switch afterwards. It seems like they are hanging or crashing. I haven’t been able to find the reason. Additionally, if the interrupt configuration is set before the scheduler starts, the interrupt handler does not function. I’m sharing my code with you. Please check it out.
Code for setting up the interrupt handler :
void GpioHandler(void *CallbackRef)
{
XGpioPs *GpioInstancePtr = (XGpioPs *)CallbackRef;
TaskStatus_t xTaskDetails;
Int_val = XGpioPs_IntrGetStatusPin(GpioInstancePtr, PS_KEY_MIO);
XGpioPs_IntrClearPin(GpioInstancePtr, PS_KEY_MIO);
if (Int_val)
{
XGpioPs_WritePin(&GPIO_PTR, PS_LED_MIO, PsLedVal);
PsLedVal = ~PsLedVal;
xil_printf("LED run\r\n");
debugTaskInfo();
}
}
void PsGpioSetup()
{
int Status ;
XGpioPs_Config *GpioCfg ;
GpioCfg = XGpioPs_LookupConfig(MIO_0_ID) ;
Status = XGpioPs_CfgInitialize(&GPIO_PTR, GpioCfg, GpioCfg->BaseAddr);
if (Status != XST_SUCCESS)
{
xil_printf("PS GPIO Configuration failed!\r\n") ;
}
//set MIO 0 as output
XGpioPs_SetDirectionPin(&GPIO_PTR, PS_LED_MIO, GPIO_OUTPUT) ;
//enable MIO 0 output
XGpioPs_SetOutputEnablePin(&GPIO_PTR, PS_LED_MIO, GPIO_OUTPUT) ;
XGpioPs_SetDirectionPin(&GPIO_PTR, PS_KEY_MIO, GPIO_INPUT) ;
XGpioPs_SetIntrTypePin(&GPIO_PTR, PS_KEY_MIO, XGPIOPS_IRQ_TYPE_EDGE_RISING);
XGpioPs_IntrClearPin(&GPIO_PTR, PS_KEY_MIO);
XGpioPs_IntrEnablePin(&GPIO_PTR, PS_KEY_MIO);
Status = IntrInitFuntion(&INTCInst, MIO_0_ID, &GPIO_PTR);
if (Status != XST_SUCCESS)
{
xil_printf("PS GPIO Configuration failed!\r\n") ;
}
}
int IntrInitFuntion(XScuGic *InstancePtr, u16 DeviceId, XGpioPs *GpioInstancePtr)
{
XScuGic_Config *IntcConfig;
int Status ;
portDISABLE_INTERRUPTS();
/* Obtain the configuration of the GIC. */
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
/* Install a default handler for each GIC interrupt. */
Status = XScuGic_CfgInitialize(InstancePtr, IntcConfig, IntcConfig->CpuBaseAddress) ;
if (Status != XST_SUCCESS)
{
return XST_FAILURE ;
}
XScuGic_SetPriorityTriggerType(InstancePtr, RX_INTR_ID, configMAX_API_CALL_INTERRUPT_PRIORITY , XGPIOPS_IRQ_TYPE_LEVEL_HIGH);
Status = XScuGic_Connect(InstancePtr, RX_INTR_ID,
(Xil_ExceptionHandler)GpioHandler, (void *)GpioInstancePtr) ;
if (Status != XST_SUCCESS)
{
return XST_FAILURE ;
}
XScuGic_Enable(InstancePtr, RX_INTR_ID) ;
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
InstancePtr);
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
return XST_SUCCESS ;
}
- Task configuration and scheduler start.
- Each of the tasks.
int main( void )
{
xil_printf( "Hello from Freertos example main\r\n" );
xTaskCreate(CanFdTask, "CanFdTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, &xCanFdTask);
xTaskCreate(UartTask, "UartTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, &xUartTask);
xTaskCreate(LedTask, "LedTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, &xLedTask);
xTimer = xTimerCreate("Timer", pdMS_TO_TICKS(DELAY_1_MS), pdTRUE, (void *) TIMER_ID, vTimerCallback);
configASSERT( xTimer );
xTimerStart( xTimer, 0);
/* Start the tasks and timer running. */
vTaskStartScheduler();
for( ;; );
}
static void CanFdTask( void *pvParameters )
{
xil_printf( "CanFdTask start\r\n" );
APP_Initialize();
APP_Tasks(0);
while (true)
{
vTaskDelay(xMS);
}
}
/*-----------------------------------------------------------*/
static void LedTask( void *pvParameters )
{
PsGpioSetup();
xil_printf( "LED On/Off task start \r\n" );
while (true)
{
vTaskDelay( xMS );
}
}
static void UartTask( void *pvParameters )
{
xil_printf( "Uart task start \r\n" );
xil_printf( "1: Initial CANFD 2: Start CANFD 3: Result CANFD (q):stop \r\n" );
while (true)
{
ReceivData = inbyte();
switch (ReceivData)
{ ...}
vTaskDelay( xMS );
}
}