1 /**
2 * @file lv_os.h
3 *
4 */
5
6 #ifndef LV_OS_H
7 #define LV_OS_H
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 /*********************
14 * OS OPTIONS
15 *********************/
16
17 /*********************
18 * INCLUDES
19 *********************/
20 #include "../lv_conf_internal.h"
21
22 #include "../misc/lv_types.h"
23
24 #if LV_USE_OS == LV_OS_NONE
25 #include "lv_os_none.h"
26 #elif LV_USE_OS == LV_OS_PTHREAD
27 #include "lv_pthread.h"
28 #elif LV_USE_OS == LV_OS_FREERTOS
29 #include "lv_freertos.h"
30 #elif LV_USE_OS == LV_OS_CMSIS_RTOS2
31 #include "lv_cmsis_rtos2.h"
32 #elif LV_USE_OS == LV_OS_RTTHREAD
33 #include "lv_rtthread.h"
34 #elif LV_USE_OS == LV_OS_WINDOWS
35 #include "lv_windows.h"
36 #elif LV_USE_OS == LV_OS_MQX
37 #include "lv_mqx.h"
38 #elif LV_USE_OS == LV_OS_SDL2
39 #include "lv_sdl2.h"
40 #elif LV_USE_OS == LV_OS_CUSTOM
41 #include LV_OS_CUSTOM_INCLUDE
42 #endif
43
44 /*********************
45 * DEFINES
46 *********************/
47
48 /**********************
49 * TYPEDEFS
50 **********************/
51 typedef enum {
52 LV_THREAD_PRIO_LOWEST,
53 LV_THREAD_PRIO_LOW,
54 LV_THREAD_PRIO_MID,
55 LV_THREAD_PRIO_HIGH,
56 LV_THREAD_PRIO_HIGHEST,
57 } lv_thread_prio_t;
58
59 /**********************
60 * GLOBAL PROTOTYPES
61 **********************/
62
63 #if LV_USE_OS != LV_OS_NONE
64
65 /*----------------------------------------
66 * These functions needs to be implemented
67 * for specific operating systems
68 *---------------------------------------*/
69
70 /**
71 * Create a new thread
72 * @param thread a variable in which the thread will be stored
73 * @param name the name of the thread
74 * @param prio priority of the thread
75 * @param callback function of the thread
76 * @param stack_size stack size in bytes
77 * @param user_data arbitrary data, will be available in the callback
78 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
79 */
80 lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name,
81 lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
82 void * user_data);
83
84 /**
85 * Delete a thread
86 * @param thread the thread to delete
87 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
88 */
89 lv_result_t lv_thread_delete(lv_thread_t * thread);
90
91 /**
92 * Create a mutex
93 * @param mutex a variable in which the thread will be stored
94 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
95 */
96 lv_result_t lv_mutex_init(lv_mutex_t * mutex);
97
98 /**
99 * Lock a mutex
100 * @param mutex the mutex to lock
101 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
102 */
103 lv_result_t lv_mutex_lock(lv_mutex_t * mutex);
104
105 /**
106 * Lock a mutex from interrupt
107 * @param mutex the mutex to lock
108 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
109 */
110 lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex);
111
112 /**
113 * Unlock a mutex
114 * @param mutex the mutex to unlock
115 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
116 */
117 lv_result_t lv_mutex_unlock(lv_mutex_t * mutex);
118
119 /**
120 * Delete a mutex
121 * @param mutex the mutex to delete
122 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
123 */
124 lv_result_t lv_mutex_delete(lv_mutex_t * mutex);
125
126 /**
127 * Create a thread synchronization object
128 * @param sync a variable in which the sync will be stored
129 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
130 */
131 lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync);
132
133 /**
134 * Wait for a "signal" on a sync object
135 * @param sync a sync object
136 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
137 */
138 lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync);
139
140 /**
141 * Send a wake-up signal to a sync object
142 * @param sync a sync object
143 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
144 */
145 lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync);
146
147 /**
148 * Send a wake-up signal to a sync object from interrupt
149 * @param sync a sync object
150 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
151 */
152 lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync);
153
154 /**
155 * Delete a sync object
156 * @param sync a sync object to delete
157 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
158 */
159 lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync);
160
161 /**
162 * Lock LVGL's general mutex.
163 * LVGL is not thread safe, so a mutex is used to avoid executing multiple LVGL functions at the same time
164 * from different threads. It shall be called when calling LVGL functions from threads
165 * different than lv_timer_handler's thread. It doesn't need to be called in LVGL events because
166 * they are called from lv_timer_handler().
167 * It is called internally in lv_timer_handler().
168 */
169 void lv_lock(void);
170
171 /**
172 * Same as `lv_lock()` but can be called from an interrupt.
173 * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
174 */
175 lv_result_t lv_lock_isr(void);
176
177 /**
178 * The pair of `lv_lock()` and `lv_lock_isr()`.
179 * It unlocks LVGL general mutex.
180 * It is called internally in lv_timer_handler().
181 */
182 void lv_unlock(void);
183
184 #else
185
186 /* Since compilation does not necessarily optimize cross-file empty functions well
187 * (-O3 optimization alone is not enough unless LTO optimization is enabled),
188 * In the absence of an operating system, use inline functions to help compile
189 * optimizations and avoid the call overhead of the OS API to ensure no performance penalty.
190 */
191
lv_thread_init(lv_thread_t * thread,const char * const name,lv_thread_prio_t prio,void (* callback)(void *),size_t stack_size,void * user_data)192 static inline lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio,
193 void (*callback)(void *), size_t stack_size, void * user_data)
194 {
195 LV_UNUSED(thread);
196 LV_UNUSED(name);
197 LV_UNUSED(callback);
198 LV_UNUSED(prio);
199 LV_UNUSED(stack_size);
200 LV_UNUSED(user_data);
201 return LV_RESULT_INVALID;
202 }
203
lv_thread_delete(lv_thread_t * thread)204 static inline lv_result_t lv_thread_delete(lv_thread_t * thread)
205 {
206 LV_UNUSED(thread);
207 return LV_RESULT_INVALID;
208 }
209
lv_mutex_init(lv_mutex_t * mutex)210 static inline lv_result_t lv_mutex_init(lv_mutex_t * mutex)
211 {
212 LV_UNUSED(mutex);
213 return LV_RESULT_OK;
214 }
215
lv_mutex_lock(lv_mutex_t * mutex)216 static inline lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
217 {
218 LV_UNUSED(mutex);
219 return LV_RESULT_OK;
220 }
221
lv_mutex_lock_isr(lv_mutex_t * mutex)222 static inline lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
223 {
224 LV_UNUSED(mutex);
225 return LV_RESULT_OK;
226 }
227
lv_mutex_unlock(lv_mutex_t * mutex)228 static inline lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
229 {
230 LV_UNUSED(mutex);
231 return LV_RESULT_OK;
232 }
233
lv_mutex_delete(lv_mutex_t * mutex)234 static inline lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
235 {
236 LV_UNUSED(mutex);
237 return LV_RESULT_OK;
238 }
239
lv_thread_sync_init(lv_thread_sync_t * sync)240 static inline lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
241 {
242 LV_UNUSED(sync);
243 return LV_RESULT_INVALID;
244 }
245
lv_thread_sync_wait(lv_thread_sync_t * sync)246 static inline lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
247 {
248 LV_UNUSED(sync);
249 return LV_RESULT_INVALID;
250 }
251
lv_thread_sync_signal(lv_thread_sync_t * sync)252 static inline lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
253 {
254 LV_UNUSED(sync);
255 return LV_RESULT_INVALID;
256 }
257
lv_thread_sync_signal_isr(lv_thread_sync_t * sync)258 static inline lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
259 {
260 LV_UNUSED(sync);
261 return LV_RESULT_INVALID;
262 }
263
lv_thread_sync_delete(lv_thread_sync_t * sync)264 static inline lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
265 {
266 LV_UNUSED(sync);
267 return LV_RESULT_INVALID;
268 }
269
lv_lock(void)270 static inline void lv_lock(void)
271 {
272 /*Do nothing*/
273 }
274
lv_lock_isr(void)275 static inline lv_result_t lv_lock_isr(void)
276 {
277 return LV_RESULT_OK;
278 }
279
lv_unlock(void)280 static inline void lv_unlock(void)
281 {
282 /*Do nothing*/
283 }
284
285 #endif /*LV_USE_OS != LV_OS_NONE*/
286
287 /**********************
288 * MACROS
289 **********************/
290
291 #ifdef __cplusplus
292 } /*extern "C"*/
293 #endif
294
295 #endif /*LV_OS_H*/
296