1 /**
2  * Copyright (c) 2015, Realtek Semiconductor Corporation. All rights reserved.
3  */
4 
5 #ifndef _OS_POOL_H_
6 #define _OS_POOL_H_
7 
8 #include <stdint.h>
9 #include <stdbool.h>
10 #include <mem_types.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /**
17  * \addtogroup  OS      OSIF
18  * \defgroup    Pool    Pool Management
19  *
20  * \brief   Manage task-safe and fixed-size blocks of dynamic memory.
21  * \details Memory pools are fixed-size blocks of memory that are task-safe. They operate much
22  *          faster than the dynamically allocated heap and do not suffer from fragmentation.
23  *          Being task-safe, they can be accessed from tasks and ISRs alike.\n
24  *          Shared memory is one of the basic models to exchange information between tasks.
25  *          Using memory pools for exchanging data, you can share more complex objects between
26  *          taks if compared to the Message Queue. Memory pool management functions are used to
27  *          define and manage such fixed-sized memory pools.\n
28  *
29  * \image html OS-pool-overview.jpg "Memory Pool Overview" width=601px height=481px
30  *
31  * \ingroup     OS
32  */
33 
34 
35 /**
36  * os_pool.h
37  *
38  * \brief The invalid pool handle. Valid pool handles should be less than OS_POOL_INVALID_HANDLE.
39  *
40  * \ingroup Pool
41  */
42 #define OS_POOL_INVALID_HANDLE  0xFF
43 
44 bool os_pool_create_intern(uint8_t *p_handle, RAM_TYPE ram_type, uint16_t buf_size,
45                            uint16_t buf_count, const char *p_func, uint32_t file_line);
46 
47 bool os_pool_extend_intern(uint8_t handle, uint16_t buf_size, uint16_t buf_count,
48                            const char *p_func, uint32_t file_line);
49 
50 bool os_pool_delete_intern(uint8_t handle, const char *p_func, uint32_t file_line);
51 
52 void *os_buffer_get_intern(uint8_t handle, uint16_t buf_size,
53                            const char *p_func, uint32_t file_line);
54 
55 bool os_buffer_put_intern(void *p_buf, const char *p_func, uint32_t file_line);
56 
57 /**
58  * os_pool.h
59  *
60  * \brief   Creates and initialize a memory pool.
61  *
62  * \param[out]  p_handle   Used to pass back a handle by which the memory pool
63  *                         can be referenced.
64  *
65  * \param[in]   ram_type            RAM type for the memory pool buffer.
66  * \arg \c      RAM_TYPE_DATA_ON    Data ON RAM type.
67  * \arg \c      RAM_TYPE_DATA_OFF   Data OFF RAM type.
68  * \arg \c      RAM_TYPE_BUFFER_ON  BUFFER ON RAM type.
69  * \arg \c      RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
70  *
71  * \param[in]   buf_size   The pool buffer size in bytes.
72  *
73  * \param[in]   buf_count  The number of pool buffers allocated.
74  *
75  * \return           The status of the memory pool creation.
76  * \retval true      Pool was created successfully.
77  * \retval false     Pool was failed to create.
78  *
79  * <b>Example usage</b>
80  * \code{.c}
81  * #define BUF_SIZE 0x40
82  * #define BUF_NUM  16
83  *
84  * int test(void)
85  * {
86  *     uint8_t handle;
87  *
88  *     // Create a memory pool capable of containing 16 buffers.
89  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true)
90  *     {
91  *         // Memory pool created successfully.
92  *     }
93  *     else
94  *     {
95  *         // Memory pool failed to create.
96  *         return -1;
97  *     }
98  *
99  *     return 0;
100  * }
101  * \endcode
102  *
103  * \ingroup  Pool
104  */
105 #define os_pool_create(p_handle, ram_type, buf_size, buf_count) \
106     os_pool_create_intern(p_handle, ram_type, buf_size, buf_count, __func__, __LINE__)
107 
108 /**
109  * os_pool.h
110  *
111  * \brief   Extend a set of buffers to the created memory pool. The extended pool
112  *          buffers have the same RAM type with the created buffers.
113  *
114  * \param[in]   handle     The handle of the created memory pool.
115  *
116  * \param[in]   buf_size   The pool buffer size in bytes.
117  *
118  * \param[in]   buf_count  The number of pool buffers allocated.
119  *
120  * \return           The status of the memory pool extension.
121  * \retval true      Pool was extended successfully.
122  * \retval false     Pool was failed to extend.
123  *
124  * <b>Example usage</b>
125  * \code{.c}
126  * #define BUF_SIZE1 0x40
127  * #define BUF_NUM1  16
128  * #define BUF_SIZE2 0x20
129  * #define BUF_NUM2  8
130  *
131  * int test(void)
132  * {
133  *     uint8_t handle;
134  *
135  *     // Create a memory pool capable of containing 16 buffers.
136  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
137  *     {
138  *         // Memory pool created successfully.
139  *     }
140  *     else
141  *     {
142  *         // Memory pool failed to create.
143  *         return -1;
144  *     }
145  *
146  *     // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
147  *     os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
148  *
149  *     return 0;
150  * }
151  * \endcode
152  *
153  * \ingroup  Pool
154  */
155 #define os_pool_extend(handle, buf_size, buf_count) \
156     os_pool_extend_intern(handle, buf_size, buf_count, __func__, __LINE__)
157 
158 /**
159  * os_pool.h
160  *
161  * \brief   Delete a memory pool.
162  *
163  * \param[in]   handle   The handle of the memory pool to be deleted.
164  *
165  * \return           The status of the memory pool deletion.
166  * \retval true      Pool was deleted successfully.
167  * \retval false     Pool was failed to delete.
168  *
169  * <b>Example usage</b>
170  * \code{.c}
171  * #define BUF_SIZE 0x40
172  * #define BUF_NUM  16
173  *
174  * int test(void)
175  * {
176  *     uint8_t handle;
177  *
178  *     // Create a memory pool capable of containing 16 buffers.
179  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true)
180  *     {
181  *         // Memory pool created successfully.
182  *     }
183  *     else
184  *     {
185  *         // Memory pool failed to create.
186  *         return -1;
187  *     }
188  *
189  *     // Delete the memory pool.
190  *     os_pool_delete(handle);
191  *
192  *     return 0;
193  * }
194  * \endcode
195  *
196  * \ingroup  Pool
197  */
198 #define os_pool_delete(handle)  os_pool_delete_intern(handle, __func__, __LINE__)
199 
200 /**
201  * os_pool.h
202  *
203  * \brief   Allocate a pool buffer from the specified memory pool. The allocated pool
204  *          buffer size may be larger than the required size.
205  *
206  * \param[in]   handle     The handle of the created memory pool.
207  *
208  * \param[in]   buf_size   The pool buffer size in bytes.
209  *
210  * \return           The address of the allocated pool buffer. If the address is NULL,
211  *                   the buffer allocation failed.
212  *
213  * <b>Example usage</b>
214  * \code{.c}
215  * #define BUF_SIZE1 0x40
216  * #define BUF_NUM1  16
217  * #define BUF_SIZE2 0x20
218  * #define BUF_NUM2  8
219  *
220  * int test(void)
221  * {
222  *     uint8_t handle;
223  *     void *p_buf;
224  *
225  *     // Create a memory pool capable of containing 16 buffers.
226  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
227  *     {
228  *         // Memory pool created successfully.
229  *     }
230  *     else
231  *     {
232  *         // Memory pool failed to create.
233  *         return -1;
234  *     }
235  *
236  *     // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
237  *     os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
238  *
239  *     // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
240  *     // give a buffer in 0x40 bytes.
241  *     p_buf = os_buffer_get(handle, 0x30);
242  *
243  *     return 0;
244  * }
245  * \endcode
246  *
247  * \ingroup  Pool
248  */
249 #define os_buffer_get(handle, buf_size) \
250     os_buffer_get_intern(handle, buf_size, __func__, __LINE__)
251 
252 /**
253  * os_pool.h
254  *
255  * \brief   Free and return the pool buffer to the specified memory pool.
256  *
257  * \param[in]   p_buf   The address of the pool buffer allocated by os_buffer_get()
258  *                      API function.
259  *
260  * \return           The status of the pool buffer freeing.
261  * \retval true      Pool was freed successfully.
262  * \retval false     Pool was failed to free.
263  *
264  * <b>Example usage</b>
265  * \code{.c}
266  * #define BUF_SIZE1 0x40
267  * #define BUF_NUM1  16
268  * #define BUF_SIZE2 0x20
269  * #define BUF_NUM2  8
270  *
271  * int test(void)
272  * {
273  *     uint8_t handle;
274  *     void *p_buf;
275  *
276  *     // Create a memory pool capable of containing 16 buffers.
277  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
278  *     {
279  *         // Memory pool created successfully.
280  *     }
281  *     else
282  *     {
283  *         // Memory pool failed to create.
284  *         return -1;
285  *     }
286  *
287  *     // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
288  *     os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
289  *
290  *     // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
291  *     // give a buffer in 0x40 bytes.
292  *     p_buf = os_buffer_get(handle, 0x30);
293  *
294  *     // Free the pool buffer by the address.
295  *     os_buffer_put(p_buf);
296  *
297  *     return 0;
298  * }
299  * \endcode
300  *
301  * \ingroup  Pool
302  */
303 #define os_buffer_put(p_buf)    \
304     os_buffer_put_intern(p_buf, __func__, __LINE__)
305 
306 /**
307  * os_pool.h
308  *
309  * \brief   Dump the pool buffers of the specified memory pool.
310  *
311  * \param[in]   handle  The handle of the memory pool buffer to be dumped. If the
312  *                      memory pool handle is invalid, all created memory pools
313  *                      will be dumped.
314  *
315  * \return     None.
316  *
317  * <b>Example usage</b>
318  * \code{.c}
319  * #define BUF_SIZE1 0x40
320  * #define BUF_NUM1  16
321  * #define BUF_SIZE2 0x20
322  * #define BUF_NUM2  8
323  *
324  * int test(void)
325  * {
326  *     uint8_t handle;
327  *     void *p_buf;
328  *
329  *     // Create a memory pool capable of containing 16 buffers.
330  *     if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
331  *     {
332  *         // Memory pool created successfully.
333  *     }
334  *     else
335  *     {
336  *         // Memory pool failed to create.
337  *         return -1;
338  *     }
339  *
340  *     // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
341  *     os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
342  *
343  *     // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
344  *     // give a buffer in 0x40 bytes.
345  *     p_buf = os_buffer_get(handle, 0x30);
346  *
347  *     // Dump the memory pool.
348  *     os_pool_dump(handle);
349  *
350  *     return 0;
351  * }
352  * \endcode
353  *
354  * \ingroup  Pool
355  */
356 void os_pool_dump(uint8_t handle);
357 
358 #ifdef __cplusplus
359 }
360 #endif
361 
362 #endif  /* _OS_POOL_H_ */
363