Thought Leadership

RTOS partition memory

For any developer of real-time systems, the word “dynamic” should ring alarm bells, as it is generally a label for something that might compromise determinism. The best and easiest to appreciate example is dynamic memory allocation. Most programmers are familiar with malloc()/free(), but may be unaware of their pitfalls: non-deterministic behavior and ill-defined failure modes …

The first problem with malloc() is that many [perhaps most] implementations are non-deterministic – it is not possible to specify how long a memory allocation may take. The second one is allocation failure. Obviously, the function can fail because there is insufficient heap space and a NULL pointer is returned. How many developers routinely check for this? I hope that the answer is “most”. The more subtle problem is that malloc() can fail even if there is enough memory, if that memory is not contiguous. The obvious solution of “defragging” the heap is not possible, as C uses direct pointers and, in any case, it would compromise determinism.

A straightforward solution to this difficulty is provided with most RTOS products: a memory block [also called “partition”] allocation system. The idea is simple. An application has a number of “memory pools”, each of which contains a specific number of fixed size blocks. The code uses an API call to request a block and this allocation will be deterministic. If there are no free blocks available, an allocation failure will occur. This either results in an error response or task suspension, pending an available block. Fragmentation cannot occur.

In many RTOSes a pool is created dynamically. With Nucleus RTOS the prototype for the API call looks like this:

STATUS NU_Create_Partition_Pool(NU_PARTITION_POOL *pool
   CHAR *name, VOID *start_address, UNSIGNED pool_size,
   UNSIGNED partition_size, OPTION suspend_type)

Here is an example call:

status = NU_Create_Partition_Pool(&MyPool, “any name”,
   (VOID *) 0xB000, 2000, 40, NU_FIFO);

This specifies that the descriptor for the object is MyPool; it has 40-byte partitions/blocks; a 2000-byte memory area, which is located at 0xB000, and task suspension is in FIFO order.

Another API call is used to request the allocation of a block:

status = NU_Allocate_Partition(&MyPool, &ptr, NU_SUSPEND);

This requests an allocation of a partition from the pool described by MyPool. The pointer ptr will point to the allocated memory and the task should be suspended on allocation failure. Another call may be used to relinquish the block:

status = NU_Deallocate_Partition(ptr);

Colin Walls

I have over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Learn more about Colin, including his go-to karaoke song and the best parts of being British: http://go.mentor.com/3_acv

More from this author

Comments

One thought about “RTOS partition memory

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.stage.sw.siemens.com/embedded-software/2019/10/07/rtos-partition-memory/