aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-03-26 16:25:26 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-03-26 16:25:26 +0000
commit810cd7514051b11eaaf93e3ffcba0c7195a6b89b (patch)
tree556bd2dfed0b9c1be4c6cba1770c884e6f08a4da
parentdfe8a03d8ad420ef00a18888c4152fc385ce69be (diff)
downloadChibiOS-810cd7514051b11eaaf93e3ffcba0c7195a6b89b.tar.gz
ChibiOS-810cd7514051b11eaaf93e3ffcba0c7195a6b89b.tar.bz2
ChibiOS-810cd7514051b11eaaf93e3ffcba0c7195a6b89b.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@247 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--readme.txt9
-rw-r--r--src/include/events.h4
-rw-r--r--src/lib/ch.cpp266
-rw-r--r--src/lib/ch.hpp310
4 files changed, 587 insertions, 2 deletions
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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <ch.hpp>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @addtogroup CPlusPlusLibrary
+ * @{
+ */
+
+#include <ch.h>
+
+#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_ */
+
+/** @} */