Semaphore in task with queue on ESP32 idf 5.0

void vTaskDisplay( void * pvParameters )
{
   while(1)
   {
      // Queue receive, wait 10
      if( xQueueReceive( displayQueue, &cmd, ( TickType_t ) 10 ) == pdPASS )
      {
         if (SHOW == cmd) {
           printf("db 1 - begin\n");
           xSemaphoreTake(s_lock, portMAX_DELAY);
           flash_db_operation();
           xSemaphoreGive(s_lock);
           printf("db 1 - end\n");
         }
      }

      printf("display_tick()\n");
      display_tick();
   }
}

I have the simplified my code, but is does basically as the code above.
My expected outcome would be:
db 1 - begin
db 1 - end
display_tick()

But sometimes I see:
db 1 - begin
display_tick()
display_tick()
db 1 - end

So it seems like the task is waiting for the semaphore, but then runs again.
Maybe I have totally misunderstood something, but I would expect the task to be blocked, until the semaphore is given. It is like the task is fork’ed or something.

According to your example code it should be impossible to get a
db 1 - begin
display_tick()
display_tick()
db 1 - end
sequence.
I assume you verified that there is only 1 task running the code.
Did you also verify that there is no stack overflow or an configASSERT ?
There must a fatal problem making the code running wild.
Alternatively you could comment out flash_db_operation and put in e.g. a vTaskDelay to simulate the flash operation to narrow down where the application gets corrupted.

1 Like

Do not rely on printf() to provide accurate output.

Also, could it be the case that you have spawned two instances of your display task, as Hartmut suggested?

@hs2 and @RAc You where correct, my Init function was called twice, and therefore xTaskCreate was called two times. :slight_smile:

Thanks for reporting back!