From f26d653e462a84bfa73387b66f5e651d5849695f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Jan 2013 08:49:45 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5011 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F407-DISCOVERY-MEMS-G++/Makefile | 5 +- os/various/ch.cpp | 409 ---------- os/various/ch.hpp | 865 --------------------- os/various/cpp_wrappers/ch.cpp | 409 ++++++++++ os/various/cpp_wrappers/ch.hpp | 865 +++++++++++++++++++++ os/various/cpp_wrappers/kernel.mk | 4 + os/various/fatfs_bindings/fatfs.mk | 2 +- 7 files changed, 1283 insertions(+), 1276 deletions(-) delete mode 100644 os/various/ch.cpp delete mode 100644 os/various/ch.hpp create mode 100644 os/various/cpp_wrappers/ch.cpp create mode 100644 os/various/cpp_wrappers/ch.hpp create mode 100644 os/various/cpp_wrappers/kernel.mk diff --git a/demos/ARMCM4-STM32F407-DISCOVERY-MEMS-G++/Makefile b/demos/ARMCM4-STM32F407-DISCOVERY-MEMS-G++/Makefile index dbbed56cd..80c926465 100644 --- a/demos/ARMCM4-STM32F407-DISCOVERY-MEMS-G++/Makefile +++ b/demos/ARMCM4-STM32F407-DISCOVERY-MEMS-G++/Makefile @@ -70,6 +70,7 @@ include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk include $(CHIBIOS)/os/hal/hal.mk include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk include $(CHIBIOS)/os/kernel/kernel.mk +include $(CHIBIOS)/os/various/cpp_wrappers/kernel.mk include $(CHIBIOS)/test/test.mk # Define linker script file here @@ -92,7 +93,8 @@ CSRC = $(PORTSRC) \ # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. -CPPSRC = $(CHIBIOS)/os/various/ch.cpp main.cpp +CPPSRC = $(CHCPPSRC) \ + main.cpp # C sources to be compiled in ARM mode regardless of the global setting. # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler @@ -119,6 +121,7 @@ ASMSRC = $(PORTASM) INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ $(HALINC) $(PLATFORMINC) $(BOARDINC) \ + $(CHCPPINC) \ $(CHIBIOS)/os/various/devices_lib/accel \ $(CHIBIOS)/os/various diff --git a/os/various/ch.cpp b/os/various/ch.cpp deleted file mode 100644 index 84678349c..000000000 --- a/os/various/ch.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - 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 . -*/ -/** - * @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/ch.hpp b/os/various/ch.hpp deleted file mode 100644 index ad3dd18af..000000000 --- a/os/various/ch.hpp +++ /dev/null @@ -1,865 +0,0 @@ -/* - 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 . -*/ - -/** - * @file ch.hpp - * @brief C++ wrapper classes and definitions. - * - * @addtogroup cpp_library - * @{ - */ - -#include - -#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 - 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 MUCH MORE 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.
- * 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.
- * 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/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 . +*/ +/** + * @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 . +*/ + +/** + * @file ch.hpp + * @brief C++ wrapper classes and definitions. + * + * @addtogroup cpp_library + * @{ + */ + +#include + +#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 + 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 MUCH MORE 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.
+ * 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.
+ * 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 diff --git a/os/various/fatfs_bindings/fatfs.mk b/os/various/fatfs_bindings/fatfs.mk index 1bbdc254f..682091e00 100644 --- a/os/various/fatfs_bindings/fatfs.mk +++ b/os/various/fatfs_bindings/fatfs.mk @@ -2,6 +2,6 @@ FATFSSRC = ${CHIBIOS}/os/various/fatfs_bindings/fatfs_diskio.c \ ${CHIBIOS}/os/various/fatfs_bindings/fatfs_syscall.c \ ${CHIBIOS}/ext/fatfs/src/ff.c \ - ${CHIBIOS}/ext/fatfs/src/option/ccsbcs.c \ + ${CHIBIOS}/ext/fatfs/src/option/ccsbcs.c FATFSINC = ${CHIBIOS}/ext/fatfs/src -- cgit v1.2.3