A task doesn't wait for a semaphore to ...

anonymous wrote on Tuesday, September 11, 2012:

A task that supposes to be waiting for a binary semaphore to be given starts running before that happens, why? Regards the next code snippet, task_Led2() runs as soon as the systems starts, however, what one expects is that this task should wait until task_led1() gives it the semaphore.

void task_Led1(void *p)
{
	uint32_t i=0;
	while(1)
	{
		led1_Toggle();
		vTaskDelay(500);
		if(++i == 5){
			i=0;
			xSemaphoreGive(bsmphUno);
		}
	}
}
void task_Led2(void *p)
{
	uint32_t i=0;
	for(;;)
	{
		xSemaphoreTake(bsmphUno,portMAX_DELAY); // doesn't wait for the semaphore to be given the first time, it goes to the for() immediatly
		for(i=0;i<5;i++){
			led2_Toggle();
			vTaskDelay(100);
		}
	}
}
int main(void)
{
         ...
	xTaskCreate(task_Led1,"",configMINIMAL_STACK_SIZE*1,NULL,1,NULL);
	xTaskCreate(task_Led2,"",configMINIMAL_STACK_SIZE*1,NULL,1,NULL);
	vSemaphoreCreateBinary(bsmphUno);
	vTaskStartScheduler();
	for(;;);
}

Any clues? Thank you!!

edwards3 wrote on Tuesday, September 11, 2012:

As this is a binary semaphore, it is already available when it is created. Add a call to xSemaphoreTake( bsmphUno, 0 ) after the semaphore is created, probably best to do that inside the task when the task starts running, and it will run how you think it should.

anonymous wrote on Tuesday, September 11, 2012:

Hi Edwards,

It works!! I added the line you pointed me out:

...
	xTaskCreate(task_Led1,"",configMINIMAL_STACK_SIZE*1,NULL,1,NULL);
	xTaskCreate(task_Led2,"",configMINIMAL_STACK_SIZE*1,NULL,1,NULL);
	vSemaphoreCreateBinary(bsmphUno);
	xSemaphoreTake(bsmphUno,0);
	vTaskStartScheduler();
...

I’m worried because this feature is not officially documented, but into a comment block inside a function in an example. I own both Barry’s  books, “A practical guided” and “Reference manual”, from 2009. In “A practical guide”’ page 76, inside vHandlerTask() function, there is an embedded comment code that says:

“/* Use the semaphore to wait for an event. The semaphore was created before the scheduler was started so before this task ran for the first time. … */”

Hope the behaviour for the other API’s functions are in fact well documented.

Thank you!!