CMSIS-RTOS2: Memory Pool

| CMSIS-RTOS2 Version 2.1.1 Real-Time Operating System: API and RTX Reference Implementation

- Main Page
- Usage and Description
- Reference

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Typedefs | Functions
Memory Pool
CMSIS-RTOS2 API

Manage thread-safe fixed-size blocks of dynamic memory. More...

## Data Structures
struct | osMemoryPoolAttr_t
| Attributes structure for memory pool. More...

## Typedefs
typedef void * | osMemoryPoolId_t

## Functions
osMemoryPoolId_t | osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)
| Create and Initialize a Memory Pool object. More...
const char * | osMemoryPoolGetName (osMemoryPoolId_t mp_id)
| Get name of a Memory Pool object. More...
void * | osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout)
| Allocate a memory block from a Memory Pool. More...
osStatus_t | osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block)
| Return an allocated memory block back to a Memory Pool. More...
uint32_t | osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id)
| Get maximum number of memory blocks in a Memory Pool. More...
uint32_t | osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id)
| Get memory block size in a Memory Pool. More...
uint32_t | osMemoryPoolGetCount (osMemoryPoolId_t mp_id)
| Get number of memory blocks used in a Memory Pool. More...
uint32_t | osMemoryPoolGetSpace (osMemoryPoolId_t mp_id)
| Get number of memory blocks available in a Memory Pool. More...
osStatus_t | osMemoryPoolDelete (osMemoryPoolId_t mp_id)
| Delete a Memory Pool object. More...

## Description

Memory Pools are fixed-size blocks of memory that are thread-safe. They operate much faster than the dynamically allocated heap and do not suffer from fragmentation. Being thread-safe, they can be accessed from threads and ISRs alike.

A Memory Pool can be seen as a linked list of available (unused) memory blocks of fixed and equal size. Allocating memory from a pool (using osMemoryPoolAlloc) simply unchains a block from the list and hands over control to the user. Freeing memory to the pool (using osMemoryPoolFree) simply rechains the block into the list.

CMSIS-RTOS Memory Pools

Note
  One must not write to freed block. It is up to the implementation to reuse the memory of unused blocks for internal control data, i.e. linked list pointers.

Shared memory is one of the basic models to exchange information between threads. Using memory pools for exchanging data, you can share more complex objects between threads if compared to a Message Queue. Memory pool management functions are used to define and manage such fixed-sized memory pools.

Note
  The functions osMemoryPoolAlloc, osMemoryPoolFree, osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize, osMemoryPoolGetCount, osMemoryPoolGetSpace can be called from Interrupt Service Routines.
  Refer to Memory Pool Configuration for RTX5 configuration options.

## Data Structure Documentation

struct osMemoryPoolAttr_t

Data Fields
const char * | name | name of the memory pool Pointer to a string with a human readable name of the memory pool object. Default: NULL.
uint32_t | attr_bits | attribute bits Reserved for future use (set to '0'). Default: 0.
void * | cb_mem | memory for control block Pointer to a memory location for the memory pool control block object. This can optionally be used for custom memory management systems. Default: NULL (uses kernel memory management).
uint32_t | cb_size | size of provided memory for control block The size of the memory block passed with cb_mem. Must be the size of a memory pool control block object or larger.
void * | mp_mem | memory for data storage Pointer to a memory location for the data of the memory pool object. Default: NULL.
uint32_t | mp_size | size of provided memory for data storage The size of the memory passed with mp_mem.

## Typedef Documentation

osMemoryPoolId_t

Memory Pool ID identifies the memory pool.

Returned by:

- osMemoryPoolNew

## Function Documentation

osMemoryPoolId_t osMemoryPoolNew | ( | uint32_t | block_count,
|  | uint32_t | block_size,
|  | const osMemoryPoolAttr_t * | attr
| ) |  |

Parameters

  [in] | block_count | maximum number of memory blocks in memory pool.
  [in] | block_size | memory block size in bytes.
  [in] | attr | memory pool attributes; NULL: default values.

Returns
  memory pool ID for reference by other functions or NULL in case of error.

The function osMemoryPoolNew creates and initializes a memory pool object and returns the pointer to the memory pool object identifier or NULL in case of an error. It can be safely called before the RTOS is started (call to osKernelStart), but not before it is initialized (call to osKernelInitialize).

The total amount of memory needed is at least `block_count * block_size`. Memory from the pool can only be allocated/freed in fixed portions of `block_size`.

Note
  This function cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os2.h" // CMSIS RTOS header file
/*----------------------------------------------------------------------------
* Memory Pool creation & usage
*---------------------------------------------------------------------------*/
#define MEMPOOL_OBJECTS 16 // number of Memory Pool Objects
typedef struct { // object data type
uint8_t Buf[32];
uint8_t Idx;
} MEM_BLOCK_t;
void Thread_MemPool (void *argument); // thread function
osThreadId_t tid_Thread_MemPool; // thread id
osMemoryPoolId_t mpid_MemPool; // memory pool id
int Init_MemPool (void)
{
mpid_MemPool = osMemoryPoolNew(MEMPOOL_OBJECTS,sizeof(MEM_BLOCK_t), NULL);
if (mpid_MemPool == NULL) {
; // MemPool object not created, handle failure
}
tid_Thread_MemPool = osThreadNew (Thread_MemPool,NULL , NULL);
if (tid_Thread_MemPool == NULL) {
return(-1);
}
return(0);
}
void Thread_MemPool (void *argument)
{
osStatus_t status;
MEM_BLOCK_t *pMem = 0;
while (1) {
; // Insert thread code here...
pMem = (MEM_BLOCK_t *)osMemoryPoolAlloc (mpid_MemPool, NULL); // get Mem Block
if (pMem) { // Mem Block was available
pMem->Buf[0] = 0x55; // do some work...
pMem->Idx = 0;
status = osMemoryPoolFree (mpid_MemPool, pMem); // free mem block
switch (status) {
case osOK:
break;
case osErrorParameter:
break;
case osErrorNoMemory:
break;
default:
break;
}
}
osThreadYield (); // suspend thread
}
}

const char * osMemoryPoolGetName | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  name as NULL terminated string.

The function osMemoryPoolGetName returns the pointer to the name string of the memory pool identified by parameter mp_id or NULL in case of an error.

Note
  This function cannot be called from Interrupt Service Routines.

void * osMemoryPoolAlloc | ( | osMemoryPoolId_t | mp_id,
|  | uint32_t | timeout
| ) |  |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.
  [in] | timeout | Timeout Value or 0 in case of no time-out.

Returns
  address of the allocated memory block or NULL in case of no memory is available.

The blocking function osMemoryPoolAlloc allocates the memory pool parameter mp_id and returns a pointer to the address of the allocated memory or 0 in case of an error.

The parameter timeout specifies how long the system waits to allocate the memory. While the system waits, the thread that is calling this function is put into the BLOCKED state. The thread will become READY as soon as at least one block of memory gets available.

The parameter timeout can have the following values:

- when timeout is 0, the function returns instantly (i.e. try semantics).
- when timeout is set to osWaitForever the function will wait for an infinite time until the memory is allocated (i.e. wait semantics).
- all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics).

The result is the pointer to the memory block allocated, or NULL if no memory is available.

Note
  It is in the responsibility of the user to respect the block size, i.e. not access memory beyond the blocks limit.
  May be called from Interrupt Service Routines if the parameter timeout is set to 0.

Code Example

Refer to osMemoryPoolNew.

osStatus_t osMemoryPoolFree | ( | osMemoryPoolId_t | mp_id,
|  | void * | block
| ) |  |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.
  [in] | block | address of the allocated memory block to be returned to the memory pool.

Returns
  status code that indicates the execution status of the function.

The function osMemoryPoolFree frees the memory pool block specified by the parameter block in the memory pool object specified by the parameter mp_id. The memory block is put back to the list of available blocks.

If another thread is waiting for memory to become available the thread is put to READY state.

Possible osStatus_t return values:

- osOK: the memory has been freed.
- osErrorParameter: parameter mp_id is NULL or invalid, block points to invalid memory.
- osErrorResource: the memory pool specified by parameter mp_id is in an invalid memory pool state.

Note
  osMemoryPoolFree may perform certain checks on the block pointer given. But using osMemoryPoolFree with a pointer other than one received from osMemoryPoolAlloc has UNPREDICTED behaviour.
  This function may be called from Interrupt Service Routines.

Code Example

Refer to osMemoryPoolNew.

uint32_t osMemoryPoolGetCapacity | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  maximum number of memory blocks.

The function osMemoryPoolGetCapacity returns the maximum number of memory blocks in the memory pool object specified by parameter mp_id or 0 in case of an error.

Note
  This function may be called from Interrupt Service Routines.

uint32_t osMemoryPoolGetBlockSize | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  memory block size in bytes.

The function osMemoryPoolGetBlockSize returns the memory block size in bytes in the memory pool object specified by parameter mp_id or 0 in case of an error.

Note
  This function may be called from Interrupt Service Routines.

uint32_t osMemoryPoolGetCount | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  number of memory blocks used.

The function osMemoryPoolGetCount returns the number of memory blocks used in the memory pool object specified by parameter mp_id or 0 in case of an error.

Note
  This function may be called from Interrupt Service Routines.

uint32_t osMemoryPoolGetSpace | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  number of memory blocks available.

The function osMemoryPoolGetSpace returns the number of memory blocks available in the memory pool object specified by parameter mp_id or 0 in case of an error.

Note
  This function may be called from Interrupt Service Routines.

osStatus_t osMemoryPoolDelete | ( | osMemoryPoolId_t | mp_id | ) |

Parameters

  [in] | mp_id | memory pool ID obtained by osMemoryPoolNew.

Returns
  status code that indicates the execution status of the function.

The function osMemoryPoolDelete deletes a memory pool object specified by parameter mp_id. It releases internal memory obtained for memory pool handling. After this call, the mp_id is no longer valid and cannot be used. The memory pool may be created again using the function osMemoryPoolNew.

Possible osStatus_t return values:

- osOK: the memory pool object has been deleted.
- osErrorParameter: parameter mp_id is NULL or invalid.
- osErrorResource: the memory pool specified by parameter mp_id is in an invalid memory pool state.
- osErrorISR: osMemoryPoolDelete cannot be called from interrupt service routines.

Note
  This function cannot be called from Interrupt Service Routines.