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