© Copyright 2003
RealTimePartner
All rights reserved
Last update 2016-01
Memory Management
Memory management can be either very simple or very difficult depending on your requirements in your project. If you do not allocate any memory dynamically during execution then memory management is normally very simple. But if you do have a lot of dynamic memory allocations in your tasks it can be very hard to make your application handle the memory correctly.
Types of Memory
Many types of memory exist, see figure 1.
All systems need RAM memory to able to store data, but many systems also place the code in RAM as this speeds up the execution time. When you decide which types of memory that you need in your system, there are a few things that you need to consider:
For real-time applications execution speed normally need to be very high, so most applications execute in RAM.
Address Layout
An address layout needs to be done before the design of the hardware. You need to decide which types of memory that you need and how much of each type. For the boards that will be used during software development and test, it is normally very good to have much more RAM than what is needed on the production boards.
In address layout you decide how much memory you need of each type and what should be the address areas for each type of memory and also I/O, an example is shown in figure 2.
Memory Layout
The next step is to specify how the memory should be used, i.e. decide where the code should be placed, both permanently and from where it should be executed (many times the code is placed in ROM or FLASH, but copied to RAM during system startup and then executed from RAM) and where data should be placed. Data also need to be split up into different sections, like vector table, initialized data, uninitialized data, constants. This should be well described in the manual for your linker. After that you have all the input data that you need to be able to create the linker file. An example is shown in figure 3.
To be able to see all the details of the linking you can specify in your link command that the linker should create a map file. The map file shows you all the addresses for both the code and the data sections.
Memory Protection
Everything that is placed in RAM can be overwritten Sometimes this happens by mistakes caused by a bug in your program, and the consequences for memory corruption can sometimes be very drastic, and for many systems it is not acceptable at all. Protecting your memory by software routines will not work, as it would increase the execution time dramatically, so it needs to be done in hardware. To be able to do this you need a MMU (Memory Management Unit). Most modern CPU:s include a MMU. Using a MMU you can decide which parts of memory that are readable and/or writeable for each task. If a task tries to write to a memory address that has been configured to be read-only an exception will be caused by the MMU.
Using an MMU will slow down your application a little bit, as at every task switch the MMU needs to be reconfigured.
Dynamic Allocation
Some applications allocate all the memory needed (except stacks) during linking time and startup of the RTOS. Others may need to allocate memory during initialization of the application, memory that will never be returned. In these cases it is normally safe to use malloc and new.
But many applications need to allocate memory during execution time and after a short while return it. In these cases it may not be recommendable to use malloc/free and new/delete. One simple reason is that you almost never know how these functions are implemented, i.e. how do they really allocate memory, which algorithm do they use. And when you free the memory you may not get to know if this call was successful or not, in other words: Did you create a memory leak or not?
There are many ways of creating your own memory handler instead of using malloc and new, from very simple implementations to more sophisticated ones. A few simple ones (and do not forget that simple sometimes means better):
Of course it is possible to create much more sophisticated memory handlers, which may help you to detect memory leaks, fragmentation, and other problems.
Memory Problems
I guess that almost every programmer has run into memory problems in their applications. For those of you who does not have this experience, probably you did have a problem, but maybe you did not look for it, or maybe the symptoms never showed up. My recommendation is that you should always analyze your memory usage if you do dynamic allocations, to make sure that everything is working correctly.
So which type of problems can you run into:
Conclusion