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