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_queue.h"
31 #include "os_util.h"
32
33
34 /**
35 * @brief Create and initialize a queue object
36 * @param[in] queue Pointer to the queue object
37 * @param[in] queueLen The maximum number of items that the queue can hold at
38 * any one time.
39 * @param[in] itemSize The size, in bytes, of each data item that can be stored
40 * in the queue.
41 * @retval OS_Status, OS_OK on success
42 */
OS_QueueCreate(OS_Queue_t * queue,uint32_t queueLen,uint32_t itemSize)43 OS_Status OS_QueueCreate(OS_Queue_t *queue, uint32_t queueLen, uint32_t itemSize)
44 {
45 // OS_HANDLE_ASSERT(!OS_QueueIsValid(queue), queue->handle);
46
47 queue->handle = rt_mq_create("os_mq", itemSize, queueLen, RT_IPC_FLAG_FIFO);
48
49 OS_DBG("%s(), handle %p\n", __func__, queue->handle);
50
51 if (queue->handle == NULL) {
52 OS_ERR("err %"OS_HANDLE_F"\n", queue->handle);
53 return OS_FAIL;
54 }
55 queue->itemSize = itemSize;
56 return OS_OK;
57 }
58
59 /**
60 * @brief Delete the queue object
61 * @param[in] queue Pointer to the queue object
62 * @retval OS_Status, OS_OK on success
63 */
OS_QueueDelete(OS_Queue_t * queue)64 OS_Status OS_QueueDelete(OS_Queue_t *queue)
65 {
66 rt_err_t ret;
67
68 OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
69 OS_DBG("%s(), handle %p\n", __func__, queue->handle);
70
71 ret = rt_mq_delete(queue->handle);
72 if (ret != RT_EOK) {
73 OS_ERR("rt_mq_delete(%p) return %ld\n", queue->handle, ret);
74 }
75
76 OS_QueueSetInvalid(queue);
77 return OS_OK;
78 }
79
80 /**
81 * @brief Send (write) an item to the back of the queue
82 * @param[in] queue Pointer to the queue object
83 * @param[in] item Pointer to the data to be copied into the queue.
84 * The size of each item the queue can hold is set when the
85 * queue is created, and that many bytes will be copied from
86 * item into the queue storage area.
87 * @param[in] waitMS The maximum amount of time the thread should remain in the
88 * blocked state to wait for space to become available on the
89 * queue, should the queue already be full.
90 * OS_WAIT_FOREVER for waiting forever, zero for no waiting.
91 * @retval OS_Status, OS_OK on success
92 */
OS_QueueSend(OS_Queue_t * queue,const void * item,OS_Time_t waitMS)93 OS_Status OS_QueueSend(OS_Queue_t *queue, const void *item, OS_Time_t waitMS)
94 {
95 rt_err_t ret;
96
97 OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
98
99 if (waitMS == 0) {
100 ret = rt_mq_send(queue->handle, item, queue->itemSize);
101 if (ret != RT_EOK) {
102 return OS_FAIL;
103 }
104 } else if (waitMS == OS_WAIT_FOREVER) {
105 while (1) {
106 ret = rt_mq_send(queue->handle, item, queue->itemSize);
107 if (ret == RT_EOK) {
108 break;
109 } else if (ret == -RT_EFULL) {
110 OS_MSleep(1);
111 } else {
112 OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
113 return OS_FAIL;
114 }
115 }
116 } else {
117 rt_tick_t endTick = rt_tick_get() + OS_CalcWaitTicks(waitMS);
118 while (OS_TimeBeforeEqual(rt_tick_get(), endTick)) {
119 ret = rt_mq_send(queue->handle, item, queue->itemSize);
120 if (ret == RT_EOK) {
121 break;
122 } else if (ret == -RT_EFULL) {
123 OS_MSleep(1);
124 } else {
125 OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
126 return OS_FAIL;
127 }
128 }
129 }
130
131 return OS_OK;
132 }
133
134 /**
135 * @brief Receive (read) an item from the queue
136 * @param[in] queue Pointer to the queue object
137 * @param[in] item Pointer to the memory into which the received data will be
138 * copied. The length of the buffer must be at least equal to
139 * the queue item size which is set when the queue is created.
140 * @param[in] waitMS The maximum amount of time the thread should remain in the
141 * blocked state to wait for data to become available on the
142 * queue, should the queue already be empty.
143 * OS_WAIT_FOREVER for waiting forever, zero for no waiting.
144 * @retval OS_Status, OS_OK on success
145 */
OS_QueueReceive(OS_Queue_t * queue,void * item,OS_Time_t waitMS)146 OS_Status OS_QueueReceive(OS_Queue_t *queue, void *item, OS_Time_t waitMS)
147 {
148 rt_err_t ret;
149
150 OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
151
152 ret = rt_mq_recv(queue->handle, item, queue->itemSize, OS_CalcWaitTicks(waitMS));
153 if (ret < 0) {
154 OS_DBG("%s() fail @ %d, %"OS_TIME_F" ms\n", __func__, __LINE__, (unsigned int)waitMS);
155 return OS_FAIL;
156 }
157
158 return OS_OK;
159 }
160