1 /**
2  * @file lv_mem.h
3  *
4  */
5 
6 #ifndef LV_MEM_H
7 #define LV_MEM_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 
18 #include <stdint.h>
19 #include <stddef.h>
20 #include "lv_log.h"
21 #include "lv_types.h"
22 
23 #if LV_MEMCPY_MEMSET_STD
24 #include <string.h>
25 #endif
26 
27 /*********************
28  *      DEFINES
29  *********************/
30 
31 #ifndef LV_MEM_BUF_MAX_NUM
32 #define LV_MEM_BUF_MAX_NUM    16
33 #endif
34 
35 /**********************
36  *      TYPEDEFS
37  **********************/
38 
39 /**
40  * Heap information structure.
41  */
42 typedef struct {
43     uint32_t total_size; /**< Total heap size */
44     uint32_t free_cnt;
45     uint32_t free_size; /**< Size of available memory */
46     uint32_t free_biggest_size;
47     uint32_t used_cnt;
48     uint32_t max_used; /**< Max size of Heap memory used */
49     uint8_t used_pct; /**< Percentage used */
50     uint8_t frag_pct; /**< Amount of fragmentation */
51 } lv_mem_monitor_t;
52 
53 typedef struct {
54     void * p;
55     uint16_t size;
56     uint8_t used    : 1;
57 } lv_mem_buf_t;
58 
59 typedef lv_mem_buf_t lv_mem_buf_arr_t[LV_MEM_BUF_MAX_NUM];
60 extern lv_mem_buf_arr_t _lv_mem_buf;
61 
62 /**********************
63  * GLOBAL PROTOTYPES
64  **********************/
65 
66 /**
67  * Initialize the dyn_mem module (work memory and other variables)
68  */
69 void _lv_mem_init(void);
70 
71 /**
72  * Clean up the memory buffer which frees all the allocated memories.
73  * @note It work only if `LV_MEM_CUSTOM == 0`
74  */
75 void _lv_mem_deinit(void);
76 
77 /**
78  * Allocate a memory dynamically
79  * @param size size of the memory to allocate in bytes
80  * @return pointer to the allocated memory
81  */
82 void * lv_mem_alloc(size_t size);
83 
84 /**
85  * Free an allocated data
86  * @param data pointer to an allocated memory
87  */
88 void lv_mem_free(const void * data);
89 
90 /**
91  * Reallocate a memory with a new size. The old content will be kept.
92  * @param data pointer to an allocated memory.
93  * Its content will be copied to the new memory block and freed
94  * @param new_size the desired new size in byte
95  * @return pointer to the new memory
96  */
97 void * lv_mem_realloc(void * data_p, size_t new_size);
98 
99 /**
100  * Join the adjacent free memory blocks
101  */
102 void lv_mem_defrag(void);
103 
104 /**
105  *
106  * @return
107  */
108 lv_res_t lv_mem_test(void);
109 
110 /**
111  * Give information about the work memory of dynamic allocation
112  * @param mon_p pointer to a dm_mon_p variable,
113  *              the result of the analysis will be stored here
114  */
115 void lv_mem_monitor(lv_mem_monitor_t * mon_p);
116 
117 /**
118  * Give the size of an allocated memory
119  * @param data pointer to an allocated memory
120  * @return the size of data memory in bytes
121  */
122 uint32_t _lv_mem_get_size(const void * data);
123 
124 /**
125  * Get a temporal buffer with the given size.
126  * @param size the required size
127  */
128 void * _lv_mem_buf_get(uint32_t size);
129 
130 /**
131  * Release a memory buffer
132  * @param p buffer to release
133  */
134 void _lv_mem_buf_release(void * p);
135 
136 /**
137  * Free all memory buffers
138  */
139 void _lv_mem_buf_free_all(void);
140 
141 
142 //! @cond Doxygen_Suppress
143 
144 #if LV_MEMCPY_MEMSET_STD
145 
146 /**
147  * Wrapper for the standard memcpy
148  * @param dst pointer to the destination buffer
149  * @param src pointer to the source buffer
150  * @param len number of byte to copy
151  */
_lv_memcpy(void * dst,const void * src,size_t len)152 static inline void * _lv_memcpy(void * dst, const void * src, size_t len)
153 {
154     return memcpy(dst, src, len);
155 }
156 
157 /**
158  * Wrapper for the standard memcpy
159  * @param dst pointer to the destination buffer
160  * @param src pointer to the source buffer
161  * @param len number of byte to copy
162  */
_lv_memcpy_small(void * dst,const void * src,size_t len)163 static inline void * _lv_memcpy_small(void * dst, const void * src, size_t len)
164 {
165     return memcpy(dst, src, len);
166 }
167 
168 /**
169  * Wrapper for the standard memset
170  * @param dst pointer to the destination buffer
171  * @param v value to set [0..255]
172  * @param len number of byte to set
173  */
_lv_memset(void * dst,uint8_t v,size_t len)174 static inline void _lv_memset(void * dst, uint8_t v, size_t len)
175 {
176     memset(dst, v, len);
177 }
178 
179 /**
180  * Wrapper for the standard memset with fixed 0x00 value
181  * @param dst pointer to the destination buffer
182  * @param len number of byte to set
183  */
_lv_memset_00(void * dst,size_t len)184 static inline void _lv_memset_00(void * dst, size_t len)
185 {
186     memset(dst, 0x00, len);
187 }
188 
189 /**
190  * Wrapper for the standard memset with fixed 0xFF value
191  * @param dst pointer to the destination buffer
192  * @param len number of byte to set
193  */
_lv_memset_ff(void * dst,size_t len)194 static inline void _lv_memset_ff(void * dst, size_t len)
195 {
196     memset(dst, 0xFF, len);
197 }
198 
199 #else
200 /**
201  * Same as `memcpy` but optimized for 4 byte operation.
202  * @param dst pointer to the destination buffer
203  * @param src pointer to the source buffer
204  * @param len number of byte to copy
205  */
206 LV_ATTRIBUTE_FAST_MEM void * _lv_memcpy(void * dst, const void * src, size_t len);
207 
208 /**
209  * Same as `memcpy` but optimized to copy only a few bytes.
210  * @param dst pointer to the destination buffer
211  * @param src pointer to the source buffer
212  * @param len number of byte to copy
213  */
_lv_memcpy_small(void * dst,const void * src,size_t len)214 LV_ATTRIBUTE_FAST_MEM static inline void * _lv_memcpy_small(void * dst, const void * src, size_t len)
215 {
216     uint8_t * d8 = (uint8_t *)dst;
217     const uint8_t * s8 = (const uint8_t *)src;
218 
219     while(len) {
220         *d8 = *s8;
221         d8++;
222         s8++;
223         len--;
224     }
225 
226     return dst;
227 }
228 
229 /**
230  * Same as `memset` but optimized for 4 byte operation.
231  * @param dst pointer to the destination buffer
232  * @param v value to set [0..255]
233  * @param len number of byte to set
234  */
235 LV_ATTRIBUTE_FAST_MEM void _lv_memset(void * dst, uint8_t v, size_t len);
236 
237 /**
238  * Same as `memset(dst, 0x00, len)` but optimized for 4 byte operation.
239  * @param dst pointer to the destination buffer
240  * @param len number of byte to set
241  */
242 LV_ATTRIBUTE_FAST_MEM void _lv_memset_00(void * dst, size_t len);
243 
244 /**
245  * Same as `memset(dst, 0xFF, len)` but optimized for 4 byte operation.
246  * @param dst pointer to the destination buffer
247  * @param len number of byte to set
248  */
249 LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len);
250 
251 //! @endcond
252 
253 #endif
254 
255 
256 /**********************
257  *      MACROS
258  **********************/
259 
260 #ifdef __cplusplus
261 } /* extern "C" */
262 #endif
263 
264 #endif /*LV_MEM_H*/
265