Gpio interrupt not working in FreeRTOS but working in standlone application on xilinx

i am using xilinx zcu102 board. I am trying to run gpio interrupt example provided in BSP by xilinx on FreeRTOS, but it is not working. Same example is working fine when run as standlone application. Program is stuck at Xil_ExceptionEnableMask Function which i have commented in program .Below is attached gpio example code:

int main(void) {
	int Status;

	xil_printf("GPIO Interrupt Example Test \r\n");

	/*
	 * Run the GPIO interrupt example, specify the parameters that
	 * are generated in xparameters.h.
	 */
	Status = GpioIntrExample(&Intc, &Gpio, GPIO_DEVICE_ID,
				 GPIO_INTERRUPT_ID);

	if (Status != XST_SUCCESS) {
		xil_printf("GPIO Interrupt Example Test Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("Successfully ran GPIO Interrupt Example Test\r\n");
	return XST_SUCCESS;
}

int GpioIntrExample(XScuGic *Intc, XGpioPs *Gpio, u16 DeviceId, u16 GpioIntrId)
{
	XGpioPs_Config *ConfigPtr;
	int Status;
	int Type_of_board;

	/* Initialize the Gpio driver. */
	ConfigPtr = XGpioPs_LookupConfig(DeviceId);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}
	Type_of_board = XGetPlatform_Info();
	switch (Type_of_board) {
		case XPLAT_ZYNQ_ULTRA_MP:
			Input_Bank_Pin = 22;
			Input_Pin = 22;
			Output_Pin = 23;
			break;

		case XPLAT_ZYNQ:
			Input_Bank_Pin = 14;
			Input_Pin = 14;
			Output_Pin = 10;
			break;
#ifdef versal
		case XPLAT_VERSAL:
			/* Accessing PMC GPIO by setting field to 1 */
			Gpio->PmcGpio  =  1;
			Input_Bank_Pin =  4;
			Input_Pin      = 56;
			Output_Pin     = 52;
			break;
#endif
	}
	XGpioPs_CfgInitialize(Gpio, ConfigPtr, ConfigPtr->BaseAddr);

	/* Run a self-test on the GPIO device. */
	Status = XGpioPs_SelfTest(Gpio);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Set the direction for the specified pin to be input */
	XGpioPs_SetDirectionPin(Gpio, Input_Pin, 0x0);

	/* Set the direction for the specified pin to be output. */
	XGpioPs_SetDirectionPin(Gpio, Output_Pin, 1);
	XGpioPs_SetOutputEnablePin(Gpio, Output_Pin, 1);
	XGpioPs_WritePin(Gpio, Output_Pin, 0x0);

	/*
	 * Setup the interrupts such that interrupt processing can occur. If
	 * an error occurs then exit.
	 */
	Status = SetupInterruptSystem(Intc, Gpio, GPIO_INTERRUPT_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	xil_printf("\n\rPush Switch button to exit\n\r");
	AllButtonsPressed = FALSE;

	/*
	 * Loop forever while the button changes are handled by the interrupt
	 * level processing.
	 */
	while(AllButtonsPressed == FALSE);

	return XST_SUCCESS;
}


static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
	XGpioPs *Gpio = (XGpioPs *)CallBackRef;
	u32 DataRead;

	/* Push the switch button */
	DataRead = XGpioPs_ReadPin(Gpio, Input_Pin);
	if (DataRead != 0) {
		XGpioPs_SetDirectionPin(Gpio, Output_Pin, 1);
		XGpioPs_SetOutputEnablePin(Gpio, Output_Pin, 1);
		XGpioPs_WritePin(Gpio, Output_Pin, DataRead);
		AllButtonsPressed = TRUE;
	}
}


static int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
				u16 GpioIntrId)
{
	int Status;

	XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */

	Xil_ExceptionInit();

	/*
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}


	/*
	 * 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,
				GicInstancePtr);

	/*
	 * 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(GicInstancePtr, GpioIntrId,
				(Xil_ExceptionHandler)XGpioPs_IntrHandler,
				(void *)Gpio);
	if (Status != XST_SUCCESS) {
		return Status;
	}

	/* Enable falling edge interrupts for all the pins in GPIO bank. */
	XGpioPs_SetIntrType(Gpio, GPIO_BANK, 0x00, 0xFFFFFFFF, 0x00);

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


	/* Enable the GPIO interrupts of GPIO Bank. */
	XGpioPs_IntrEnable(Gpio, GPIO_BANK, (1 << Input_Bank_Pin));


	/* Enable the interrupt for the GPIO device. */
	XScuGic_Enable(GicInstancePtr, GpioIntrId);


	/* Enable interrupts in the Processor. */
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);  
     **/* Program stuck in above function */**
	return XST_SUCCESS;
}
 // End of Code

Same issue is persistent with all interrupt examples using xil_ExceptionEnable call. Kindly guide as i am new to this board as well FreeRTOS.

Do you configure the interrupts before starting the FreeRTOS scheduler? If so, try doing it afterwards as I think the interrupt controller may get reset as FreeRTOS starts.

…additionally wanted to make sure you have read the docs starting under the header " Interrupt vector table" on this page: https://www.freertos.org/RTOS-Xilinx-Zynq.html

i have not started scheduler in my code. Will it automatically get called?.

yes i have gone through it.

vTaskStartScheduler starts the scheduler and startup code has to invoke it.
What do you mean by stuck at Xil_ExceptionEnableMask ? Is there an assertion or a crash ? Where exactly ? Did you try to investigate the call with a debugger to see what’s going wrong ?
Did you define configASSERT macro appropriately ?
BTW as far as I can see you don’t use any FreeRTOS API call in your code. It’s just a bare metal test program, right ? Then maybe check the Xilinx forum for help.

Hint: When posting a code block please enclose it by 3 tildas ‘~~~’ or backticks ‘```’ for better readability. There is also a button </> for inline quoting. Thanks !

Thanks for the reply and editing my post .yes i know vTaskStartScheduler will start the Scheduler, but i am using a standalone application without any FreeRTOS application. when FreeRTOS is not ported,the application works fine but when FreeRTOS is ported then application is not running. Will application not run on FreeRTOS environment without running the Scheduler?? . By program stuck at xil_ExceptionEnable Mask , i meant that when i put debug prints with xil_printf then debug prints before this function call are printed but debug prints after this function call are not printed. I have checked configASSERT macro and it is correct as far as i know.

PS: Thanks for the editing guidance for the posts.

Starting the scheduler basically starts a FreeRTOS application. You know, without scheduling tasks a multi-tasing RTOS is pretty useless :wink:
As Richard pointed out when enabling interrupts and using FreeRTOS API in the ISR you’ve to ensure that all necessary resources (e.g. semaphores or queues with their handles) are properly created before enabling interrupts because an interrupt might immediately occur after enabling it.
Again, do you have a debugger attached to halt the target and check the reason of the crash and/or the call stack ? Did you verify that it’s not an assert (configASSERT) stopping execution ? Debug prints are fine but might be not sufficient for detailed debugging.

I don’t understand the question because you say it is not working when FreeRTOS is ported but you are not starting the scheduler. Does that mean just building the FreeRTOS code in your otherwise bare metal application is enough to stop it working? If so, do you make any FreeRTOS API calls? As per the FAQ, be aware that FreeRTOS will mask interrupts between making an API call and starting the scheduler.

There is an example of setting up interrupts for FreeRTOS on ZU+ at:

github . com/Xilinx/embeddedsw/blob/master/ThirdParty/bsp/freertos10_xilinx/examples/freertos_intr_example.c