1/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 2// ==== Memory Pool Management ==== 3/** 4\addtogroup CMSIS_RTOS_PoolMgmt Memory Pool 5\ingroup CMSIS_RTOS 6\brief Manage thread-safe fixed-size blocks of dynamic memory. 7\details 8\b Memory \b Pools are fixed-size blocks of memory that are thread-safe. They operate much faster than the dynamically 9allocated heap and do not suffer from fragmentation. Being thread-safe, they can be accessed from threads and ISRs alike. 10 11A Memory Pool can be seen as a linked list of available (unused) memory blocks of fixed and equal size. Allocating memory 12from a pool (using \ref osMemoryPoolAlloc) simply unchains a block from the list and hands over control to the user. Freeing 13memory to the pool (using \ref osMemoryPoolFree) simply rechains the block into the list. 14 15\image html "mempool.png" "CMSIS-RTOS Memory Pools" 16 17\note One must not write to freed block. It is up to the implementation to reuse the memory of unused blocks for internal 18control data, i.e. linked list pointers. 19 20\b Shared \b memory is one of the basic models to exchange information between threads. Using memory pools for exchanging 21data, you can share more complex objects between threads if compared to a \ref CMSIS_RTOS_Message. Memory pool management 22functions are used to define and manage such fixed-sized memory pools. 23 24\note The functions \ref osMemoryPoolAlloc, \ref osMemoryPoolFree, \ref osMemoryPoolGetCapacity, 25\ref osMemoryPoolGetBlockSize, \ref osMemoryPoolGetCount, \ref osMemoryPoolGetSpace can be called from 26\ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 27 28@{ 29*/ 30 31/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 32/** 33\typedef osMemoryPoolId_t 34\details 35Returned by: 36- \ref osMemoryPoolNew 37*/ 38 39/** 40\struct osMemoryPoolAttr_t 41\details 42Attributes to configure a memory pool. 43 44Refer to \ref CMSIS_RTOS_MemoryMgmt for details about usage of 45 - osMemoryPoolAttr_t::cb_mem 46 - osMemoryPoolAttr_t::cb_size 47 - osMemoryPoolAttr_t::mp_mem 48 - osMemoryPoolAttr_t::mp_size 49*/ 50 51/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 52/** 53\fn osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) 54\details 55The function \b osMemoryPoolNew creates and initializes a memory pool object and returns the pointer to the memory pool 56object identifier or \token{NULL} in case of an error. It can be safely called before the RTOS is 57started (call to \ref osKernelStart), but not before it is initialized (call to \ref osKernelInitialize). 58 59The total amount of memory needed is at least <code>block_count * block_size</code>. Memory from the pool can only be 60allocated/freed in fixed portions of \c block_size. 61 62\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 63 64\b Code \b Example 65\code 66#include "cmsis_os2.h" // CMSIS RTOS header file 67 68/*---------------------------------------------------------------------------- 69 * Memory Pool creation & usage 70 *---------------------------------------------------------------------------*/ 71 72#define MEMPOOL_OBJECTS 16 // number of Memory Pool Objects 73 74typedef struct { // object data type 75 uint8_t Buf[32]; 76 uint8_t Idx; 77} MEM_BLOCK_t; 78 79osMemoryPoolId_t mpid_MemPool; // memory pool id 80 81osThreadId_t tid_Thread_MemPool; // thread id 82 83void Thread_MemPool (void *argument); // thread function 84 85int Init_MemPool (void) { 86 87 mpid_MemPool = osMemoryPoolNew(MEMPOOL_OBJECTS, sizeof(MEM_BLOCK_t), NULL); 88 if (mpid_MemPool == NULL) { 89 ; // MemPool object not created, handle failure 90 } 91 92 tid_Thread_MemPool = osThreadNew(Thread_MemPool, NULL, NULL); 93 if (tid_Thread_MemPool == NULL) { 94 return(-1); 95 } 96 97 return(0); 98} 99 100void Thread_MemPool (void *argument) { 101 MEM_BLOCK_t *pMem; 102 osStatus_t status; 103 104 while (1) { 105 ; // Insert thread code here... 106 107 pMem = (MEM_BLOCK_t *)osMemoryPoolAlloc(mpid_MemPool, 0U); // get Mem Block 108 if (pMem != NULL) { // Mem Block was available 109 pMem->Buf[0] = 0x55U; // do some work... 110 pMem->Idx = 0U; 111 112 status = osMemoryPoolFree(mpid_MemPool, pMem); // free mem block 113 switch (status) { 114 case osOK: 115 break; 116 case osErrorParameter: 117 break; 118 case osErrorNoMemory: 119 break; 120 default: 121 break; 122 } 123 } 124 125 osThreadYield(); // suspend thread 126 } 127} 128\endcode 129*/ 130 131/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 132/** 133\fn const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) 134\details 135The function \b osMemoryPoolGetName returns the pointer to the name string of the memory pool identified by parameter \a 136mp_id or \token{NULL} in case of an error. 137 138\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 139*/ 140 141/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 142/** 143\fn void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) 144\details 145The blocking function \b osMemoryPoolAlloc allocates the memory pool parameter \a mp_id and returns a pointer to the address 146of the allocated memory or \token{0} in case of an error. 147 148The parameter \a timeout specifies how long the system waits to allocate the memory. While the system waits, the thread 149that is calling this function is put into the \ref ThreadStates "BLOCKED" state. The thread will become \ref ThreadStates "READY" 150as soon as at least one block of memory gets available. 151 152The parameter \ref CMSIS_RTOS_TimeOutValue "timeout" can have the following values: 153 - when \a timeout is \token{0}, the function returns instantly (i.e. try semantics). 154 - when \a timeout is set to \b osWaitForever the function will wait for an infinite time until the memory is allocated (i.e. wait semantics). 155 - all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics). 156 157The result is the pointer to the memory block allocated, or NULL if no memory is available. 158 159\note It is in the responsibility of the user to respect the block size, i.e. not access memory beyond the blocks limit. 160 161\note May be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" if the parameter \a timeout is set to 162\token{0}. 163 164\b Code \b Example 165 166Refer to \ref osMemoryPoolNew. 167*/ 168 169/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 170/** 171\fn osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) 172\details 173The function \b osMemoryPoolFree frees the memory pool block specified by the parameter \a block in the memory pool object 174specified by the parameter \a mp_id. The memory block is put back to the list of available blocks. 175 176If another thread is waiting for memory to become available the thread is put to \ref ThreadStates "READY" state. 177 178Possible \ref osStatus_t return values: 179 - \em osOK: the memory has been freed. 180 - \em osErrorParameter: parameter \a mp_id is \token{NULL} or invalid, \a block points to invalid memory. 181 - \em osErrorResource: the memory pool is in an invalid state. 182 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified memory pool. 183 184\note \b osMemoryPoolFree may perform certain checks on the \a block pointer given. But using \b osMemoryPoolFree 185with a pointer other than one received from \ref osMemoryPoolAlloc has \b UNPREDICTED behaviour. 186 187\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 188 189\b Code \b Example 190 191Refer to \ref osMemoryPoolNew. 192*/ 193 194/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 195/** 196\fn uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) 197\details 198The function \b osMemoryPoolGetCapacity returns the maximum number of memory blocks in the memory pool object specified by 199parameter \a mp_id or \token{0} in case of an error. 200 201\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 202*/ 203 204/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 205/** 206\fn uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) 207\details 208The function \b osMemoryPoolGetBlockSize returns the memory block size in bytes in the memory pool object specified by 209parameter \a mp_id or \token{0} in case of an error. 210 211\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 212*/ 213 214/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 215/** 216\fn uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) 217\details 218The function \b osMemoryPoolGetCount returns the number of memory blocks used in the memory pool object specified by 219parameter \a mp_id or \token{0} in case of an error. 220 221\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 222*/ 223 224/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 225/** 226\fn uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) 227\details 228The function \b osMemoryPoolGetSpace returns the number of memory blocks available in the memory pool object specified by 229parameter \a mp_id or \token{0} in case of an error. 230 231\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 232*/ 233 234/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 235/** 236\fn osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) 237\details 238The function \b osMemoryPoolDelete deletes a memory pool object specified by parameter \a mp_id. It releases internal 239memory obtained for memory pool handling. After this call, the \a mp_id is no longer valid and cannot be used. The 240memory pool may be created again using the function \ref osMemoryPoolNew. 241 242Possible \ref osStatus_t return values: 243 - \em osOK: the memory pool object has been deleted. 244 - \em osErrorParameter: parameter \a mp_id is \token{NULL} or invalid. 245 - \em osErrorResource: the memory pool is in an invalid state. 246 - \em osErrorISR: \b osMemoryPoolDelete cannot be called from interrupt service routines. 247 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified memory pool. 248 249\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 250*/ 251/// @} 252 253// these struct members must stay outside the group to avoid double entries in documentation 254/** 255\var osMemoryPoolAttr_t::attr_bits 256\details 257Reserved for future use (set to '0').\n 258Default: \token{0}. 259 260\var osMemoryPoolAttr_t::cb_mem 261\details 262Pointer to a memory location for the memory pool control block object. This can optionally be used for custom memory management systems.\n 263Default: \token{NULL} (uses kernel memory management). 264 265\var osMemoryPoolAttr_t::cb_size 266\details 267The size of the memory block passed with \ref cb_mem. Must be the size of a memory pool control block object or larger. 268 269\var osMemoryPoolAttr_t::name 270\details 271Pointer to a string with a human readable name of the memory pool object.\n 272Default: \token{NULL}. 273 274\var osMemoryPoolAttr_t::mp_mem 275\details 276Pointer to a memory location for the data of the memory pool object.\n 277Default: \token{NULL}. 278 279\var osMemoryPoolAttr_t::mp_size 280\details 281The size of the memory passed with \ref mp_mem. 282*/ 283