dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_queue.c
Go to the documentation of this file.
1 
11 /*
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, see <http://www.gnu.org/licenses/>
24  */
25 
26 #include "pios.h"
27 #include "pios_queue.h"
28 
29 #if !defined(PIOS_INCLUDE_CHIBIOS)
30 #error "pios_queue.c requires PIOS_INCLUDE_CHIBIOS"
31 #endif
32 
33 #if defined(PIOS_INCLUDE_CHIBIOS)
34 
35 #include "ch.h"
36 
37 struct pios_queue
38 {
39  Mailbox mb;
40  MemoryPool mp;
41  void *mpb;
42 };
43 
44 #if !defined(PIOS_QUEUE_MAX_WAITERS)
45 #define PIOS_QUEUE_MAX_WAITERS 2
46 #endif /* !defined(PIOS_QUEUE_MAX_WAITERS) */
47 
55 struct pios_queue *PIOS_Queue_Create(size_t queue_length, size_t item_size)
56 {
57  struct pios_queue *queuep = PIOS_malloc_no_dma(sizeof(struct pios_queue));
58  if (queuep == NULL)
59  return NULL;
60 
61  /* Create the memory pool. */
62  queuep->mpb = PIOS_malloc_no_dma(item_size * (queue_length + PIOS_QUEUE_MAX_WAITERS));
63  if (queuep->mpb == NULL) {
64  PIOS_free(queuep);
65  return NULL;
66  }
67  chPoolInit(&queuep->mp, item_size, NULL);
68  chPoolLoadArray(&queuep->mp, queuep->mpb, queue_length + PIOS_QUEUE_MAX_WAITERS);
69 
70  /* Create the mailbox. */
71  msg_t *mb_buf = PIOS_malloc_no_dma(sizeof(msg_t) * queue_length);
72  chMBInit(&queuep->mb, mb_buf, queue_length);
73 
74  return queuep;
75 }
76 
84 void PIOS_Queue_Delete(struct pios_queue *queuep)
85 {
86  PIOS_free(queuep->mpb);
87  PIOS_free(queuep);
88 }
89 
101 bool PIOS_Queue_Send(struct pios_queue *queuep, const void *itemp, uint32_t timeout_ms)
102 {
103  void *buf = chPoolAlloc(&queuep->mp);
104  if (buf == NULL)
105  return false;
106 
107  memcpy(buf, itemp, queuep->mp.mp_object_size);
108 
109  systime_t timeout;
110  if (timeout_ms == PIOS_QUEUE_TIMEOUT_MAX)
111  timeout = TIME_INFINITE;
112  else if (timeout_ms == 0)
113  timeout = TIME_IMMEDIATE;
114  else
115  timeout = MS2ST(timeout_ms);
116 
117  msg_t result = chMBPost(&queuep->mb, (msg_t)buf, timeout);
118 
119  if (result != RDY_OK)
120  {
121  chPoolFree(&queuep->mp, buf);
122  return false;
123  }
124 
125  return true;
126 }
127 
139 bool PIOS_Queue_Send_FromISR(struct pios_queue *queuep, const void *itemp, bool *wokenp)
140 {
141  chSysLockFromIsr();
142  void *buf = chPoolAllocI(&queuep->mp);
143  if (buf == NULL)
144  {
145  chSysUnlockFromIsr();
146  return false;
147  }
148 
149  memcpy(buf, itemp, queuep->mp.mp_object_size);
150 
151  msg_t result = chMBPostI(&queuep->mb, (msg_t)buf);
152 
153  if (result != RDY_OK)
154  {
155  chPoolFreeI(&queuep->mp, buf);
156  chSysUnlockFromIsr();
157  return false;
158  }
159 
160  chSysUnlockFromIsr();
161 
162  return true;
163 }
164 
176 bool PIOS_Queue_Receive(struct pios_queue *queuep, void *itemp, uint32_t timeout_ms)
177 {
178  msg_t buf;
179 
180  systime_t timeout;
181  if (timeout_ms == PIOS_QUEUE_TIMEOUT_MAX)
182  timeout = TIME_INFINITE;
183  else if (timeout_ms == 0)
184  timeout = TIME_IMMEDIATE;
185  else
186  timeout = MS2ST(timeout_ms);
187 
188  msg_t result = chMBFetch(&queuep->mb, &buf, timeout);
189 
190  if (result != RDY_OK)
191  return false;
192 
193  memcpy(itemp, (void*)buf, queuep->mp.mp_object_size);
194 
195  chPoolFree(&queuep->mp, (void*)buf);
196 
197  return true;
198 }
199 
200 /*
201  * @brief Gets the item size of a queue.
202  *
203  * @param[in] queuep Pointer to instance of @p struct pios_queue
204  *
205  * @returns Size of item
206  *
207  */
208 size_t PIOS_Queue_GetItemSize(struct pios_queue *queuep)
209 {
210  PIOS_Assert(queuep);
211  return queuep->mp.mp_object_size;
212 }
213 
214 #endif /* defined(PIOS_INCLUDE_CHIBIOS) */
struct pios_queue * PIOS_Queue_Create(size_t queue_length, size_t item_size)
Definition: pios_queue.c:47
Main PiOS header to include all the compiled in PiOS options.
bool PIOS_Queue_Send_FromISR(struct pios_queue *queuep, const void *itemp, bool *wokenp)
Definition: pios_queue.c:163
bool PIOS_Queue_Send(struct pios_queue *queuep, const void *itemp, uint32_t timeout_ms)
Definition: pios_queue.c:141
bool PIOS_Queue_Receive(struct pios_queue *queuep, void *itemp, uint32_t timeout_ms)
Definition: pios_queue.c:213
void * PIOS_malloc_no_dma(size_t size)
Definition: pios_heap.c:166
void PIOS_Queue_Delete(struct pios_queue *queuep)
Definition: pios_queue.c:89
uint16_t item_size
Definition: pios_queue.c:41
#define PIOS_QUEUE_TIMEOUT_MAX
Definition: pios_queue.h:30
size_t PIOS_Queue_GetItemSize(struct pios_queue *queuep)
Definition: pios_queue.c:235
void PIOS_free(void *buf)
Definition: pios_heap.c:174
#define PIOS_Assert(test)
Definition: pios_debug.h:52