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