forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemaphore.c
159 lines (128 loc) · 3.38 KB
/
semaphore.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <string.h>
#include "wrapper.h"
K_MEM_SLAB_DEFINE(cv2_semaphore_slab, sizeof(struct cv2_sem),
CONFIG_CMSIS_V2_SEMAPHORE_MAX_COUNT, 4);
static const osSemaphoreAttr_t init_sema_attrs = {
.name = "ZephyrSem",
.attr_bits = 0,
.cb_mem = NULL,
.cb_size = 0,
};
/**
* @brief Create and Initialize a semaphore object.
*/
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count,
const osSemaphoreAttr_t *attr)
{
struct cv2_sem *semaphore;
if (k_is_in_isr()) {
return NULL;
}
if (attr == NULL) {
attr = &init_sema_attrs;
}
if (k_mem_slab_alloc(&cv2_semaphore_slab,
(void **)&semaphore, K_MSEC(100)) == 0) {
(void)memset(semaphore, 0, sizeof(struct cv2_sem));
} else {
return NULL;
}
k_sem_init(&semaphore->z_semaphore, initial_count, max_count);
if (attr->name == NULL) {
strncpy(semaphore->name, init_sema_attrs.name,
sizeof(semaphore->name) - 1);
} else {
strncpy(semaphore->name, attr->name,
sizeof(semaphore->name) - 1);
}
return (osSemaphoreId_t)semaphore;
}
/**
* @brief Wait until a semaphore becomes available.
*/
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
{
struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id;
int status;
if (semaphore_id == NULL) {
return osErrorParameter;
}
/* Can be called from ISRs only if timeout is set to 0 */
if (timeout > 0 && k_is_in_isr()) {
return osErrorParameter;
}
if (timeout == osWaitForever) {
status = k_sem_take(&semaphore->z_semaphore, K_FOREVER);
} else if (timeout == 0U) {
status = k_sem_take(&semaphore->z_semaphore, K_NO_WAIT);
} else {
status = k_sem_take(&semaphore->z_semaphore,
k_ticks_to_ms_floor64(timeout));
}
if (status == -EBUSY) {
return osErrorResource;
} else if (status == -EAGAIN) {
return osErrorTimeout;
} else {
return osOK;
}
}
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
{
struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;
if (semaphore_id == NULL) {
return 0;
}
return k_sem_count_get(&semaphore->z_semaphore);
}
/**
* @brief Release a semaphore that was obtained by osSemaphoreWait.
*/
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
{
struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id;
if (semaphore_id == NULL) {
return osErrorParameter;
}
/* All tokens have already been released */
if (k_sem_count_get(&semaphore->z_semaphore) ==
semaphore->z_semaphore.limit) {
return osErrorResource;
}
k_sem_give(&semaphore->z_semaphore);
return osOK;
}
/**
* @brief Delete a semaphore that was created by osSemaphoreCreate.
*/
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
{
struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;
if (semaphore_id == NULL) {
return osErrorParameter;
}
if (k_is_in_isr()) {
return osErrorISR;
}
/* The status code "osErrorResource" (the semaphore specified by
* parameter semaphore_id is in an invalid semaphore state) is not
* supported in Zephyr.
*/
k_mem_slab_free(&cv2_semaphore_slab, (void *) &semaphore);
return osOK;
}
const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
{
struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;
if (!k_is_in_isr() && (semaphore_id != NULL)) {
return semaphore->name;
} else {
return NULL;
}
}