1 /**
2  * @file lv_cmsis_rtos2.c
3  *
4  */
5 
6 /*
7  * Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved.
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 /*********************
13  *      INCLUDES
14  *********************/
15 #include "lv_os.h"
16 
17 #if LV_USE_OS == LV_OS_CMSIS_RTOS2
18 
19 #include "../misc/lv_log.h"
20 
21 /*********************
22  *      DEFINES
23  *********************/
24 
25 /**********************
26  *      TYPEDEFS
27  **********************/
28 
29 /**********************
30  *  STATIC PROTOTYPES
31  **********************/
32 
33 /**********************
34  *  STATIC VARIABLES
35  **********************/
36 
37 /**********************
38  *      MACROS
39  **********************/
40 
41 /**********************
42  *   GLOBAL FUNCTIONS
43  **********************/
44 
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)45 lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio,
46                            void (*callback)(void *), size_t stack_size,
47                            void * user_data)
48 {
49     LV_UNUSED(name);
50     static const osPriority_t prio_map[] = {
51         [LV_THREAD_PRIO_LOWEST] = osPriorityLow,
52         [LV_THREAD_PRIO_LOW] = osPriorityBelowNormal,
53         [LV_THREAD_PRIO_MID] = osPriorityNormal,
54         [LV_THREAD_PRIO_HIGH] = osPriorityHigh,
55         [LV_THREAD_PRIO_HIGHEST] = osPriorityRealtime7,
56     };
57 
58     osThreadAttr_t c_tThreadAttribute = {
59         .stack_size = stack_size,
60         .priority = prio_map[prio],
61     };
62 
63     *thread = osThreadNew(callback, user_data, &c_tThreadAttribute);
64 
65     if(NULL == *thread) {
66         LV_LOG_WARN("Error: Failed to create a cmsis-rtos2 thread.");
67         return LV_RESULT_INVALID;
68     }
69 
70     return LV_RESULT_OK;
71 
72 }
73 
lv_thread_delete(lv_thread_t * thread)74 lv_result_t lv_thread_delete(lv_thread_t * thread)
75 {
76     osThreadDetach(*thread);
77     osStatus_t status = osThreadTerminate(*thread);
78     if(status == osOK) {
79         return LV_RESULT_OK;
80     }
81     return LV_RESULT_INVALID;
82 }
83 
lv_mutex_init(lv_mutex_t * mutex)84 lv_result_t lv_mutex_init(lv_mutex_t * mutex)
85 {
86     const osMutexAttr_t Thread_Mutex_attr = {
87         "LVGLMutex",
88         osMutexRecursive | osMutexPrioInherit | osMutexRobust,
89     };
90 
91     *mutex = osMutexNew(&Thread_Mutex_attr);
92     if(*mutex == NULL)  {
93         LV_LOG_WARN("Error: failed to create cmsis-rtos mutex");
94         return LV_RESULT_INVALID;
95     }
96 
97     return LV_RESULT_OK;
98 
99 }
100 
lv_mutex_lock(lv_mutex_t * mutex)101 lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
102 {
103     osStatus_t status = osMutexAcquire(*mutex, 0U);
104     if(status != osOK)  {
105         LV_LOG_WARN("Error: failed to lock cmsis-rtos2 mutex %d", (int)status);
106         return LV_RESULT_INVALID;
107     }
108 
109     return LV_RESULT_OK;
110 }
111 
lv_mutex_lock_isr(lv_mutex_t * mutex)112 lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
113 {
114     osStatus_t status = osMutexAcquire(*mutex, 0U);
115     if(status != osOK)  {
116         LV_LOG_WARN("Error: failed to lock cmsis-rtos2 mutex in an ISR %d", (int)status);
117         return LV_RESULT_INVALID;
118     }
119 
120     return LV_RESULT_OK;
121 }
122 
lv_mutex_unlock(lv_mutex_t * mutex)123 lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
124 {
125     osStatus_t status = osMutexRelease(*mutex);
126     if(status != osOK)  {
127         LV_LOG_WARN("Error: failed to release cmsis-rtos2 mutex %d", (int)status);
128         return LV_RESULT_INVALID;
129     }
130 
131     return LV_RESULT_OK;
132 }
133 
lv_mutex_delete(lv_mutex_t * mutex)134 lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
135 {
136     osStatus_t status = osMutexDelete(*mutex);
137     if(status != osOK)  {
138         LV_LOG_WARN("Error: failed to delete cmsis-rtos2 mutex %d", (int)status);
139         return LV_RESULT_INVALID;
140     }
141 
142     return LV_RESULT_OK;
143 }
144 
lv_thread_sync_init(lv_thread_sync_t * sync)145 lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
146 {
147     *sync = osEventFlagsNew(NULL);
148     if(NULL == *sync) {
149         LV_LOG_WARN("Error: failed to create a cmsis-rtos2 EventFlag");
150         return LV_RESULT_INVALID;
151     }
152     return LV_RESULT_OK;
153 }
154 
lv_thread_sync_wait(lv_thread_sync_t * sync)155 lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
156 {
157     uint32_t ret = osEventFlagsWait(*sync, 0x01, osFlagsWaitAny, osWaitForever);
158     if(ret & (1 << 31)) {
159         LV_LOG_WARN("Error: failed to wait a cmsis-rtos2 EventFlag %d", ret);
160         return LV_RESULT_INVALID;
161     }
162 
163     return LV_RESULT_OK;
164 }
165 
lv_thread_sync_signal(lv_thread_sync_t * sync)166 lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
167 {
168     uint32_t ret = osEventFlagsSet(*sync, 0x01);
169     if(ret & (1 << 31)) {
170         LV_LOG_WARN("Error: failed to set a cmsis-rtos2 EventFlag %d", ret);
171         return LV_RESULT_INVALID;
172     }
173 
174     return LV_RESULT_OK;
175 }
176 
lv_thread_sync_signal_isr(lv_thread_sync_t * sync)177 lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
178 {
179     return lv_thread_sync_signal(sync);
180 }
181 
lv_thread_sync_delete(lv_thread_sync_t * sync)182 lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
183 {
184     osStatus_t status = osEventFlagsDelete(*sync);
185     if(status != osOK)  {
186         LV_LOG_WARN("Error: failed to delete a cmsis-rtos2 EventFlag %d", (int)status);
187         return LV_RESULT_INVALID;
188     }
189 
190     return LV_RESULT_OK;
191 }
192 
193 /**********************
194  *   STATIC FUNCTIONS
195  **********************/
196 
197 #endif /*LV_USE_OS == LV_OS_CMSIS_RTOS2*/
198