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 --- os/various/cpp_wrappers/ch.hpp | 865 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 865 insertions(+) create mode 100644 os/various/cpp_wrappers/ch.hpp (limited to 'os/various/cpp_wrappers/ch.hpp') 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_ */ + +/** @} */ -- cgit v1.2.3