xSemaphoreGive doesn't give the semaphore when it has higher priority than xSemaphoreTake

sasikalaswathi wrote on Friday, November 08, 2019:

Created the semaphore using the API( vSemaphoreCreateBinary) with two tasks (prioirty 1) which take the semaphore and one task(priority 2) which gives the semaphore. In this case, xSemaphoreGive API not even given the semaphore at once. While checked the return value, it always return 0. what problem occured in this case?
but while setting the semaphore given and taken task to same priority, semaphore given successfully.

rtel wrote on Friday, November 08, 2019:

Please post the code you are using.

sasikalaswathi wrote on Monday, November 11, 2019:

Attached the code for reference.

void vTaskFunction1(void);
void vTaskFunction2(void);
void vTaskFunction3(void);
BaseType_t xReturned,xReturned1,xReturned2;
SemaphoreHandle_t UARTAccess,UARTAccess1;
char rec_data;

int main(void)
{
UARTAccess=xSemaphoreCreateBinary();
if (UARTAccess!=NULL)
{
xReturned =xTaskCreate( vTaskFunction1, “Task 1”, 512,NULL, 1, NULL );
xReturned1=xTaskCreate( vTaskFunction2, “Task 2”, 512, NULL, 1, NULL );
xReturned2=xTaskCreate( vTaskFunction3, “Task 3”, 512, NULL, 2, NULL );

    if(xReturned==1&& xReturned1==1 && xReturned2==1)
    {
 	   vTaskStartScheduler();
    }

}
else
{
// created semaphore was null
// printf();
}

}
void vTaskFunction1( void)
{
for(;:wink:
{
if(xSemaphoreTake(UARTAccess,10))
{

// HAL_GPIO_WritePin(GPIOE,GPIO_PIN_10,1);
printf(“Task1-get\n”);

	}
	else
	{
		printf("Task1-not get\n");
	}
}

}
void vTaskFunction2( void)
{
for(;:wink:
{
if(xSemaphoreTake(UARTAccess,10))
{

// HAL_GPIO_WritePin(GPIOE,GPIO_PIN_10,0);
printf(“Task2-get\n”);

	}
	else
	{
		printf("Task2-not get\n");
	}
}

}
void vTaskFunction3( void)
{

 BaseType_t give_result;
 	for(;;)
 	{
 		    give_result=xSemaphoreGive( UARTAccess);
 			 if( give_result != pdTRUE )
 			 {

// printf(“semaphore not given:%ld\n”,give_result);
}
else
{
printf(“semaphore given:%ld\n”,give_result);
}

}
}

rtel wrote on Monday, November 11, 2019:

First thing to note is the prototype of your task functions is wrong -
there should be a void * parameter passed in. That won’t be the source
of your problem though.

As the code is posted the expected behaviour would be:

  1. vTaskFunction3() will run first as it has the highest priority.
  2. vTaskFunction3() gives the semaphore - that give should succeed.
  3. vTaskFunction3() has not entered the Blocked state, so continues
    executing.
  4. vTaskFunction3() calls printf() - what happens at this point is very
    dependent on your application, library, and where the output of printf()
    is sent. In most non trivial examples calling printf() will be
    problematic, as a minimum for stack use, but also as it could call
    malloc() and is unlikely to be thread safe (as it is also called from
    other threads).
  5. vTaskFunction3() still hasn’t entered the Blocked state so loops back
    around and attempts to give the semaphore again - as it is a binary
    semaphore and has already been given, this time the ‘give’ operation
    will fail.
  6. vTaskFunction3() keeps looping indefinitely, printing out messages
    and failing to repeatedly give the semaphore.

sasikalaswathi wrote on Monday, November 11, 2019:

Hi Richard,
Thanks for the quick response and got clarified from your explanation.