xQueueSend does not work if it is the last instruction of a Task

I have this part of code:

char *mystring = "800A";

static void vMyTask( void *pvParameter )
{
xQueueSend(xPrintQueue,&mystring,portMAX_DELAY);
}

this will never work and string won’t be shown in the LCD.
but if I put a for(;;) or a vTaskDelay() after xQueueSend, it works.

I don’t understand why though… The task, to terminate, has to complete the xQueueSend code, so why the LCD does not show the text?

A task is not allowed to return. If you just want to do that one thing in your task, you need to call vTaskDelete at the end:

static void vMyTask( void *pvParameter )
{
xQueueSend(xPrintQueue,&mystring,portMAX_DELAY);
vTaskDelete( NULL );
}
1 Like

thanks for answer.

A task is not allowed to return

what you mean? If I put a vTaskDelay() as last instruction, it’s actually able to show the string in the LCD. so what you mean?

A task function can not return to its caller. It can be one of the two:

  1. An infinite loop that never returns:
static void vMyTask( void *pvParameter )
{
    for( ;; )
    {
        /* Do work here. */
    }
}
  1. The task deletes itself by calling vTaskDelete:
static void vMyTask( void *pvParameter )
{
    /* Do work here. */

    vTaskDelete( NULL );
}

This page provides more details - Writing RTOS tasks in FreeRTOS - implementing tasks as forever loops.

ok thanks for clarification!

What is probably happening is at the point that the task function returns, you hit an ASSERT which halts the system, which keeps your LCD task from operating. Giving some time before that happens, lets it display the information, then crash.

Probably simpler that that. If his task function returns (to whereever) his variable mystring goes out of scope and with it his text disappears to the byte bucket. Thus his text can never be displayed. Waiting after xQueueSend keeps it alive long enough to be displayed before it gone forever.

Yes or no. There are several different possibilities that explain the behavior. It may also be a race condition in which the scheduler attempts to restore an invalid task context and faults before the display task has a chance to display the string. This is similar to what Richard sketched out but hits a “raw” fault instread of a “controlled” assert. In such a scenario, sometimes parts or all of the text may still be visible, sometimes not, depending on the exact timing. In any case, a typical race condition that is not allowed.

Not uninteresting to muse about this, but really moot as the explanation of @aggarg fully addresses the issue.

Edit: Of course you are correct in that even the “correct” use case vTaskDelete() may break with the stack based var going out of scope.