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