xQueueSend() creates trouble

Hi,
I am new to the concept of RTOS. I worked with a code , the code get reset after some time.When we have a look the issue is with the xQueueSend function. there is ‘pvItemToQueue’ which is the pointer to the message .When we change the scope of the variable structure which we wished to pass to queue to global scope then the issue get resolved…I just want to know whether there is any matter to the scope of the structure variable that we are passing to message…here when we change the scope from the function to the whole file it works.
Please help me to find the issue

When sending queue items by reference/pointer the storage it points to must remain valid.
It’s similar to e.g. wrongly returning a pointer to a function local buffer or struct (on stack) from a function and try to access the pointed to buffer/struct in the outside/caller code. This would return a so called dangling pointer which can cause really nasty problems.
So in your case it would be sufficient if you don’t leave the scope of the struct variable. It’s not needed that it’s a global/static variable.
In this example the local variables Msg and Msg2 (on stack) can be safely be sent because their scope is not left (and the structs are not destroyed).

void Task( void* pArg )
{
    struct tMsg Msg;
    
    for (;;)
    {
        struct tMsg Msg2;
        
        ...
        ...    
        xQueueSend( hQ, &Msg, To );
        ...

            xQueueSend( hQ, &Msg2, To );
            ...
        ...
    }
}

Hi,
Thanks for the reply…The below shown is the rough demonstration of my code…I just make the X::Y Data; to global scope and that change the reset issue…Is there any scope for such a thing…the variable is created only that if condition is satisfied…So no scope of any other dummy pointer address too.

void recieve(int num){
if (true == Received1 && true == Received2) {
        X::Y<Z> Data;
        Data.num = num;
               if (nullptr != mTelemQueueHandle) {
           xQueueSend(mTelemQueueHandle, &Data, 0);
        }    
    }   
}

So can you help me figure out what can be the reason

BTW please quote source code either using the </> button or by enclosing the code snippet in 3 backticks (`). Otherwise it’s unreadable.

I tried hard providing good explanation and useful example code… and failed :wink:
Another try:

void receive()
{
  X::Y* pDanglingPointer = NULL;

  if (true == Received1 && true == Received2) 
  {
    X::Y Data;
    pDanglingPointer = &Data;
    
    // Although 'Data' is valid here it get's out of sope and detroyed soon
    // The other task will access invalid storage through the received pDanglingPointer !
    xQueueSend( hQ, pDanglingPointer, To ); 
        
  }
  // <-- 'Data' got detroyed here and it's (stack) storage will be reused 
  //     Don't access 'Data' (mis-)using pDanglingPointer !!!
  pDanglingPointer->Value = 5; // BUG !!! Might just SEEM to work (for a while)
}

Review my initial example and check the scope/lifetime the tMsg variables. You’ll see the stay alive as long as the task stays alive.

Hi,
Thanks for the suggestion on how to update code in this forum…
I have one more doubt how this problem will be resolved by updating the variable declaration as a global variable…In my case the data variable update only in that function…not updated or used anywhere else…

I’m not sure about your doubt… But moving the variable to file or module scope (global or static) just changes the scope of that variable and its storage.
There is no fundamental problem doing so and if you just change the variable in a single function it’s fine.
You could also define it as static variable inside a function to narrow down it’s visibility / improve encapsulation but still having persistent storage with unlimited lifetime.

Would you please share your code for queue create? If I understand correctly, you are copying the whole X::Y<Z> Data to the queue and therefore it should not be needed after the call to xQueueSend. If the size of Data is big, you might be causing memory corruption because of stack overflow - it will be good to increase the size of stack and see if the problem persists.

Thanks.

One thing to watch out here, xQueueSend will copy the data by memcpy, not a move constructor, so if X::Y isn’t a ‘POD’ it won’t work right. If X::Y has any pointers in it, the copy is a shallow copy, so just the pointer is copied, a new copy of the referenced data isn’t made.

Thanks - looks like it has solved an intermittent problem that I was seeing with xQueueSend( ) and also xQueueSendFromISR( ).