1 /**
2  * @file os_queue.c
3  * @author ALLWINNERTECH IOT WLAN Team
4  */
5 
6 /*
7  * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *    1. Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *    2. Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in the
16  *       documentation and/or other materials provided with the
17  *       distribution.
18  *    3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
19  *       its contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "os_queue.h"
36 #include "os_util.h"
37 
38 
39 /**
40  * @brief Create and initialize a queue object
41  * @param[in] queue Pointer to the queue object
42  * @param[in] queueLen The maximum number of items that the queue can hold at
43  *                     any one time.
44  * @param[in] itemSize The size, in bytes, of each data item that can be stored
45  *                     in the queue.
46  * @retval OS_Status, OS_OK on success
47  */
OS_QueueCreate(OS_Queue_t * queue,uint32_t queueLen,uint32_t itemSize)48 OS_Status OS_QueueCreate(OS_Queue_t *queue, uint32_t queueLen, uint32_t itemSize)
49 {
50 //  OS_HANDLE_ASSERT(!OS_QueueIsValid(queue), queue->handle);
51 
52     queue->handle = xQueueCreate(queueLen, itemSize);
53     if (queue->handle == NULL) {
54         OS_ERR("err %"OS_HANDLE_F"\n", queue->handle);
55         return OS_FAIL;
56     }
57 
58     return OS_OK;
59 }
60 
61 /**
62  * @brief Delete the queue object
63  * @param[in] queue Pointer to the queue object
64  * @retval OS_Status, OS_OK on success
65  */
OS_QueueDelete(OS_Queue_t * queue)66 OS_Status OS_QueueDelete(OS_Queue_t *queue)
67 {
68     UBaseType_t ret;
69 
70     OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
71 
72     ret = uxQueueMessagesWaiting(queue->handle);
73     if (ret > 0) {
74         OS_ERR("queue %"OS_HANDLE_F" is not empty\n", queue->handle);
75         return OS_FAIL;
76     }
77 
78     vQueueDelete(queue->handle);
79     OS_QueueSetInvalid(queue);
80     return OS_OK;
81 }
82 
83 /**
84  * @brief Send (write) an item to the back of the queue
85  * @param[in] queue Pointer to the queue object
86  * @param[in] item Pointer to the data to be copied into the queue.
87  *                 The size of each item the queue can hold is set when the
88  *                 queue is created, and that many bytes will be copied from
89  *                 item into the queue storage area.
90  * @param[in] waitMS The maximum amount of time the thread should remain in the
91  *                   blocked state to wait for space to become available on the
92  *                   queue, should the queue already be full.
93  *                   OS_WAIT_FOREVER for waiting forever, zero for no waiting.
94  * @retval OS_Status, OS_OK on success
95  */
OS_QueueSend(OS_Queue_t * queue,const void * item,OS_Time_t waitMS)96 OS_Status OS_QueueSend(OS_Queue_t *queue, const void *item, OS_Time_t waitMS)
97 {
98     BaseType_t ret;
99     BaseType_t taskWoken;
100 
101     OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
102 
103     if (OS_IsISRContext()) {
104         taskWoken = pdFALSE;
105         ret = xQueueSendFromISR(queue->handle, item, &taskWoken);
106         if (ret != pdPASS) {
107             OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
108             return OS_FAIL;
109         }
110         portEND_SWITCHING_ISR(taskWoken);
111     } else {
112         ret = xQueueSend(queue->handle, item, OS_CalcWaitTicks(waitMS));
113         if (ret != pdPASS) {
114             OS_DBG("%s() fail @ %d, %"OS_TIME_F" ms\n", __func__, __LINE__, waitMS);
115             return OS_FAIL;
116         }
117     }
118 
119     return OS_OK;
120 }
121 
122 /**
123  * @brief Receive (read) an item from the queue
124  * @param[in] queue Pointer to the queue object
125  * @param[in] item Pointer to the memory into which the received data will be
126  *                 copied. The length of the buffer must be at least equal to
127  *                 the queue item size which is set when the queue is created.
128  * @param[in] waitMS The maximum amount of time the thread should remain in the
129  *                   blocked state to wait for data to become available on the
130  *                   queue, should the queue already be empty.
131  *                   OS_WAIT_FOREVER for waiting forever, zero for no waiting.
132  * @retval OS_Status, OS_OK on success
133  */
OS_QueueReceive(OS_Queue_t * queue,void * item,OS_Time_t waitMS)134 OS_Status OS_QueueReceive(OS_Queue_t *queue, void *item, OS_Time_t waitMS)
135 {
136     BaseType_t ret;
137     BaseType_t taskWoken;
138 
139     OS_HANDLE_ASSERT(OS_QueueIsValid(queue), queue->handle);
140 
141     if (OS_IsISRContext()) {
142         taskWoken = pdFALSE;
143         ret = xQueueReceiveFromISR(queue->handle, item, &taskWoken);
144         if (ret != pdPASS) {
145             OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
146             return OS_FAIL;
147         }
148         portEND_SWITCHING_ISR(taskWoken);
149     } else {
150         ret = xQueueReceive(queue->handle, item, OS_CalcWaitTicks(waitMS));
151         if (ret != pdPASS) {
152             OS_DBG("%s() fail @ %d, %"OS_TIME_F" ms\n", __func__, __LINE__, waitMS);
153             return OS_FAIL;
154         }
155     }
156 
157     return OS_OK;
158 }
159