From 810cd7514051b11eaaf93e3ffcba0c7195a6b89b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 26 Mar 2008 16:25:26 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@247 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- readme.txt | 9 ++ src/include/events.h | 4 +- src/lib/ch.cpp | 266 +++++++++++++++++++++++++++++++++++++++++++ src/lib/ch.hpp | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 587 insertions(+), 2 deletions(-) create mode 100644 src/lib/ch.cpp create mode 100644 src/lib/ch.hpp diff --git a/readme.txt b/readme.txt index b748143bc..52554c513 100644 --- a/readme.txt +++ b/readme.txt @@ -61,9 +61,18 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, ***************************************************************************** *** 0.6.2 *** +- NEW: Added C++ wrapper around the ChibiOS/RT core APIs, now it is possible + to use the OS in a fully object oriented application. The wrapper offers + classes that encapsulate threads, semaphores, mutexes, timers etc. Normal C + APIs are still accessible from C++ code as usual. +- NEW: Added a new LPC2148 demo using the new C++ wrapper, it is a good + example of C++ used for an embedded application. The demo does not use RTTI + nor standard libraries so the resulting code is very compact. - Fixed a minor problem in the ARM7 port, the extctx structure definition was missing one field, the effect was to allocate stacks 4 bytes shorter than the declared size. +- Fixed a compile time error into the chThdSleepUntil() macro. +- Fixes in various headers to make some macros compatible with both C and C++. - More work on the ARM-CM3 port but it is still not complete. *** 0.6.1 *** diff --git a/src/include/events.h b/src/include/events.h index 5bcb70e84..30fa50ccb 100644 --- a/src/include/events.h +++ b/src/include/events.h @@ -61,7 +61,7 @@ typedef struct EventSource { * @note Can be called with interrupts disabled or enabled. */ #define chEvtInit(esp) \ - ((esp)->es_next = (void *)(esp)) + ((esp)->es_next = (EventListener *)(void *)(esp)) /** * Verifies if there is at least one \p EventListener registered on the @@ -70,7 +70,7 @@ typedef struct EventSource { * @note Can be called with interrupts disabled or enabled. */ #define chEvtIsListening(esp) \ - ((esp) != (void *)(esp)->es_next) + ((esp) != (EventListener *)(void *)(esp)->es_next) /** Event Handler callback function.*/ diff --git a/src/lib/ch.cpp b/src/lib/ch.cpp new file mode 100644 index 000000000..ad4be5f4d --- /dev/null +++ b/src/lib/ch.cpp @@ -0,0 +1,266 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 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 . +*/ + +#include + +namespace chibios_rt { + + /*------------------------------------------------------------------------* + * chibios_rt::System * + *------------------------------------------------------------------------*/ + void System::Init(void) { + + chSysInit(); + } + + void Lock(void) { + + chSysLock(); + } + + void Unlock(void) { + + chSysUnlock(); + } + +#ifdef CH_USE_SYSTEMTIME + systime_t System::GetTime(void) { + + return chSysGetTime(); + } +#endif /* CH_USE_SYSTEMTIME */ + +#ifdef CH_USE_VIRTUAL_TIMERS + /*------------------------------------------------------------------------* + * chibios_rt::Timer * + *------------------------------------------------------------------------*/ + void Timer::Set(systime_t time, vtfunc_t vtfunc, void *par) { + + chVTSetI(&timer, time, vtfunc, par); + } + + void Timer::Reset() { + + chVTResetI(&timer); + } + + bool Timer::IsArmed(void) { + + return chVTIsArmedI(&timer); + } +#endif /* CH_USE_VIRTUAL_TIMER */ + + /*------------------------------------------------------------------------* + * chibios_rt::BaseThread * + *------------------------------------------------------------------------*/ + static msg_t thdstart(void *arg) { + BaseThread *btp = (BaseThread *)arg; + + return btp->Main(); + } + + BaseThread::BaseThread(tprio_t prio, tmode_t mode, void *workspace, size_t wsize) { + msg_t thdstart(void *arg); + + thread_ref = chThdCreate(prio, mode, workspace, wsize, thdstart, this); + } + + void BaseThread::Exit(msg_t msg) { + + chThdExit(msg); + } + +#ifdef CH_USE_WAITEXIT + msg_t BaseThread::Wait(void) { + + return chThdWait(thread_ref); + } +#endif /* CH_USE_WAITEXIT */ + + void BaseThread::SetPriority(tprio_t newprio) { + + chThdSetPriority(newprio); + } + +#ifdef CH_USE_RESUME + void BaseThread::Resume(void) { + + chThdResume(thread_ref); + } +#endif /* CH_USE_RESUME */ + +#ifdef CH_USE_TERMINATE + void BaseThread::Terminate(void) { + + chThdTerminate(thread_ref); + } +#endif /* CH_USE_TERMINATE */ + +#ifdef CH_USE_SLEEP + void BaseThread::Sleep(systime_t n) { + + chThdSleep(n); + } + +#ifdef CH_USE_SYSTEMTIME + void BaseThread::SleepUntil(systime_t time) { + + chThdSleepUntil(time); + } +#endif /* CH_USE_SYSTEMTIME */ +#endif /* CH_USE_SLEEP */ + +#ifdef CH_USE_MESSAGES + msg_t BaseThread::SendMessage(msg_t msg) { + + return chMsgSend(thread_ref, msg); + } + + msg_t BaseThread::WaitMessage(void) { + + return chMsgWait(); + } + + msg_t BaseThread::GetMessage(void) { + + return chMsgGet(); + } + + void BaseThread::ReleaseMessage(msg_t msg) { + + chMsgRelease(msg); + } + + bool BaseThread::IsPendingMessage(void) { + + return chMsgIsPendingI(thread_ref); + } +#endif /* CH_USE_MESSAGES */ + + msg_t BaseThread::Main(void) { + + return 0; + } + +#ifdef 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); + } + +#ifdef CH_USE_SEMAPHORES_TIMEOUT + msg_t Semaphore::WaitTimeout(systime_t time) { + + return chSemWaitTimeout(&sem, time); + } +#endif /* CH_USE_SEMAPHORES_TIMEOUT */ + + void Semaphore::Signal(void) { + + chSemSignal(&sem); + } +#endif /* CH_USE_SEMAPHORES */ + +#ifdef 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 UnlockAll(void) { + + chMtxUnlockAll(); + } +#endif /* CH_USE_MUTEXES */ + +#ifdef CH_USE_EVENTS + /*------------------------------------------------------------------------* + * chibios_rt::Event * + *------------------------------------------------------------------------*/ + Event::Event(void) { + + chEvtInit(&event); + } + + void Event::Register(EventListener *elp, eventid_t eid) { + + chEvtRegister(&event,elp, eid); + } + + void Event::Unregister(EventListener *elp) { + + chEvtUnregister(&event, elp); + } + + void Event::Send(void) { + + chEvtSend(&event); + } + + void Event::Clear(eventmask_t mask) { + + chEvtClear(mask); + } + + eventid_t Event::Wait(eventmask_t ewmask, const evhandler_t handlers[]) { + + return chEvtWait(ewmask, handlers); + } + +#ifdef CH_USE_EVENTS_TIMEOUT + eventid_t Event::WaitTimeout(eventmask_t ewmask, + const evhandler_t handlers[], + systime_t time) { + + return chEvtWaitTimeout(ewmask, handlers, time); + } +#endif /* CH_USE_EVENTS_TIMEOUT */ +#endif /* CH_USE_EVENTS */ +} diff --git a/src/lib/ch.hpp b/src/lib/ch.hpp new file mode 100644 index 000000000..9f46b757b --- /dev/null +++ b/src/lib/ch.hpp @@ -0,0 +1,310 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 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 . +*/ + +/** + * @addtogroup CPlusPlusLibrary + * @{ + */ + +#include + +#ifndef _CH_HPP_ +#define _CH_HPP_ + +namespace chibios_rt { + + /** + * Class encapsulating the base system functionalities. + */ + class System { + public: + /** + * ChibiOS/RT initialization. + */ + static void Init(void); + + /** + * Disables interrupts. + * @note On some ports it is faster to invoke chSysLock() directly. + */ + static void Lock(void); + /** + * Enables interrupts. + * @note On some ports it is faster to invoke chSysUnlock() directly. + */ + static void Unlock(void); + +#ifdef CH_USE_SYSTEMTIME + /** + * Returns the system time as system ticks. + */ + static systime_t GetTime(void); +#endif /* CH_USE_SYSTEMTIME */ + }; + +#ifdef CH_USE_VIRTUAL_TIMERS + /** + * Timer class. + */ + class Timer { + public: + ::VirtualTimer timer; + + /** + * Starts the timer. + * @note It must be called with the interrupts disabled. + * @note The associated function is invoked by an interrupt handler. + */ + void Set(systime_t time, vtfunc_t vtfunc, void *par); + + /** + * Resets the timer. + * @note It must be called with the interrupts disabled. + * @note The timer MUST be active when this function is invoked. + */ + void Reset(); + + /** + * Returns true if the timer is armed. + */ + bool IsArmed(void); + }; +#endif /* CH_USE_VIRTUAL_TIMER */ + + /** + * Base class for a ChibiOS/RT thread, the thread body is the virtual + * function /p Main(). + */ + class BaseThread { + protected: + /** + * Thread exit. + */ +// __attribute__((noreturn)) + void Exit(msg_t msg); + + /** + * Change thread priority. + */ + void SetPriority(tprio_t newprio); + +#ifdef CH_USE_MESSAGES + /** + * Waits for a message and returns it. + */ + msg_t WaitMessage(void); + + /** + * Returns an enqueued message or /p NULL. + */ + msg_t GetMessage(void); + + /** + * Releases the next message in queue with a reply. + */ + void ReleaseMessage(msg_t msg); + + /** + * Returns true if there is at least one message in queue. + */ + bool IsPendingMessage(void); +#endif /* CH_USE_MESSAGES */ + + public: + ::Thread *thread_ref; + + /** + * Thread constructor. + */ + BaseThread(tprio_t prio, tmode_t mode, void *workspace, size_t wsize); + +#ifdef CH_USE_WAITEXIT + /** + * Synchronization on Thread exit. + */ + msg_t Wait(void); +#endif /* CH_USE_WAITEXIT */ + +#ifdef CH_USE_RESUME + /** + * Resumes thread. + */ + void Resume(void); +#endif /* CH_USE_RESUME */ + +#ifdef CH_USE_TERMINATE + /** + * Requests thread termination. + */ + void Terminate(void); +#endif /* CH_USE_TERMINATE */ + +#ifdef CH_USE_SLEEP + /** + * Suspends the thread execution for the specified number of system ticks. + */ + void Sleep(systime_t n); + +#ifdef CH_USE_SYSTEMTIME + /** + * Suspends the thread execution until the specified time arrives. + */ + void SleepUntil(systime_t time); +#endif /* CH_USE_SYSTEMTIME */ +#endif /* CH_USE_SLEEP */ + +#ifdef CH_USE_MESSAGES + /** + * Sends a message to the thread and returns the answer. + */ + msg_t SendMessage(msg_t msg); +#endif /* CH_USE_MESSAGES */ + + /** + * Thread body function. + */ +// __attribute__((naked)) + virtual msg_t Main(void); + }; + +#ifdef CH_USE_SEMAPHORES + /** + * Class encapsulating a /p Semaphore. + */ + class Semaphore { + public: + ::Semaphore sem; + + /** + * Semaphore constructor. + */ + Semaphore(cnt_t n); + + /** + * Resets a semaphore to a given positive value. + */ + void Reset(cnt_t n); + + /** + * Wait operation on the semaphore. + */ + msg_t Wait(void); + +#ifdef CH_USE_SEMAPHORES_TIMEOUT + /** + * Wait operation on the semaphore with timeout. + */ + msg_t WaitTimeout(systime_t time); +#endif /* CH_USE_SEMAPHORES_TIMEOUT */ + + /** + * Signal operation on the semaphore. + */ + void Signal(void); + }; +#endif /* CH_USE_SEMAPHORES */ + +#ifdef CH_USE_MUTEXES + /** + * Class encapsulating a /p Mutex. + */ + class Mutex { + public: + ::Mutex mutex; + + /** + * Mutex constructor. + */ + Mutex(void); + + /** + * Tries a lock operation on the mutex. + */ + bool TryLock(void); + + /** + * Lock operation on the mutex. + */ + void Lock(void); + + /** + * Unlock operation on the most recently locked mutex. + */ + static void Unlock(void); + + /** + * Unlocks all the mutexes owned by the invoking thread. + */ + static void UnlockAll(void); + }; +#endif /* CH_USE_MUTEXES */ + +#ifdef CH_USE_EVENTS + /** + * Class encapsulating an /p EventSource. + */ + class Event { + public: + EventSource event; + + /** + * Event constructor. + */ + Event(void); + + /** + * Registers a listener on the event source. + */ + void Register(EventListener *elp, eventid_t eid); + + /** + * Unregisters a listener from the event source. + */ + void Unregister(EventListener *elp); + + /** + * Sends an event. + */ + void Send(void); + + /** + * Clears specified events from the pending events mask. + */ + static void Clear(eventmask_t mask); + + /** + * Waits and dispatchs events. + */ + static eventid_t Wait(eventmask_t ewmask, const evhandler_t handlers[]); + +#ifdef CH_USE_EVENTS_TIMEOUT + /** + * Waits and dispatchs events with timeout specification. + */ + static eventid_t WaitTimeout(eventmask_t ewmask, + const evhandler_t handlers[], + systime_t time); +#endif /* CH_USE_EVENTS_TIMEOUT */ + }; +#endif /* CH_USE_EVENTS */ +} + +#endif /* _CH_HPP_ */ + +/** @} */ -- cgit v1.2.3