1 /*
2 * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "os_wrapper/thread.h"
9 #include "os_wrapper/mutex.h"
10 #include "os_wrapper/semaphore.h"
11 #include "os_wrapper/delay.h"
12
13 #include "cmsis_os2.h"
14
15 #include "tfm_nsid_manager.h"
16 #ifdef TFM_NS_MANAGE_NSID
17 #include "tfm_nsid_map_table.h"
18 #endif
19
20 /* This is an example OS abstraction layer for CMSIS-RTOSv2 */
21
os_wrapper_thread_new(const char * name,int32_t stack_size,os_wrapper_thread_func func,void * arg,uint32_t priority)22 void *os_wrapper_thread_new(const char *name, int32_t stack_size,
23 os_wrapper_thread_func func, void *arg,
24 uint32_t priority)
25 {
26 osThreadAttr_t task_attribs = {
27 .tz_module = ((TZ_ModuleId_t)TFM_DEFAULT_NSID)
28 };
29
30 /* By default, the thread starts as osThreadDetached */
31 if (stack_size != OS_WRAPPER_DEFAULT_STACK_SIZE) {
32 task_attribs.stack_size = stack_size;
33 }
34 task_attribs.name = name;
35 task_attribs.priority = (osPriority_t) priority;
36
37 #ifdef TFM_NS_MANAGE_NSID
38 task_attribs.tz_module = (TZ_ModuleId_t)nsid_mgr_get_thread_nsid(name);
39 #endif
40
41 return (void *)osThreadNew(func, arg, &task_attribs);
42 }
43
os_wrapper_semaphore_create(uint32_t max_count,uint32_t initial_count,const char * name)44 void *os_wrapper_semaphore_create(uint32_t max_count, uint32_t initial_count,
45 const char *name)
46 {
47 osSemaphoreAttr_t sema_attrib = {0};
48
49 sema_attrib.name = name;
50
51 return (void *)osSemaphoreNew(max_count, initial_count, &sema_attrib);
52 }
53
os_wrapper_semaphore_acquire(void * handle,uint32_t timeout)54 uint32_t os_wrapper_semaphore_acquire(void *handle, uint32_t timeout)
55 {
56 osStatus_t status;
57
58 status = osSemaphoreAcquire((osSemaphoreId_t)handle,
59 (timeout == OS_WRAPPER_WAIT_FOREVER) ?
60 osWaitForever : timeout);
61 if (status != osOK) {
62 return OS_WRAPPER_ERROR;
63 }
64
65 return OS_WRAPPER_SUCCESS;
66 }
67
os_wrapper_semaphore_release(void * handle)68 uint32_t os_wrapper_semaphore_release(void *handle)
69 {
70 osStatus_t status;
71
72 status = osSemaphoreRelease((osSemaphoreId_t)handle);
73 if (status != osOK) {
74 return OS_WRAPPER_ERROR;
75 }
76
77 return OS_WRAPPER_SUCCESS;
78 }
79
os_wrapper_semaphore_delete(void * handle)80 uint32_t os_wrapper_semaphore_delete(void *handle)
81 {
82 osStatus_t status;
83
84 status = osSemaphoreDelete((osSemaphoreId_t)handle);
85 if (status != osOK) {
86 return OS_WRAPPER_ERROR;
87 }
88
89 return OS_WRAPPER_SUCCESS;
90 }
91
os_wrapper_mutex_create(void)92 void *os_wrapper_mutex_create(void)
93 {
94 const osMutexAttr_t attr = {
95 .name = NULL,
96 .attr_bits = osMutexPrioInherit, /* Priority inheritance is recommended
97 * to enable if it is supported.
98 * For recursive mutex and the ability
99 * of auto release when owner being
100 * terminated is not required.
101 */
102 .cb_mem = NULL,
103 .cb_size = 0U
104 };
105
106 return (void *)osMutexNew(&attr);
107 }
108
os_wrapper_mutex_acquire(void * handle,uint32_t timeout)109 uint32_t os_wrapper_mutex_acquire(void *handle, uint32_t timeout)
110 {
111 osStatus_t status = osOK;
112
113 if (!handle) {
114 return OS_WRAPPER_ERROR;
115 }
116
117 status = osMutexAcquire((osMutexId_t)handle,
118 (timeout == OS_WRAPPER_WAIT_FOREVER) ?
119 osWaitForever : timeout);
120 if (status != osOK) {
121 return OS_WRAPPER_ERROR;
122 }
123
124 return OS_WRAPPER_SUCCESS;
125 }
126
os_wrapper_mutex_release(void * handle)127 uint32_t os_wrapper_mutex_release(void *handle)
128 {
129 osStatus_t status = osOK;
130
131 if (!handle) {
132 return OS_WRAPPER_ERROR;
133 }
134
135 status = osMutexRelease((osMutexId_t)handle);
136 if (status != osOK) {
137 return OS_WRAPPER_ERROR;
138 }
139
140 return OS_WRAPPER_SUCCESS;
141 }
142
os_wrapper_mutex_delete(void * handle)143 uint32_t os_wrapper_mutex_delete(void *handle)
144 {
145 osStatus_t status = osOK;
146
147 if (!handle) {
148 return OS_WRAPPER_ERROR;
149 }
150
151 status = osMutexDelete((osMutexId_t)handle);
152 if (status != osOK) {
153 return OS_WRAPPER_ERROR;
154 }
155
156 return OS_WRAPPER_SUCCESS;
157 }
158
os_wrapper_thread_get_handle(void)159 void *os_wrapper_thread_get_handle(void)
160 {
161 return (void *)osThreadGetId();
162 }
163
os_wrapper_thread_get_priority(void * handle,uint32_t * priority)164 uint32_t os_wrapper_thread_get_priority(void *handle, uint32_t *priority)
165 {
166 osPriority_t prio;
167
168 prio = osThreadGetPriority((osThreadId_t)handle);
169 if (prio == osPriorityError) {
170 return OS_WRAPPER_ERROR;
171 }
172
173 *priority = (uint32_t)prio;
174
175 return OS_WRAPPER_SUCCESS;
176 }
177
os_wrapper_thread_exit(void)178 void os_wrapper_thread_exit(void)
179 {
180 osThreadExit();
181 }
182
os_wrapper_thread_set_flag(void * handle,uint32_t flags)183 uint32_t os_wrapper_thread_set_flag(void *handle, uint32_t flags)
184 {
185 uint32_t ret;
186
187 ret = osThreadFlagsSet((osThreadId_t)handle, flags);
188 if (ret & osFlagsError) {
189 return OS_WRAPPER_ERROR;
190 }
191
192 return OS_WRAPPER_SUCCESS;
193 }
194
195 /*
196 * According to the description of CMSIS-RTOS v2 Thread Flags,
197 * osThreadFlagsSet() can be called inside Interrupt Service Routine.
198 */
os_wrapper_thread_set_flag_isr(void * handle,uint32_t flags)199 uint32_t os_wrapper_thread_set_flag_isr(void *handle, uint32_t flags)
200 {
201 uint32_t ret;
202
203 ret = osThreadFlagsSet((osThreadId_t)handle, flags);
204 if (ret & osFlagsError) {
205 return OS_WRAPPER_ERROR;
206 }
207
208 return OS_WRAPPER_SUCCESS;
209 }
210
os_wrapper_thread_wait_flag(uint32_t flags,uint32_t timeout)211 uint32_t os_wrapper_thread_wait_flag(uint32_t flags, uint32_t timeout)
212 {
213 uint32_t ret;
214
215 ret = osThreadFlagsWait(flags, osFlagsWaitAll,
216 (timeout == OS_WRAPPER_WAIT_FOREVER) ?
217 osWaitForever : timeout);
218 if (ret & osFlagsError) {
219 return OS_WRAPPER_ERROR;
220 }
221
222 return OS_WRAPPER_SUCCESS;
223 }
224
os_wrapper_get_tick(void)225 uint32_t os_wrapper_get_tick(void)
226 {
227 return osKernelGetTickCount();
228 }
229
os_wrapper_msg_queue_create(size_t msg_size,uint8_t msg_count)230 void *os_wrapper_msg_queue_create(size_t msg_size, uint8_t msg_count)
231 {
232 osMessageQueueId_t mq_id;
233
234 mq_id = osMessageQueueNew(msg_count, msg_size, NULL);
235
236 return (void *)mq_id;
237 }
238
os_wrapper_msg_queue_send(void * mq_handle,const void * msg_ptr)239 int32_t os_wrapper_msg_queue_send(void *mq_handle,
240 const void *msg_ptr)
241 {
242 osStatus_t status;
243
244 status = osMessageQueuePut(mq_handle, msg_ptr, 0, 0);
245 if (status == osOK) {
246 return OS_WRAPPER_SUCCESS;
247 }
248
249 return OS_WRAPPER_ERROR;
250 }
251
os_wrapper_msg_queue_receive(void * mq_handle,void * msg_ptr)252 int32_t os_wrapper_msg_queue_receive(void *mq_handle,
253 void *msg_ptr)
254 {
255 osStatus_t status;
256
257 status = osMessageQueueGet(mq_handle, msg_ptr, NULL, osWaitForever);
258 if (status == osOK) {
259 return OS_WRAPPER_SUCCESS;
260 }
261
262 return OS_WRAPPER_ERROR;
263 }
264
os_wrapper_delay(uint32_t ticks)265 int32_t os_wrapper_delay(uint32_t ticks)
266 {
267 osStatus_t status;
268
269 status = osDelay(ticks);
270 if (status == osOK) {
271 return OS_WRAPPER_SUCCESS;
272 }
273
274 return OS_WRAPPER_ERROR;
275 }
276