3

Currently I am developing an embedded system, running multiple tasks within an RTOS on a heavily constrained (mainly memory-wise) system.

My team-lead advised the use of dynamic memory allocation. However, safety-critical standards like MISRA C advise against it.

So what are the sensible alternatives? Creating shared memory and handling it with mutexes / gates? Currently I am dynamically allocating memory and passing pointers to it between tasks, but I would greatly appreciate some insight on how to improve this design.

Some more info: The embedded system's goal is to a central communication module, communicating with several outside systems. These outside systems want information from the different tasks on the embedded system, and vice versa.

To accomplish this, all tasks must communicate with that communication module. This is currently done by dynamically allocating storage for that message, and passing the pointers between the tasks. The receiving task then frees the allocated memory. The choice for dynamic allocation was made because most tasks will not communicate very much, while our hardware platform is very memory-constrained.

1 Answer 1

2

Unconstrained dynamic allocation in a resource constrained (embedded) system is a bad idea, because it will quickly become impossible to tell if you have enough memory to satisfy all allocation requests. This is considered especially problematic for safety-related software, because it might mean that a safety function can't be performed.

Sometimes, dynamic allocation can't really be avoided. In such cases, the advise is to do the allocation at power-up and never release the memory. That way, you at least know shortly after power-up if there is a problem with the required amount of memory, rather than getting reports that the device suddenly fails after weeks of operation.

In the case of a message queue, the usual solution is to use "dynamic allocation from a dedicated pool". You statically allocate a message pool that is large enough to hold "a sufficient number" of the largest messages. When one task needs to send a message, it requests one from the message pool and transfers the pointer to the message to the receiving task, who will return the message to the pool after handling it. The message pool may need to do some locking to protect its internal administration from concurrent access.

If the message pool hands out fixed size blocks, then this is relatively safe, as you only have to account for the possibility that the total number of concurrent messages is too large, but there is no rist of "losing" memory due to fragmentation.

More elaborate schemes are possible to use variable-sized messages without fragmentation.

3
  • Hi Bart, thank you for your response. But wouldn't allocating it all at start-up and not releasing it essentially be similar to just static allocation? And what would be the best solution when not using dynamic memory allocation? Passing pointers to local variables guarded by mutexes/gates/locks or are there better alternatives?
    – Kodiak
    Commented Nov 4, 2019 at 9:02
  • @DerpyDerp, perhaps you can elaborate (in your question) what problem you are trying to solve that your team lead suggested to use dynamic allocation for. Commented Nov 4, 2019 at 9:08
  • Hi Bart, thank you again for your response. I have updated the main post according to your suggestion. Hopefully this is clearer.
    – Kodiak
    Commented Nov 4, 2019 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.