/* 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 */ } /** @} */