blob: f582b073d21970bb552346174d2b2ceb5cd687e7 [file] [log] [blame]
Kevin Peng62a87112020-07-07 15:07:46 +08001/*
Feder Liangf9fbd582022-02-15 17:59:11 +08002 * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
Kevin Peng62a87112020-07-07 15:07:46 +08003 *
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"
Feder Liang7e15ea92021-12-08 16:37:30 +080011#include "os_wrapper/delay.h"
Kevin Peng62a87112020-07-07 15:07:46 +080012
Kevin Peng62a87112020-07-07 15:07:46 +080013#include "cmsis_os2.h"
14
Xinyu Zhangeebbea32021-09-01 15:26:39 +080015#include "tfm_nsid_manager.h"
16#ifdef TFM_NS_MANAGE_NSID
17#include "tfm_nsid_map_table.h"
18#endif
19
Kevin Peng62a87112020-07-07 15:07:46 +080020/* This is an example OS abstraction layer for CMSIS-RTOSv2 */
21
22void *os_wrapper_thread_new(const char *name, int32_t stack_size,
23 os_wrapper_thread_func func, void *arg,
24 uint32_t priority)
25{
Xinyu Zhangeebbea32021-09-01 15:26:39 +080026 osThreadAttr_t task_attribs = {
27 .tz_module = ((TZ_ModuleId_t)TFM_DEFAULT_NSID)
28 };
Kevin Peng62a87112020-07-07 15:07:46 +080029
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
Xinyu Zhangeebbea32021-09-01 15:26:39 +080037#ifdef TFM_NS_MANAGE_NSID
38 task_attribs.tz_module = (TZ_ModuleId_t)nsid_mgr_get_thread_nsid(name);
39#endif
40
Kevin Peng62a87112020-07-07 15:07:46 +080041 return (void *)osThreadNew(func, arg, &task_attribs);
42}
43
44void *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
54uint32_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
68uint32_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
80uint32_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
92void *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
109uint32_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
127uint32_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
143uint32_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
159void *os_wrapper_thread_get_handle(void)
160{
161 return (void *)osThreadGetId();
162}
163
164uint32_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
178void os_wrapper_thread_exit(void)
179{
180 osThreadExit();
181}
182
183uint32_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 */
199uint32_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
211uint32_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
225uint32_t os_wrapper_get_tick(void)
226{
227 return osKernelGetTickCount();
228}
David Hu27d45be2020-06-12 13:47:24 +0800229
230void *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
239int32_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
252int32_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}
Feder Liang7e15ea92021-12-08 16:37:30 +0800264
Feder Liangf9fbd582022-02-15 17:59:11 +0800265int32_t os_wrapper_delay(uint32_t ticks)
Feder Liang7e15ea92021-12-08 16:37:30 +0800266{
267 osStatus_t status;
268
Feder Liangf9fbd582022-02-15 17:59:11 +0800269 status = osDelay(ticks);
Feder Liang7e15ea92021-12-08 16:37:30 +0800270 if (status == osOK) {
271 return OS_WRAPPER_SUCCESS;
272 }
273
274 return OS_WRAPPER_ERROR;
275}