1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include "wrapper.h"
10
11 K_MEM_SLAB_DEFINE(cv2_mutex_slab, sizeof(struct cv2_mutex),
12 CONFIG_CMSIS_V2_MUTEX_MAX_COUNT, 4);
13
14 static const osMutexAttr_t init_mutex_attrs = {
15 .name = "ZephyrMutex",
16 .attr_bits = osMutexPrioInherit,
17 .cb_mem = NULL,
18 .cb_size = 0,
19 };
20
21 /**
22 * @brief Create and Initialize a Mutex object.
23 */
osMutexNew(const osMutexAttr_t * attr)24 osMutexId_t osMutexNew(const osMutexAttr_t *attr)
25 {
26 struct cv2_mutex *mutex;
27
28 if (k_is_in_isr()) {
29 return NULL;
30 }
31
32 if (attr == NULL) {
33 attr = &init_mutex_attrs;
34 }
35
36 __ASSERT(attr->attr_bits & osMutexPrioInherit,
37 "Zephyr supports osMutexPrioInherit by default. Do not unselect it\n");
38
39 __ASSERT(!(attr->attr_bits & osMutexRobust),
40 "Zephyr does not support osMutexRobust.\n");
41
42 if (k_mem_slab_alloc(&cv2_mutex_slab, (void **)&mutex, K_MSEC(100)) == 0) {
43 memset(mutex, 0, sizeof(struct cv2_mutex));
44 } else {
45 return NULL;
46 }
47
48 k_mutex_init(&mutex->z_mutex);
49 mutex->state = attr->attr_bits;
50
51 if (attr->name == NULL) {
52 strncpy(mutex->name, init_mutex_attrs.name,
53 sizeof(mutex->name) - 1);
54 } else {
55 strncpy(mutex->name, attr->name, sizeof(mutex->name) - 1);
56 }
57
58 return (osMutexId_t)mutex;
59 }
60
61 /**
62 * @brief Wait until a Mutex becomes available.
63 */
osMutexAcquire(osMutexId_t mutex_id,uint32_t timeout)64 osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
65 {
66 struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
67 int status;
68
69 if (mutex_id == NULL) {
70 return osErrorParameter;
71 }
72
73 if (k_is_in_isr()) {
74 return osErrorISR;
75 }
76
77 if (timeout == osWaitForever) {
78 status = k_mutex_lock(&mutex->z_mutex, K_FOREVER);
79 } else if (timeout == 0U) {
80 status = k_mutex_lock(&mutex->z_mutex, K_NO_WAIT);
81 } else {
82 status = k_mutex_lock(&mutex->z_mutex,
83 K_TICKS(timeout));
84 }
85
86 if (timeout != 0 && (status == -EAGAIN || status == -EBUSY)) {
87 return osErrorTimeout;
88 } else if (status != 0) {
89 return osErrorResource;
90 } else {
91 return osOK;
92 }
93 }
94
95 /**
96 * @brief Release a Mutex that was obtained by osMutexWait.
97 */
osMutexRelease(osMutexId_t mutex_id)98 osStatus_t osMutexRelease(osMutexId_t mutex_id)
99 {
100 struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
101
102 if (mutex_id == NULL) {
103 return osErrorParameter;
104 }
105
106 if (k_is_in_isr()) {
107 return osErrorISR;
108 }
109
110 if (k_mutex_unlock(&mutex->z_mutex) != 0) {
111 return osErrorResource;
112 }
113
114 return osOK;
115 }
116
117 /**
118 * @brief Delete a Mutex that was created by osMutexCreate.
119 */
osMutexDelete(osMutexId_t mutex_id)120 osStatus_t osMutexDelete(osMutexId_t mutex_id)
121 {
122 struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
123
124 if (mutex_id == NULL) {
125 return osErrorParameter;
126 }
127
128 if (k_is_in_isr()) {
129 return osErrorISR;
130 }
131
132 /* The status code "osErrorResource" (mutex specified by parameter
133 * mutex_id is in an invalid mutex state) is not supported in Zephyr.
134 */
135
136 k_mem_slab_free(&cv2_mutex_slab, (void *) &mutex);
137
138 return osOK;
139 }
140
141
osMutexGetOwner(osMutexId_t mutex_id)142 osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
143 {
144 struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
145
146 if (k_is_in_isr() || (mutex == NULL)) {
147 return NULL;
148 }
149
150 /* Mutex was not obtained before */
151 if (mutex->z_mutex.lock_count == 0U) {
152 return NULL;
153 }
154
155 return get_cmsis_thread_id(mutex->z_mutex.owner);
156 }
157
osMutexGetName(osMutexId_t mutex_id)158 const char *osMutexGetName(osMutexId_t mutex_id)
159 {
160 struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
161
162 if (k_is_in_isr() || (mutex == NULL)) {
163 return NULL;
164 }
165
166 return mutex->name;
167 }
168