| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
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

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:

- MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
- MEMORY_MANAGER_XSMALL_BLOCK_COUNT
- MEMORY_MANAGER_SMALL_BLOCK_COUNT
- MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
- MEMORY_MANAGER_LARGE_BLOCK_COUNT
- MEMORY_MANAGER_XLARGE_BLOCK_COUNT
- MEMORY_MANAGER_XXLARGE_BLOCK_COUNT

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:

- MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
- MEMORY_MANAGER_XSMALL_BLOCK_SIZE
- MEMORY_MANAGER_SMALL_BLOCK_SIZE
- MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
- MEMORY_MANAGER_LARGE_BLOCK_SIZE
- MEMORY_MANAGER_XLARGE_BLOCK_SIZE
- MEMORY_MANAGER_XXLARGE_BLOCK_SIZE

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)