1 /**
2  * Copyright (c) 2017, Realtek Semiconductor Corporation. All rights reserved.
3  */
4 
5 #ifndef _OS_MEM_H_
6 #define _OS_MEM_H_
7 
8 #include <stdint.h>
9 #include <stddef.h>
10 #include <mem_types.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /**
17  * \addtogroup  OS      OSIF
18  * \defgroup    Memory  Memory Management
19  *
20  * \brief   Allocate, free, and peek memory functions.
21  * \details The Memory Management function group allows to allocate, free, and peek heap
22  *          memory in the system.\n
23  *
24  * \ingroup     OS
25  */
26 
27 
28 void *os_mem_alloc_intern(RAM_TYPE ram_type, size_t size,
29                           const char *p_func, uint32_t file_line);
30 
31 void *os_mem_zalloc_intern(RAM_TYPE ram_type, size_t size,
32                            const char *p_func, uint32_t file_line);
33 
34 void *os_mem_aligned_alloc_intern(RAM_TYPE ram_type, size_t size, uint8_t alignment,
35                                   const char *p_func, uint32_t file_line);
36 
37 /**
38  * os_mem.h
39  *
40  * \brief    Allocate a memory block with required size.
41  *
42  * \param[in]   ram_type            RAM type for allocation.
43  * \arg \c      RAM_TYPE_DATA_ON    Data ON RAM type.
44  * \arg \c      RAM_TYPE_DATA_OFF   Data OFF RAM type.
45  * \arg \c      RAM_TYPE_BUFFER_ON  BUFFER ON RAM type.
46  * \arg \c      RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
47  *
48  * \param[in]   size     Required memory size.
49  *
50  * \return     The address of the allocated memory block. If the address is NULL, the
51  *             memory allocation failed.
52  *
53  * <b>Example usage</b>
54  * \code{.c}
55  * int test(void)
56  * {
57  *     size_t mem_size = 0x1000;
58  *     void *p_mem = NULL;
59  *
60  *     p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size);
61  *     if (p_mem != NULL)
62  *     {
63  *         // Memory allocation successed, and free it.
64  *         os_mem_free(p_mem);
65  *     }
66  *     else
67  *     {
68  *         // Memory allocation failed.
69  *         return -1;
70  *     }
71  *
72  *     return 0;
73  * }
74  * \endcode
75  *
76  * \ingroup  Memory
77  */
78 #define os_mem_alloc(ram_type, size)    \
79     os_mem_alloc_intern(ram_type, size, __func__, __LINE__)
80 
81 /**
82  * os_mem.h
83  *
84  * \brief    Allocate and clear a memory block with required size.
85  *
86  * \param[in]   ram_type            RAM type for allocation.
87  * \arg \c      RAM_TYPE_DATA_ON    Data ON RAM type.
88  * \arg \c      RAM_TYPE_DATA_OFF   Data OFF RAM type.
89  * \arg \c      RAM_TYPE_BUFFER_ON  BUFFER ON RAM type.
90  * \arg \c      RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
91  *
92  * \param[in]   size     Required memory size.
93  *
94  * \return     The address of the allocated memory block. If the address is NULL, the
95  *             memory allocation failed.
96  *
97  * <b>Example usage</b>
98  * \code{.c}
99  * int test(void)
100  * {
101  *     size_t mem_size = 0x1000;
102  *     void *p_mem = NULL;
103  *
104  *     p_mem = os_mem_zalloc(RAM_TYPE_DATA_ON, mem_size);
105  *     if (p_mem != NULL)
106  *     {
107  *         // Memory allocation successed, and free it.
108  *         os_mem_free(p_mem);
109  *     }
110  *     else
111  *     {
112  *         // Memory allocation failed.
113  *         return -1;
114  *     }
115  *
116  *     return 0;
117  * }
118  * \endcode
119  *
120  * \ingroup  Memory
121  */
122 #define os_mem_zalloc(ram_type, size)   \
123     os_mem_zalloc_intern(ram_type, size, __func__, __LINE__)
124 
125 /**
126  * os_mem.h
127  *
128  * \brief    Allocate an aligned memory block with required size.
129  *
130  * \param[in]   ram_type            RAM type for allocation.
131  * \arg \c      RAM_TYPE_DATA_ON    Data ON RAM type.
132  * \arg \c      RAM_TYPE_DATA_OFF   Data OFF RAM type.
133  * \arg \c      RAM_TYPE_BUFFER_ON  BUFFER ON RAM type.
134  * \arg \c      RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
135  *
136  * \param[in]   size        Required memory size.
137  *
138  * \param[in]   alignment   memory alignment in 2^N bytes. If alignment is 0, use
139  *                          system default memory alignment. The aligned memory block
140  *                          must use os_mem_aligned_free() API function to free.
141  *
142  * \return     The address of the allocated memory block. If the address is NULL, the
143  *             memory allocation failed.
144  *
145  * <b>Example usage</b>
146  * \code{.c}
147  * int test(void)
148  * {
149  *     size_t mem_size = 0x1000;
150  *     uint8_t mem_alignment = 16;
151  *     void *p_mem = NULL;
152  *
153  *     p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment);
154  *     if (p_mem != NULL)
155  *     {
156  *         // Aligned memory allocation successed, and free it.
157  *         os_mem_aligned_free(p_mem);
158  *     }
159  *     else
160  *     {
161  *         // Aligned memory allocation failed.
162  *         return -1;
163  *     }
164  *
165  *     return 0;
166  * }
167  * \endcode
168  *
169  * \ingroup  Memory
170  */
171 #define os_mem_aligned_alloc(ram_type, size, alignment) \
172     os_mem_aligned_alloc_intern(ram_type, size, alignment, __func__, __LINE__)
173 
174 /**
175  * os_mem.h
176  *
177  * \brief    Free a memory block that had been allocated.
178  *
179  * \param[in]   p_block     The address of memory block being freed.
180  *
181  * \return     None.
182  *
183  * <b>Example usage</b>
184  * \code{.c}
185  * int test(void)
186  * {
187  *     size_t mem_size = 0x1000;
188  *     void *p_mem = NULL;
189  *
190  *     p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size);
191  *     if (p_mem != NULL)
192  *     {
193  *         // Memory allocation successed, and free it.
194  *         os_mem_free(p_mem);
195  *     }
196  *     else
197  *     {
198  *         // Memory allocation failed.
199  *         return -1;
200  *     }
201  *
202  *     return 0;
203  * }
204  * \endcode
205  *
206  * \ingroup  Memory
207  */
208 void os_mem_free(void *p_block);
209 
210 /**
211  * os_mem.h
212  *
213  * \brief    Free an aligned memory block that had been allocated.
214  *
215  * \param[in]   p_block     The address of memory block being freed.
216  *
217  * \return     None.
218  *
219  * <b>Example usage</b>
220  * \code{.c}
221  * int test(void)
222  * {
223  *     size_t mem_size = 0x1000;
224  *     uint8_t mem_alignment = 16;
225  *     void *p_mem = NULL;
226  *
227  *     p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment);
228  *     if (p_mem != NULL)
229  *     {
230  *         // Aligned memory allocation successed, and free it.
231  *         os_mem_aligned_free(p_mem);
232  *     }
233  *     else
234  *     {
235  *         // Aligned memory allocation failed.
236  *         return -1;
237  *     }
238  *
239  *     return 0;
240  * }
241  * \endcode
242  *
243  * \ingroup  Memory
244  */
245 void os_mem_aligned_free(void *p_block);
246 
247 /**
248  * os_mem.h
249  *
250  * \brief    Peek the unused memory size of the specified RAM type.
251  *
252  * \param[in]   ram_type            RAM type for allocation.
253  * \arg \c      RAM_TYPE_DATA_ON    Data ON RAM type.
254  * \arg \c      RAM_TYPE_DATA_OFF   Data OFF RAM type.
255  * \arg \c      RAM_TYPE_BUFFER_ON  BUFFER ON RAM type.
256  * \arg \c      RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
257  *
258  * \return     The unused memory size in btyes.
259  *
260  * <b>Example usage</b>
261  * \code{.c}
262  * int test(void)
263  * {
264  *     size_t unused_data_on;
265  *     size_t unused_data_off;
266  *
267  *     // Peek unused DATA ON memory size.
268  *     unused_size = os_mem_peek(RAM_TYPE_DATA_ON);
269  *
270  *     // Peek unused DATA OFF memory size.
271  *     unused_size = os_mem_peek(RAM_TYPE_DATA_OFF);
272  *
273  *     return 0;
274  * }
275  * \endcode
276  *
277  * \ingroup  Memory
278  */
279 size_t os_mem_peek(RAM_TYPE ram_type);
280 
281 #ifdef __cplusplus
282 }
283 #endif
284 
285 #endif /* _OS_MEM_H_ */
286