Retain queue through reboot/Copy queue's buffer content directly


I am working on an embedded project, and I am using the static method API to create queue. The goal is to make the FREERTOS queue retain through a reboot. I already figure out a way to retain a memory space through a reboot (which is by using noinit memory), but to do that with a FREERTOS queue, I need some help.

I have 2 ideas here, one is to make the whole FREERTOS queue retainable, by statically allocating queue buffer and queue structure in noinit memory space. I assume this will let queue keep its state and after reboot I just need to use the saved pointer of the queue and it will work, but I am not exactly sure. Can someone comment on this method?

Another work around is instead of making the queue retainable, I save all the items of the queue to another buffer. To do this, I know there is no official API doing ‘copy all item of queue to another buffer’ and the only way to me is to pop each item one by one but this is to trivial. So to make it easier, I have an idea of directly copying the content in the statically allocated queue buffer into buffer#2 by using memcpy(), I wonder will this method work? And when I interpret the buffer content can I interpret it as front item is at lower address?


I looked over the code prvInitialiseNewQueue() briefly and I think your first strategy won’t work because prvInitialiseNewQueue() would always reinitialize the queue even if “there already is some fully static valid data” in it (how should FreeRTOS know if that’s the case?)

Another thing is that you shouldn’t make assumptions about the inner structure of any OS data type being constant. What if, say, you upgraded your firmware to something that has a different version of FreeRTOS in it in which queues have different internal structures than in the previous version?

Thus I’d strongly suggest your second approach; however, it implies that all of your reboots are under your control and allow you to keep the queue and its copy in sync (I don’t think you can simply “pop” all of your queue items from the old queue at startup for pretty much the same reasons outlined above). That would be difficult, though, because it’s hard to completly and reliably eliminate asynchronous resets.

Needless to say, you must be very very careful that in any case, every piece of data in your persistent memory must be marshalled.

1 Like

One key point is that there is some state in a Queue that should NOT live across a re-boot, like the list of tasks that are blocked on the Queue.

I think the real answer is to think what you are actually trying to solve, and not work on this ‘xy’ problem (getting stuck looking for an answer of how to do a technique that doesn’t actually solve your real problem)

1 Like