aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/various
diff options
context:
space:
mode:
authorAkshay <[email protected]>2022-04-10 12:13:40 +0100
committerAkshay <[email protected]>2022-04-10 12:13:40 +0100
commitdc90387ce7d8ba7b607d9c48540bf6d8b560f14d (patch)
tree4ccb8fa5886b66fa9d480edef74236c27f035e16 /lib/chibios/os/various
Diffstat (limited to 'lib/chibios/os/various')
-rw-r--r--lib/chibios/os/various/cpp_wrappers/ch.cpp45
-rw-r--r--lib/chibios/os/various/cpp_wrappers/ch.hpp3133
-rw-r--r--lib/chibios/os/various/cpp_wrappers/chcpp.mk9
-rw-r--r--lib/chibios/os/various/cpp_wrappers/syscalls_cpp.cpp41
-rw-r--r--lib/chibios/os/various/cpp_wrappers/syscalls_cpp.hpp13
-rw-r--r--lib/chibios/os/various/evtimer.c85
-rw-r--r--lib/chibios/os/various/evtimer.h94
-rw-r--r--lib/chibios/os/various/fatfs_bindings/fatfs.mk11
-rw-r--r--lib/chibios/os/various/fatfs_bindings/fatfs_diskio.c267
-rw-r--r--lib/chibios/os/various/fatfs_bindings/fatfs_syscall.c84
-rw-r--r--lib/chibios/os/various/fatfs_bindings/readme.txt12
-rw-r--r--lib/chibios/os/various/lwip_bindings/arch/cc.h89
-rw-r--r--lib/chibios/os/various/lwip_bindings/arch/perf.h57
-rw-r--r--lib/chibios/os/various/lwip_bindings/arch/sys_arch.c239
-rw-r--r--lib/chibios/os/various/lwip_bindings/arch/sys_arch.h68
-rw-r--r--lib/chibios/os/various/lwip_bindings/lwip.mk23
-rw-r--r--lib/chibios/os/various/lwip_bindings/lwipthread.c530
-rw-r--r--lib/chibios/os/various/lwip_bindings/lwipthread.h275
-rw-r--r--lib/chibios/os/various/lwip_bindings/readme.txt6
-rw-r--r--lib/chibios/os/various/lwip_bindings/static_lwipopts.h42
-rw-r--r--lib/chibios/os/various/shell/shell.c604
-rw-r--r--lib/chibios/os/various/shell/shell.h235
-rw-r--r--lib/chibios/os/various/shell/shell.mk9
-rw-r--r--lib/chibios/os/various/shell/shell_cmd.c248
-rw-r--r--lib/chibios/os/various/shell/shell_cmd.h114
-rw-r--r--lib/chibios/os/various/syscalls.c197
-rw-r--r--lib/chibios/os/various/various.dox91
-rw-r--r--lib/chibios/os/various/wolfssl_bindings/hwrng.c80
-rw-r--r--lib/chibios/os/various/wolfssl_bindings/user_settings.h86
-rw-r--r--lib/chibios/os/various/wolfssl_bindings/wolfssl.mk98
-rw-r--r--lib/chibios/os/various/wolfssl_bindings/wolfssl_chibios.c252
-rw-r--r--lib/chibios/os/various/wolfssl_bindings/wolfssl_chibios.h70
32 files changed, 7207 insertions, 0 deletions
diff --git a/lib/chibios/os/various/cpp_wrappers/ch.cpp b/lib/chibios/os/various/cpp_wrappers/ch.cpp
new file mode 100644
index 000000000..155e56ebc
--- /dev/null
+++ b/lib/chibios/os/various/cpp_wrappers/ch.cpp
@@ -0,0 +1,45 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/**
17 * @file ch.cpp
18 * @brief C++ wrapper code.
19 *
20 * @addtogroup cpp_library
21 * @{
22 */
23
24#include "ch.hpp"
25
26namespace chibios_rt {
27
28#if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__)
29 ThreadReference System::getIdleThreadX(void) {
30
31 return ThreadReference(chSysGetIdleThreadX());
32 }
33#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */
34
35 /*------------------------------------------------------------------------*
36 * chibios_rt::BaseStaticThread *
37 *------------------------------------------------------------------------*/
38
39 void _thd_start(void *arg) {
40
41 ((BaseThread *)arg)->main();
42 }
43}
44
45/** @} */
diff --git a/lib/chibios/os/various/cpp_wrappers/ch.hpp b/lib/chibios/os/various/cpp_wrappers/ch.hpp
new file mode 100644
index 000000000..5c2e022e1
--- /dev/null
+++ b/lib/chibios/os/various/cpp_wrappers/ch.hpp
@@ -0,0 +1,3133 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file ch.hpp
19 * @brief C++ wrapper classes and definitions.
20 *
21 * @addtogroup cpp_library
22 * @{
23 */
24
25#include <ch.h>
26
27#ifndef _CH_HPP_
28#define _CH_HPP_
29
30/**
31 * @brief ChibiOS-RT kernel-related classes and interfaces.
32 */
33namespace chibios_rt {
34
35 /* Forward declaration of some classes.*/
36 class ThreadReference;
37
38 /*------------------------------------------------------------------------*
39 * chibios_rt::System *
40 *------------------------------------------------------------------------*/
41 /**
42 * @brief Class encapsulating the base system functionalities.
43 */
44 class System {
45 public:
46 /**
47 * @brief ChibiOS/RT initialization.
48 * @details After executing this function the current instructions stream
49 * becomes the main thread.
50 * @pre Interrupts must be still disabled when @p chSysInit() is invoked
51 * and are internally enabled.
52 * @post The main thread is created with priority @p NORMALPRIO.
53 * @note This function has special, architecture-dependent, requirements,
54 * see the notes into the various port reference manuals.
55 *
56 * @special
57 */
58 static void init(void) {
59
60 chSysInit();
61 }
62
63 /**
64 * @brief Halts the system.
65 * @details This function is invoked by the operating system when an
66 * unrecoverable error is detected, for example because a programming
67 * error in the application code that triggers an assertion while
68 * in debug mode.
69 * @note Can be invoked from any system state.
70 *
71 * @param[in] reason pointer to an error string
72 *
73 * @special
74 */
75 static void halt(const char *reason) {
76
77 chSysHalt(reason);
78 }
79
80 /**
81 * @brief System integrity check.
82 * @details Performs an integrity check of the important ChibiOS/RT data
83 * structures.
84 * @note The appropriate action in case of failure is to halt the system
85 * before releasing the critical zone.
86 * @note If the system is corrupted then one possible outcome of this
87 * function is an exception caused by @p nullptr or corrupted
88 * pointers in list elements. Exception vectors must be monitored
89 * as well.
90 * @note This function is not used internally, it is up to the
91 * application to define if and where to perform system
92 * checking.
93 * @note Performing all tests at once can be a slow operation and can
94 * degrade the system response time. It is suggested to execute
95 * one test at time and release the critical zone in between tests.
96 *
97 * @param[in] testmask Each bit in this mask is associated to a test to be
98 * performed.
99 * @return The test result.
100 * @retval false The test succeeded.
101 * @retval true Test failed.
102 *
103 * @iclass
104 */
105 static bool integrityCheckI(unsigned int testmask) {
106
107 return chSysIntegrityCheckI(testmask);
108 }
109
110 /**
111 * @brief Raises the system interrupt priority mask to the maximum level.
112 * @details All the maskable interrupt sources are disabled regardless their
113 * hardware priority.
114 * @note Do not invoke this API from within a kernel lock.
115 *
116 * @special
117 */
118 static void disable(void) {
119
120 chSysDisable();
121 }
122
123 /**
124 * @brief Raises the system interrupt priority mask to system level.
125 * @details The interrupt sources that should not be able to preempt the kernel
126 * are disabled, interrupt sources with higher priority are still
127 * enabled.
128 * @note Do not invoke this API from within a kernel lock.
129 * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
130 * could do more than just disable the interrupts.
131 *
132 * @special
133 */
134 static void suspend(void) {
135
136 chSysSuspend();
137 }
138
139 /**
140 * @brief Lowers the system interrupt priority mask to user level.
141 * @details All the interrupt sources are enabled.
142 * @note Do not invoke this API from within a kernel lock.
143 * @note This API is no replacement for @p chSysUnlock(), the
144 * @p chSysUnlock() could do more than just enable the interrupts.
145 *
146 * @special
147 */
148 static void enable(void) {
149
150 chSysEnable();
151 }
152
153 /**
154 * @brief Enters the kernel lock mode.
155 *
156 * @special
157 */
158 static void lock(void) {
159
160 chSysLock();
161 }
162
163 /**
164 * @brief Leaves the kernel lock mode.
165 *
166 * @special
167 */
168 static void unlock(void) {
169
170 chSysUnlock();
171 }
172
173 /**
174 * @brief Enters the kernel lock mode from within an interrupt handler.
175 * @note This API may do nothing on some architectures, it is required
176 * because on ports that support preemptable interrupt handlers
177 * it is required to raise the interrupt mask to the same level of
178 * the system mutual exclusion zone.<br>
179 * It is good practice to invoke this API before invoking any I-class
180 * syscall from an interrupt handler.
181 * @note This API must be invoked exclusively from interrupt handlers.
182 *
183 * @special
184 */
185 static void lockFromIsr(void) {
186
187 chSysLockFromISR();
188 }
189
190 /**
191 * @brief Leaves the kernel lock mode from within an interrupt handler.
192 *
193 * @note This API may do nothing on some architectures, it is required
194 * because on ports that support preemptable interrupt handlers
195 * it is required to raise the interrupt mask to the same level of
196 * the system mutual exclusion zone.<br>
197 * It is good practice to invoke this API after invoking any I-class
198 * syscall from an interrupt handler.
199 * @note This API must be invoked exclusively from interrupt handlers.
200 *
201 * @special
202 */
203 static void unlockFromIsr(void) {
204
205 chSysUnlockFromISR();
206 }
207
208 /**
209 * @brief Unconditionally enters the kernel lock state.
210 * @note Can be called without previous knowledge of the current lock state.
211 * The final state is "s-locked".
212 *
213 * @special
214 */
215 static void unconditionalLock(void) {
216
217 chSysUnconditionalLock();
218 }
219
220 /**
221 * @brief Unconditionally leaves the kernel lock state.
222 * @note Can be called without previous knowledge of the current lock state.
223 * The final state is "normal".
224 *
225 * @special
226 */
227 static void unconditionalUnlock(void) {
228
229 chSysUnconditionalUnlock();
230 }
231
232 /**
233 * @brief Returns the execution status and enters a critical zone.
234 * @details This functions enters into a critical zone and can be called
235 * from any context. Because its flexibility it is less efficient
236 * than @p chSysLock() which is preferable when the calling context
237 * is known.
238 * @post The system is in a critical zone.
239 *
240 * @return The previous system status, the encoding of this
241 * status word is architecture-dependent and opaque.
242 *
243 * @xclass
244 */
245 static syssts_t getStatusAndLockX(void) {
246
247 return chSysGetStatusAndLockX();
248 }
249
250 /**
251 * @brief Restores the specified execution status and leaves a critical zone.
252 * @note A call to @p chSchRescheduleS() is automatically performed
253 * if exiting the critical zone and if not in ISR context.
254 *
255 * @param[in] sts the system status to be restored.
256 *
257 * @xclass
258 */
259 static void restoreStatusX(syssts_t sts) {
260
261 chSysRestoreStatusX(sts);
262 }
263
264#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
265 /**
266 * @brief Returns the current value of the system real time counter.
267 * @note This function is only available if the port layer supports the
268 * option @p PORT_SUPPORTS_RT.
269 *
270 * @return The value of the system realtime counter of
271 * type rtcnt_t.
272 *
273 * @xclass
274 */
275 static rtcnt_t getRealtimeCounterX(void) {
276
277 return chSysGetRealtimeCounterX();
278 }
279
280 /**
281 * @brief Realtime window test.
282 * @details This function verifies if the current realtime counter value
283 * lies within the specified range or not. The test takes care
284 * of the realtime counter wrapping to zero on overflow.
285 * @note When start==end then the function returns always true because the
286 * whole time range is specified.
287 * @note This function is only available if the port layer supports the
288 * option @p PORT_SUPPORTS_RT.
289 *
290 * @param[in] cnt the counter value to be tested
291 * @param[in] start the start of the time window (inclusive)
292 * @param[in] end the end of the time window (non inclusive)
293 * @retval true current time within the specified time window.
294 * @retval false current time not within the specified time window.
295 *
296 * @xclass
297 */
298 static bool isCounterWithinX(rtcnt_t cnt,
299 rtcnt_t start,
300 rtcnt_t end) {
301
302 return chSysIsCounterWithinX(cnt, start, end);
303 }
304
305 /**
306 * @brief Polled delay.
307 * @note The real delay is always few cycles in excess of the specified
308 * value.
309 * @note This function is only available if the port layer supports the
310 * option @p PORT_SUPPORTS_RT.
311 *
312 * @param[in] cycles number of cycles
313 *
314 * @xclass
315 */
316 static void polledDelayX(rtcnt_t cycles) {
317
318 chSysPolledDelayX(cycles);
319 }
320#endif /* PORT_SUPPORTS_RT == TRUE */
321
322 /**
323 * @brief Returns the system time as system ticks.
324 * @note The system tick time interval is implementation dependent.
325 *
326 * @return The system time.
327 *
328 * @api
329 */
330 static systime_t getTime(void) {
331
332 return chVTGetSystemTime();
333 }
334
335 /**
336 * @brief Returns the system time as system ticks.
337 * @note The system tick time interval is implementation dependent.
338 *
339 * @return The system time.
340 *
341 * @xclass
342 */
343 static systime_t getTimeX(void) {
344
345 return chVTGetSystemTimeX();
346 }
347
348 /**
349 * @brief Checks if the current system time is within the specified time
350 * window.
351 * @note When start==end then the function returns always true because the
352 * whole time range is specified.
353 *
354 * @param[in] start the start of the time window (inclusive)
355 * @param[in] end the end of the time window (non inclusive)
356 * @retval true current time within the specified time window.
357 * @retval false current time not within the specified time window.
358 *
359 * @api
360 */
361 static bool isSystemTimeWithin(systime_t start, systime_t end) {
362
363 return chVTIsSystemTimeWithin(start, end);
364 }
365
366#if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__)
367 /**
368 * @brief Returns a reference to the idle thread.
369 * @pre In order to use this function the option @p CH_CFG_NO_IDLE_THREAD
370 * must be disabled.
371 * @note The reference counter of the idle thread is not incremented but
372 * it is not strictly required being the idle thread a static
373 * object.
374 *
375 * @return Reference to the idle thread.
376 *
377 * @xclass
378 */
379 static ThreadReference getIdleThreadX(void);
380#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */
381 };
382
383 /*------------------------------------------------------------------------*
384 * chibios_rt::CriticalSectionLocker *
385 *------------------------------------------------------------------------*/
386 /**
387 * @brief RAII helper for reentrant critical sections.
388 */
389 class CriticalSectionLocker {
390 volatile const syssts_t syssts = chSysGetStatusAndLockX();
391
392 public:
393 ~CriticalSectionLocker() {
394
395 chSysRestoreStatusX(syssts);
396 }
397 };
398
399 /*------------------------------------------------------------------------*
400 * chibios_rt::Scheduler *
401 *------------------------------------------------------------------------*/
402 /**
403 * @brief Class encapsulating the low level scheduler functionalities.
404 */
405 class Scheduler {
406 public:
407 /**
408 * @brief Performs a reschedule if a higher priority thread is runnable.
409 * @details If a thread with a higher priority than the current thread is in
410 * the ready list then make the higher priority thread running.
411 *
412 * @sclass
413 */
414 static void rescheduleS(void) {
415
416 void chSchRescheduleS();
417 }
418 };
419
420#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
421 /*------------------------------------------------------------------------*
422 * chibios_rt::Core *
423 *------------------------------------------------------------------------*/
424 /**
425 * @brief Class encapsulating the base system functionalities.
426 */
427 class Core {
428 public:
429 /**
430 * @brief Allocates a memory block.
431 * @details The size of the returned block is aligned to the alignment
432 * type so it is not possible to allocate less
433 * than <code>MEM_ALIGN_SIZE</code>.
434 *
435 * @param[in] size the size of the block to be allocated
436 * @return A pointer to the allocated memory block.
437 * @retval nullptr allocation failed, core memory exhausted.
438 *
439 * @api
440 */
441 static void *alloc(size_t size) {
442
443 return chCoreAlloc(size);
444 }
445
446 /**
447 * @brief Allocates a memory block.
448 * @details The size of the returned block is aligned to the alignment
449 * type so it is not possible to allocate less than
450 * <code>MEM_ALIGN_SIZE</code>.
451 *
452 * @param[in] size the size of the block to be allocated.
453 * @return A pointer to the allocated memory block.
454 * @retval nullptr allocation failed, core memory exhausted.
455 *
456 * @iclass
457 */
458 static void *allocI(size_t size) {
459
460 return chCoreAllocI(size);
461 }
462
463 /**
464 * @brief Core memory status.
465 *
466 * @return The size, in bytes, of the free core memory.
467 *
468 * @xclass
469 */
470 static size_t getStatusX(void) {
471
472 return chCoreGetStatusX();
473 }
474 };
475#endif /* CH_CFG_USE_MEMCORE == TRUE */
476
477 /*------------------------------------------------------------------------*
478 * chibios_rt::Timer *
479 *------------------------------------------------------------------------*/
480 /**
481 * @brief Timer class.
482 */
483 class Timer {
484 /**
485 * @brief Embedded @p virtual_timer_t structure.
486 */
487 virtual_timer_t vt;
488
489 public:
490 /**
491 * @brief Construct a virtual timer.
492 */
493 Timer() : vt() {
494
495 chVTObjectInit(&vt);
496 }
497
498 /* Prohibit copy construction and assignment.*/
499 Timer(const Timer &) = delete;
500 Timer &operator=(const Timer &) = delete;
501
502 /**
503 * @brief Enables a virtual timer.
504 * @note The associated function is invoked from interrupt context.
505 *
506 * @param[in] timeout the number of ticks before the operation timeouts,
507 * the special values are handled as follow:
508 * - @a TIME_INFINITE is allowed but interpreted as a
509 * normal time specification.
510 * - @a TIME_IMMEDIATE this value is not allowed.
511 * .
512 * @param[in] vtfunc the timer callback function. After invoking the
513 * callback the timer is disabled and the structure
514 * can be disposed or reused.
515 * @param[in] par a parameter that will be passed to the callback
516 * function
517 *
518 * @api
519 */
520 void set(sysinterval_t timeout, vtfunc_t vtfunc, void *par) {
521
522 chVTSet(&vt, timeout, vtfunc, par);
523 }
524
525 /**
526 * @brief Enables a virtual timer.
527 * @note The associated function is invoked from interrupt context.
528 *
529 * @param[in] timeout the number of ticks before the operation timeouts,
530 * the special values are handled as follow:
531 * - @a TIME_INFINITE is allowed but interpreted as a
532 * normal time specification.
533 * - @a TIME_IMMEDIATE this value is not allowed.
534 * .
535 * @param[in] vtfunc the timer callback function. After invoking the
536 * callback the timer is disabled and the structure
537 * can be disposed or reused.
538 * @param[in] par a parameter that will be passed to the callback
539 * function
540 *
541 * @iclass
542 */
543 void setI(sysinterval_t timeout, vtfunc_t vtfunc, void *par) {
544
545 chVTSetI(&vt, timeout, vtfunc, par);
546 }
547
548 /**
549 * @brief Resets the timer, if armed.
550 *
551 * @api
552 */
553 void reset() {
554
555 chVTReset(&vt);
556 }
557
558 /**
559 * @brief Resets the timer, if armed.
560 *
561 * @iclass
562 */
563 void resetI() {
564
565 chVTResetI(&vt);
566 }
567
568 /**
569 * @brief Returns the timer status.
570 *
571 * @return The timer status.
572 * @retval true If the timer is armed.
573 * @retval false If the timer already fired its callback.
574 *
575 * @iclass
576 */
577 bool isArmedI(void) const {
578
579 return chVTIsArmedI(&vt);
580 }
581 };
582
583 /*------------------------------------------------------------------------*
584 * chibios_rt::ThreadReference *
585 *------------------------------------------------------------------------*/
586 /**
587 * @brief Thread reference class.
588 * @details This class encapsulates a reference to a system thread. All
589 * operations involving another thread are performed through
590 * an object of this type.
591 */
592 class ThreadReference final {
593 /**
594 * @brief Pointer to the system thread.
595 */
596 thread_t *thread_ref;
597
598 public:
599 /**
600 * @brief Thread reference constructor.
601 * @note Do not call this version directly, this constructor is empty
602 * and is here only to do nothing when an object of this kind
603 * is declared then assigned.
604 * @note Automatic instances of this object are not initialized
605 * because this constructor, this is intentional.
606 *
607 * @param[in] tp the target thread
608 *
609 * @init
610 */
611 ThreadReference(void) {
612
613 }
614
615 /**
616 * @brief Thread reference constructor.
617 *
618 * @param[in] tp the target thread
619 *
620 * @init
621 */
622 ThreadReference(thread_t *tp) : thread_ref(tp) {
623
624 }
625
626 /**
627 * @brief Returns the reference state.
628 *
629 * @return The reference state.
630 * @retval false if the reference is still valid.
631 * @retval true if the reference is set to @p nullptr.
632 */
633 bool isNull(void) const {
634
635 return (bool)(thread_ref == nullptr);
636 }
637
638 /**
639 * @brief Returns the low level pointer to the referenced thread.
640 */
641 thread_t *getInner(void) {
642
643 return thread_ref;
644 }
645
646 /**
647 * @brief Requests a thread termination.
648 * @pre The target thread must be written to invoke periodically
649 * @p chThdShouldTerminate() and terminate cleanly if it returns
650 * @p TRUE.
651 * @post The specified thread will terminate after detecting the
652 * termination condition.
653 *
654 * @api
655 */
656 void requestTerminate(void) const {
657
658 chThdTerminate(thread_ref);
659 }
660
661#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
662 /**
663 * @brief Adds a reference to a thread object.
664 * @pre The configuration option @p CH_CFG_USE_REGISTRY must be enabled
665 * in order to use this function.
666 *
667 * @return A new thread reference.
668 *
669 * @api
670 */
671 ThreadReference addRef(void) const {
672
673 return ThreadReference(chThdAddRef(thread_ref));
674 }
675
676 /**
677 * @brief Releases a reference to a thread object.
678 * @details If the references counter reaches zero <b>and</b> the thread
679 * is in the @p CH_STATE_FINAL state then the thread's memory is
680 * returned to the proper allocator and the thread is removed
681 * from the registry.<br>
682 * Threads whose counter reaches zero and are still active become
683 * "detached" and will be removed from registry on termination.
684 * @pre The configuration option @p CH_CFG_USE_REGISTRY must be enabled in
685 * order to use this function.
686 * @post The reference is set to @p nullptr.
687 * @note Static threads are not affected.
688 *
689 * @api
690 */
691 void release(void) {
692 thread_t *tp = thread_ref;
693 thread_ref = nullptr;
694
695 chThdRelease(tp);
696 }
697#endif /* CH_CFG_USE_REGISTRY == TRUE */
698
699#if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__)
700 /**
701 * @brief Blocks the execution of the invoking thread until the specified
702 * thread terminates then the exit code is returned.
703 * @details This function waits for the specified thread to terminate then
704 * decrements its reference counter, if the counter reaches zero
705 * then the thread working area is returned to the proper
706 * allocator.<br>
707 * The memory used by the exited thread is handled in different
708 * ways depending on the API that spawned the thread:
709 * - If the thread was spawned by @p chThdCreateStatic() or by
710 * @p chThdCreateI() then nothing happens and the thread working
711 * area is not released or modified in any way. This is the
712 * default, totally static, behavior.
713 * - If the thread was spawned by @p chThdCreateFromHeap() then
714 * the working area is returned to the system heap.
715 * - If the thread was spawned by @p chThdCreateFromMemoryPool()
716 * then the working area is returned to the owning memory pool.
717 * .
718 * @pre The configuration option @p CH_USE_WAITEXIT must be enabled in
719 * order to use this function.
720 * @post Enabling @p chThdWait() requires 2-4 (depending on the
721 * architecture) extra bytes in the @p Thread structure.
722 * @post The reference is set to @p nullptr.
723 * @note If @p CH_USE_DYNAMIC is not specified this function just waits
724 * for the thread termination, no memory allocators are involved.
725 *
726 * @return The exit code from the terminated thread.
727 *
728 * @api
729 */
730 msg_t wait(void) {
731 thread_t *tp = thread_ref;
732 thread_ref = nullptr;
733
734 msg_t msg = chThdWait(tp);
735 return msg;
736 }
737#endif /* CH_CFG_USE_WAITEXIT == TRUE */
738
739#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
740 /**
741 * @brief Sends a message to the thread and returns the answer.
742 *
743 * @param[in] msg the sent message
744 * @return The returned message.
745 *
746 * @api
747 */
748 msg_t sendMessage(msg_t msg) const {
749
750 return chMsgSend(thread_ref, msg);
751 }
752
753 /**
754 * @brief Returns true if there is at least one message in queue.
755 *
756 * @retval true A message is waiting in queue.
757 * @retval false A message is not waiting in queue.
758 *
759 * @api
760 */
761 bool isPendingMessage(void) const {
762
763 return chMsgIsPendingI(thread_ref);
764 }
765
766 /**
767 * @brief Returns an enqueued message or @p nullptr.
768 *
769 * @return The incoming message.
770 *
771 * @api
772 */
773 msg_t getMessage(void) const {
774
775 return chMsgGet(thread_ref);
776 }
777
778 /**
779 * @brief Releases the next message in queue with a reply.
780 * @post The reference is set to @p nullptr.
781 *
782 * @param[in] msg the answer message
783 *
784 * @api
785 */
786 void releaseMessage(msg_t msg) {
787 thread_t *tp = thread_ref;
788 thread_ref = nullptr;
789
790 chMsgRelease(tp, msg);
791 }
792#endif /* CH_CFG_USE_MESSAGES == TRUE */
793
794#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
795 /**
796 * @brief Adds a set of event flags directly to specified @p Thread.
797 *
798 * @param[in] mask the event flags set to be ORed
799 *
800 * @api
801 */
802 void signalEvents(eventmask_t mask) const {
803
804 chEvtSignal(thread_ref, mask);
805 }
806
807 /**
808 * @brief Adds a set of event flags directly to specified @p Thread.
809 *
810 * @param[in] mask the event flags set to be ORed
811 *
812 * @iclass
813 */
814 void signalEventsI(eventmask_t mask) const {
815
816 chEvtSignalI(thread_ref, mask);
817 }
818#endif /* CH_CFG_USE_EVENTS == TRUE */
819
820#if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
821 /**
822 * @brief Returns the number of ticks consumed by the specified thread.
823 * @note This function is only available when the
824 * @p CH_DBG_THREADS_PROFILING configuration option is enabled.
825 *
826 * @param[in] tp pointer to the thread
827 * @return The number of consumed system ticks.
828 *
829 * @xclass
830 */
831 systime_t getTicksX(void) const {
832
833 return chThdGetTicksX(thread_ref);
834 }
835#endif /* CH_DBG_THREADS_PROFILING == TRUE */
836 };
837
838#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
839 /*------------------------------------------------------------------------*
840 * chibios_rt::Registry *
841 *------------------------------------------------------------------------*/
842 class Registry {
843 public:
844 /**
845 * @brief Returns the first thread in the system.
846 * @details Returns the most ancient thread in the system, usually this is
847 * the main thread unless it terminated. A reference is added to the
848 * returned thread in order to make sure its status is not lost.
849 * @note This function cannot return @p nullptr because there is always at
850 * least one thread in the system.
851 *
852 * @return A reference to the most ancient thread.
853 *
854 * @api
855 */
856 static ThreadReference firstThread(void) {
857
858 return ThreadReference(chRegFirstThread());
859 }
860
861 /**
862 * @brief Returns the thread next to the specified one.
863 * @details The reference counter of the specified thread is decremented and
864 * the reference counter of the returned thread is incremented.
865 *
866 * @param[in] tref reference to the thread
867 * @return A reference to the next thread. The reference is
868 * set to @p nullptr if there is no next thread.
869 *
870 * @api
871 */
872 static ThreadReference nextThread(ThreadReference tref) {
873
874 return ThreadReference(chRegNextThread(tref.getInner()));
875 }
876
877 /**
878 * @brief Retrieves a thread reference by name.
879 * @note The reference counter of the found thread is increased by one so
880 * it cannot be disposed incidentally after the pointer has been
881 * returned.
882 *
883 * @param[in] name the thread name
884 * @return A pointer to the found thread.
885 * @return A reference to the found thread. The reference is
886 * set to @p nullptr if no next thread is found.
887 *
888 * @api
889 */
890 static ThreadReference findThreadByName(const char *name) {
891
892 return ThreadReference(chRegFindThreadByName(name));
893 }
894 };
895#endif /* CH_CFG_USE_REGISTRY == TRUE */
896
897 /*------------------------------------------------------------------------*
898 * chibios_rt::BaseThread *
899 *------------------------------------------------------------------------*/
900 /**
901 * @brief Abstract base class for a ChibiOS/RT thread.
902 * @details The thread body is the virtual function @p Main().
903 */
904 class BaseThread {
905 public:
906 /**
907 * @brief BaseThread constructor.
908 *
909 * @init
910 */
911 BaseThread(void) {
912
913 }
914
915 /**
916 * @brief Thread body function.
917 *
918 * @return The exit message.
919 *
920 * @api
921 */
922 virtual void main(void) = 0;
923
924 /**
925 * @brief Creates and starts a system thread.
926 *
927 * @param[in] prio thread priority
928 * @return A reference to the created thread with
929 * reference counter set to one.
930 *
931 * @api
932 */
933 virtual ThreadReference start(tprio_t prio) = 0;
934
935 /**
936 * @brief Returns a reference to the current thread.
937 *
938 * @return A reference to the current thread.
939 *
940 * @xclass
941 */
942 static ThreadReference getSelfX(void) {
943
944 return ThreadReference(chThdGetSelfX());
945 }
946
947 /**
948 * @brief Sets the current thread name.
949 * @pre This function only stores the pointer to the name if the option
950 * @p CH_USE_REGISTRY is enabled else no action is performed.
951 *
952 * @param[in] tname thread name as a zero terminated string
953 *
954 * @api
955 */
956 static void setName(const char *tname) {
957
958 chRegSetThreadName(tname);
959 }
960
961 /**
962 * @brief Changes the running thread priority level then reschedules if
963 * necessary.
964 * @note The function returns the real thread priority regardless of the
965 * current priority that could be higher than the real priority
966 * because the priority inheritance mechanism.
967 *
968 * @param[in] newprio the new priority level of the running thread
969 * @return The old priority level.
970 *
971 * @api
972 */
973 static tprio_t setPriority(tprio_t newprio) {
974
975 return chThdSetPriority(newprio);
976 }
977
978 /**
979 * @brief Returns the current thread priority.
980 * @note Can be invoked in any context.
981 *
982 * @return The current thread priority.
983 *
984 * @xclass
985 */
986 static tprio_t getPriorityX(void) {
987
988 return chThdGetPriorityX();
989 }
990
991 /**
992 * @brief Terminates the current thread.
993 * @details The thread goes in the @p THD_STATE_FINAL state holding the
994 * specified exit status code, other threads can retrieve the
995 * exit status code by invoking the function @p chThdWait().
996 * @post Eventual code after this function will never be executed,
997 * this function never returns. The compiler has no way to
998 * know this so do not assume that the compiler would remove
999 * the dead code.
1000 *
1001 * @param[in] msg thread exit code
1002 *
1003 * @api
1004 */
1005 static void exit(msg_t msg) {
1006
1007 chThdExit(msg);
1008 }
1009
1010 /**
1011 * @brief Terminates the current thread.
1012 * @details The thread goes in the @p THD_STATE_FINAL state holding the
1013 * specified exit status code, other threads can retrieve the
1014 * exit status code by invoking the function @p chThdWait().
1015 * @post Eventual code after this function will never be executed,
1016 * this function never returns. The compiler has no way to
1017 * know this so do not assume that the compiler would remove
1018 * the dead code.
1019 *
1020 * @param[in] msg thread exit code
1021 *
1022 * @sclass
1023 */
1024 static void exitS(msg_t msg) {
1025
1026 chThdExitS(msg);
1027 }
1028
1029 /**
1030 * @brief Verifies if the current thread has a termination request
1031 * pending.
1032 * @note Can be invoked in any context.
1033 *
1034 * @retval TRUE termination request pending.
1035 * @retval FALSE termination request not pending.
1036 *
1037 * @special
1038 */
1039 static bool shouldTerminate(void) {
1040
1041 return chThdShouldTerminateX();
1042 }
1043
1044 /**
1045 * @brief Suspends the invoking thread for the specified time.
1046 *
1047 * @param[in] interval the delay in system ticks, the special values are
1048 * handled as follow:
1049 * - @a TIME_INFINITE the thread enters an infinite
1050 * sleep state.
1051 * - @a TIME_IMMEDIATE this value is not allowed.
1052 * .
1053 *
1054 * @api
1055 */
1056 static void sleep(sysinterval_t interval) {
1057
1058 chThdSleep(interval);
1059 }
1060
1061 /**
1062 * @brief Suspends the invoking thread until the system time arrives to
1063 * the specified value.
1064 *
1065 * @param[in] time absolute system time
1066 *
1067 * @api
1068 */
1069 static void sleepUntil(systime_t time) {
1070
1071 chThdSleepUntil(time);
1072 }
1073
1074 /**
1075 * @brief Suspends the invoking thread until the system time arrives to the
1076 * specified value.
1077 * @note The system time is assumed to be between @p prev and @p time
1078 * else the call is assumed to have been called outside the
1079 * allowed time interval, in this case no sleep is performed.
1080 * @see chThdSleepUntil()
1081 *
1082 * @param[in] prev absolute system time of the previous deadline
1083 * @param[in] next absolute system time of the next deadline
1084 * @return the @p next parameter
1085 *
1086 * @api
1087 */
1088 static systime_t sleepUntilWindowed(systime_t prev, systime_t next) {
1089
1090 return chThdSleepUntilWindowed(prev, next);
1091 }
1092
1093 /**
1094 * @brief Yields the time slot.
1095 * @details Yields the CPU control to the next thread in the ready list
1096 * with equal priority, if any.
1097 *
1098 * @api
1099 */
1100 static void yield(void) {
1101
1102 chThdYield();
1103 }
1104
1105#if CH_CFG_USE_MESSAGES || defined(__DOXYGEN__)
1106 /**
1107 * @brief Waits for a message.
1108 * @post On the returned reference it is mandatory to call
1109 * @p releaseMessage() or the sender thread would be waiting
1110 * undefinitely.
1111 *
1112 * @return The sender thread reference.
1113 *
1114 * @api
1115 */
1116 static ThreadReference waitMessage(void) {
1117
1118 return ThreadReference(chMsgWait());
1119 }
1120#endif /* CH_CFG_USE_MESSAGES == TRUE */
1121
1122#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
1123 /**
1124 * @brief Clears the pending events specified in the mask.
1125 *
1126 * @param[in] mask the events to be cleared
1127 * @return The pending events that were cleared.
1128 *
1129 * @api
1130 */
1131 static eventmask_t getAndClearEvents(eventmask_t mask) {
1132
1133 return chEvtGetAndClearEvents(mask);
1134 }
1135
1136 /**
1137 * @brief Adds (OR) a set of event flags on the current thread, this is
1138 * @b much faster than using @p chEvtBroadcast() or
1139 * @p chEvtSignal().
1140 *
1141 * @param[in] mask the event flags to be added
1142 * @return The current pending events mask.
1143 *
1144 * @api
1145 */
1146 static eventmask_t addEvents(eventmask_t mask) {
1147
1148 return chEvtAddEvents(mask);
1149 }
1150
1151 /**
1152 * @brief Waits for a single event.
1153 * @details A pending event among those specified in @p ewmask is selected,
1154 * cleared and its mask returned.
1155 * @note One and only one event is served in the function, the one with
1156 * the lowest event id. The function is meant to be invoked into
1157 * a loop in order to serve all the pending events.<br>
1158 * This means that Event Listeners with a lower event identifier
1159 * have an higher priority.
1160 *
1161 * @param[in] ewmask mask of the events that the function should
1162 * wait for, @p ALL_EVENTS enables all the events
1163 * @return The mask of the lowest id served and cleared
1164 * event.
1165 *
1166 * @api
1167 */
1168 static eventmask_t waitOneEvent(eventmask_t ewmask) {
1169
1170 return chEvtWaitOne(ewmask);
1171 }
1172
1173 /**
1174 * @brief Waits for any of the specified events.
1175 * @details The function waits for any event among those specified in
1176 * @p ewmask to become pending then the events are cleared and
1177 * returned.
1178 *
1179 * @param[in] ewmask mask of the events that the function should
1180 * wait for, @p ALL_EVENTS enables all the events
1181 * @return The mask of the served and cleared events.
1182 *
1183 * @api
1184 */
1185 static eventmask_t waitAnyEvent(eventmask_t ewmask) {
1186
1187 return chEvtWaitAny(ewmask);
1188 }
1189
1190 /**
1191 * @brief Waits for all the specified event flags then clears them.
1192 * @details The function waits for all the events specified in @p ewmask
1193 * to become pending then the events are cleared and returned.
1194 *
1195 * @param[in] ewmask mask of the event ids that the function should
1196 * wait for
1197 * @return The mask of the served and cleared events.
1198 *
1199 * @api
1200 */
1201 static eventmask_t waitAllEvents(eventmask_t ewmask) {
1202
1203 return chEvtWaitAll(ewmask);
1204 }
1205
1206#if CH_CFG_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__)
1207 /**
1208 * @brief Waits for a single event.
1209 * @details A pending event among those specified in @p ewmask is selected,
1210 * cleared and its mask returned.
1211 * @note One and only one event is served in the function, the one with
1212 * the lowest event id. The function is meant to be invoked into
1213 * a loop in order to serve all the pending events.<br>
1214 * This means that Event Listeners with a lower event identifier
1215 * have an higher priority.
1216 *
1217 * @param[in] ewmask mask of the events that the function should
1218 * wait for, @p ALL_EVENTS enables all the events
1219 *
1220 * @param[in] timeout the number of ticks before the operation
1221 * timouts
1222 * @return The mask of the lowest id served and cleared
1223 * event.
1224 * @retval 0 if the specified timeout expired.
1225 *
1226 * @api
1227 */
1228 static eventmask_t waitOneEventTimeout(eventmask_t ewmask,
1229 sysinterval_t timeout) {
1230
1231 return chEvtWaitOneTimeout(ewmask, timeout);
1232 }
1233
1234 /**
1235 * @brief Waits for any of the specified events.
1236 * @details The function waits for any event among those specified in
1237 * @p ewmask to become pending then the events are cleared and
1238 * returned.
1239 *
1240 * @param[in] ewmask mask of the events that the function should
1241 * wait for, @p ALL_EVENTS enables all the events
1242 * @param[in] timeout the number of ticks before the operation
1243 * timouts
1244 * @return The mask of the served and cleared events.
1245 * @retval 0 if the specified timeout expired.
1246 *
1247 * @api
1248 */
1249 static eventmask_t waitAnyEventTimeout(eventmask_t ewmask,
1250 sysinterval_t timeout) {
1251
1252 return chEvtWaitAnyTimeout(ewmask, timeout);
1253 }
1254
1255 /**
1256 * @brief Waits for all the specified event flags then clears them.
1257 * @details The function waits for all the events specified in @p ewmask
1258 * to become pending then the events are cleared and returned.
1259 *
1260 * @param[in] ewmask mask of the event ids that the function should
1261 * wait for
1262 * @param[in] timeout the number of ticks before the operation
1263 * timouts
1264 * @return The mask of the served and cleared events.
1265 * @retval 0 if the specified timeout expired.
1266 *
1267 * @api
1268 */
1269 static eventmask_t waitAllEventsTimeout(eventmask_t ewmask,
1270 sysinterval_t timeout) {
1271
1272 return chEvtWaitAllTimeout(ewmask, timeout);
1273 }
1274#endif /* CH_CFG_USE_EVENTS_TIMEOUT == TRUE */
1275
1276 /**
1277 * @brief Invokes the event handlers associated to an event flags mask.
1278 *
1279 * @param[in] mask mask of the event flags to be dispatched
1280 * @param[in] handlers an array of @p evhandler_t. The array must have
1281 * size equal to the number of bits in eventmask_t.
1282 *
1283 * @api
1284 */
1285 static void dispatchEvents(const evhandler_t handlers[],
1286 eventmask_t mask) {
1287
1288 chEvtDispatch(handlers, mask);
1289 }
1290#endif /* CH_CFG_USE_EVENTS == TRUE */
1291
1292#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
1293 /**
1294 * @brief Unlocks all the mutexes owned by the invoking thread.
1295 * @post The stack of owned mutexes is emptied and all the found
1296 * mutexes are unlocked.
1297 * @note This function is <b>MUCH MORE</b> efficient than releasing the
1298 * mutexes one by one and not just because the call overhead,
1299 * this function does not have any overhead related to the
1300 * priority inheritance mechanism.
1301 *
1302 * @api
1303 */
1304 static void unlockAllMutexes(void) {
1305
1306 chMtxUnlockAll();
1307 }
1308#endif /* CH_CFG_USE_MUTEXES == TRUE */
1309 };
1310
1311 /*------------------------------------------------------------------------*
1312 * chibios_rt::BaseStaticThread *
1313 *------------------------------------------------------------------------*/
1314 /**
1315 * @brief Static threads template base class.
1316 * @details This class introduces static working area instantiation.
1317 *
1318 * @param N the working area size for the thread class
1319 */
1320 template <int N>
1321 class BaseStaticThread : public BaseThread {
1322 protected:
1323 THD_WORKING_AREA(wa, N);
1324
1325 public:
1326 /**
1327 * @brief Starts a static thread.
1328 *
1329 * @param[in] prio thread priority
1330 * @return A reference to the created thread with
1331 * reference counter set to one.
1332 *
1333 * @api
1334 */
1335 ThreadReference start(tprio_t prio) override {
1336 void _thd_start(void *arg);
1337
1338 return ThreadReference(chThdCreateStatic(wa, sizeof(wa), prio,
1339 _thd_start, this));
1340 }
1341 };
1342
1343 /*------------------------------------------------------------------------*
1344 * chibios_rt::BaseDynamicThread *
1345 *------------------------------------------------------------------------*/
1346 /**
1347 * @brief Dynamic threads base class.
1348 */
1349 class BaseDynamicThread : public BaseThread {
1350 };
1351
1352 /*------------------------------------------------------------------------*
1353 * chibios_rt::ThreadStayPoint *
1354 *------------------------------------------------------------------------*/
1355 /**
1356 * @brief Thread suspension point class.
1357 * @details This class encapsulates a reference to a suspended thread.
1358 */
1359 class ThreadStayPoint {
1360 /**
1361 * @brief Pointer to the suspended thread.
1362 */
1363 thread_reference_t thread_ref = nullptr;
1364
1365 public:
1366 /**
1367 * @brief Thread stay point constructor.
1368 *
1369 * @init
1370 */
1371 ThreadStayPoint() {
1372
1373 }
1374
1375 /* Prohibit copy construction and assignment.*/
1376 ThreadStayPoint(const ThreadStayPoint &) = delete;
1377 ThreadStayPoint &operator=(const ThreadStayPoint &) = delete;
1378
1379 /**
1380 * @brief Suspends the current thread on the stay point.
1381 * @details The suspended thread becomes the referenced thread. It is
1382 * possible to use this method only if the thread reference
1383 * was set to @p nullptr.
1384 *
1385 * @return The incoming message.
1386 *
1387 * @sclass
1388 */
1389 msg_t suspendS(void) {
1390
1391 return chThdSuspendS(&thread_ref);
1392 }
1393
1394 /**
1395 * @brief Suspends the current thread on the stay point with timeout.
1396 * @details The suspended thread becomes the referenced thread. It is
1397 * possible to use this method only if the thread reference
1398 * was set to @p nullptr.
1399 *
1400 *
1401 * @param[in] timeout the number of ticks before the operation timeouts,
1402 * the following special values are allowed:
1403 * - @a TIME_IMMEDIATE immediate timeout.
1404 * - @a TIME_INFINITE no timeout.
1405 * .
1406 * @return A message specifying how the invoking thread has
1407 * been released from the semaphore.
1408 * @retval MSG_OK if the binary semaphore has been successfully
1409 * taken.
1410 * @retval MSG_RESET if the binary semaphore has been reset using
1411 * @p bsemReset().
1412 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled
1413 * or reset within the specified timeout.
1414 *
1415 * @sclass
1416 */
1417 msg_t suspendS(sysinterval_t timeout) {
1418
1419 return chThdSuspendTimeoutS(&thread_ref, timeout);
1420 }
1421
1422 /**
1423 * @brief Resumes the currently referenced thread, if any.
1424 *
1425 * @param[in] msg the wakeup message
1426 *
1427 * @iclass
1428 */
1429 void resumeI(msg_t msg) {
1430
1431 chThdResumeI(&thread_ref, msg);
1432 }
1433
1434 /**
1435 * @brief Resumes the currently referenced thread, if any.
1436 *
1437 * @param[in] msg the wakeup message
1438 *
1439 * @sclass
1440 */
1441 void resumeS(msg_t msg) {
1442
1443 chThdResumeS(&thread_ref, msg);
1444 }
1445 };
1446
1447 /*------------------------------------------------------------------------*
1448 * chibios_rt::SynchronizationObject *
1449 *------------------------------------------------------------------------*/
1450 /**
1451 * @brief Base class for all synchronization objects.
1452 * @note No other uses.
1453 */
1454 class SynchronizationObject {
1455 };
1456
1457 /*------------------------------------------------------------------------*
1458 * chibios_rt::ThreadsQueue *
1459 *------------------------------------------------------------------------*/
1460 /**
1461 * @brief Threads queue class.
1462 * @details This class encapsulates a queue of threads.
1463 */
1464 class ThreadsQueue : public SynchronizationObject {
1465 /**
1466 * @brief Pointer to the system thread.
1467 */
1468 threads_queue_t threads_queue;
1469
1470 public:
1471 /**
1472 * @brief Threads queue constructor.
1473 *
1474 * @init
1475 */
1476 ThreadsQueue() {
1477
1478 chThdQueueObjectInit(&threads_queue);
1479 }
1480
1481 /* Prohibit copy construction and assignment.*/
1482 ThreadsQueue(const ThreadsQueue &) = delete;
1483 ThreadsQueue &operator=(const ThreadsQueue &) = delete;
1484
1485 /**
1486 * @brief Enqueues the caller thread on a threads queue object.
1487 * @details The caller thread is enqueued and put to sleep until it is
1488 * dequeued or the specified timeouts expires.
1489 *
1490 * @param[in] timeout the timeout in system ticks, the special values are
1491 * handled as follow:
1492 * - @a TIME_INFINITE the thread enters an infinite sleep
1493 * state.
1494 * - @a TIME_IMMEDIATE the thread is not enqueued and
1495 * the function returns @p MSG_TIMEOUT as if a timeout
1496 * occurred.
1497 * .
1498 * @return The message from @p osalQueueWakeupOneI() or
1499 * @p osalQueueWakeupAllI() functions.
1500 * @retval MSG_TIMEOUT if the thread has not been dequeued within the
1501 * specified timeout or if the function has been
1502 * invoked with @p TIME_IMMEDIATE as timeout
1503 * specification.
1504 *
1505 * @sclass
1506 */
1507 msg_t enqueueSelfS(sysinterval_t timeout) {
1508
1509 return chThdEnqueueTimeoutS(&threads_queue, timeout);
1510 }
1511
1512 /**
1513 * @brief Dequeues and wakes up one thread from the threads queue object,
1514 * if any.
1515 *
1516 * @param[in] msg the message code
1517 *
1518 * @iclass
1519 */
1520 void dequeueNextI(msg_t msg) {
1521
1522 chThdDequeueNextI(&threads_queue, msg);
1523 }
1524
1525 /**
1526 * @brief Dequeues and wakes up all threads from the threads queue object.
1527 *
1528 * @param[in] msg the message code
1529 *
1530 * @iclass
1531 */
1532 void chdequeueAllI(msg_t msg) {
1533
1534 chThdDequeueAllI(&threads_queue, msg);
1535 }
1536};
1537
1538#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
1539 /*------------------------------------------------------------------------*
1540 * chibios_rt::CounterSemaphore *
1541 *------------------------------------------------------------------------*/
1542 /**
1543 * @brief Class encapsulating a semaphore.
1544 */
1545 class CounterSemaphore : public SynchronizationObject {
1546 /**
1547 * @brief Embedded @p semaphore_t structure.
1548 */
1549 semaphore_t sem;
1550
1551 public:
1552 /**
1553 * @brief CounterSemaphore constructor.
1554 * @details The embedded @p Semaphore structure is initialized.
1555 *
1556 * @param[in] n the semaphore counter value, must be greater
1557 * or equal to zero
1558 *
1559 * @init
1560 */
1561 CounterSemaphore(cnt_t n) {
1562
1563 chSemObjectInit(&sem, n);
1564 }
1565
1566 /**
1567 * @brief Performs a reset operation on the semaphore.
1568 * @post After invoking this function all the threads waiting on the
1569 * semaphore, if any, are released and the semaphore counter is
1570 * set to the specified, non negative, value.
1571 * @note The released threads can recognize they were waked up by a
1572 * reset rather than a signal because the @p chSemWait() will
1573 * return @p MSG_RESET instead of @p MSG_OK.
1574 *
1575 * @param[in] n the new value of the semaphore counter. The value
1576 * must be non-negative.
1577 *
1578 * @api
1579 */
1580 void reset(cnt_t n) {
1581
1582 chSemReset(&sem, n);
1583 }
1584
1585 /**
1586 * @brief Performs a reset operation on the semaphore.
1587 * @post After invoking this function all the threads waiting on the
1588 * semaphore, if any, are released and the semaphore counter is
1589 * set to the specified, non negative, value.
1590 * @post This function does not reschedule so a call to a rescheduling
1591 * function must be performed before unlocking the kernel. Note
1592 * that interrupt handlers always reschedule on exit so an
1593 * explicit reschedule must not be performed in ISRs.
1594 * @note The released threads can recognize they were waked up by a
1595 * reset rather than a signal because the @p chSemWait() will
1596 * return @p MSG_RESET instead of @p MSG_OK.
1597 *
1598 * @param[in] n the new value of the semaphore counter. The value
1599 * must be non-negative.
1600 *
1601 * @iclass
1602 */
1603 void resetI(cnt_t n) {
1604
1605 chSemResetI(&sem, n);
1606 }
1607
1608 /**
1609 * @brief Performs a wait operation on a semaphore.
1610 *
1611 * @return A message specifying how the invoking thread has
1612 * been released from the semaphore.
1613 * @retval MSG_OK if the thread has not stopped on the semaphore or
1614 * the semaphore has been signaled.
1615 * @retval MSG_RESET if the semaphore has been reset using
1616 * @p chSemReset().
1617 *
1618 * @api
1619 */
1620 msg_t wait(void) {
1621
1622 return chSemWait(&sem);
1623 }
1624
1625 /**
1626 * @brief Performs a wait operation on a semaphore.
1627 *
1628 * @return A message specifying how the invoking thread has
1629 * been released from the semaphore.
1630 * @retval MSG_OK if the thread has not stopped on the semaphore or
1631 * the semaphore has been signaled.
1632 * @retval MSG_RESET if the semaphore has been reset using
1633 * @p chSemReset().
1634 *
1635 * @sclass
1636 */
1637 msg_t waitS(void) {
1638
1639 return chSemWaitS(&sem);
1640 }
1641
1642 /**
1643 * @brief Performs a wait operation on a semaphore with timeout
1644 * specification.
1645 *
1646 * @param[in] timeout the number of ticks before the operation timeouts,
1647 * the following special values are allowed:
1648 * - @a TIME_IMMEDIATE immediate timeout.
1649 * - @a TIME_INFINITE no timeout.
1650 * .
1651 * @return A message specifying how the invoking thread has
1652 * been released from the semaphore.
1653 * @retval MSG_OK if the thread has not stopped on the semaphore or
1654 * the semaphore has been signaled.
1655 * @retval MSG_RESET if the semaphore has been reset using
1656 * @p chSemReset().
1657 * @retval MSG_TIMEOUT if the semaphore has not been signaled or reset
1658 * within the specified timeout.
1659 *
1660 * @api
1661 */
1662 msg_t wait(sysinterval_t timeout) {
1663
1664 return chSemWaitTimeout(&sem, timeout);
1665 }
1666
1667 /**
1668 * @brief Performs a wait operation on a semaphore with timeout
1669 * specification.
1670 *
1671 * @param[in] timeout the number of ticks before the operation timeouts,
1672 * the following special values are allowed:
1673 * - @a TIME_IMMEDIATE immediate timeout.
1674 * - @a TIME_INFINITE no timeout.
1675 * .
1676 * @return A message specifying how the invoking thread has
1677 * been released from the semaphore.
1678 * @retval MSG_OK if the thread has not stopped on the semaphore or
1679 * the semaphore has been signaled.
1680 * @retval MSG_RESET if the semaphore has been reset using
1681 * @p chSemReset().
1682 * @retval MSG_TIMEOUT if the semaphore has not been signaled or reset
1683 * within the specified timeout.
1684 *
1685 * @sclass
1686 */
1687 msg_t waitS(sysinterval_t timeout) {
1688
1689 return chSemWaitTimeoutS(&sem, timeout);
1690 }
1691
1692 /**
1693 * @brief Performs a signal operation on a semaphore.
1694 *
1695 * @api
1696 */
1697 void signal(void) {
1698
1699 chSemSignal(&sem);
1700 }
1701
1702 /**
1703 * @brief Performs a signal operation on a semaphore.
1704 * @post This function does not reschedule so a call to a rescheduling
1705 * function must be performed before unlocking the kernel. Note
1706 * that interrupt handlers always reschedule on exit so an
1707 * explicit reschedule must not be performed in ISRs.
1708 *
1709 * @iclass
1710 */
1711 void signalI(void) {
1712
1713 chSemSignalI(&sem);
1714 }
1715
1716 /**
1717 * @brief Adds the specified value to the semaphore counter.
1718 * @post This function does not reschedule so a call to a rescheduling
1719 * function must be performed before unlocking the kernel. Note
1720 * that interrupt handlers always reschedule on exit so an explicit
1721 * reschedule must not be performed in ISRs.
1722 *
1723 * @param[in] n value to be added to the semaphore counter. The
1724 * value must be positive.
1725 *
1726 * @iclass
1727 */
1728 void addCounterI(cnt_t n) {
1729
1730 chSemAddCounterI(&sem, n);
1731 }
1732
1733 /**
1734 * @brief Returns the semaphore counter value.
1735 *
1736 * @return The semaphore counter value.
1737 *
1738 * @iclass
1739 */
1740 cnt_t getCounterI(void) const {
1741
1742 return chSemGetCounterI(&sem);
1743 }
1744
1745 /**
1746 * @brief Atomic signal and wait operations.
1747 *
1748 * @param[in] ssem @p Semaphore object to be signaled
1749 * @param[in] wsem @p Semaphore object to wait on
1750 * @return A message specifying how the invoking thread
1751 * has been released from the semaphore.
1752 * @retval MSG_OK if the thread has not stopped on the semaphore
1753 * or the semaphore has been signaled.
1754 * @retval MSG_RESET if the semaphore has been reset using
1755 * @p chSemReset().
1756 *
1757 * @api
1758 */
1759 static msg_t signalWait(CounterSemaphore *ssem,
1760 CounterSemaphore *wsem) {
1761
1762 return chSemSignalWait(&ssem->sem, &wsem->sem);
1763 }
1764 };
1765
1766 /*------------------------------------------------------------------------*
1767 * chibios_rt::BinarySemaphore *
1768 *------------------------------------------------------------------------*/
1769 /**
1770 * @brief Class encapsulating a binary semaphore.
1771 */
1772 class BinarySemaphore : public SynchronizationObject {
1773 /**
1774 * @brief Embedded @p binary_semaphore_t structure.
1775 */
1776 binary_semaphore_t bsem;
1777
1778 public:
1779 /**
1780 * @brief BinarySemaphore constructor.
1781 * @details The embedded @p ::BinarySemaphore structure is initialized.
1782 *
1783 * @param[in] taken initial state of the binary semaphore:
1784 * - @a false, the initial state is not taken.
1785 * - @a true, the initial state is taken.
1786 * .
1787 *
1788 * @init
1789 */
1790 BinarySemaphore(bool taken) {
1791
1792 chBSemObjectInit(&bsem, taken);
1793 }
1794
1795 /**
1796 * @brief Wait operation on the binary semaphore.
1797 *
1798 * @return A message specifying how the invoking thread has
1799 * been released from the semaphore.
1800 * @retval MSG_OK if the binary semaphore has been successfully
1801 * taken.
1802 * @retval MSG_RESET if the binary semaphore has been reset using
1803 * @p bsemReset().
1804 *
1805 * @api
1806 */
1807 msg_t wait(void) {
1808
1809 return chBSemWait(&bsem);
1810 }
1811
1812 /**
1813 * @brief Wait operation on the binary semaphore.
1814 *
1815 * @return A message specifying how the invoking thread has
1816 * been released from the semaphore.
1817 * @retval MSG_OK if the binary semaphore has been successfully
1818 * taken.
1819 * @retval MSG_RESET if the binary semaphore has been reset using
1820 * @p bsemReset().
1821 *
1822 * @sclass
1823 */
1824 msg_t waitS(void) {
1825
1826 return chBSemWaitS(&bsem);
1827 }
1828
1829 /**
1830 * @brief Wait operation on the binary semaphore.
1831 *
1832 * @param[in] timeout the number of ticks before the operation timeouts,
1833 * the following special values are allowed:
1834 * - @a TIME_IMMEDIATE immediate timeout.
1835 * - @a TIME_INFINITE no timeout.
1836 * .
1837 * @return A message specifying how the invoking thread has
1838 * been released from the semaphore.
1839 * @retval MSG_OK if the binary semaphore has been successfully
1840 * taken.
1841 * @retval MSG_RESET if the binary semaphore has been reset using
1842 * @p bsemReset().
1843 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled
1844 * or reset within the specified timeout.
1845 *
1846 * @api
1847 */
1848 msg_t wait(sysinterval_t timeout) {
1849
1850 return chBSemWaitTimeout(&bsem, timeout);
1851 }
1852
1853 /**
1854 * @brief Wait operation on the binary semaphore.
1855 *
1856 * @param[in] timeout the number of ticks before the operation timeouts,
1857 * the following special values are allowed:
1858 * - @a TIME_IMMEDIATE immediate timeout.
1859 * - @a TIME_INFINITE no timeout.
1860 * .
1861 * @return A message specifying how the invoking thread has
1862 * been released from the semaphore.
1863 * @retval MSG_OK if the binary semaphore has been successfully
1864 * taken.
1865 * @retval MSG_RESET if the binary semaphore has been reset using
1866 * @p bsemReset().
1867 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled
1868 * or reset within the specified timeout.
1869 *
1870 * @sclass
1871 */
1872 msg_t waitS(sysinterval_t timeout) {
1873
1874 return chBSemWaitTimeoutS(&bsem, timeout);
1875 }
1876
1877 /**
1878 * @brief Reset operation on the binary semaphore.
1879 * @note The released threads can recognize they were waked up by a
1880 * reset rather than a signal because the @p bsemWait() will
1881 * return @p MSG_RESET instead of @p MSG_OK.
1882 *
1883 * @param[in] taken new state of the binary semaphore
1884 * - @a FALSE, the new state is not taken.
1885 * - @a TRUE, the new state is taken.
1886 * .
1887 *
1888 * @api
1889 */
1890 void reset(bool taken) {
1891
1892 chBSemReset(&bsem, taken);
1893 }
1894
1895 /**
1896 * @brief Reset operation on the binary semaphore.
1897 * @note The released threads can recognize they were waked up by a
1898 * reset rather than a signal because the @p bsemWait() will
1899 * return @p MSG_RESET instead of @p MSG_OK.
1900 * @note This function does not reschedule.
1901 *
1902 * @param[in] taken new state of the binary semaphore
1903 * - @a FALSE, the new state is not taken.
1904 * - @a TRUE, the new state is taken.
1905 * .
1906 *
1907 * @iclass
1908 */
1909 void resetI(bool taken) {
1910
1911 chBSemResetI(&bsem, taken);
1912 }
1913
1914 /**
1915 * @brief Performs a signal operation on a binary semaphore.
1916 *
1917 * @api
1918 */
1919 void signal(void) {
1920
1921 chBSemSignal(&bsem);
1922 }
1923
1924 /**
1925 * @brief Performs a signal operation on a binary semaphore.
1926 * @note This function does not reschedule.
1927 *
1928 * @iclass
1929 */
1930 void signalI(void) {
1931
1932 chBSemSignalI(&bsem);
1933 }
1934
1935 /**
1936 * @brief Returns the binary semaphore current state.
1937 *
1938 * @return The binary semaphore current state.
1939 * @retval false if the binary semaphore is not taken.
1940 * @retval true if the binary semaphore is taken.
1941 *
1942 * @iclass
1943 */
1944 bool getStateI(void) const {
1945
1946 return (bool)chBSemGetStateI(&bsem);
1947 }
1948};
1949#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
1950
1951#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
1952 /*------------------------------------------------------------------------*
1953 * chibios_rt::Mutex *
1954 *------------------------------------------------------------------------*/
1955 /**
1956 * @brief Class encapsulating a mutex.
1957 */
1958 class Mutex : public SynchronizationObject {
1959 /**
1960 * @brief Embedded @p mutex_t structure.
1961 */
1962 mutex_t mutex;
1963
1964 public:
1965 /**
1966 * @brief Mutex object constructor.
1967 * @details The embedded @p mutex_t structure is initialized.
1968 *
1969 * @init
1970 */
1971 Mutex(void) {
1972
1973 chMtxObjectInit(&mutex);
1974 }
1975
1976 /**
1977 * @brief Tries to lock a mutex.
1978 * @details This function attempts to lock a mutex, if the mutex is already
1979 * locked by another thread then the function exits without
1980 * waiting.
1981 * @post The mutex is locked and inserted in the per-thread stack of
1982 * owned mutexes.
1983 * @note This function does not have any overhead related to the
1984 * priority inheritance mechanism because it does not try to
1985 * enter a sleep state.
1986 *
1987 * @return The operation status.
1988 * @retval TRUE if the mutex has been successfully acquired
1989 * @retval FALSE if the lock attempt failed.
1990 *
1991 * @api
1992 */
1993 bool tryLock(void) {
1994
1995 return chMtxTryLock(&mutex);
1996 }
1997
1998 /**
1999 * @brief Tries to lock a mutex.
2000 * @details This function attempts to lock a mutex, if the mutex is already
2001 * taken by another thread then the function exits without
2002 * waiting.
2003 * @post The mutex is locked and inserted in the per-thread stack of
2004 * owned mutexes.
2005 * @note This function does not have any overhead related to the
2006 * priority inheritance mechanism because it does not try to
2007 * enter a sleep state.
2008 *
2009 * @return The operation status.
2010 * @retval TRUE if the mutex has been successfully acquired
2011 * @retval FALSE if the lock attempt failed.
2012 *
2013 * @sclass
2014 */
2015 bool tryLockS(void) {
2016
2017 return chMtxTryLockS(&mutex);
2018 }
2019
2020 /**
2021 * @brief Locks the specified mutex.
2022 * @post The mutex is locked and inserted in the per-thread stack of
2023 * owned mutexes.
2024 *
2025 * @api
2026 */
2027 void lock(void) {
2028
2029 chMtxLock(&mutex);
2030 }
2031
2032 /**
2033 * @brief Locks the specified mutex.
2034 * @post The mutex is locked and inserted in the per-thread stack of
2035 * owned mutexes.
2036 *
2037 * @sclass
2038 */
2039 void lockS(void) {
2040
2041 chMtxLockS(&mutex);
2042 }
2043
2044 /**
2045 * @brief Unlocks the next owned mutex in reverse lock order.
2046 * @pre The invoking thread <b>must</b> have at least one owned mutex.
2047 * @post The mutex is unlocked and removed from the per-thread stack of
2048 * owned mutexes.
2049 *
2050 * @api
2051 */
2052 void unlock(void) {
2053
2054 chMtxUnlock(&mutex);
2055 }
2056
2057 /**
2058 * @brief Unlocks the next owned mutex in reverse lock order.
2059 * @pre The invoking thread <b>must</b> have at least one owned mutex.
2060 * @post The mutex is unlocked and removed from the per-thread stack of
2061 * owned mutexes.
2062 * @post This function does not reschedule so a call to a rescheduling
2063 * function must be performed before unlocking the kernel.
2064 *
2065 * @sclass
2066 */
2067 void unlockS(void) {
2068
2069 chMtxUnlockS(&mutex);
2070 }
2071
2072 /**
2073 * @brief Unlocks the next owned mutex in reverse lock order.
2074 * @pre The invoking thread <b>must</b> have at least one owned mutex.
2075 * @post The mutex is unlocked and removed from the per-thread stack of
2076 * owned mutexes.
2077 *
2078 * @return A pointer to the unlocked mutex.
2079 *
2080 * @api
2081 */
2082 void unlockMutex(void) {
2083
2084 chMtxUnlock(&mutex);
2085 }
2086
2087 /**
2088 * @brief Unlocks the next owned mutex in reverse lock order.
2089 * @pre The invoking thread <b>must</b> have at least one owned mutex.
2090 * @post The mutex is unlocked and removed from the per-thread stack of
2091 * owned mutexes.
2092 * @post This function does not reschedule so a call to a rescheduling
2093 * function must be performed before unlocking the kernel.
2094 *
2095 * @return A pointer to the unlocked mutex.
2096 *
2097 * @sclass
2098 */
2099 void unlockMutexS(void) {
2100
2101 chMtxUnlockS(&mutex);
2102 }
2103 };
2104
2105 /*------------------------------------------------------------------------*
2106 * chibios_rt::MutexLocker *
2107 *------------------------------------------------------------------------*/
2108 /**
2109 * @brief RAII helper for mutexes.
2110 */
2111 class MutexLocker
2112 {
2113 Mutex& mutex;
2114
2115 public:
2116 MutexLocker(Mutex& m) : mutex(m) {
2117
2118 mutex.lock();
2119 }
2120
2121 ~MutexLocker() {
2122
2123 mutex.unlock();
2124 }
2125 };
2126
2127#if (CH_CFG_USE_CONDVARS == TRUE) || defined(__DOXYGEN__)
2128 /*------------------------------------------------------------------------*
2129 * chibios_rt::Monitor *
2130 *------------------------------------------------------------------------*/
2131 /**
2132 * @brief Template class to be used for implementing a monitor.
2133 */
2134 template <unsigned N>
2135 class Monitor: protected Mutex {
2136 condition_variable_t condvars[N];
2137
2138 protected:
2139 /**
2140 * @brief Waits on the condition variable releasing the mutex lock.
2141 *
2142 * @param[in] var the condition variable index
2143 * @return A message specifying how the invoking thread has
2144 * been released from the condition variable.
2145 * @retval MSG_OK if the condition variable has been signaled using
2146 * @p signal().
2147 * @retval MSG_RESET if the condition variable has been signaled using
2148 * @p broadcast().
2149 *
2150 * @api
2151 */
2152 msg_t wait(unsigned var) {
2153
2154 chDbgCheck(var < N);
2155
2156 return chCondWait(&condvars[var]);
2157 }
2158
2159 /**
2160 * @brief Waits on the condition variable releasing the mutex lock.
2161 *
2162 * @param[in] var the condition variable index
2163 * @return A message specifying how the invoking thread has
2164 * been released from the condition variable.
2165 * @retval MSG_OK if the condition variable has been signaled using
2166 * @p signal().
2167 * @retval MSG_RESET if the condition variable has been signaled using
2168 * @p broadcast().
2169 *
2170 * @sclass
2171 */
2172 msg_t waitS(unsigned var) {
2173
2174 chDbgCheck(var < N);
2175
2176 return chCondWaitS(&condvars[var]);
2177 }
2178
2179#if (CH_CFG_USE_CONDVARS_TIMEOUT == TRUE) || defined(__DOXYGEN__)
2180 /**
2181 * @brief Waits on the CondVar while releasing the controlling mutex.
2182 *
2183 * @param[in] var the condition variable index
2184 * @param[in] timeout the number of ticks before the operation fails
2185 * @return The wakep mode.
2186 * @retval MSG_OK if the condition variable was signaled using
2187 * @p signal().
2188 * @retval MSG_RESET if the condition variable was signaled using
2189 * @p broadcast().
2190 * @retval MSG_TIMEOUT if the condition variable was not signaled
2191 * within the specified timeout.
2192 *
2193 * @api
2194 */
2195 msg_t wait(unsigned var, sysinterval_t timeout) {
2196
2197 chDbgCheck(var < N);
2198
2199 return chCondWaitTimeout(&condvars[var], timeout);
2200 }
2201
2202 /**
2203 * @brief Waits on the CondVar while releasing the controlling mutex.
2204 *
2205 * @param[in] var the condition variable index
2206 * @param[in] timeout the number of ticks before the operation fails
2207 * @return The wakep mode.
2208 * @retval MSG_OK if the condition variable was signaled using
2209 * @p signal().
2210 * @retval MSG_RESET if the condition variable was signaled using
2211 * @p broadcast().
2212 * @retval MSG_TIMEOUT if the condition variable was not signaled
2213 * within the specified timeout.
2214 *
2215 * @sclass
2216 */
2217 msg_t waitS(unsigned var, sysinterval_t timeout) {
2218
2219 chDbgCheck(var < N);
2220
2221 return chCondWaitTimeoutS(&condvars[var], timeout);
2222 }
2223#endif /* CH_CFG_USE_CONDVARS_TIMEOUT == TRUE */
2224
2225 public:
2226 /**
2227 * @brief Monitor object constructor.
2228 *
2229 * @init
2230 */
2231 Monitor(void) : Mutex() {
2232
2233 for (unsigned i = 0; i < N; i++) {
2234 chCondObjectInit(&condvars[i]);
2235 }
2236 }
2237
2238 /**
2239 * @brief Signals one thread that is waiting on the condition variable.
2240 *
2241 * @param[in] var the condition variable index
2242 *
2243 * @api
2244 */
2245 void signal(unsigned var) {
2246
2247 chDbgCheck(var < N);
2248
2249 chCondSignal(&condvars[var]);
2250 }
2251
2252 /**
2253 * @brief Signals one thread that is waiting on the condition variable.
2254 * @post This function does not reschedule so a call to a rescheduling
2255 * function must be performed before unlocking the kernel. Note
2256 * that interrupt handlers always reschedule on exit so an
2257 * explicit reschedule must not be performed in ISRs.
2258 *
2259 * @param[in] var the condition variable index
2260 *
2261 * @iclass
2262 */
2263 void signalI(unsigned var) {
2264
2265 chDbgCheck(var < N);
2266
2267 chCondSignalI(&condvars[var]);
2268 }
2269
2270 /**
2271 * @brief Signals all threads that are waiting on the condition variable.
2272 *
2273 * @param[in] var the condition variable index
2274 *
2275 * @api
2276 */
2277 void broadcast(unsigned var) {
2278
2279 chDbgCheck(var < N);
2280
2281 chCondBroadcast(&condvars[var]);
2282 }
2283
2284 /**
2285 * @brief Signals all threads that are waiting on the condition variable.
2286 * @post This function does not reschedule so a call to a rescheduling
2287 * function must be performed before unlocking the kernel. Note
2288 * that interrupt handlers always reschedule on exit so an
2289 * explicit reschedule must not be performed in ISRs.
2290 *
2291 * @param[in] var the condition variable index
2292 *
2293 * @iclass
2294 */
2295 void broadcastI(unsigned var) {
2296
2297 chDbgCheck(var < N);
2298
2299 chCondBroadcastI(&condvars[var]);
2300 }
2301 };
2302
2303#endif /* CH_CFG_USE_CONDVARS == TRUE */
2304#endif /* CH_CFG_USE_MUTEXES == TRUE */
2305
2306#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
2307 /*------------------------------------------------------------------------*
2308 * chibios_rt::EvtListener *
2309 *------------------------------------------------------------------------*/
2310 /**
2311 * @brief Class encapsulating an event listener.
2312 */
2313 class EventListener {
2314 public:
2315 /**
2316 * @brief Embedded @p event_listener_t structure.
2317 */
2318 event_listener_t ev_listener;
2319
2320 /**
2321 * @brief Returns the pending flags from the listener and clears them.
2322 *
2323 * @return The flags added to the listener by the
2324 * associated event source.
2325 *
2326 * @api
2327 */
2328 eventflags_t getAndClearFlags(void) {
2329
2330 return chEvtGetAndClearFlags(&ev_listener);
2331 }
2332
2333 /**
2334 * @brief Returns the flags associated to an @p event_listener_t.
2335 * @details The flags are returned and the @p event_listener_t flags mask is
2336 * cleared.
2337 *
2338 * @return The flags added to the listener by the associated
2339 * event source.
2340 *
2341 * @iclass
2342 */
2343 eventflags_t getAndClearFlagsI(void) {
2344
2345 return chEvtGetAndClearFlagsI(&ev_listener);
2346 }
2347 };
2348
2349 /*------------------------------------------------------------------------*
2350 * chibios_rt::EvtSource *
2351 *------------------------------------------------------------------------*/
2352 /**
2353 * @brief Class encapsulating an event source.
2354 */
2355 class EventSource {
2356 /**
2357 * @brief Embedded @p event_source_t structure.
2358 */
2359 event_source_t ev_source;
2360
2361 public:
2362 /**
2363 * @brief EvtSource object constructor.
2364 * @details The embedded @p event_source_t structure is initialized.
2365 *
2366 * @init
2367 */
2368 EventSource(void) {
2369
2370 chEvtObjectInit(&ev_source);
2371 }
2372
2373 /**
2374 * @brief Registers a listener on the event source.
2375 *
2376 * @param[in] elp pointer to the @p EvtListener object
2377 * @param[in] eid numeric identifier assigned to the Event
2378 * Listener
2379 *
2380 * @api
2381 */
2382 void registerOne(EventListener *elp,
2383 eventid_t eid) {
2384
2385 chEvtRegister(&ev_source, &elp->ev_listener, eid);
2386 }
2387
2388 /**
2389 * @brief Registers an Event Listener on an Event Source.
2390 * @note Multiple Event Listeners can specify the same bits to be added.
2391 *
2392 * @param[in] elp pointer to the @p EvtListener object
2393 * @param[in] emask the mask of event flags to be pended to the
2394 * thread when the event source is broadcasted
2395 *
2396 * @api
2397 */
2398 void registerMask(EventListener *elp,
2399 eventmask_t emask) {
2400
2401 chEvtRegisterMask(&ev_source, &elp->ev_listener, emask);
2402 }
2403
2404 /**
2405 * @brief Unregisters a listener.
2406 * @details The specified listeners is no more signaled by the event
2407 * source.
2408 *
2409 * @param[in] elp the listener to be unregistered
2410 *
2411 * @api
2412 */
2413 void unregister(EventListener *elp) {
2414
2415 chEvtUnregister(&ev_source, &elp->ev_listener);
2416 }
2417
2418 /**
2419 * @brief Broadcasts on an event source.
2420 * @details All the listeners registered on the event source are signaled
2421 * and the flags are added to the listener's flags mask.
2422 *
2423 * @param[in] flags the flags set to be added to the listener
2424 * flags mask
2425 *
2426 * @api
2427 */
2428 void broadcastFlags(eventflags_t flags) {
2429
2430 chEvtBroadcastFlags(&ev_source, flags);
2431 }
2432
2433 /**
2434 * @brief Broadcasts on an event source.
2435 * @details All the listeners registered on the event source are signaled
2436 * and the flags are added to the listener's flags mask.
2437 *
2438 * @param[in] flags the flags set to be added to the listener
2439 * flags mask
2440 *
2441 * @iclass
2442 */
2443 void broadcastFlagsI(eventflags_t flags) {
2444
2445 chEvtBroadcastFlagsI(&ev_source, flags);
2446 }
2447 };
2448#endif /* CH_CFG_USE_EVENTS == TRUE */
2449
2450#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__)
2451 /*------------------------------------------------------------------------*
2452 * chibios_rt::Mailbox *
2453 *------------------------------------------------------------------------*/
2454 /**
2455 * @brief Base mailbox class.
2456 *
2457 * @param T type of objects that mailbox able to handle
2458 */
2459 template <typename T>
2460 class MailboxBase {
2461
2462 /**
2463 * @brief Embedded @p mailbox_t structure.
2464 */
2465 mailbox_t mb;
2466
2467 public:
2468 /**
2469 * @brief Mailbox constructor.
2470 * @details The embedded @p mailbox_t structure is initialized.
2471 *
2472 * @param[in] buf pointer to the messages buffer as an array of
2473 * @p msg_t
2474 * @param[in] n number of elements in the buffer array
2475 *
2476 * @init
2477 */
2478 MailboxBase(msg_t *buf, cnt_t n) {
2479
2480 chMBObjectInit(&mb, buf, n);
2481 }
2482
2483 /**
2484 * @brief Resets a Mailbox object.
2485 * @details All the waiting threads are resumed with status @p MSG_RESET
2486 * and the queued messages are lost.
2487 *
2488 * @api
2489 */
2490 void reset(void) {
2491
2492 chMBReset(&mb);
2493 }
2494
2495 /**
2496 * @brief Terminates the reset state.
2497 *
2498 * @xclass
2499 */
2500 void resumeX(void) {
2501
2502 chMBResumeX(&mb);
2503 }
2504
2505 /**
2506 * @brief Posts a message into a mailbox.
2507 * @details The invoking thread waits until a empty slot in the mailbox
2508 * becomes available or the specified time runs out.
2509 *
2510 * @param[in] msg the message to be posted on the mailbox
2511 * @param[in] timeout the number of ticks before the operation timeouts,
2512 * the following special values are allowed:
2513 * - @a TIME_IMMEDIATE immediate timeout.
2514 * - @a TIME_INFINITE no timeout.
2515 * .
2516 * @return The operation status.
2517 * @retval MSG_OK if a message has been correctly posted.
2518 * @retval MSG_RESET if the mailbox has been reset while waiting.
2519 * @retval MSG_TIMEOUT if the operation has timed out.
2520 *
2521 * @api
2522 */
2523 msg_t post(T msg, sysinterval_t timeout) {
2524
2525 return chMBPostTimeout(&mb, reinterpret_cast<msg_t>(msg), timeout);
2526 }
2527
2528 /**
2529 * @brief Posts a message into a mailbox.
2530 * @details The invoking thread waits until a empty slot in the mailbox
2531 * becomes available or the specified time runs out.
2532 *
2533 * @param[in] msg the message to be posted on the mailbox
2534 * @param[in] timeout the number of ticks before the operation timeouts,
2535 * the following special values are allowed:
2536 * - @a TIME_IMMEDIATE immediate timeout.
2537 * - @a TIME_INFINITE no timeout.
2538 * .
2539 * @return The operation status.
2540 * @retval MSG_OK if a message has been correctly posted.
2541 * @retval MSG_RESET if the mailbox has been reset while waiting.
2542 * @retval MSG_TIMEOUT if the operation has timed out.
2543 *
2544 * @sclass
2545 */
2546 msg_t postS(T msg, sysinterval_t timeout) {
2547
2548 return chMBPostTimeoutS(&mb, reinterpret_cast<msg_t>(msg), timeout);
2549 }
2550
2551 /**
2552 * @brief Posts a message into a mailbox.
2553 * @details This variant is non-blocking, the function returns a timeout
2554 * condition if the queue is full.
2555 *
2556 * @param[in] msg the message to be posted on the mailbox
2557 * @return The operation status.
2558 * @retval MSG_OK if a message has been correctly posted.
2559 * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
2560 * posted.
2561 *
2562 * @iclass
2563 */
2564 msg_t postI(T msg) {
2565
2566 return chMBPostI(&mb, reinterpret_cast<msg_t>(msg));
2567 }
2568
2569 /**
2570 * @brief Posts an high priority message into a mailbox.
2571 * @details The invoking thread waits until a empty slot in the mailbox
2572 * becomes available or the specified time runs out.
2573 *
2574 * @param[in] msg the message to be posted on the mailbox
2575 * @param[in] timeout the number of ticks before the operation timeouts,
2576 * the following special values are allowed:
2577 * - @a TIME_IMMEDIATE immediate timeout.
2578 * - @a TIME_INFINITE no timeout.
2579 * .
2580 * @return The operation status.
2581 * @retval MSG_OK if a message has been correctly posted.
2582 * @retval MSG_RESET if the mailbox has been reset while waiting.
2583 * @retval MSG_TIMEOUT if the operation has timed out.
2584 *
2585 * @api
2586 */
2587 msg_t postAhead(T msg, sysinterval_t timeout) {
2588
2589 return chMBPostAheadTimeout(&mb, reinterpret_cast<msg_t>(msg), timeout);
2590 }
2591
2592 /**
2593 * @brief Posts an high priority message into a mailbox.
2594 * @details The invoking thread waits until a empty slot in the mailbox
2595 * becomes available or the specified time runs out.
2596 *
2597 * @param[in] msg the message to be posted on the mailbox
2598 * @param[in] timeout the number of ticks before the operation timeouts,
2599 * the following special values are allowed:
2600 * - @a TIME_IMMEDIATE immediate timeout.
2601 * - @a TIME_INFINITE no timeout.
2602 * .
2603 * @return The operation status.
2604 * @retval MSG_OK if a message has been correctly posted.
2605 * @retval MSG_RESET if the mailbox has been reset while waiting.
2606 * @retval MSG_TIMEOUT if the operation has timed out.
2607 *
2608 * @sclass
2609 */
2610 msg_t postAheadS(T msg, sysinterval_t timeout) {
2611
2612 return chMBPostAheadTimeoutS(&mb, reinterpret_cast<msg_t>(msg), timeout);
2613 }
2614
2615 /**
2616 * @brief Posts an high priority message into a mailbox.
2617 * @details This variant is non-blocking, the function returns a timeout
2618 * condition if the queue is full.
2619 *
2620 * @param[in] msg the message to be posted on the mailbox
2621 * @return The operation status.
2622 * @retval MSG_OK if a message has been correctly posted.
2623 * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
2624 * posted.
2625 *
2626 * @iclass
2627 */
2628 msg_t postAheadI(T msg) {
2629
2630 return chMBPostAheadI(&mb, reinterpret_cast<msg_t>(msg));
2631 }
2632
2633 /**
2634 * @brief Retrieves a message from a mailbox.
2635 * @details The invoking thread waits until a message is posted in the
2636 * mailbox or the specified time runs out.
2637 *
2638 * @param[out] msgp pointer to a message variable for the received
2639 * @param[in] timeout message the number of ticks before the operation
2640 * timeouts, the following special values are allowed:
2641 * - @a TIME_IMMEDIATE immediate timeout.
2642 * - @a TIME_INFINITE no timeout.
2643 * .
2644 * @return The operation status.
2645 * @retval MSG_OK if a message has been correctly fetched.
2646 * @retval MSG_RESET if the mailbox has been reset while waiting.
2647 * @retval MSG_TIMEOUT if the operation has timed out.
2648 *
2649 * @api
2650 */
2651 msg_t fetch(T *msgp, sysinterval_t timeout) {
2652
2653 return chMBFetchTimeout(&mb, reinterpret_cast<msg_t*>(msgp), timeout);
2654 }
2655
2656 /**
2657 * @brief Retrieves a message from a mailbox.
2658 * @details The invoking thread waits until a message is posted in the
2659 * mailbox or the specified time runs out.
2660 *
2661 * @param[out] msgp pointer to a message variable for the received
2662 * @param[in] timeout message the number of ticks before the operation
2663 * timeouts, the following special values are allowed:
2664 * - @a TIME_IMMEDIATE immediate timeout.
2665 * - @a TIME_INFINITE no timeout.
2666 * .
2667 * @return The operation status.
2668 * @retval MSG_OK if a message has been correctly fetched.
2669 * @retval MSG_RESET if the mailbox has been reset while waiting.
2670 * @retval MSG_TIMEOUT if the operation has timed out.
2671 *
2672 * @sclass
2673 */
2674 msg_t fetchS(T *msgp, sysinterval_t timeout) {
2675
2676 return chMBFetchTimeoutS(&mb, reinterpret_cast<msg_t*>(msgp), timeout);
2677 }
2678
2679 /**
2680 * @brief Retrieves a message from a mailbox.
2681 * @details This variant is non-blocking, the function returns a timeout
2682 * condition if the queue is empty.
2683 *
2684 * @param[out] msgp pointer to a message variable for the received
2685 * message
2686 * @return The operation status.
2687 * @retval MSG_OK if a message has been correctly fetched.
2688 * @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be
2689 * fetched.
2690 *
2691 * @iclass
2692 */
2693 msg_t fetchI(T *msgp) {
2694
2695 return chMBFetchI(&mb, reinterpret_cast<msg_t*>(msgp));
2696 }
2697
2698 /**
2699 * @brief Returns the next message in the queue without removing it.
2700 * @pre A message must be waiting in the queue for this function to work
2701 * or it would return garbage. The correct way to use this macro is
2702 * to use @p getUsedCountI() and then use this macro, all within
2703 * a lock state.
2704 *
2705 * @return The next message in queue.
2706 *
2707 * @iclass
2708 */
2709 T peekI(const mailbox_t *mbp) const {
2710
2711 return chMBPeekI(&mb);
2712 }
2713
2714 /**
2715 * @brief Returns the number of free message slots into a mailbox.
2716 * @note Can be invoked in any system state but if invoked out of a
2717 * locked state then the returned value may change after reading.
2718 * @note The returned value can be less than zero when there are waiting
2719 * threads on the internal semaphore.
2720 *
2721 * @return The number of empty message slots.
2722 *
2723 * @iclass
2724 */
2725 cnt_t getFreeCountI(void) const {
2726
2727 return chMBGetFreeCountI(&mb);
2728 }
2729
2730 /**
2731 * @brief Returns the number of used message slots into a mailbox.
2732 * @note Can be invoked in any system state but if invoked out of a
2733 * locked state then the returned value may change after reading.
2734 * @note The returned value can be less than zero when there are waiting
2735 * threads on the internal semaphore.
2736 *
2737 * @return The number of queued messages.
2738 *
2739 * @iclass
2740 */
2741 cnt_t getUsedCountI(void) const {
2742
2743 return chMBGetUsedCountI(&mb);
2744 }
2745 };
2746
2747 /*------------------------------------------------------------------------*
2748 * chibios_rt::Mailbox *
2749 *------------------------------------------------------------------------*/
2750 /**
2751 * @brief Template class encapsulating a mailbox and its messages buffer.
2752 *
2753 * @param N length of the mailbox buffer
2754 */
2755 template <typename T, int N>
2756 class Mailbox : public MailboxBase<T> {
2757
2758 static_assert(sizeof(T) <= sizeof(msg_t),
2759 "Mailbox type does not fit in msg_t");
2760
2761 private:
2762 msg_t mb_buf[N];
2763
2764 public:
2765 /**
2766 * @brief Mailbox constructor.
2767 *
2768 * @init
2769 */
2770 Mailbox(void) :
2771 MailboxBase<T>(mb_buf, (cnt_t)(sizeof mb_buf / sizeof (msg_t))) {
2772 }
2773 };
2774#endif /* CH_CFG_USE_MAILBOXES == TRUE */
2775
2776#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
2777 /*------------------------------------------------------------------------*
2778 * chibios_rt::MemoryPool *
2779 *------------------------------------------------------------------------*/
2780 /**
2781 * @brief Class encapsulating a memory pool.
2782 */
2783 class MemoryPool {
2784 /**
2785 * @brief Embedded @p memory_pool_t structure.
2786 */
2787 memory_pool_t pool;
2788
2789 public:
2790 /**
2791 * @brief MemoryPool constructor.
2792 *
2793 * @param[in] size the size of the objects contained in this memory
2794 * pool, the minimum accepted size is the size of
2795 * a pointer to void.
2796 * @param[in] provider memory provider function for the memory pool or
2797 * @p nullptr if the pool is not allowed to grow
2798 * automatically
2799 *
2800 * @init
2801 */
2802 MemoryPool(size_t size, memgetfunc_t provider=0) : pool() {
2803
2804 chPoolObjectInit(&pool, size, provider);
2805 }
2806
2807 /**
2808 * @brief MemoryPool constructor.
2809 *
2810 * @param[in] size the size of the objects contained in this memory
2811 * pool, the minimum accepted size is the size of
2812 * a pointer to void.
2813 * @param[in] provider memory provider function for the memory pool or
2814 * @p nullptr if the pool is not allowed to grow
2815 * automatically
2816 * @param[in] p pointer to the array first element
2817 * @param[in] n number of elements in the array
2818 *
2819 * @init
2820 */
2821 MemoryPool(size_t size, void* p, size_t n,
2822 memgetfunc_t provider=0) : pool() {
2823
2824 chPoolObjectInit(&pool, size, provider);
2825 chPoolLoadArray(&pool, p, n);
2826 }
2827
2828 /* Prohibit copy construction and assignment, but allow move.*/
2829 MemoryPool(const MemoryPool &) = delete;
2830 MemoryPool &operator=(const MemoryPool &) = delete;
2831 MemoryPool(MemoryPool &&) = default;
2832 MemoryPool &operator=(MemoryPool &&) = default;
2833
2834 /**
2835 * @brief Loads a memory pool with an array of static objects.
2836 * @pre The memory pool must be already been initialized.
2837 * @pre The array elements must be of the right size for the specified
2838 * memory pool.
2839 * @post The memory pool contains the elements of the input array.
2840 *
2841 * @param[in] p pointer to the array first element
2842 * @param[in] n number of elements in the array
2843 *
2844 * @api
2845 */
2846 void loadArray(void *p, size_t n) {
2847
2848 chPoolLoadArray(&pool, p, n);
2849 }
2850
2851 /**
2852 * @brief Allocates an object from a memory pool.
2853 * @pre The memory pool must be already been initialized.
2854 *
2855 * @return The pointer to the allocated object.
2856 * @retval nullptr if pool is empty.
2857 *
2858 * @iclass
2859 */
2860 void *allocI(void) {
2861
2862 return chPoolAllocI(&pool);
2863 }
2864
2865 /**
2866 * @brief Allocates an object from a memory pool.
2867 * @pre The memory pool must be already been initialized.
2868 *
2869 * @return The pointer to the allocated object.
2870 * @retval nullptr if pool is empty.
2871 *
2872 * @api
2873 */
2874 void *alloc(void) {
2875
2876 return chPoolAlloc(&pool);
2877 }
2878
2879 /**
2880 * @brief Releases an object into a memory pool.
2881 * @pre The memory pool must be already been initialized.
2882 * @pre The freed object must be of the right size for the specified
2883 * memory pool.
2884 * @pre The object must be properly aligned to contain a pointer to
2885 * void.
2886 *
2887 * @param[in] objp the pointer to the object to be released
2888 *
2889 * @iclass
2890 */
2891 void free(void *objp) {
2892
2893 chPoolFree(&pool, objp);
2894 }
2895
2896 /**
2897 * @brief Adds an object to a memory pool.
2898 * @pre The memory pool must be already been initialized.
2899 * @pre The added object must be of the right size for the specified
2900 * memory pool.
2901 * @pre The added object must be memory aligned to the size of
2902 * @p stkalign_t type.
2903 * @note This function is just an alias for @p chPoolFree() and has been
2904 * added for clarity.
2905 *
2906 * @param[in] objp the pointer to the object to be added
2907 *
2908 * @iclass
2909 */
2910 void freeI(void *objp) {
2911
2912 chPoolFreeI(&pool, objp);
2913 }
2914 };
2915
2916 /*------------------------------------------------------------------------*
2917 * chibios_rt::ObjectsPool *
2918 *------------------------------------------------------------------------*/
2919 /**
2920 * @brief Template class encapsulating a memory pool and its elements.
2921 */
2922 template<class T, size_t N>
2923 class ObjectsPool : public MemoryPool {
2924 /* The buffer is declared as an array of pointers to void for two
2925 reasons:
2926 1) The objects must be properly aligned to hold a pointer as
2927 first field.
2928 2) Objects are dirtied when loaded in the pool.*/
2929 void *pool_buf[(N * sizeof (T)) / sizeof (void *)];
2930
2931 public:
2932 /**
2933 * @brief ObjectsPool constructor.
2934 *
2935 * @init
2936 */
2937 ObjectsPool(void) : MemoryPool(sizeof (T), nullptr) {
2938
2939 loadArray(pool_buf, N);
2940 }
2941 };
2942
2943 /*------------------------------------------------------------------------*
2944 * chibios_rt::ThreadsPool *
2945 *------------------------------------------------------------------------*/
2946 /**
2947 * @brief Template class encapsulating a pool of threads.
2948 */
2949 template<size_t S, size_t N, const char *C>
2950 class ThreadsPool : public BaseDynamicThread {
2951 THD_WORKING_AREA(working_areas, S)[N];
2952 MemoryPool threads_pool;
2953
2954 public:
2955 /**
2956 * @brief ThreadsPool constructor.
2957 *
2958 * @init
2959 */
2960 ThreadsPool(void) : threads_pool(THD_WORKING_AREA_SIZE(S)) {
2961
2962 threads_pool.loadArray(working_areas, N);
2963 }
2964
2965 /**
2966 * @brief Starts a dynamic thread from the pool.
2967 *
2968 * @param[in] prio thread priority
2969 * @return A reference to the created thread with
2970 * reference counter set to one.
2971 *
2972 * @api
2973 */
2974 ThreadReference start(tprio_t prio) override {
2975 void _thd_start(void *arg);
2976
2977 return ThreadReference(chThdCreateFromMemoryPool(&threads_pool.pool,
2978 C,
2979 prio,
2980 _thd_start,
2981 this));
2982 }
2983 };
2984#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
2985
2986#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
2987 /*------------------------------------------------------------------------*
2988 * chibios_rt::Heap *
2989 *------------------------------------------------------------------------*/
2990 /**
2991 * @brief Class encapsulating a heap.
2992 */
2993 class Heap {
2994 /**
2995 * @brief Embedded @p memory_heap_t structure.
2996 */
2997 memory_heap_t heap;
2998
2999 public:
3000 /**
3001 * @brief Heap constructor.
3002 * @pre Both the heap buffer base and the heap size must be aligned to
3003 * the @p stkalign_t type size.
3004 *
3005 * @param[in] buffer heap buffer base
3006 * @param[in] size the size of the memory area located at \e buffer
3007 * @init
3008 */
3009 Heap(void *buffer, const size_t size) : heap() {
3010
3011 chHeapObjectInit(&heap, buffer, size);
3012 }
3013
3014 /* Prohibit copy construction and assignment, but allow move.*/
3015 Heap(const Heap &) = delete;
3016 Heap &operator=(const Heap &) = delete;
3017 Heap(Heap &&) = default;
3018 Heap &operator=(Heap &&) = default;
3019
3020 /**
3021 * @brief Allocates an object from a heap.
3022 * @pre The heap must be already been initialized.
3023 *
3024 * @return The pointer to the allocated object.
3025 * @retval nullptr if pool is empty.
3026 *
3027 * @api
3028 */
3029 void *alloc(const size_t size) {
3030
3031 return chHeapAlloc(&heap, size);
3032 }
3033
3034 /**
3035 * @brief Releases an object into the heap.
3036 *
3037 * @param[in] objp the pointer to the object to be released
3038 *
3039 * @api
3040 */
3041 void free(void *objp) {
3042
3043 chHeapFree(objp);
3044 }
3045
3046 /**
3047 * @brief Reports the heap status.
3048 *
3049 * @param[out] frag the size of total fragmented free space
3050 * @param[in] largestp pointer to a variable that will receive the largest
3051 * free free block found space or @p nullptr
3052 * @return the number of fragments in the heap
3053 *
3054 * @api
3055 */
3056 size_t status(size_t &frag, size_t *largestp=0) {
3057
3058 return chHeapStatus(&heap, &frag, largestp);
3059 }
3060 };
3061#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
3062
3063 /*------------------------------------------------------------------------*
3064 * chibios_rt::BaseSequentialStreamInterface *
3065 *------------------------------------------------------------------------*/
3066 /**
3067 * @brief Interface of a BaseSequentialStream.
3068 * @note You can cast a BaseSequentialStream to this interface and use
3069 * it, the memory layout is the same.
3070 */
3071 class BaseSequentialStreamInterface {
3072 public:
3073 /**
3074 * @brief Sequential Stream write.
3075 * @details The function writes data from a buffer to a stream.
3076 *
3077 * @param[in] bp pointer to the data buffer
3078 * @param[in] n the maximum amount of data to be transferred
3079 * @return The number of bytes transferred. The return value
3080 * can be less than the specified number of bytes if
3081 * an end-of-file condition has been met.
3082 *
3083 * @api
3084 */
3085 virtual size_t write(const uint8_t *bp, const size_t n) = 0;
3086
3087 /**
3088 * @brief Sequential Stream read.
3089 * @details The function reads data from a stream into a buffer.
3090 *
3091 * @param[out] bp pointer to the data buffer
3092 * @param[in] n the maximum amount of data to be transferred
3093 * @return The number of bytes transferred. The return value
3094 * can be less than the specified number of bytes if
3095 * an end-of-file condition has been met.
3096 *
3097 * @api
3098 */
3099 virtual size_t read(uint8_t *bp, const size_t n) = 0;
3100
3101 /**
3102 * @brief Sequential Stream blocking byte write.
3103 * @details This function writes a byte value to a channel. If the channel
3104 * is not ready to accept data then the calling thread is
3105 * suspended.
3106 *
3107 * @param[in] b the byte value to be written to the channel
3108 *
3109 * @return The operation status.
3110 * @retval Q_OK if the operation succeeded.
3111 * @retval Q_RESET if an end-of-file condition has been met.
3112 *
3113 * @api
3114 */
3115 virtual msg_t put(const uint8_t b) = 0;
3116
3117 /**
3118 * @brief Sequential Stream blocking byte read.
3119 * @details This function reads a byte value from a channel. If the data
3120 * is not available then the calling thread is suspended.
3121 *
3122 * @return A byte value from the queue.
3123 * @retval Q_RESET if an end-of-file condition has been met.
3124 *
3125 * @api
3126 */
3127 virtual msg_t get(void) = 0;
3128 };
3129}
3130
3131#endif /* _CH_HPP_ */
3132
3133/** @} */
diff --git a/lib/chibios/os/various/cpp_wrappers/chcpp.mk b/lib/chibios/os/various/cpp_wrappers/chcpp.mk
new file mode 100644
index 000000000..b32334e29
--- /dev/null
+++ b/lib/chibios/os/various/cpp_wrappers/chcpp.mk
@@ -0,0 +1,9 @@
1# C++ wrapper files.
2CHCPPSRC = $(CHIBIOS)/os/various/cpp_wrappers/ch.cpp \
3 $(CHIBIOS)/os/various/cpp_wrappers/syscalls_cpp.cpp
4
5CHCPPINC = $(CHIBIOS)/os/various/cpp_wrappers
6
7# Shared variables
8ALLCPPSRC += $(CHCPPSRC)
9ALLINC += $(CHCPPINC)
diff --git a/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.cpp b/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.cpp
new file mode 100644
index 000000000..486461a76
--- /dev/null
+++ b/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.cpp
@@ -0,0 +1,41 @@
1#include <stdio.h>
2#include <errno.h>
3
4#include "osal.h"
5
6#include "syscalls_cpp.hpp"
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12void _exit(int status){
13 (void) status;
14 osalSysHalt("Unrealized");
15 while(TRUE){}
16}
17
18pid_t _getpid(void){
19 return 1;
20}
21
22#undef errno
23extern int errno;
24int _kill(int pid, int sig) {
25 (void)pid;
26 (void)sig;
27 errno = EINVAL;
28 return -1;
29}
30
31void _open_r(void){
32 return;
33}
34
35void __cxa_pure_virtual() {
36 osalSysHalt("Pure virtual function call.");
37}
38
39#ifdef __cplusplus
40}
41#endif
diff --git a/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.hpp b/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.hpp
new file mode 100644
index 000000000..cd78a9c5d
--- /dev/null
+++ b/lib/chibios/os/various/cpp_wrappers/syscalls_cpp.hpp
@@ -0,0 +1,13 @@
1#ifndef SYSCALLS_CPP_HPP_
2#define SYSCALLS_CPP_HPP_
3
4/* The ABI requires a 32-bit type.*/
5typedef int __guard;
6
7int __cxa_guard_acquire(__guard *);
8void __cxa_guard_release (__guard *);
9void __cxa_guard_abort (__guard *);
10
11void *__dso_handle = NULL;
12
13#endif /* SYSCALLS_CPP_HPP_ */
diff --git a/lib/chibios/os/various/evtimer.c b/lib/chibios/os/various/evtimer.c
new file mode 100644
index 000000000..310a339c6
--- /dev/null
+++ b/lib/chibios/os/various/evtimer.c
@@ -0,0 +1,85 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file evtimer.c
19 * @brief Events Generator Timer code.
20 *
21 * @addtogroup event_timer
22 * @{
23 */
24
25#include "ch.h"
26#include "evtimer.h"
27
28/*===========================================================================*/
29/* Module local definitions. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Module exported variables. */
34/*===========================================================================*/
35
36/*===========================================================================*/
37/* Module local types. */
38/*===========================================================================*/
39
40/*===========================================================================*/
41/* Module local variables. */
42/*===========================================================================*/
43
44/*===========================================================================*/
45/* Module local functions. */
46/*===========================================================================*/
47
48static void tmrcb(void *p) {
49 event_timer_t *etp = p;
50
51 chSysLockFromISR();
52 chEvtBroadcastI(&etp->et_es);
53 chVTDoSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
54 chSysUnlockFromISR();
55}
56
57/*===========================================================================*/
58/* Module exported functions. */
59/*===========================================================================*/
60
61/**
62 * @brief Initializes an @p event_timer_t structure.
63 *
64 * @param[out] etp the @p event_timer_t structure to be initialized
65 * @param[in] time the interval in system ticks
66 */
67void evtObjectInit(event_timer_t *etp, systime_t time) {
68
69 chEvtObjectInit(&etp->et_es);
70 chVTObjectInit(&etp->et_vt);
71 etp->et_interval = time;
72}
73
74/**
75 * @brief Starts the timer
76 * @details If the timer was already running then the function has no effect.
77 *
78 * @param[in] etp pointer to an initialized @p event_timer_t structure.
79 */
80void evtStart(event_timer_t *etp) {
81
82 chVTSet(&etp->et_vt, etp->et_interval, tmrcb, etp);
83}
84
85/** @} */
diff --git a/lib/chibios/os/various/evtimer.h b/lib/chibios/os/various/evtimer.h
new file mode 100644
index 000000000..60e9939cf
--- /dev/null
+++ b/lib/chibios/os/various/evtimer.h
@@ -0,0 +1,94 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file evtimer.h
19 * @brief Events Generator Timer structures and macros.
20 *
21 * @addtogroup event_timer
22 * @{
23 */
24
25#ifndef EVTIMER_H
26#define EVTIMER_H
27
28/*===========================================================================*/
29/* Module constants. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Module pre-compile time settings. */
34/*===========================================================================*/
35
36/*===========================================================================*/
37/* Derived constants and error checks. */
38/*===========================================================================*/
39
40/*
41 * Module dependencies check.
42 */
43#if !CH_CFG_USE_EVENTS
44#error "Event Timers require CH_CFG_USE_EVENTS"
45#endif
46
47/*===========================================================================*/
48/* Module data structures and types. */
49/*===========================================================================*/
50
51/**
52 * @brief Type of a event timer structure.
53 */
54typedef struct {
55 virtual_timer_t et_vt;
56 event_source_t et_es;
57 systime_t et_interval;
58} event_timer_t;
59
60/*===========================================================================*/
61/* Module macros. */
62/*===========================================================================*/
63
64/*===========================================================================*/
65/* External declarations. */
66/*===========================================================================*/
67
68#ifdef __cplusplus
69extern "C" {
70#endif
71 void evtObjectInit(event_timer_t *etp, systime_t time);
72 void evtStart(event_timer_t *etp);
73#ifdef __cplusplus
74}
75#endif
76
77/*===========================================================================*/
78/* Module inline functions. */
79/*===========================================================================*/
80
81/**
82 * @brief Stops the timer.
83 * @details If the timer was already stopped then the function has no effect.
84 *
85 * @param[in] etp pointer to an initialized @p event_timer_t structure.
86 */
87static inline void evtStop(event_timer_t *etp) {
88
89 chVTReset(&etp->et_vt);
90}
91
92#endif /* EVTIMER_H */
93
94/** @} */
diff --git a/lib/chibios/os/various/fatfs_bindings/fatfs.mk b/lib/chibios/os/various/fatfs_bindings/fatfs.mk
new file mode 100644
index 000000000..02f1c8e38
--- /dev/null
+++ b/lib/chibios/os/various/fatfs_bindings/fatfs.mk
@@ -0,0 +1,11 @@
1# FATFS files.
2FATFSSRC = $(CHIBIOS)/os/various/fatfs_bindings/fatfs_diskio.c \
3 $(CHIBIOS)/os/various/fatfs_bindings/fatfs_syscall.c \
4 $(CHIBIOS)/ext/fatfs/source/ff.c \
5 $(CHIBIOS)/ext/fatfs/source/ffunicode.c
6
7FATFSINC = $(CHIBIOS)/ext/fatfs/source
8
9# Shared variables
10ALLCSRC += $(FATFSSRC)
11ALLINC += $(FATFSINC)
diff --git a/lib/chibios/os/various/fatfs_bindings/fatfs_diskio.c b/lib/chibios/os/various/fatfs_bindings/fatfs_diskio.c
new file mode 100644
index 000000000..941943a90
--- /dev/null
+++ b/lib/chibios/os/various/fatfs_bindings/fatfs_diskio.c
@@ -0,0 +1,267 @@
1/*-----------------------------------------------------------------------*/
2/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
3/*-----------------------------------------------------------------------*/
4/* This is a stub disk I/O module that acts as front end of the existing */
5/* disk I/O modules and attach it to FatFs module with common interface. */
6/*-----------------------------------------------------------------------*/
7
8#include "hal.h"
9#include "ffconf.h"
10#include "ff.h"
11#include "diskio.h"
12
13#if HAL_USE_MMC_SPI && HAL_USE_SDC
14#error "cannot specify both MMC_SPI and SDC drivers"
15#endif
16
17#if !defined(FATFS_HAL_DEVICE)
18#if HAL_USE_MMC_SPI
19#define FATFS_HAL_DEVICE MMCD1
20#else
21#define FATFS_HAL_DEVICE SDCD1
22#endif
23#endif
24
25#if HAL_USE_MMC_SPI
26extern MMCDriver FATFS_HAL_DEVICE;
27#elif HAL_USE_SDC
28extern SDCDriver FATFS_HAL_DEVICE;
29#else
30#error "MMC_SPI or SDC driver must be specified"
31#endif
32
33#if HAL_USE_RTC
34extern RTCDriver RTCD1;
35#endif
36
37/*-----------------------------------------------------------------------*/
38/* Correspondence between physical drive number and physical drive. */
39
40#define MMC 0
41#define SDC 0
42
43
44
45/*-----------------------------------------------------------------------*/
46/* Inidialize a Drive */
47
48DSTATUS disk_initialize (
49 BYTE pdrv /* Physical drive number (0..) */
50)
51{
52 DSTATUS stat;
53
54 switch (pdrv) {
55#if HAL_USE_MMC_SPI
56 case MMC:
57 stat = 0;
58 /* It is initialized externally, just reads the status.*/
59 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
60 stat |= STA_NOINIT;
61 if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
62 stat |= STA_PROTECT;
63 return stat;
64#else
65 case SDC:
66 stat = 0;
67 /* It is initialized externally, just reads the status.*/
68 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
69 stat |= STA_NOINIT;
70 if (sdcIsWriteProtected(&FATFS_HAL_DEVICE))
71 stat |= STA_PROTECT;
72 return stat;
73#endif
74 }
75 return STA_NOINIT;
76}
77
78
79
80/*-----------------------------------------------------------------------*/
81/* Return Disk Status */
82
83DSTATUS disk_status (
84 BYTE pdrv /* Physical drive number (0..) */
85)
86{
87 DSTATUS stat;
88
89 switch (pdrv) {
90#if HAL_USE_MMC_SPI
91 case MMC:
92 stat = 0;
93 /* It is initialized externally, just reads the status.*/
94 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
95 stat |= STA_NOINIT;
96 if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
97 stat |= STA_PROTECT;
98 return stat;
99#else
100 case SDC:
101 stat = 0;
102 /* It is initialized externally, just reads the status.*/
103 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
104 stat |= STA_NOINIT;
105 if (sdcIsWriteProtected(&FATFS_HAL_DEVICE))
106 stat |= STA_PROTECT;
107 return stat;
108#endif
109 }
110 return STA_NOINIT;
111}
112
113
114
115/*-----------------------------------------------------------------------*/
116/* Read Sector(s) */
117
118DRESULT disk_read (
119 BYTE pdrv, /* Physical drive number (0..) */
120 BYTE *buff, /* Data buffer to store read data */
121 DWORD sector, /* Sector address (LBA) */
122 UINT count /* Number of sectors to read (1..255) */
123)
124{
125 switch (pdrv) {
126#if HAL_USE_MMC_SPI
127 case MMC:
128 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
129 return RES_NOTRDY;
130 if (mmcStartSequentialRead(&FATFS_HAL_DEVICE, sector))
131 return RES_ERROR;
132 while (count > 0) {
133 if (mmcSequentialRead(&FATFS_HAL_DEVICE, buff))
134 return RES_ERROR;
135 buff += MMCSD_BLOCK_SIZE;
136 count--;
137 }
138 if (mmcStopSequentialRead(&FATFS_HAL_DEVICE))
139 return RES_ERROR;
140 return RES_OK;
141#else
142 case SDC:
143 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
144 return RES_NOTRDY;
145 if (sdcRead(&FATFS_HAL_DEVICE, sector, buff, count))
146 return RES_ERROR;
147 return RES_OK;
148#endif
149 }
150 return RES_PARERR;
151}
152
153
154
155/*-----------------------------------------------------------------------*/
156/* Write Sector(s) */
157
158#if !FF_FS_READONLY
159DRESULT disk_write (
160 BYTE pdrv, /* Physical drive number (0..) */
161 const BYTE *buff, /* Data to be written */
162 DWORD sector, /* Sector address (LBA) */
163 UINT count /* Number of sectors to write (1..255) */
164)
165{
166 switch (pdrv) {
167#if HAL_USE_MMC_SPI
168 case MMC:
169 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
170 return RES_NOTRDY;
171 if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
172 return RES_WRPRT;
173 if (mmcStartSequentialWrite(&FATFS_HAL_DEVICE, sector))
174 return RES_ERROR;
175 while (count > 0) {
176 if (mmcSequentialWrite(&FATFS_HAL_DEVICE, buff))
177 return RES_ERROR;
178 buff += MMCSD_BLOCK_SIZE;
179 count--;
180 }
181 if (mmcStopSequentialWrite(&FATFS_HAL_DEVICE))
182 return RES_ERROR;
183 return RES_OK;
184#else
185 case SDC:
186 if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
187 return RES_NOTRDY;
188 if (sdcWrite(&FATFS_HAL_DEVICE, sector, buff, count))
189 return RES_ERROR;
190 return RES_OK;
191#endif
192 }
193 return RES_PARERR;
194}
195#endif /* _FS_READONLY */
196
197
198
199/*-----------------------------------------------------------------------*/
200/* Miscellaneous Functions */
201
202DRESULT disk_ioctl (
203 BYTE pdrv, /* Physical drive number (0..) */
204 BYTE cmd, /* Control code */
205 void *buff /* Buffer to send/receive control data */
206)
207{
208 (void)buff;
209
210 switch (pdrv) {
211#if HAL_USE_MMC_SPI
212 case MMC:
213 switch (cmd) {
214 case CTRL_SYNC:
215 return RES_OK;
216#if FF_MAX_SS > FF_MIN_SS
217 case GET_SECTOR_SIZE:
218 *((WORD *)buff) = MMCSD_BLOCK_SIZE;
219 return RES_OK;
220#endif
221#if FF_USE_TRIM
222 case CTRL_TRIM:
223 mmcErase(&FATFS_HAL_DEVICE, *((DWORD *)buff), *((DWORD *)buff + 1));
224 return RES_OK;
225#endif
226 default:
227 return RES_PARERR;
228 }
229#else
230 case SDC:
231 switch (cmd) {
232 case CTRL_SYNC:
233 return RES_OK;
234 case GET_SECTOR_COUNT:
235 *((DWORD *)buff) = mmcsdGetCardCapacity(&FATFS_HAL_DEVICE);
236 return RES_OK;
237#if FF_MAX_SS > FF_MIN_SS
238 case GET_SECTOR_SIZE:
239 *((WORD *)buff) = MMCSD_BLOCK_SIZE;
240 return RES_OK;
241#endif
242 case GET_BLOCK_SIZE:
243 *((DWORD *)buff) = 256; /* 512b blocks in one erase block */
244 return RES_OK;
245#if FF_USE_TRIM
246 case CTRL_TRIM:
247 sdcErase(&FATFS_HAL_DEVICE, *((DWORD *)buff), *((DWORD *)buff + 1));
248 return RES_OK;
249#endif
250 default:
251 return RES_PARERR;
252 }
253#endif
254 }
255 return RES_PARERR;
256}
257
258DWORD get_fattime(void) {
259#if HAL_USE_RTC
260 RTCDateTime timespec;
261
262 rtcGetTime(&RTCD1, &timespec);
263 return rtcConvertDateTimeToFAT(&timespec);
264#else
265 return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */
266#endif
267}
diff --git a/lib/chibios/os/various/fatfs_bindings/fatfs_syscall.c b/lib/chibios/os/various/fatfs_bindings/fatfs_syscall.c
new file mode 100644
index 000000000..51bfec127
--- /dev/null
+++ b/lib/chibios/os/various/fatfs_bindings/fatfs_syscall.c
@@ -0,0 +1,84 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*------------------------------------------------------------------------*/
18/* Sample code of OS dependent controls for FatFs */
19/* (C)ChaN, 2014 */
20/*------------------------------------------------------------------------*/
21
22#include "hal.h"
23#include "ff.h"
24
25#if FF_FS_REENTRANT
26/*------------------------------------------------------------------------*/
27/* Static array of Synchronization Objects */
28/*------------------------------------------------------------------------*/
29static semaphore_t ff_sem[FF_VOLUMES];
30
31/*------------------------------------------------------------------------*/
32/* Create a Synchronization Object */
33/*------------------------------------------------------------------------*/
34int ff_cre_syncobj(BYTE vol, FF_SYNC_t *sobj) {
35
36 *sobj = &ff_sem[vol];
37 chSemObjectInit(*sobj, 1);
38 return TRUE;
39}
40
41/*------------------------------------------------------------------------*/
42/* Delete a Synchronization Object */
43/*------------------------------------------------------------------------*/
44int ff_del_syncobj(FF_SYNC_t sobj) {
45
46 chSemReset(sobj, 0);
47 return TRUE;
48}
49
50/*------------------------------------------------------------------------*/
51/* Request Grant to Access the Volume */
52/*------------------------------------------------------------------------*/
53int ff_req_grant(FF_SYNC_t sobj) {
54
55 msg_t msg = chSemWaitTimeout(sobj, (systime_t)FF_FS_TIMEOUT);
56 return msg == MSG_OK;
57}
58
59/*------------------------------------------------------------------------*/
60/* Release Grant to Access the Volume */
61/*------------------------------------------------------------------------*/
62void ff_rel_grant(FF_SYNC_t sobj) {
63
64 chSemSignal(sobj);
65}
66#endif /* FF_FS_REENTRANT */
67
68#if FF_USE_LFN == 3 /* LFN with a working buffer on the heap */
69/*------------------------------------------------------------------------*/
70/* Allocate a memory block */
71/*------------------------------------------------------------------------*/
72void *ff_memalloc(UINT size) {
73
74 return chHeapAlloc(NULL, size);
75}
76
77/*------------------------------------------------------------------------*/
78/* Free a memory block */
79/*------------------------------------------------------------------------*/
80void ff_memfree(void *mblock) {
81
82 chHeapFree(mblock);
83}
84#endif /* FF_USE_LFN == 3 */
diff --git a/lib/chibios/os/various/fatfs_bindings/readme.txt b/lib/chibios/os/various/fatfs_bindings/readme.txt
new file mode 100644
index 000000000..7f57b8ace
--- /dev/null
+++ b/lib/chibios/os/various/fatfs_bindings/readme.txt
@@ -0,0 +1,12 @@
1This directory contains the ChibiOS/RT "official" bindings with the FatFS
2library by ChaN: http://elm-chan.org
3
4In order to use FatFS within ChibiOS/RT project:
51. unzip FatFS under ./ext/fatfs [See Note 2]
62. include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk in your makefile.
73. Add $(FATFSSRC) to $(CSRC)
84. Add $(FATFSINC) to $(INCDIR)
9
10Note:
111. These files modified for use with version 0.13 of fatfs.
122. In the original distribution, the source directory is called 'source' rather than 'src'
diff --git a/lib/chibios/os/various/lwip_bindings/arch/cc.h b/lib/chibios/os/various/lwip_bindings/arch/cc.h
new file mode 100644
index 000000000..67371e828
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/arch/cc.h
@@ -0,0 +1,89 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/*
17 * **** This file incorporates work covered by the following copyright and ****
18 * **** permission notice: ****
19 *
20 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without modification,
24 * are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 * 3. The name of the author may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
37 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
39 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
43 * OF SUCH DAMAGE.
44 *
45 * This file is part of the lwIP TCP/IP stack.
46 *
47 * Author: Adam Dunkels <[email protected]>
48 *
49 */
50
51#ifndef __CC_H__
52#define __CC_H__
53
54#include <hal.h>
55
56/* Use errno provided by system. */
57#define LWIP_ERRNO_INCLUDE <errno.h>
58
59/**
60 * @brief Use system provided struct timeval by default.
61 */
62#ifndef LWIP_TIMEVAL_PRIVATE
63#define LWIP_TIMEVAL_PRIVATE 0
64#include <sys/time.h>
65#endif
66
67/**
68 * @brief Use a no-op diagnostic output macro by default.
69 */
70#if !defined(LWIP_PLATFORM_DIAG)
71#define LWIP_PLATFORM_DIAG(x)
72#endif
73
74/**
75 * @brief Halt the system on lwIP assert failure by default.
76 */
77#if !defined(LWIP_PLATFORM_ASSERT)
78#define LWIP_PLATFORM_ASSERT(x) osalSysHalt(x)
79#endif
80
81/**
82 * @brief The NETIF API is required by lwipthread.
83 */
84#ifdef LWIP_NETIF_API
85#undef LWIP_NETIF_API
86#endif
87#define LWIP_NETIF_API 1
88
89#endif /* __CC_H__ */
diff --git a/lib/chibios/os/various/lwip_bindings/arch/perf.h b/lib/chibios/os/various/lwip_bindings/arch/perf.h
new file mode 100644
index 000000000..dc786cade
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/arch/perf.h
@@ -0,0 +1,57 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/*
17 * **** This file incorporates work covered by the following copyright and ****
18 * **** permission notice: ****
19 *
20 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without modification,
24 * are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 * 3. The name of the author may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
37 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
39 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
43 * OF SUCH DAMAGE.
44 *
45 * This file is part of the lwIP TCP/IP stack.
46 *
47 * Author: Adam Dunkels <[email protected]>
48 *
49 */
50
51#ifndef __PERF_H__
52#define __PERF_H__
53
54#define PERF_START
55#define PERF_STOP(x)
56
57#endif /* __PERF_H__ */
diff --git a/lib/chibios/os/various/lwip_bindings/arch/sys_arch.c b/lib/chibios/os/various/lwip_bindings/arch/sys_arch.c
new file mode 100644
index 000000000..12e4fba13
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/arch/sys_arch.c
@@ -0,0 +1,239 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/*
17 * **** This file incorporates work covered by the following copyright and ****
18 * **** permission notice: ****
19 *
20 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without modification,
24 * are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 * 3. The name of the author may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
37 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
39 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
43 * OF SUCH DAMAGE.
44 *
45 * This file is part of the lwIP TCP/IP stack.
46 *
47 * Author: Adam Dunkels <[email protected]>
48 *
49 */
50
51/*
52 * See http://lwip.wikia.com/wiki/Porting_for_an_OS for instructions.
53 */
54
55#include "hal.h"
56
57#include "lwip/opt.h"
58#include "lwip/mem.h"
59#include "lwip/sys.h"
60#include "lwip/stats.h"
61
62#include "arch/cc.h"
63#include "arch/sys_arch.h"
64
65void sys_init(void) {
66
67}
68
69err_t sys_sem_new(sys_sem_t *sem, u8_t count) {
70
71 *sem = chHeapAlloc(NULL, sizeof(semaphore_t));
72 if (*sem == 0) {
73 SYS_STATS_INC(sem.err);
74 return ERR_MEM;
75 }
76 else {
77 chSemObjectInit(*sem, (cnt_t)count);
78 SYS_STATS_INC_USED(sem);
79 return ERR_OK;
80 }
81}
82
83void sys_sem_free(sys_sem_t *sem) {
84
85 chHeapFree(*sem);
86 *sem = SYS_SEM_NULL;
87 SYS_STATS_DEC(sem.used);
88}
89
90void sys_sem_signal(sys_sem_t *sem) {
91
92 chSemSignal(*sem);
93}
94
95/* CHIBIOS FIX: specific variant of this call to be called from within
96 a lock.*/
97void sys_sem_signal_S(sys_sem_t *sem) {
98
99 chSemSignalI(*sem);
100 chSchRescheduleS();
101}
102
103u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) {
104 systime_t start;
105 sysinterval_t tmo, remaining;
106
107 chSysLock();
108 tmo = timeout > 0 ? TIME_MS2I((time_msecs_t)timeout) : TIME_INFINITE;
109 start = chVTGetSystemTimeX();
110 if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) {
111 chSysUnlock();
112 return SYS_ARCH_TIMEOUT;
113 }
114 remaining = chTimeDiffX(start, chVTGetSystemTimeX());
115 chSysUnlock();
116 return (u32_t)TIME_I2MS(remaining);
117}
118
119int sys_sem_valid(sys_sem_t *sem) {
120 return *sem != SYS_SEM_NULL;
121}
122
123// typically called within lwIP after freeing a semaphore
124// to make sure the pointer is not left pointing to invalid data
125void sys_sem_set_invalid(sys_sem_t *sem) {
126 *sem = SYS_SEM_NULL;
127}
128
129err_t sys_mbox_new(sys_mbox_t *mbox, int size) {
130
131 *mbox = chHeapAlloc(NULL, sizeof(mailbox_t) + sizeof(msg_t) * size);
132 if (*mbox == 0) {
133 SYS_STATS_INC(mbox.err);
134 return ERR_MEM;
135 }
136 else {
137 chMBObjectInit(*mbox, (void *)(((uint8_t *)*mbox) + sizeof(mailbox_t)), size);
138 SYS_STATS_INC(mbox.used);
139 return ERR_OK;
140 }
141}
142
143void sys_mbox_free(sys_mbox_t *mbox) {
144 cnt_t tmpcnt;
145
146 chSysLock();
147 tmpcnt = chMBGetUsedCountI(*mbox);
148 chSysUnlock();
149
150 if (tmpcnt != 0) {
151 // If there are messages still present in the mailbox when the mailbox
152 // is deallocated, it is an indication of a programming error in lwIP
153 // and the developer should be notified.
154 SYS_STATS_INC(mbox.err);
155 chMBReset(*mbox);
156 }
157 chHeapFree(*mbox);
158 *mbox = SYS_MBOX_NULL;
159 SYS_STATS_DEC(mbox.used);
160}
161
162void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
163
164 chMBPostTimeout(*mbox, (msg_t)msg, TIME_INFINITE);
165}
166
167err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
168
169 if (chMBPostTimeout(*mbox, (msg_t)msg, TIME_IMMEDIATE) == MSG_TIMEOUT) {
170 SYS_STATS_INC(mbox.err);
171 return ERR_MEM;
172 }
173 return ERR_OK;
174}
175
176u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
177 systime_t start;
178 sysinterval_t tmo, remaining;
179
180 chSysLock();
181 tmo = timeout > 0 ? TIME_MS2I((time_msecs_t)timeout) : TIME_INFINITE;
182 start = chVTGetSystemTimeX();
183 if (chMBFetchTimeoutS(*mbox, (msg_t *)msg, tmo) != MSG_OK) {
184 chSysUnlock();
185 return SYS_ARCH_TIMEOUT;
186 }
187 remaining = chTimeDiffX(start, chVTGetSystemTimeX());
188 chSysUnlock();
189 return (u32_t)TIME_I2MS(remaining);
190}
191
192u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) {
193
194 if (chMBFetchTimeout(*mbox, (msg_t *)msg, TIME_IMMEDIATE) == MSG_TIMEOUT)
195 return SYS_MBOX_EMPTY;
196 return 0;
197}
198
199int sys_mbox_valid(sys_mbox_t *mbox) {
200 return *mbox != SYS_MBOX_NULL;
201}
202
203// typically called within lwIP after freeing an mbox
204// to make sure the pointer is not left pointing to invalid data
205void sys_mbox_set_invalid(sys_mbox_t *mbox) {
206 *mbox = SYS_MBOX_NULL;
207}
208
209sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread,
210 void *arg, int stacksize, int prio) {
211 thread_t *tp;
212
213 tp = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(stacksize),
214 name, prio, (tfunc_t)thread, arg);
215 return (sys_thread_t)tp;
216}
217
218sys_prot_t sys_arch_protect(void) {
219
220 return chSysGetStatusAndLockX();
221}
222
223void sys_arch_unprotect(sys_prot_t pval) {
224
225 chSysRestoreStatusX((syssts_t)pval);
226}
227
228u32_t sys_now(void) {
229
230#if OSAL_ST_FREQUENCY == 1000
231 return (u32_t)chVTGetSystemTimeX();
232#elif (OSAL_ST_FREQUENCY / 1000) >= 1 && (OSAL_ST_FREQUENCY % 1000) == 0
233 return ((u32_t)chVTGetSystemTimeX() - 1) / (OSAL_ST_FREQUENCY / 1000) + 1;
234#elif (1000 / OSAL_ST_FREQUENCY) >= 1 && (1000 % OSAL_ST_FREQUENCY) == 0
235 return ((u32_t)chVTGetSystemTimeX() - 1) * (1000 / OSAL_ST_FREQUENCY) + 1;
236#else
237 return (u32_t)(((u64_t)(chVTGetSystemTimeX() - 1) * 1000) / OSAL_ST_FREQUENCY) + 1;
238#endif
239}
diff --git a/lib/chibios/os/various/lwip_bindings/arch/sys_arch.h b/lib/chibios/os/various/lwip_bindings/arch/sys_arch.h
new file mode 100644
index 000000000..0c5938ce2
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/arch/sys_arch.h
@@ -0,0 +1,68 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/*
17 * **** This file incorporates work covered by the following copyright and ****
18 * **** permission notice: ****
19 *
20 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without modification,
24 * are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 * 3. The name of the author may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
37 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
39 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
43 * OF SUCH DAMAGE.
44 *
45 * This file is part of the lwIP TCP/IP stack.
46 *
47 * Author: Adam Dunkels <[email protected]>
48 *
49 */
50
51#include <hal.h>
52
53#ifndef __SYS_ARCH_H__
54#define __SYS_ARCH_H__
55
56typedef semaphore_t * sys_sem_t;
57typedef mailbox_t * sys_mbox_t;
58typedef thread_t * sys_thread_t;
59typedef syssts_t sys_prot_t;
60
61#define SYS_MBOX_NULL (mailbox_t *)0
62#define SYS_THREAD_NULL (thread_t *)0
63#define SYS_SEM_NULL (semaphore_t *)0
64
65/* let sys.h use binary semaphores for mutexes */
66#define LWIP_COMPAT_MUTEX 1
67
68#endif /* __SYS_ARCH_H__ */
diff --git a/lib/chibios/os/various/lwip_bindings/lwip.mk b/lib/chibios/os/various/lwip_bindings/lwip.mk
new file mode 100644
index 000000000..ec1f44cf9
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/lwip.mk
@@ -0,0 +1,23 @@
1# List of the required lwIP files.
2LWIPDIR = $(CHIBIOS)/ext/lwip/src
3
4# The various blocks of files are outlined in Filelists.mk.
5include $(LWIPDIR)/Filelists.mk
6
7LWBINDSRC = \
8 $(CHIBIOS)/os/various/lwip_bindings/lwipthread.c \
9 $(CHIBIOS)/os/various/lwip_bindings/arch/sys_arch.c
10
11
12# Add blocks of files from Filelists.mk as required for enabled options
13LWSRC_REQUIRED = $(COREFILES) $(CORE4FILES) $(APIFILES) $(LWBINDSRC) $(NETIFFILES)
14LWSRC_EXTRAS ?= $(HTTPFILES)
15
16LWINC = \
17 $(CHIBIOS)/os/various/lwip_bindings \
18 $(LWIPDIR)/include
19
20# Shared variables
21ALLCSRC += $(LWSRC_REQUIRED) $(LWSRC_EXTRAS)
22ALLINC += $(LWINC) \
23 $(CHIBIOS)/os/various
diff --git a/lib/chibios/os/various/lwip_bindings/lwipthread.c b/lib/chibios/os/various/lwip_bindings/lwipthread.c
new file mode 100644
index 000000000..0260ae61b
--- /dev/null
+++ b/lib/chibios/os/various/lwip_bindings/lwipthread.c
@@ -0,0 +1,530 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16/*
17 * **** This file incorporates work covered by the following copyright and ****
18 * **** permission notice: ****
19 *
20 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without modification,
24 * are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 * 3. The name of the author may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
37 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
39 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
43 * OF SUCH DAMAGE.
44 *
45 * This file is part of the lwIP TCP/IP stack.
46 *
47 * Author: Adam Dunkels <adam@sic