1 /*
2 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "os_semaphore.h"
31 #include "os_util.h"
32
33
34 /**
35 * @brief Create and initialize a counting semaphore object
36 * @param[in] sem Pointer to the semaphore object
37 * @param[in] initCount The count value assigned to the semaphore when it is
38 * created.
39 * @param[in] maxCount The maximum count value that can be reached. When the
40 * semaphore reaches this value it can no longer be
41 * released.
42 * @retval OS_Status, OS_OK on success
43 */
OS_SemaphoreCreate(OS_Semaphore_t * sem,uint32_t initCount,uint32_t maxCount)44 OS_Status OS_SemaphoreCreate(OS_Semaphore_t *sem, uint32_t initCount, uint32_t maxCount)
45 {
46 // OS_HANDLE_ASSERT(!OS_SemaphoreIsValid(sem), sem->handle);
47
48 sem->handle = rt_sem_create("os_sem", initCount, RT_IPC_FLAG_PRIO);
49 OS_DBG("%s(), handle %p\n", __func__, sem->handle);
50
51 if (sem->handle == NULL) {
52 OS_ERR("err %"OS_HANDLE_F"\n", sem->handle);
53 return OS_FAIL;
54 }
55
56 return OS_OK;
57 }
58
59 /**
60 * @brief Create and initialize a binary semaphore object
61 * @note A binary semaphore is equal to a counting semaphore created by calling
62 OS_SemaphoreCreate(sem, 0, 1).
63 * @param[in] sem Pointer to the semaphore object
64 * @retval OS_Status, OS_OK on success
65 */
OS_SemaphoreCreateBinary(OS_Semaphore_t * sem)66 OS_Status OS_SemaphoreCreateBinary(OS_Semaphore_t *sem)
67 {
68 OS_ERR("OS_SemaphoreCreateBinary() NOT SUPPORT!\n");
69
70 return OS_SemaphoreCreate(sem, 0, 1);
71 }
72
73 /**
74 * @brief Delete the semaphore object
75 * @param[in] sem Pointer to the semaphore object
76 * @retval OS_Status, OS_OK on success
77 */
OS_SemaphoreDelete(OS_Semaphore_t * sem)78 OS_Status OS_SemaphoreDelete(OS_Semaphore_t *sem)
79 {
80 rt_err_t ret;
81
82 OS_HANDLE_ASSERT(OS_SemaphoreIsValid(sem), sem->handle);
83
84 ret = rt_sem_delete(sem->handle);
85 if (ret != RT_EOK) {
86 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
87 return OS_FAIL;
88 }
89 OS_SemaphoreSetInvalid(sem);
90 return OS_OK;
91 }
92
93 /**
94 * @brief Wait until the semaphore object becomes available
95 * @param[in] sem Pointer to the semaphore object
96 * @param[in] waitMS The maximum amount of time (in millisecond) the thread
97 * should remain in the blocked state to wait for the
98 * semaphore to become available.
99 * OS_WAIT_FOREVER for waiting forever, zero for no waiting.
100 * @retval OS_Status, OS_OK on success
101 */
OS_SemaphoreWait(OS_Semaphore_t * sem,OS_Time_t waitMS)102 OS_Status OS_SemaphoreWait(OS_Semaphore_t *sem, OS_Time_t waitMS)
103 {
104 rt_err_t ret;
105
106 OS_DBG("%s(), handle %p, wait %u ms\n", __func__, sem->handle, (unsigned int)waitMS);
107 OS_HANDLE_ASSERT(OS_SemaphoreIsValid(sem), sem->handle);
108
109 ret = rt_sem_take(sem->handle, OS_CalcWaitTicks(waitMS));
110 if (ret != RT_EOK) {
111 OS_DBG("%s() fail @ %d, %"OS_TIME_F" ms\n", __func__, __LINE__, (unsigned int)waitMS);
112 return OS_E_TIMEOUT;
113 }
114
115 return OS_OK;
116 }
117
118 /**
119 * @brief Release the semaphore object
120 * @param[in] sem Pointer to the semaphore object
121 * @retval OS_Status, OS_OK on success
122 */
OS_SemaphoreRelease(OS_Semaphore_t * sem)123 OS_Status OS_SemaphoreRelease(OS_Semaphore_t *sem)
124 {
125 rt_err_t ret;
126
127 OS_HANDLE_ASSERT(OS_SemaphoreIsValid(sem), sem->handle);
128
129 ret = rt_sem_release(sem->handle);
130 if (ret != RT_EOK) {
131 OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
132 return OS_FAIL;
133 }
134
135 return OS_OK;
136 }
137
138 /**
139 * @brief Release the semaphore object
140 * @param[in] sem Pointer to the semaphore object
141 * @retval OS_Status, OS_OK on success
142 */
OS_SemaphoreReset(OS_Semaphore_t * sem)143 OS_Status OS_SemaphoreReset(OS_Semaphore_t *sem)
144 {
145 rt_err_t ret;
146
147 OS_HANDLE_ASSERT(OS_SemaphoreIsValid(sem), sem->handle);
148
149 ret = rt_sem_control(sem->handle, RT_IPC_CMD_RESET, NULL);
150 if (ret != RT_EOK) {
151 OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
152 return OS_FAIL;
153 }
154
155 return OS_OK;
156 }
157