aboutsummaryrefslogtreecommitdiffstats
path: root/os/various/cpp_wrappers
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-01-02 08:49:45 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-01-02 08:49:45 +0000
commitf26d653e462a84bfa73387b66f5e651d5849695f (patch)
tree78d708986c619eabef58ff452b35a3fc15ec6f55 /os/various/cpp_wrappers
parent462ab6bcaffc7ee98c418f17abab1178beb83db1 (diff)
downloadChibiOS-f26d653e462a84bfa73387b66f5e651d5849695f.tar.gz
ChibiOS-f26d653e462a84bfa73387b66f5e651d5849695f.tar.bz2
ChibiOS-f26d653e462a84bfa73387b66f5e651d5849695f.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5011 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/various/cpp_wrappers')
-rw-r--r--os/various/cpp_wrappers/ch.cpp409
-rw-r--r--os/various/cpp_wrappers/ch.hpp865
-rw-r--r--os/various/cpp_wrappers/kernel.mk4
3 files changed, 1278 insertions, 0 deletions
diff --git a/os/various/cpp_wrappers/ch.cpp b/os/various/cpp_wrappers/ch.cpp
new file mode 100644
index 000000000..84678349c
--- /dev/null
+++ b/os/various/cpp_wrappers/ch.cpp
@@ -0,0 +1,409 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @file ch.cpp
+ * @brief C++ wrapper code.
+ *
+ * @addtogroup cpp_library
+ * @{
+ */
+
+#include "ch.hpp"
+
+namespace chibios_rt {
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::System *
+ *------------------------------------------------------------------------*/
+ void System::init(void) {
+
+ chSysInit();
+ }
+
+ void System::lock(void) {
+
+ chSysLock();
+ }
+
+ void System::unlock(void) {
+
+ chSysUnlock();
+ }
+
+ systime_t System::getTime(void) {
+
+ return chTimeNow();
+ }
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Timer *
+ *------------------------------------------------------------------------*/
+ void Timer::setI(systime_t time, vtfunc_t vtfunc, void *par) {
+
+ chVTSetI(&timer_ref, time, vtfunc, par);
+ }
+
+ void Timer::resetI() {
+
+ if (chVTIsArmedI(&timer_ref))
+ chVTResetI(&timer_ref);
+ }
+
+ bool Timer::isArmedI(void) {
+
+ return (bool)chVTIsArmedI(&timer_ref);
+ }
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::ThreadReference *
+ *------------------------------------------------------------------------*/
+ msg_t ThreadReference::suspend(void) {
+ msg_t msg;
+
+ chSysLock();
+
+ chDbgAssert(thread_ref != NULL,
+ "ThreadReference, #1",
+ "already referenced");
+
+ thread_ref = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ msg = thread_ref->p_u.rdymsg;
+
+ chSysUnlock();
+ return msg;
+ }
+
+ msg_t ThreadReference::suspendS(void) {
+
+ chDbgAssert(thread_ref == NULL,
+ "ThreadReference, #2",
+ "already referenced");
+
+ thread_ref = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ return thread_ref->p_u.rdymsg;
+ }
+
+ void ThreadReference::resume(msg_t msg) {
+
+ chSysLock()
+
+ chDbgAssert(thread_ref != NULL,
+ "ThreadReference, #3",
+ "not referenced");
+
+ if (thread_ref) {
+ Thread *tp = thread_ref;
+ thread_ref = NULL;
+ chSchWakeupS(tp, msg);
+ }
+
+ chSysUnlock();
+ }
+
+ void ThreadReference::resumeI(msg_t msg) {
+
+ chDbgAssert(thread_ref != NULL,
+ "ThreadReference, #4",
+ "not referenced");
+
+ if (thread_ref) {
+ Thread *tp = thread_ref;
+ thread_ref = NULL;
+ tp->p_msg = msg;
+ chSchReadyI(tp);
+ }
+ }
+
+ void ThreadReference::requestTerminate(void) {
+
+ chThdTerminate(thread_ref);
+ }
+
+#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
+ msg_t ThreadReference::wait(void) {
+
+ chDbgAssert(thread_ref != NULL,
+ "ThreadReference, #5",
+ "not referenced");
+
+ msg_t msg = chThdWait(thread_ref);
+ thread_ref = NULL;
+ return msg;
+ }
+#endif /* CH_USE_WAITEXIT */
+
+#if CH_USE_MESSAGES || defined(__DOXYGEN__)
+ msg_t ThreadReference::sendMessage(msg_t msg) {
+
+ chDbgAssert(thread_ref != NULL,
+ "ThreadReference, #6",
+ "not referenced");
+
+ return chMsgSend(thread_ref, msg);
+ }
+
+ bool ThreadReference::isPendingMessage(void) {
+
+ return (bool)chMsgIsPendingI(thread_ref);
+ }
+#endif /* CH_USE_MESSAGES */
+
+#if CH_USE_DYNAMIC
+#endif /* CH_USE_DYNAMIC */
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::BaseThread *
+ *------------------------------------------------------------------------*/
+ BaseThread::BaseThread() : ThreadReference(NULL) {
+
+ }
+
+ msg_t _thd_start(void *arg) {
+
+ return ((BaseThread *)arg)->Main();
+ }
+
+ void BaseThread::exit(msg_t msg) {
+
+ chThdExit(msg);
+ }
+
+ tprio_t BaseThread::setPriority(tprio_t newprio) {
+
+ return chThdSetPriority(newprio);
+ }
+
+ bool BaseThread::shouldTerminate(void) {
+
+ return (bool)chThdShouldTerminate();
+ }
+
+ void BaseThread::sleep(systime_t interval){
+
+ chThdSleep(interval);
+ }
+
+ void BaseThread::sleepUntil(systime_t time) {
+
+ chThdSleepUntil(time);
+ }
+
+#if CH_USE_MESSAGES
+ msg_t BaseThread::getMessage(ThreadReference* trp) {
+
+ return chMsgGet(trp->thread_ref);
+ }
+
+ void BaseThread::releaseMessage(ThreadReference* trp, msg_t msg) {
+
+ chMsgRelease(trp->thread_ref, msg);
+ }
+#endif /* CH_USE_MESSAGES */
+
+#if CH_USE_SEMAPHORES
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Semaphore *
+ *------------------------------------------------------------------------*/
+ Semaphore::Semaphore(cnt_t n) {
+
+ chSemInit(&sem, n);
+ }
+
+ void Semaphore::reset(cnt_t n) {
+
+ chSemReset(&sem, n);
+ }
+
+ msg_t Semaphore::wait(void) {
+
+ return chSemWait(&sem);
+ }
+
+ msg_t Semaphore::waitTimeout(systime_t time) {
+
+ return chSemWaitTimeout(&sem, time);
+ }
+
+ void Semaphore::signal(void) {
+
+ chSemSignal(&sem);
+ }
+
+#if CH_USE_SEMSW
+ msg_t Semaphore::signalWait(Semaphore *ssem, Semaphore *wsem) {
+
+ return chSemSignalWait(&ssem->sem, &wsem->sem);
+ }
+#endif /* CH_USE_SEMSW */
+#endif /* CH_USE_SEMAPHORES */
+
+#if CH_USE_MUTEXES
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Mutex *
+ *------------------------------------------------------------------------*/
+ Mutex::Mutex(void) {
+
+ chMtxInit(&mutex);
+ }
+
+ bool Mutex::tryLock(void) {
+
+ return chMtxTryLock(&mutex);
+ }
+
+ void Mutex::lock(void) {
+
+ chMtxLock(&mutex);
+ }
+
+ void Mutex::unlock(void) {
+
+ chMtxUnlock();
+ }
+
+ void Mutex::unlockAll(void) {
+
+ chMtxUnlockAll();
+ }
+
+#if CH_USE_CONDVARS
+ /*------------------------------------------------------------------------*
+ * chibios_rt::CondVar *
+ *------------------------------------------------------------------------*/
+ CondVar::CondVar(void) {
+
+ chCondInit(&condvar);
+ }
+
+ void CondVar::signal(void) {
+
+ chCondSignal(&condvar);
+ }
+
+ void CondVar::broadcast(void) {
+
+ chCondBroadcast(&condvar);
+ }
+
+ msg_t CondVar::wait(void) {
+
+ return chCondWait(&condvar);
+ }
+
+#if CH_USE_CONDVARS_TIMEOUT
+ msg_t CondVar::waitTimeout(systime_t time) {
+
+ return chCondWaitTimeout(&condvar, time);
+ }
+#endif /* CH_USE_CONDVARS_TIMEOUT */
+#endif /* CH_USE_CONDVARS */
+#endif /* CH_USE_MUTEXES */
+
+#if CH_USE_EVENTS
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Event *
+ *------------------------------------------------------------------------*/
+ Event::Event(void) {
+
+ chEvtInit(&event);
+ }
+
+ void Event::registerOne(EventListener *elp, eventid_t eid) {
+
+ chEvtRegister(&event,elp, eid);
+ }
+
+ void Event::registerMask(EventListener *elp, eventmask_t emask) {
+
+ chEvtRegisterMask(&event,elp, emask);
+ }
+
+ void Event::unregister(EventListener *elp) {
+
+ chEvtUnregister(&event, elp);
+ }
+
+ void Event::broadcastFlags(flagsmask_t flags) {
+
+ chEvtBroadcastFlags(&event, flags);
+ }
+
+ void Event::broadcastFlagsI(flagsmask_t flags) {
+
+ chEvtBroadcastFlagsI(&event, flags);
+ }
+
+ flagsmask_t Event::getAndClearFlags(EventListener *elp) {
+
+ return chEvtGetAndClearFlags(elp);
+ }
+
+ eventmask_t Event::getAndClearEvents(eventmask_t mask) {
+
+ return chEvtGetAndClearEvents(mask);
+ }
+
+ eventmask_t Event::addEvents(eventmask_t mask) {
+
+ return chEvtAddEvents(mask);
+ }
+
+ void Event::dispatch(const evhandler_t handlers[], eventmask_t mask) {
+
+ chEvtDispatch(handlers, mask);
+ }
+
+ eventmask_t Event::waitOne(eventmask_t ewmask) {
+
+ return chEvtWaitOne(ewmask);
+ }
+
+ eventmask_t Event::waitAny(eventmask_t ewmask) {
+
+ return chEvtWaitAny(ewmask);
+ }
+
+ eventmask_t Event::waitAll(eventmask_t ewmask) {
+
+ return chEvtWaitAll(ewmask);
+ }
+
+#if CH_USE_EVENTS_TIMEOUT
+ eventmask_t Event::waitOneTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitOneTimeout(ewmask, time);
+ }
+
+ eventmask_t Event::waitAnyTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitAnyTimeout(ewmask, time);
+ }
+
+ eventmask_t Event::waitAllTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitAllTimeout(ewmask, time);
+ }
+#endif /* CH_USE_EVENTS_TIMEOUT */
+#endif /* CH_USE_EVENTS */
+}
+
+/** @} */
diff --git a/os/various/cpp_wrappers/ch.hpp b/os/various/cpp_wrappers/ch.hpp
new file mode 100644
index 000000000..ad3dd18af
--- /dev/null
+++ b/os/various/cpp_wrappers/ch.hpp
@@ -0,0 +1,865 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ch.hpp
+ * @brief C++ wrapper classes and definitions.
+ *
+ * @addtogroup cpp_library
+ * @{
+ */
+
+#include <ch.h>
+
+#ifndef _CH_HPP_
+#define _CH_HPP_
+
+namespace chibios_rt {
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::System *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Class encapsulating the base system functionalities.
+ */
+ class System {
+ public:
+ /**
+ * @brief ChibiOS/RT initialization.
+ * @details The system is initialized, the idle thread is spawned and the
+ * current instruction flow becomes the main thread with priority
+ * @p NORMALPRIO.
+ *
+ * @api
+ */
+ static void init(void);
+
+ /**
+ * @brief Kernel lock.
+ * @note On some ports it is faster to invoke chSysLock() directly
+ * because inlining.
+ *
+ * @special
+ */
+ static void lock(void);
+
+ /**
+ * @brief Kernel unlock.
+ * @note On some ports it is faster to invoke chSysUnlock() directly
+ * because inlining.
+ *
+ * @special
+ */
+ static void unlock(void);
+
+ /**
+ * @brief Returns the system time as system ticks.
+ * @note The system tick time interval is implementation dependent.
+ *
+ * @return The system time.
+ *
+ * @api
+ */
+ static systime_t getTime(void);
+ };
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Timer *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Timer class.
+ */
+ class Timer {
+ public:
+ /**
+ * @brief Embedded @p VirtualTimer structure.
+ */
+ struct ::VirtualTimer timer_ref;
+
+ /**
+ * @brief Starts the timer.
+ * @note It must be called with the interrupts disabled.
+ * @note The associated function is invoked by an interrupt handler.
+ *
+ * @param[in] time the time in system ticks
+ * @param[in] vtfunc the timer callback function
+ * @param[in] par the parameter for the callback function
+ *
+ * @iclass
+ */
+ void setI(systime_t time, vtfunc_t vtfunc, void *par);
+
+ /**
+ * @brief Resets the timer, if armed.
+ *
+ * @iclass
+ */
+ void resetI();
+
+ /**
+ * @brief Returns the timer status.
+ *
+ * @retval TRUE The timer is armed.
+ * @retval FALSE The timer already fired its callback.
+ *
+ * @iclass
+ */
+ bool isArmedI(void);
+ };
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::ThreadReference *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Thread reference class.
+ * @details This class encapsulates a reference to a system thread.
+ */
+ class ThreadReference {
+ public:
+ /**
+ * @brief Pointer to the system thread.
+ */
+ ::Thread *thread_ref;
+
+ /**
+ * @brief Thread reference constructor.
+ *
+ * @param[in] tp the target thread. This parameter can be
+ * @p NULL if the thread is not known at
+ * creation time.
+ *
+ * @api
+ */
+ ThreadReference(Thread * tp) : thread_ref(tp) {
+
+ };
+
+ /**
+ * @brief Suspends the current thread on the reference.
+ * @details The suspended thread becomes the referenced thread. It is
+ * possible to use this method only if the thread reference
+ * was set to @p NULL.
+ *
+ * @return The incoming message.
+ *
+ * @api
+ */
+ msg_t suspend(void);
+
+ /**
+ * @brief Suspends the current thread on the reference.
+ * @details The suspended thread becomes the referenced thread. It is
+ * possible to use this method only if the thread reference
+ * was set to @p NULL.
+ *
+ * @return The incoming message.
+ *
+ * @sclass
+ */
+ msg_t suspendS(void);
+
+ /**
+ * @brief Resumes the currently referenced thread, if any.
+ *
+ * @api
+ */
+ void resume(msg_t msg);
+
+ /**
+ * @brief Resumes the currently referenced thread, if any.
+ *
+ * @iclass
+ */
+ void resumeI(msg_t msg);
+
+ /**
+ * @brief Requests thread termination.
+ * @details A termination flag is added to the thread, it is thread
+ * responsibility to detect it and exit.
+ */
+ void requestTerminate(void);
+
+#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
+ /**
+ * @brief Synchronization on Thread exit.
+ *
+ * @return The exit message from the thread.
+ *
+ * @api
+ */
+ msg_t wait(void);
+#endif /* CH_USE_WAITEXIT */
+
+#if CH_USE_MESSAGES || defined(__DOXYGEN__)
+ /**
+ * @brief Sends a message to the thread and returns the answer.
+ *
+ * @param[in] msg the sent message
+ * @return The returned message.
+ *
+ * @api
+ */
+ msg_t sendMessage(msg_t msg);
+
+ /**
+ * @brief Returns true if there is at least one message in queue.
+ *
+ * @retval true A message is waiting in queue.
+ * @retval false A message is not waiting in queue.
+ *
+ * @api
+ */
+ bool isPendingMessage(void);
+#endif /* CH_USE_MESSAGES */
+
+#if CH_USE_DYNAMIC
+#endif /* CH_USE_DYNAMIC */
+ };
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::BaseThread *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Abstract base class for a ChibiOS/RT thread.
+ * @details The thread body is the virtual function @p Main().
+ */
+ class BaseThread : public ThreadReference {
+ public:
+
+ /**
+ * @brief BaseThread constructor.
+ *
+ * @api
+ */
+ BaseThread(void);
+
+ /**
+ * @brief Thread body function.
+ *
+ * @return The exit message.
+ *
+ * @api
+ */
+ virtual msg_t Main(void) {
+ return 0;
+ };
+
+ /**
+ * @brief Creates and starts a system thread.
+ *
+ * @param[in] tname the name to be assigned to the thread
+ * @param[in] prio thread priority
+ * @return Error flag.
+ * @retval false if the operation failed.
+ * @retval true if the operation succeeded.
+ *
+ * @api
+ */
+ virtual bool start(const char *tname, tprio_t prio){
+ (void) tname;
+ (void) prio;
+ return false;
+ };
+
+ /**
+ * @brief Thread exit.
+ *
+ * @param[in] msg the exit message
+ *
+ * @api
+ */
+ static void exit(msg_t msg);
+
+#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
+ /**
+ * @brief Synchronization on Thread exit.
+ *
+ * @return The exit message from the thread.
+ *
+ * @api
+ */
+ msg_t wait(void);
+#endif /* CH_USE_WAITEXIT */
+
+ /**
+ * @brief Changes the current thread priority.
+ *
+ * @param[in] newprio The new priority level
+ * @return The old priority level.
+ *
+ * @api
+ */
+ static tprio_t setPriority(tprio_t newprio);
+
+ /**
+ * @brief Requests thread termination.
+ * @details A termination flag is added to the thread, it is thread
+ * responsibility to detect it and exit.
+ *
+ * @api
+ */
+ void requestTerminate(void);
+
+ /**
+ * @brief Determines if there is a pending termination request.
+ *
+ * @return The termination status.
+ * @retval false if there is no termination request pending.
+ * @retval true if there is a termination request pending.
+ *
+ * @api
+ */
+ bool shouldTerminate(void);
+
+ /**
+ * @brief Suspends the thread execution for the specified number of
+ * system ticks.
+ *
+ * @param[in] interval the number of system ticks
+ *
+ * @api
+ */
+ static void sleep(systime_t interval);
+
+ /**
+ * @brief Suspends the thread execution until the specified time arrives.
+ *
+ * @param[in] time the system time
+ *
+ * @api
+ */
+ static void sleepUntil(systime_t time);
+
+#if CH_USE_MESSAGES
+ /**
+ * @brief Waits for a message.
+ *
+ * @return The sender thread.
+ *
+ * @api
+ */
+ static ThreadReference waitMessage(void);
+
+ /**
+ * @brief Returns an enqueued message or @p NULL.
+ *
+ * @param[in] trp the sender thread reference
+ * @return The incoming message.
+ *
+ * @api
+ */
+ static msg_t getMessage(ThreadReference* trp);
+
+ /**
+ * @brief Releases the next message in queue with a reply.
+ *
+ * @param[in] trp the sender thread reference
+ * @param[in] msg the answer message
+ *
+ * @api
+ */
+ static void releaseMessage(ThreadReference* trp, msg_t msg);
+#endif /* CH_USE_MESSAGES */
+ };
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::BaseStaticThread *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Static threads template class.
+ * @details This class introduces static working area allocation.
+ *
+ * @param N the working area size for the thread class
+ */
+ template <int N>
+ class BaseStaticThread : public BaseThread {
+ protected:
+ WORKING_AREA(wa, N); // Thread working area.
+
+ public:
+ /**
+ * @brief Thread constructor.
+ * @details The thread object is initialized but the thread is not
+ * started here.
+ *
+ * @api
+ */
+ BaseStaticThread(void) : BaseThread() {
+
+ }
+
+ /**
+ * @brief Creates and starts a system thread.
+ *
+ * @param[in] tname the name to be assigned to the thread
+ * @param[in] prio thread priority
+ * @return Error flag.
+ * @retval false if the operation succeeded.
+ * @retval true if the operation failed.
+ *
+ * @api
+ */
+ bool start(const char *tname, tprio_t prio) {
+ (void)tname;
+ msg_t _thd_start(void *arg);
+
+ thread_ref = chThdCreateStatic(wa, sizeof(wa), prio, _thd_start, this);
+ return false;
+ }
+ };
+
+#if CH_USE_SEMAPHORES
+ /**
+ * @brief Class encapsulating a semaphore.
+ */
+ class Semaphore {
+ public:
+ /**
+ * @brief Embedded @p ::Semaphore structure.
+ */
+ struct ::Semaphore sem;
+
+ /**
+ * @brief Semaphore constructor.
+ * @details The embedded @p ::Semaphore structure is initialized.
+ *
+ * @param[in] n the semaphore counter value, must be greater
+ * or equal to zero
+ *
+ * @api
+ */
+ Semaphore(cnt_t n);
+
+ /**
+ * @brief Resets a semaphore.
+ *
+ * @param[in] n the new semaphore counter value, must be
+ * greater or equal to zero
+ *
+ * @api
+ */
+ void reset(cnt_t n);
+
+ /**
+ * @brief Wait operation on the semaphore.
+ *
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ *
+ * @api
+ */
+ msg_t wait(void);
+
+ /**
+ * @brief Wait operation on the semaphore with timeout.
+ *
+ * @param[in] time the number of ticks before the operation fails
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ * @retval RDY_TIMEOUT if the semaphore was not signaled or reset
+ * within the specified timeout.
+ *
+ * @api
+ */
+ msg_t waitTimeout(systime_t time);
+
+ /**
+ * @brief Signal operation on the semaphore.
+ * @details The semaphore is signaled, the next thread in queue, if any,
+ * is awakened.
+ *
+ * @api
+ */
+ void signal(void);
+
+#if CH_USE_SEMSW
+ /**
+ * @brief Atomic signal and wait operations.
+ *
+ * @param[in] ssem pointer to a @p Semaphore to be signaled
+ * @param[in] wsem pointer to a @p Semaphore to be wait on
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ *
+ * @api
+ */
+ static msg_t signalWait(Semaphore *ssem, Semaphore *wsem);
+#endif /* CH_USE_SEMSW */
+ };
+#endif /* CH_USE_SEMAPHORES */
+
+#if CH_USE_MUTEXES
+ /**
+ * @brief Class encapsulating a mutex.
+ */
+ class Mutex {
+ public:
+ /**
+ * @brief Embedded @p ::Mutex structure.
+ */
+ struct ::Mutex mutex;
+
+ /**
+ * @brief Mutex constructor.
+ * @details The embedded @p ::Mutex structure is initialized.
+ *
+ * @api
+ */
+ Mutex(void);
+
+ /**
+ * @brief Tries a lock operation on the mutex.
+ *
+ * @retval TRUE if the mutex was successfully acquired
+ * @retval FALSE if the lock attempt failed.
+ *
+ * @api
+ */
+ bool tryLock(void);
+
+ /**
+ * @brief Locks the mutex.
+ * @details Performs a lock operation on the mutex, if the mutex is
+ * already locked then the thread enters the mutex priority
+ * queue and waits.
+ *
+ * @api
+ */
+ void lock(void);
+
+ /**
+ * @brief Unlocks the mutex.
+ * @details Performs an unlock operation on the mutex, the next waiting
+ * thread, if any, is resumed and locks the mutex.
+ *
+ * @api
+ */
+ static void unlock(void);
+
+ /**
+ * @brief Unlocks all the mutexes owned by the invoking thread.
+ * @details This operation is <b>MUCH MORE</b> efficient than releasing
+ * the mutexes one by one and not just because the call overhead,
+ * this function does not have any overhead related to the
+ * priority inheritance mechanism.
+ *
+ * @api
+ */
+ static void unlockAll(void);
+ };
+
+#if CH_USE_CONDVARS
+ /**
+ * @brief Class encapsulating a conditional variable.
+ */
+ class CondVar {
+ public:
+ /**
+ * @brief Embedded @p ::CondVar structure.
+ */
+ struct ::CondVar condvar;
+
+ /**
+ * @brief CondVar constructor.
+ * @details The embedded @p ::CondVar structure is initialized.
+ *
+ * @api
+ */
+ CondVar(void);
+
+ /**
+ * @brief Signals the CondVar.
+ * @details The next thread waiting on the @p CondVar, if any, is awakened.
+ *
+ * @api
+ */
+ void signal(void);
+
+ /**
+ * @brief Broadcasts the CondVar.
+ * @details All the threads waiting on the @p CondVar, if any, are awakened.
+ *
+ * @api
+ */
+ void broadcast(void);
+
+ /**
+ * @brief Waits on the CondVar while releasing the controlling mutex.
+ *
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using
+ * @p chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using
+ * @p chCondBroadcast().
+ *
+ * @api
+ */
+ msg_t wait(void);
+
+#if CH_USE_CONDVARS_TIMEOUT
+ /**
+ * @brief Waits on the CondVar while releasing the controlling mutex.
+ *
+ * @param[in] time the number of ticks before the operation fails
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using
+ * @p chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using
+ * @p chCondBroadcast().
+ * @retval RDY_TIMEOUT if the condvar was not signaled within the
+ * specified timeout.
+ *
+ * @api
+ */
+ msg_t waitTimeout(systime_t time);
+#endif /* CH_USE_CONDVARS_TIMEOUT */
+ };
+#endif /* CH_USE_CONDVARS */
+#endif /* CH_USE_MUTEXES */
+
+#if CH_USE_EVENTS
+ /**
+ * @brief Class encapsulating an event source.
+ */
+ class Event {
+ public:
+ /**
+ * @brief Embedded @p ::EventSource structure.
+ */
+ struct ::EventSource event;
+
+ /**
+ * @brief Event constructor.
+ * @details The embedded @p ::EventSource structure is initialized.
+ *
+ * @api
+ */
+ Event(void);
+
+ /**
+ * @brief Registers a listener on the event source.
+ *
+ * @param[in] elp pointer to the @p EventListener structure
+ * @param[in] eid numeric identifier assigned to the Event
+ * Listener
+ *
+ * @api
+ */
+ void registerOne(EventListener *elp, eventid_t eid);
+
+ /**
+ * @brief Registers an Event Listener on an Event Source.
+ * @note Multiple Event Listeners can specify the same bits to be added.
+ *
+ * @param[in] elp pointer to the @p EventListener structure
+ * @param[in] emask the mask of event flags to be pended to the
+ * thread when the event source is broadcasted
+ *
+ * @api
+ */
+ void registerMask(EventListener *elp, eventmask_t emask);
+
+ /**
+ * @brief Unregisters a listener.
+ * @details The specified listeners is no more signaled by the event
+ * source.
+ *
+ * @param[in] elp the listener to be unregistered
+ *
+ * @api
+ */
+ void unregister(EventListener *elp);
+
+ /**
+ * @brief Broadcasts an event.
+ * @details All the listeners registered on the event source are signaled.
+ *
+ * @param[in] flags the flags set to be added to the listener
+ * flags mask
+ *
+ * @api
+ */
+ void broadcastFlags(flagsmask_t flags);
+
+ /**
+ * @brief Broadcasts an event.
+ * @details All the listeners registered on the event source are signaled.
+ *
+ * @param[in] flags the flags set to be added to the listener
+ * flags mask
+ *
+ * @api
+ */
+ void broadcastFlagsI(flagsmask_t flags);
+
+ /**
+ * @brief Clears specified events from the pending events mask.
+ *
+ * @param[in] elp pointer to the @p EventListener structure
+ * @param[in] flags the events to be cleared
+ * @return The flags added to the listener by the
+ * associated event source.
+ *
+ * @api
+ */
+ static flagsmask_t getAndClearFlags(EventListener *elp);
+
+ /**
+ * @brief Clears specified events from the pending events mask.
+ *
+ * @param[in] mask the events to be cleared
+ * @return The pending events that were cleared.
+ *
+ * @api
+ */
+ static eventmask_t getAndClearEvents(eventmask_t mask);
+
+ /**
+ * @brief Makes an events mask pending in the current thread.
+ * @details This functon is @b much faster than using @p Broadcast().
+ *
+ * @param[in] mask the events to be pended
+ * @return The current pending events mask.
+ *
+ * @api
+ */
+ static eventmask_t addEvents(eventmask_t mask);
+
+ /**
+ * @brief Invokes the event handlers associated with a mask.
+ *
+ * @param[in] mask mask of the events to be dispatched
+ * @param[in] handlers an array of @p evhandler_t. The array must be
+ * have indexes from zero up the higher registered
+ * event identifier.
+ *
+ * @api
+ */
+ static void dispatch(const evhandler_t handlers[], eventmask_t mask);
+
+ /**
+ * @brief Waits for a single event.
+ * @details A pending event among those specified in @p ewmask is selected,
+ * cleared and its mask returned.
+ * @note One and only one event is served in the function, the one with
+ * the lowest event id. The function is meant to be invoked into
+ * a loop in order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier
+ * have an higher priority.
+ *
+ * @param[in] ewmask mask of the events that the function should
+ * wait for, @p ALL_EVENTS enables all the events
+ * @return The mask of the lowest id served and cleared
+ * event.
+ *
+ * @api
+ */
+ static eventmask_t waitOne(eventmask_t ewmask);
+
+ /**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and
+ * returned.
+ *
+ * @param[in] ewmask mask of the events that the function should
+ * wait for, @p ALL_EVENTS enables all the events
+ * @return The mask of the served and cleared events.
+ *
+ * @api
+ */
+ static eventmask_t waitAny(eventmask_t ewmask);
+
+ /**
+ * @brief Waits for all the specified event flags then clears them.
+ * @details The function waits for all the events specified in @p ewmask
+ * to become pending then the events are cleared and returned.
+ *
+ * @param[in] ewmask mask of the event ids that the function should
+ * wait for
+ * @return The mask of the served and cleared events.
+ *
+ * @api
+ */
+ static eventmask_t waitAll(eventmask_t ewmask);
+
+#if CH_USE_EVENTS_TIMEOUT
+ /**
+ * @brief Waits for a single event.
+ * @details A pending event among those specified in @p ewmask is selected,
+ * cleared and its mask returned.
+ * @note One and only one event is served in the function, the one with
+ * the lowest event id. The function is meant to be invoked into
+ * a loop in order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier
+ * have an higher priority.
+ *
+ * @param[in] ewmask mask of the events that the function should
+ * wait for, @p ALL_EVENTS enables all the events
+ *
+ * @param[in] time the number of ticks before the operation timouts
+ * @return The mask of the lowest id served and cleared
+ * event.
+ * @retval 0 if the specified timeout expired.
+ *
+ * @api
+ */
+ static eventmask_t waitOneTimeout(eventmask_t ewmask, systime_t time);
+
+ /**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and
+ * returned.
+ *
+ * @param[in] ewmask mask of the events that the function should
+ * wait for, @p ALL_EVENTS enables all the events
+ * @param[in] time the number of ticks before the operation
+ * timouts
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ *
+ * @api
+ */
+ static eventmask_t waitAnyTimeout(eventmask_t ewmask, systime_t time);
+
+ /**
+ * @brief Waits for all the specified event flags then clears them.
+ * @details The function waits for all the events specified in @p ewmask
+ * to become pending then the events are cleared and returned.
+ *
+ * @param[in] ewmask mask of the event ids that the function should
+ * wait for
+ * @param[in] time the number of ticks before the operation
+ * timouts
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ *
+ * @api
+ */
+ static eventmask_t waitAllTimeout(eventmask_t ewmask, systime_t time);
+#endif /* CH_USE_EVENTS_TIMEOUT */
+ };
+#endif /* CH_USE_EVENTS */
+}
+
+#endif /* _CH_HPP_ */
+
+/** @} */
diff --git a/os/various/cpp_wrappers/kernel.mk b/os/various/cpp_wrappers/kernel.mk
new file mode 100644
index 000000000..6cd787658
--- /dev/null
+++ b/os/various/cpp_wrappers/kernel.mk
@@ -0,0 +1,4 @@
+# C++ wrapper files.
+CHCPPSRC = ${CHIBIOS}/os/various/cpp_wrappers/ch.cpp
+
+CHCPPINC = ${CHIBIOS}/os/various/cpp_wrappers