dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_semaphore.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_semaphore.h"
28 
30 {
31 #if defined(PIOS_INCLUDE_CHIBIOS)
32  BinarySemaphore sema;
33 #else
34  uint32_t sema_count;
35 #endif
36 };
37 
38 #if defined(PIOS_INCLUDE_CHIBIOS)
39 
48 {
49  struct pios_semaphore *sema = PIOS_malloc(sizeof(struct pios_semaphore));
50 
51  if (sema == NULL)
52  return NULL;
53 
54  /*
55  * The initial state of a binary semaphore is "given".
56  */
57  chBSemInit(&sema->sema, false);
58 
59  return sema;
60 }
61 
72 bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
73 {
74  PIOS_Assert(sema != NULL);
75 
76  if (timeout_ms == PIOS_SEMAPHORE_TIMEOUT_MAX)
77  return chBSemWait(&sema->sema) == RDY_OK;
78  else if (timeout_ms == 0)
79  return chBSemWaitTimeout(&sema->sema, TIME_IMMEDIATE) == RDY_OK;
80  else
81  return chBSemWaitTimeout(&sema->sema, MS2ST(timeout_ms)) == RDY_OK;
82 }
83 
93 bool PIOS_Semaphore_Give(struct pios_semaphore *sema)
94 {
95  PIOS_Assert(sema != NULL);
96 
97  chBSemSignal(&sema->sema);
98 
99  return true;
100 }
101 
112 bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken)
113 {
114  /* Waiting on a semaphore within an interrupt is not supported by ChibiOS. */
115  PIOS_Assert(false);
116  return false;
117 }
118 
129 bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken)
130 {
131  PIOS_Assert(sema != NULL);
132  PIOS_Assert(woken != NULL);
133 
134  chSysLockFromIsr();
135  chBSemSignalI(&sema->sema);
136  chSysUnlockFromIsr();
137 
138  return true;
139 }
140 
141 #else /* No RTOS */
142 
151 {
152  struct pios_semaphore *sema = PIOS_malloc_no_dma(sizeof(struct pios_semaphore));
153 
154  if (sema == NULL)
155  return NULL;
156 
157  /*
158  * The initial state of a binary semaphore is "given".
159  */
160  sema->sema_count = 1;
161 
162  return sema;
163 }
164 
175 bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
176 {
177  PIOS_Assert(sema != NULL);
178 
179  uint32_t start = PIOS_DELAY_GetRaw();
180 
181  uint32_t temp_sema_count;
182  do {
184  if ((temp_sema_count = sema->sema_count) != 0)
185  --sema->sema_count;
186  PIOS_IRQ_Enable();
187  } while (temp_sema_count == 0 &&
188  PIOS_DELAY_DiffuS(start) < timeout_ms * 1000);
189 
190  return temp_sema_count != 0;
191 }
192 
203 {
204  PIOS_Assert(sema != NULL);
205 
206  bool result = true;
207 
209 
210  if (sema->sema_count == 0)
211  ++sema->sema_count;
212  else
213  result = false;
214 
215  PIOS_IRQ_Enable();
216 
217  return result;
218 }
219 
220 bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken)
221 {
222  bool ret = PIOS_Semaphore_Take(sema, 0);
223 
224  if (ret && woken) {
225  *woken = true;
226  }
227 
228  return ret;
229 }
230 
231 bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken)
232 {
233  bool ret = PIOS_Semaphore_Give(sema);
234 
235  if (ret && woken) {
236  *woken = true;
237  }
238 
239  return ret;
240 }
241 
242 #endif /* no-rtos */
Definition: common.h:35
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
Definition: pios_delay.c:159
int32_t PIOS_IRQ_Enable(void)
Definition: pios_irq.c:53
#define PIOS_SEMAPHORE_TIMEOUT_MAX
Main PiOS header to include all the compiled in PiOS options.
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken)
void * PIOS_malloc_no_dma(size_t size)
Definition: pios_heap.c:166
struct pios_semaphore * PIOS_Semaphore_Create(void)
Creates a binary semaphore.
bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken)
bool PIOS_Semaphore_Give(struct pios_semaphore *sema)
Gives binary semaphore.
int32_t PIOS_IRQ_Disable(void)
Definition: pios_irq.c:40
bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
Takes binary semaphore.
uint32_t sema_count
#define PIOS_Assert(test)
Definition: pios_debug.h:52
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.
Definition: pios_delay.c:153