Suicide Bunny
Suicide Bunny

Reputation: 928

vTaskStartScheduler() overwrites the pointer param values, how to avoid that?

I have created a freeRTOS task, and passed a pointer of a struct as the function param.

I noticed the struct property was changed after vTaskStartScheduler()

How do I protect my struct?

Here is the code

Main

    xTaskCreate(
                        SHELL_Main, // function the task calls
                        "shell", // nametag for debug console
                        512, // assigned buffersize
                        &user_context,// Parameter passed in
                        1, // task priority
                        NULL); //task handle

    printf("exit=%i", (&user_context)-> exit);
    vTaskStartScheduler();

SHELL_Main()

int32_t SHELL_Main(p_shell_context_t context)
{

    printf("entered shell_main\n");
    uint8_t ch;
    int32_t i;

    if (!context)
    {
        return -1;
    }

    context->exit = false;
    context->printf_data_func("\r\nSHELL (build: %s)\r\n", __DATE__);
    context->printf_data_func("Copyright (c) 2017 NXP Semiconductor\r\n");
    context->printf_data_func(context->prompt);


    while (1)
    {
      printf("context.exit=%s", (context->exit)?"true\n":"false\n");
      printf("context.exit=%i", (context->exit));

        if (context->exit)
        {
            printf("wtf");
            break;
        }

...

Here is the console

exit=0entered shell_main

SHELL (build: Oct 26 2018)
Copyright (c) 2017 NXP Semiconductor
SHELL>> context.exit=true
context.exit=253wtf

If I call SHELL_Main() directly in main instead of wrapping it in task, here's the console

exit=0entered shell_main

SHELL (build: Oct 26 2018)
Copyright (c) 2017 NXP Semiconductor
SHELL>> context.exit=false
context.exit=0

I speculate there is an overflow somewhere that overwrites my context.exit after calling vTaskStartScheduler(), but I do not know how to protect my struct. Can someone kindly share some idea?

Upvotes: 1

Views: 248

Answers (2)

John Auld
John Auld

Reputation: 486

[This question is old, but I'm adding an answer since it came up in Google search results]

You haven't included the definition of user_context in main(), but I suspect it's a local. Some ports of FreeRTOS repurpose main()'s stack space for use by interrupts, so you can't rely on local variables surviving the call to vTaskStartScheduler(). Making user_context static should solve the problem. See this FreeRTOS FAQ.

Upvotes: 0

Kon
Kon

Reputation: 4099

SHELL_Main is what modifies your struct (context->exit = false;). You create that task and pass context to it as param. When you start the scheduler, that task gets run and sets it to false.

In fact vTaskStartScheduler() never returns. See doc here: https://www.freertos.org/a00132.html

From comments below, sounds like printf_data_func() is causing the issues. Dig further into it.

Upvotes: 1

Related Questions