nRF5 SDK v13.0.0
Memory Manager

The Memory Manager provides dynamic access to RAM, which makes it possible to use memory as needed instead of having to reserve it statically at compile time. To avoid memory fragmentation and the resulting need to move data, the module implements fixed-size block allocation.

The fixed-size blocks are categorized into seven categories: xxsmall, xsmall, small, medium, large, xlarge, xxlarge. The application can configure how big each block should be and how many of these blocks should be allocated.

The following table shows which parameters must be set to define the number and size of memory blocks of a certain category:

Category Parameters
XXSmall MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
XSmall MEMORY_MANAGER_XSMALL_BLOCK_SIZE
MEMORY_MANAGER_XSMALL_BLOCK_COUNT
Small MEMORY_MANAGER_SMALL_BLOCK_SIZE
MEMORY_MANAGER_SMALL_BLOCK_COUNT
Medium MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
Large MEMORY_MANAGER_LARGE_BLOCK_COUNT
MEMORY_MANAGER_LARGE_BLOCK_SIZE
XLarge MEMORY_MANAGER_XLARGE_BLOCK_COUNT
MEMORY_MANAGER_XLARGE_BLOCK_SIZE
XXLarge MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
MEMORY_MANAGER_XXLARGE_BLOCK_SIZE

If you do not want to use all seven categories, define the block count of the categories that you do not want to use to be zero. Alternatively, only set the block count and size for the block categories that you want to use.

Memory allocation

The application that requests the memory does not need to know how the memory allocation is handled internally. The Memory Manager hides the information which pool was used to allocate the requested memory from the application.

The requested memory can be of any size; the application does not need to request a buffer that is equal to the size of one of the block sizes. The application is not informed which block category was used for the allocation. In most cases, the smallest block that can hold the requested memory is used. However, in a situation where all blocks of best fitting are in use and another memory block is requested, the module will provide memory from the next free block category.

For example, assume that the module is configured to use three block sizes (small, medium, and large) of 128, 512, and 1024 bytes, respectively. If the application requests 80 bytes of memory, the best fitting category is the small block category. However, if all small blocks are in use, the module will promote the block category to medium and look for a free block. If no blocks are available in this category either, the module will promote the block category to large to find a buffer.

See the following flow chart for the buffer allocation algorithm that is used. The function that is used to allocate a buffer is called nrf_malloc.

memory_manager_allocation_algorithm.svg
Memory Manager allocation algorithm

To determine the best configuration of blocks for the application, use the diagnostic function nrf_mem_diagnose. This function is disabled by default, but it can be enabled by defining MEM_MANAGER_ENABLE_DIAGNOSTICS to 1. If this macro is defined, the module keeps track of the maximum and minimum memory sizes allocated in each category for each block until nrf_mem_diagnose is called. It also provides information on the number of blocks that are in use when the function is called. The diagnostic information is displayed using app_trace. To enable only diagnostic trace and disable all other trace output, define MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY to 1.

Configuration parameters

The following configuration parameters should be defined in sdk_config.h.

MEM_MANAGER_ENABLE_LOGS

Enable debug tracing in the module. To enable tracing, this flag must be set to 1 and ENABLE_DEBUG_LOG_SUPPORT must be set to 1. By default, debug tracing is disabled.

Description Value
Enable debug trace 1
Disable debug trace 0
Dependencies ENABLE_DEBUG_LOG_SUPPORT

MEM_MANAGER_ENABLE_DIAGNOSTICS

Enable diagnostic information on block usage in the module. To enable diagnostics, this flag must be defined. To display diagnostic information, at least one of MEM_MANAGER_ENABLE_LOGS or MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY must be set to 1. By default, diagnostics is disabled.

Description Value
Dependencies MEM_MANAGER_ENABLE_LOGS or MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY

MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY

Disable display of trace information other than diagnostic information. To display only diagnostic information, this flag must be set to 1. By default, this macro is disabled.

Description Value
Enable debug trace 1
Disable debug trace 0
Dependencies MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY

If diagnostics is not enabled, that is, if MEM_MANAGER_ENABLE_DIAGNOSTICS is not defined, this define is ignored.

MEM_MANAGER_DISABLE_API_PARAM_CHECK

Disable API parameter checks in the module. Set this define to 1 to disable checks on API parameters in the module. API parameter checks are added to ensure that the correct parameters are passed to the module. These checks are useful during the development phase, but they might be redundant when the application is finalized. Disabling these checks might improve performance. By default, API parameter checks are enabled.

Description Value
Enable API parameters check 0
Disable API parameters check 1
Dependencies None

Block count

The following defines configure the maximum number of memory blocks of the respective category:

If you do not want to use all categories, define the block count of the categories that you do not want to use to be zero or do not define it at all.

Restriction Value
Minimum value 0
Maximum value 255
Dependencies None

Block size

The following defines configure the size of each memory block of the respective category:

The block size must be a multiple of the word size.

The block size of the smallest category that is used (thus that has a block count greater than zero) must be greater than zero. The block size of each following category that is used must be greater than the block size of the previous category.

Note that the module uses one bit per block to keep track of the status of the block (free or in use). The bits are maintained in an array of unsigned 32-bit integers.

Restriction Value
Minimum value Block size of the previous category (0 if no previous category) + word size
Maximum value Block size of the following category - word size (no restriction if there is no following category)
Dependencies Block size of the previous and following used category (if any)

Documentation feedback | Developer Zone | Subscribe | Updated