1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <cmsis_os.h>
9 #include <string.h>
10
11 K_MEM_SLAB_DEFINE(cmsis_mutex_slab, sizeof(struct k_mutex),
12 CONFIG_CMSIS_MUTEX_MAX_COUNT, 4);
13
14 /**
15 * @brief Create and Initialize a Mutex object.
16 */
osMutexCreate(const osMutexDef_t * mutex_def)17 osMutexId osMutexCreate(const osMutexDef_t *mutex_def)
18 {
19 struct k_mutex *mutex;
20
21 if (mutex_def == NULL) {
22 return NULL;
23 }
24
25 if (k_is_in_isr()) {
26 return NULL;
27 }
28
29 if (k_mem_slab_alloc(&cmsis_mutex_slab, (void **)&mutex, K_MSEC(100)) == 0) {
30 (void)memset(mutex, 0, sizeof(struct k_mutex));
31 } else {
32 return NULL;
33 }
34
35 k_mutex_init(mutex);
36
37 return (osMutexId)mutex;
38 }
39
40 /**
41 * @brief Wait until a Mutex becomes available.
42 */
osMutexWait(osMutexId mutex_id,uint32_t timeout)43 osStatus osMutexWait(osMutexId mutex_id, uint32_t timeout)
44 {
45 struct k_mutex *mutex = (struct k_mutex *) mutex_id;
46 int status;
47
48 if (mutex_id == NULL) {
49 return osErrorParameter;
50 }
51
52 if (k_is_in_isr()) {
53 return osErrorISR;
54 }
55
56 if (timeout == osWaitForever) {
57 status = k_mutex_lock(mutex, K_FOREVER);
58 } else if (timeout == 0U) {
59 status = k_mutex_lock(mutex, K_NO_WAIT);
60 } else {
61 status = k_mutex_lock(mutex, K_MSEC(timeout));
62 }
63
64 if (timeout != 0 && (status == -EAGAIN || status == -EBUSY)) {
65 return osErrorTimeoutResource;
66 } else if (status == 0) {
67 return osOK;
68 } else {
69 return osErrorResource;
70 }
71 }
72
73 /**
74 * @brief Release a Mutex that was obtained by osMutexWait.
75 */
osMutexRelease(osMutexId mutex_id)76 osStatus osMutexRelease(osMutexId mutex_id)
77 {
78 struct k_mutex *mutex = (struct k_mutex *) mutex_id;
79
80 if (mutex_id == NULL) {
81 return osErrorParameter;
82 }
83
84 if (k_is_in_isr()) {
85 return osErrorISR;
86 }
87
88 if (k_mutex_unlock(mutex) != 0) {
89 return osErrorResource;
90 }
91
92 return osOK;
93 }
94
95 /**
96 * @brief Delete a Mutex that was created by osMutexCreate.
97 */
osMutexDelete(osMutexId mutex_id)98 osStatus osMutexDelete(osMutexId mutex_id)
99 {
100 struct k_mutex *mutex = (struct k_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 /* The status code "osErrorResource" (mutex object could
111 * not be deleted) is not supported in Zephyr.
112 */
113
114 k_mem_slab_free(&cmsis_mutex_slab, (void *)mutex);
115
116 return osOK;
117 }
118