Priorities with Queue and Semaphore from ISR

Sorry for answering late.
@aggarg the vTaskDelay() in vTask_Video_DMA_App is just for debugging, I made many versions adding vTaskDelay() in the tasks just to understand what is going on here. I attached the compete code at the bottom of the message

Yes, I did it , but nothing changed , all tasks work perfectly as long as I don’t use vTaskDelay()

In debugging mode, I noticed that:

  • If I use the all tasks without vTaskDelay , everything work well, but FreeRTOS_Tick_Handler() is not called, but FreeRTOS_SWI_Handler → vTaskSwitchContext() is called .
  • If I don’t create the task vTask_Video_DMA_App, The FreeRTOS_Tick_Handler() is called only if i use vTaskDelay().
  • If I use VDMA interruptions and vTaskDelay() , The FreeRTOS_Tick_Handler() is not called. but FreeRTOS_SWI_Handler → vTaskSwitchContext() is called, and vTask_Video_DMA_App() is called also.

I am confused, it is not supposed that The FreeRTOS_Tick_Handler() has to be called ? even if vTaslDelay is not used?

I added FreeRTOS_SetupTickInterrupt() in the SetupIntrSystem_WR_RD() function just in case, but nothing changed

Here is the code :


int main( void )
{

	SemVDMARd = xSemaphoreCreateBinary(); // Declared as Global variable
	SemVDMAWr = xSemaphoreCreateBinary(); // Declared as Global variable


	if(xTaskCreate( 	prvTxTask, ( const char * ) "Tx", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &xTxTask ) != pdPASS)
	{
		xil_printf("Tx Task was not created\r\n");
		for(;;);
	}

	if(xTaskCreate( prvRxTask, ( const char * ) "GB", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, &xRxTask ) != pdPASS)
	{
		xil_printf("Rx Task was not created\r\n");
		for(;;);

	}
	
	if( xTaskCreate( vTask_Video_DMA_App, ( const char * ) "VDMA", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 3, &xHandler_VDMA ) != pdPASS )
	{
		xil_printf("VDMA Task was not created\r\n");
		for(;;);
	}
	
	xQueue = xQueueCreate( 	4,sizeof( HWstring ) );

	configASSERT( xQueue );

	vTaskStartScheduler();
	for( ;; );
}


static void prvTxTask( void *pvParameters )
{

	for( ;; )
	{
		TxTaskEnterCounter++;
		vTaskDelay(pdMS_TO_TICKS(500));

		if(xQueueSend( xQueue, HWstring, 0L )){
			TxTaskSendStringCounter++;
		}
		TxTaskExitCounter++;
	}
}

static void prvRxTask( void *pvParameters )
{
	char Recdstring[15] = "";
	const TickType_t x1second = pdMS_TO_TICKS( DELAY_1_SECOND );

	//xil_printf("Rx Task started\r\n");
	for( ;; )
	{	RxTaskEnterCounter++;
		Tick_Cnt_dbg = xTaskGetTickCount();
		if(xQueueReceive( xQueue,	Recdstring,  portMAX_DELAY))//portMAX_DELAY
		{
			RxTaskReceivedStringCounter++;
		}
		RxTaskExitCounter++;
	}
}

The VDMA code and the interruption config ( as suggested in zynq-7020-interrupts-under-freertos :

void vTask_Video_DMA_App(void *args){
	int status;
	int Index;
	u32 Addr;

	XAxiVdma myVDMA;
	ptr_myVDMA = &myVDMA;
	XAxiVdma_Config *config = XAxiVdma_LookupConfig(XPAR_AXIVDMA_0_DEVICE_ID);
	XAxiVdma_DmaSetup ReadCfg;
	XAxiVdma_DmaSetup WriteCfg;

	uint32_t VDMA_TaskEnterCounter = 0;
    uint32_t VDMA_TookSmphr = 0;
	uint32_t VDMA_TaskExitCounter = 0;

	xil_printf("Task VDMA Started\r\n");


	if(SemVDMARd==NULL){
		xil_printf("Could not create semaphore SemVDMARd\n");
		for(;;);
	}

	if(SemVDMAWr==NULL){
		xil_printf("Could not create semaphore SemVDMAWr\n");
		for(;;);
		}

	status = XAxiVdma_CfgInitialize(&myVDMA, config, config->BaseAddress);
    if(status != XST_SUCCESS){
    	xil_printf("DMA Initialization failed");
    	for(;;);
    }

    status = XAxiVdma_SetFrmStore(&myVDMA, myVDMA.MaxNumFrames, XAXIVDMA_WRITE);
	if (status != XST_SUCCESS) {

		xil_printf(
		    "Setting Frame Store Number Failed in Write Channel"
							" %d\r\n", status);

		for(;;);
	}

	status = XAxiVdma_SetFrmStore(&myVDMA, myVDMA.MaxNumFrames, XAXIVDMA_READ);
	if (status != XST_SUCCESS) {

		xil_printf(
		    "Setting Frame Store Number Failed in Read Channel"
							" %d\r\n", status);

		for(;;);
	}

	// READ CHANNEL CONFIG
    ReadCfg.VertSizeInput = VSize;
    ReadCfg.HoriSizeInput = HSize*Bytes_Per_Data;
    ReadCfg.Stride = HSize*Bytes_Per_Data;
    ReadCfg.FrameDelay = 0;
    ReadCfg.EnableCircularBuf = 1;
    ReadCfg.EnableSync = 1;
    ReadCfg.PointNum = 0;
    ReadCfg.EnableFrameCounter = 0;
    ReadCfg.FixedFrameStoreAddr = 0;
    ReadCfg.GenLockRepeat = 0;
    status = XAxiVdma_DmaConfig(&myVDMA, XAXIVDMA_READ, &ReadCfg);
    if (status != XST_SUCCESS) {
    	xil_printf("Read channel config failed %d\r\n", status);
    	for(;;);
    }
    Addr = (u32)&(Buffer[0]);
    for(Index = 0; Index < myVDMA.MaxNumFrames; Index++) {
		ReadCfg.FrameStoreStartAddr[Index] = Addr;
		Addr +=  FrameSize;
	}

	status = XAxiVdma_DmaSetBufferAddr(&myVDMA, XAXIVDMA_READ,ReadCfg.FrameStoreStartAddr);
	if (status != XST_SUCCESS) {
		xil_printf("Read channel set buffer address failed %d\r\n", status);
		for(;;);
	}
	XAxiVdma_IntrEnable(&myVDMA, XAXIVDMA_IXR_COMPLETION_MASK, XAXIVDMA_READ);


    WriteCfg.VertSizeInput = VSize;
    WriteCfg.HoriSizeInput = HSize*Bytes_Per_Data;
    WriteCfg.Stride = HSize*Bytes_Per_Data;
    WriteCfg.FrameDelay = 0;
    WriteCfg.EnableCircularBuf = 1;
    WriteCfg.EnableSync = 1;
    WriteCfg.PointNum = 0;
    WriteCfg.EnableFrameCounter = 0;
    WriteCfg.FixedFrameStoreAddr = 0;
    WriteCfg.GenLockRepeat = 0;
    status = XAxiVdma_DmaConfig(&myVDMA, XAXIVDMA_WRITE, &WriteCfg);
    if (status != XST_SUCCESS) {
    	xil_printf("Write channel config failed %d\r\n", status);
    	for(;;);
    }

    Addr = (u32)&(Buffer[0]);
    for(Index = 0; Index < myVDMA.MaxNumFrames; Index++) {
    	WriteCfg.FrameStoreStartAddr[Index] = Addr;
		Addr +=  FrameSize;
	}

	status = XAxiVdma_DmaSetBufferAddr(&myVDMA, XAXIVDMA_WRITE,WriteCfg.FrameStoreStartAddr);
	if (status != XST_SUCCESS) {
		xil_printf("write channel set buffer address failed %d\r\n", status);
		for(;;);
	}

	XAxiVdma_IntrEnable(&myVDMA, XAXIVDMA_IXR_COMPLETION_MASK, XAXIVDMA_WRITE);

	memset((void *)Buffer, 0,FrameSize);
	Xil_DCacheFlush();
	//Xil_DCacheFlushRange(WriteFrameAddr, FRAME_HORIZONTAL_LEN * FRAME_VERTICAL_LEN * WriteCount);


	status = SetupIntrSystem_WR_RD(&myVDMA, WRITE_INTR_ID, READ_INTR_ID);


	if (status != XST_SUCCESS) {

		xil_printf(
		    "Setup interrupt system failed %d\r\n", status);

		for(;;);
	}

	status = XAxiVdma_DmaStart(&myVDMA, XAXIVDMA_WRITE);
	if (status != XST_SUCCESS) {
		xil_printf("Start Write transfer failed %d\r\n", status);

		for(;;);
	}
	status = XAxiVdma_DmaStart(&myVDMA,XAXIVDMA_READ);
	if (status != XST_SUCCESS) {
		if(status == XST_VDMA_MISMATCH_ERROR) xil_printf("Start Read transfer failed %d\r\n",status);
		for(;;);
	}
	
	// Binary semaphores are set in main()

	for(;;){
		VDMA_TaskEnterCounter++;
        //vTaskDelay( pdMS_TO_TICKS(500) ); JUTS FOR DEBUGGING
		if( xSemaphoreTake( SemVDMAWr, portMAX_DELAY) == pdTRUE ){//portMAX_DELAY
			VDMA_TookSmphr++;
			//xil_printf("VDMA: Semphr took \r\n");
		}
		VDMA_TaskExitCounter++;
	}
}

static void WriteCallBack(void *CallbackRef, u32 Mask)
{
	static BaseType_t xHigherPriorityTaskWoken2 = pdFALSE;
	static int counterTx = 0;

	xHigherPriorityTaskWoken2 = pdFALSE;
	counterTx++;
	//xSemaphoreGiveFromISR(SemVDMAWr, &xHigherPriorityTaskWoken2);

	if(counterTx > 30){

		counterTx = 0;
		xSemaphoreGiveFromISR(SemVDMAWr, &xHigherPriorityTaskWoken2);
	}
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken2);

}

static void WriteErrorCallBack(void *CallbackRef, u32 Mask)
{

	xil_printf("W_ERR\r\n");
}

static void ReadCallBack(void *CallbackRef, u32 Mask)
{
	static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	static int counterRx = 0;

	xHigherPriorityTaskWoken = pdFALSE;
	counterRx++;

	if(counterRx>100){
		xSemaphoreGiveFromISR(SemVDMARd, &xHigherPriorityTaskWoken);
	}
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken);
}

static void ReadErrorCallBack(void *CallbackRef, u32 Mask)
{
	/* User can add his code in this call back function */
	xil_printf("R_ERR\r\n");

}

static int SetupIntrSystem_WR_RD(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId, u16 WriteIntrId)
{
	int Status;

	configSETUP_TICK_INTERRUPT();
		/* Instance of the Interrupt Controller */
	XScuGic *IntcInstancePtr = &xInterruptController;
	Status = xPortInstallInterruptHandler( ReadIntrId, (XInterruptHandler) XAxiVdma_ReadIntrHandler, AxiVdmaPtr);
	Status = xPortInstallInterruptHandler( WriteIntrId, (XInterruptHandler) XAxiVdma_WriteIntrHandler, AxiVdmaPtr);

	XScuGic_SetPriorityTriggerType(IntcInstancePtr, ReadIntrId, 0xA0, 0x3);//(configMAX_API_CALL_INTERRUPT_PRIORITY + 1) << portPRIORITY_SHIFT
	XScuGic_SetPriorityTriggerType(IntcInstancePtr, WriteIntrId, 0xA0, 0x3);


	//Xil_ExceptionInit();
	// Connect the interrupt controller interrupt handler to the hardware interrupt handling logic in the processor.
	//Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,IntcInstancePtr);
	Xil_ExceptionEnable();//Enable interrupts in the Processor.

	/* Register callback functions
	 */

	XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, ReadCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);

	XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR, ReadErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);

	XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, WriteCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);

	XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR, WriteErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);


	vPortEnableInterrupt(ReadIntrId);
	vPortEnableInterrupt(WriteIntrId);

	return XST_SUCCESS;
}