import ChibiOS 2.0.8

This commit is contained in:
NIIBE Yutaka
2010-11-30 13:54:43 +09:00
parent 27543cfeca
commit c560d0ad0c
1982 changed files with 5318 additions and 4046 deletions

View File

@@ -0,0 +1,342 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @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::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);
}
/*------------------------------------------------------------------------*
* chibios_rt::BaseThread *
*------------------------------------------------------------------------*/
static msg_t thdstart(void *arg) {
return ((BaseThread *)arg)->Main();
}
BaseThread::BaseThread(void *workspace, size_t wsize, tprio_t prio) {
thread_ref = chThdCreateStatic(workspace, wsize, prio, thdstart, this);
}
void BaseThread::Exit(msg_t msg) {
chThdExit(msg);
}
#if CH_USE_WAITEXIT
msg_t BaseThread::Wait(void) {
return chThdWait(thread_ref);
}
#endif /* CH_USE_WAITEXIT */
void BaseThread::SetPriority(tprio_t newprio) {
chThdSetPriority(newprio);
}
void BaseThread::Resume(void) {
chThdResume(thread_ref);
}
void BaseThread::Terminate(void) {
chThdTerminate(thread_ref);
}
void BaseThread::Sleep(systime_t n) {
chThdSleep(n);
}
void BaseThread::SleepUntil(systime_t time) {
chThdSleepUntil(time);
}
#if CH_USE_MESSAGES
msg_t BaseThread::SendMessage(::Thread* tp, msg_t msg) {
return chMsgSend(tp, msg);
}
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(currp);
}
#endif /* CH_USE_MESSAGES */
msg_t BaseThread::Main(void) {
return 0;
}
#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 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::Register(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::Broadcast(void) {
chEvtBroadcast(&event);
}
eventmask_t Event::Clear(eventmask_t mask) {
return chEvtClear(mask);
}
eventmask_t Event::Pend(eventmask_t mask) {
return chEvtPend(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 */
}
/** @} */

View File

@@ -0,0 +1,625 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file ch.hpp
* @brief C++ wrapper classes and definitions.
* @addtogroup cpp_library
* @{
*/
#include <ch.h>
#ifndef _CH_HPP_
#define _CH_HPP_
namespace chibios_rt {
/**
* @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.
*/
static void Init(void);
/**
* @brief Kernel lock.
*
* @note On some ports it is faster to invoke chSysLock() directly because
* inlining.
*/
static void Lock(void);
/**
* @brief Kernel unlock.
*
* @note On some ports it is faster to invoke chSysUnlock() directly
* because inlining.
*/
static void Unlock(void);
/**
* @brief Returns the system time as system ticks.
*
* @note the system tick time interval is implementation dependent.
*/
static systime_t GetTime(void);
};
/**
* @brief Timer class.
*/
class Timer {
public:
/**
* @brief Embedded @p VirtualTimer structure.
*/
struct ::VirtualTimer timer;
/**
* @brief Starts the timer.
*
* @param time the time in system ticks
* @param vtfunc the timer callback function
* @param par the parameter for the callback function
* @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);
/**
* @brief 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();
/**
* @brief Returns the timer status.
*
* @retval TRUE The timer is armed.
* @retval FALSE The timer already fired its callback.
*/
bool IsArmed(void);
};
/**
* @brief Base class for a ChibiOS/RT thread.
* @details The thread body is the virtual function @p Main().
*/
class BaseThread {
public:
/**
* @brief Pointer to the system thread.
*/
::Thread *thread_ref;
/**
* @brief Thread constructor.
* @details The thread object is initialized and a system thread is
* started.
*
* @param workspace pointer to the workspace area
* @param wsize size of the workspace area
* @param prio thread priority
*/
BaseThread(void *workspace, size_t wsize, tprio_t prio);
/**
* @brief Thread exit.
*
* @param msg the exit message
*/
static void Exit(msg_t msg);
#if CH_USE_WAITEXIT
/**
* @brief Synchronization on Thread exit.
*
* @return the exit message from the thread
*/
msg_t Wait(void);
#endif /* CH_USE_WAITEXIT */
/**
* @brief Resumes the thread.
* @details The thread encapsulated into the object is resumed.
*/
void Resume(void);
/**
* @brief Changes the thread priority.
*
* @param newprio the new priority level
*/
static void SetPriority(tprio_t newprio);
/**
* @brief Requests thread termination.
* @details A termination flag is pended on the thread, it is thread
* responsibility to detect it and exit.
*/
void Terminate(void);
/**
* @brief Suspends the thread execution for the specified number of
* system ticks.
*
* @param n the number of system ticks
*/
static void Sleep(systime_t n);
/**
* @brief Suspends the thread execution until the specified time arrives.
*
* @param time the system time
*/
static void SleepUntil(systime_t time);
#if CH_USE_MESSAGES
/**
* @brief Sends a message to the thread and returns the answer.
*
* @param tp the target thread
* @param msg the sent message
* @return The returned message.
*/
static msg_t SendMessage(::Thread *tp, msg_t msg);
/**
* @brief Sends a message to the thread and returns the answer.
*
* @param msg the sent message
* @return The returned message.
*/
msg_t SendMessage(msg_t msg);
/**
* @brief Waits for a message and returns it.
*
* @return The incoming message.
*/
static msg_t WaitMessage(void);
/**
* @brief Returns an enqueued message or @p NULL.
*
* @return The incoming message.
* @retval NULL No incoming message.
*/
static msg_t GetMessage(void);
/**
* @brief Releases the next message in queue with a reply.
*
* @param msg the answer message
*/
static void ReleaseMessage(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.
*/
static bool IsPendingMessage(void);
#endif /* CH_USE_MESSAGES */
/**
* @brief Thread body function.
*
* @return The exit message.
*/
virtual msg_t Main(void);
};
/**
* @brief Enhanced threads template class.
* @details This class introduces thread names and static working area
* allocation.
*
* @param N the working area size for the thread class
*/
template <int N>
class EnhancedThread : public BaseThread {
protected:
WORKING_AREA(wa, N); // Thread working area.
public:
/**
* @brief The thread name.
*/
const char *name;
/**
* @brief Full constructor.
* @details This constructor allows to set a priority level for the new
* thread.
* @param tname the name to be assigned to the thread
* @param prio the priority to be assigned to the thread
*/
EnhancedThread(const char *tname, tprio_t prio) :
BaseThread(wa, sizeof wa, prio) {
name = tname;
}
/**
* @brief Simplified constructor.
* @details This constructor allows to create a thread by simply
* specifying a name. In is assumed @p NORMALPRIO as initial priority.
*
* @param tname the name to be assigned to the thread
*/
EnhancedThread(const char *tname) :
BaseThread(wa, sizeof wa, NORMALPRIO) {
name = tname;
}
};
#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 n the semaphore counter value, must be greater or equal to zero
*/
Semaphore(cnt_t n);
/**
* @brief Resets a semaphore.
*
* @param n the new semaphore counter value, must be greater or equal to zero
*/
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.
*/
msg_t Wait(void);
/**
* @brief Wait operation on the semaphore with timeout.
*
* @param 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.
*/
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.
*/
void Signal(void);
#if CH_USE_SEMSW
/**
* @brief Atomic signal and wait operations.
*
* @param ssem pointer to a @p Semaphore to be signaled
* @param 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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
static void Unlock(void);
/**
* @brief Unlocks all the mutexes owned by the invoking thread.
* @details This operation is <b>MUCH MORE</b> 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.
*/
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.
*/
CondVar(void);
/**
* @brief Signals the CondVar.
* @details The next thread waiting on the @p CondVar, if any, is awakened.
*/
void Signal(void);
/**
* @brief Broadcasts the CondVar.
* @details All the threads waiting on the @p CondVar, if any, are awakened.
*/
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 chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
*/
msg_t Wait(void);
#if CH_USE_CONDVARS_TIMEOUT
/**
* @brief Waits on the CondVar while releasing the controlling mutex.
*
* @param time the number of ticks before the operation fails
* @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar was not signaled within the specified
* timeout.
*/
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.
*/
Event(void);
/**
* @brief Registers a listener on the event source.
*
* @param elp pointer to the @p EventListener structure
* @param eid numeric identifier assigned to the Event Listener
*/
void Register(EventListener *elp, eventid_t eid);
/**
* @brief Registers an Event Listener on an Event Source.
*
* @param elp pointer to the @p EventListener structure
* @param emask the mask of event flags to be pended to the thread when the
* event source is broadcasted
* @note Multiple Event Listeners can specify the same bits to be pended.
*/
void RegisterMask(EventListener *elp, eventmask_t emask);
/**
* @brief Unregisters a listener.
* @details The specified listeners is no more signaled by the event
* source.
*
* @param elp the listener to be unregistered
*/
void Unregister(EventListener *elp);
/**
* @brief Broadcasts an event.
* @details All the listeners registered on the event source are signaled.
*/
void Broadcast(void);
/**
* @brief Clears specified events from the pending events mask.
*
* @param mask the events to be cleared
* @return The pending events that were cleared.
*/
static eventmask_t Clear(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 mask the events to be pended
* @return The current pending events mask.
*/
static eventmask_t Pend(eventmask_t mask);
/**
* @brief Invokes the event handlers associated with a mask.
*
* @param mask mask of the events to be dispatched
* @param handlers an array of @p evhandler_t. The array must be
* have indexes from zero up the higher registered event
* identifier.
*/
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.
*
* @param 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.
* @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.<br>
* This means that Event Listeners with a lower event identifier have
* an higher priority.
*/
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 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.
*/
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 ewmask mask of the event ids that the function should wait for
* @return The mask of the served and cleared events.
*/
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.
* @param ewmask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param 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.
* @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.<br>
* This means that Event Listeners with a lower event identifier have
* an higher priority.
*/
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 ewmask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param 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.
*/
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 ewmask mask of the event ids that the function should wait for
* @param 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.
*/
static eventmask_t WaitAllTimeout(eventmask_t ewmask, systime_t time);
#endif /* CH_USE_EVENTS_TIMEOUT */
};
#endif /* CH_USE_EVENTS */
}
#endif /* _CH_HPP_ */
/** @} */

View File

@@ -0,0 +1,76 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file evtimer.c
* @brief Events Generator Timer code.
* @addtogroup event_timer
* @{
*/
#include "ch.h"
#include "evtimer.h"
static void tmrcb(void *p) {
EvTimer *etp = p;
chEvtBroadcastI(&etp->et_es);
chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
}
/**
* @brief Starts the timer
* @details If the timer was already running then the function has no effect.
*
* @param etp pointer to an initialized @p EvTimer structure.
*/
void evtStart(EvTimer *etp) {
chSysLock();
if (!chVTIsArmedI(&etp->et_vt))
chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
chSysUnlock();
}
/**
* @brief Stops the timer.
* @details If the timer was already stopped then the function has no effect.
*
* @param etp pointer to an initialized @p EvTimer structure.
*/
void evtStop(EvTimer *etp) {
chSysLock();
if (chVTIsArmedI(&etp->et_vt))
chVTResetI(&etp->et_vt);
chSysUnlock();
}
/** @} */

View File

@@ -0,0 +1,69 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file evtimer.h
* @brief Events Generator Timer structures and macros.
* @addtogroup event_timer
* @{
*/
#ifndef _EVTIMER_H_
#define _EVTIMER_H_
/**
* @brief Event timer structure.
*/
typedef struct {
VirtualTimer et_vt;
EventSource et_es;
systime_t et_interval;
} EvTimer;
#ifdef __cplusplus
extern "C" {
#endif
void evtStart(EvTimer *etp);
void evtStop(EvTimer *etp);
#ifdef __cplusplus
}
#endif
/**
* @brief Initializes an @p EvTimer structure.
*
* @param etp the EvTimer structure to be initialized
* @param time the interval in system ticks
*/
#define evtInit(etp, time) { \
chEvtInit(&(etp)->et_es); \
(etp)->et_vt.vt_func = NULL; \
(etp)->et_interval = (time); \
}
#endif /* _EVTIMER_H_ */
/** @} */

View File

@@ -0,0 +1,102 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file memstreams.c
* @brief Memory streams code.
*
* @addtogroup memory_streams
* @{
*/
#include <string.h>
#include "ch.h"
#include "memstreams.h"
/*
* @brief Write virtual method implementation.
*
* @param[in] ip pointer to a @p MemoryStream object
* @param[in] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred
* @return The number of bytes transferred. The return value can
* be less than the specified number of bytes if the
* stream reaches a physical end of file and cannot be
* extended.
*/
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
MemoryStream *msp = ip;
if (msp->size - msp->eos < n)
n = msp->size - msp->eos;
memcpy(msp->buffer + msp->eos, bp, n);
msp->eos += n;
return n;
}
/*
* @brief Read virtual method implementation.
*
* @param[in] ip pointer to a @p MemoryStream object
* @param[out] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred
* @return The number of bytes transferred. The return value can
* be less than the specified number of bytes if the
* stream reaches the end of the available data.
*/
static size_t reads(void *ip, uint8_t *bp, size_t n) {
MemoryStream *msp = ip;
if (msp->eos - msp->offset < n)
n = msp->eos - msp->offset;
memcpy(bp, msp->buffer + msp->offset, n);
msp->offset += n;
return n;
}
static const struct MemStreamVMT vmt = {writes, reads};
/**
* @brief Memory stream object initialization.
*
* @param[out] msp pointer to the @p MemoryStream object to be initialized
* @param[in] buffer pointer to the memory buffer for the memory stream
* @param[in] size total size of the memory stream buffer
* @param[in] eos initial End Of Stream offset. Normally you need to
* put this to zero for RAM buffers or equal to @p size
* for ROM streams.
*/
void msObjectInit(MemoryStream *msp, uint8_t *buffer, size_t size, size_t eos) {
msp->vmt = &vmt;
msp->buffer = buffer;
msp->size = size;
msp->eos = eos;
msp->offset = 0;
}
/** @} */

View File

@@ -0,0 +1,80 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file memstreams.h
* @brief Memory streams structures and macros.
* @addtogroup memory_streams
* @{
*/
#ifndef _MEMSTREAMS_H_
#define _MEMSTREAMS_H_
/**
* @brief @p RamStream specific data.
*/
#define _memory_stream_data \
_base_sequential_stream_data \
/* Pointer to the stream buffer.*/ \
uint8_t *buffer; \
/* Size of the stream.*/ \
size_t size; \
/* Current end of stream.*/ \
size_t eos; \
/* Current read offset.*/ \
size_t offset;
/**
* @brief @p MemStream virtual methods table.
*/
struct MemStreamVMT {
_base_sequential_stream_methods
};
/**
* @extends BaseSequentialStream
*
* @brief Memory stream object.
*/
typedef struct {
/** @brief Virtual Methods Table.*/
const struct MemStreamVMT *vmt;
_memory_stream_data
} MemoryStream;
#ifdef __cplusplus
extern "C" {
#endif
void msObjectInit(MemoryStream *msp, uint8_t *buffer, size_t size, size_t eos);
#ifdef __cplusplus
}
#endif
#endif /* _MEMSTREAMS_H_ */
/** @} */

View File

@@ -0,0 +1,306 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file shell.c
* @brief Simple CLI shell code.
* @addtogroup SHELL
* @{
*/
#include <stdio.h>
#include <string.h>
#include "ch.h"
#include "hal.h"
#include "shell.h"
#if SHELL_USE_IPRINTF
#define sprintf siprintf
#endif
/**
* @brief Shell termination event source.
*/
EventSource shell_terminated;
#if defined(WIN32)
/*
* MinGW does not seem to have this function...
*/
static char *strtok_r(char *str, const char *delim, char **saveptr) {
char *token;
if (str)
*saveptr = str;
token = *saveptr;
if (!token)
return NULL;
token += strspn(token, delim);
*saveptr = strpbrk(token, delim);
if (*saveptr)
*(*saveptr)++ = '\0';
return *token ? token : NULL;
}
#endif
static void usage(BaseChannel *chp, char *p) {
shellPrint(chp, "Usage: ");
shellPrintLine(chp, p);
}
static void list_commands(BaseChannel *chp, const ShellCommand *scp) {
while (scp->sc_name != NULL) {
shellPrint(chp, scp->sc_name);
shellPrint(chp, " ");
scp++;
}
}
static void cmd_info(BaseChannel *chp, int argc, char *argv[]) {
(void)argv;
if (argc > 0) {
usage(chp, "info");
return;
}
shellPrint(chp, "Kernel version: ");
shellPrintLine(chp, CH_KERNEL_VERSION);
#ifdef __GNUC__
shellPrint(chp, "GCC Version: ");
shellPrintLine(chp, __VERSION__);
#endif
shellPrint(chp, "Architecture: ");
shellPrintLine(chp, CH_ARCHITECTURE_NAME);
#ifdef CH_CORE_VARIANT_NAME
shellPrint(chp, "Core Variant: ");
shellPrintLine(chp, CH_CORE_VARIANT_NAME);
#endif
#ifdef PLATFORM_NAME
shellPrint(chp, "Platform: ");
shellPrintLine(chp, PLATFORM_NAME);
#endif
#ifdef BOARD_NAME
shellPrint(chp, "Board: ");
shellPrintLine(chp, BOARD_NAME);
#endif
}
static void cmd_systime(BaseChannel *chp, int argc, char *argv[]) {
char buf[12];
(void)argv;
if (argc > 0) {
usage(chp, "systime");
return;
}
sprintf(buf, "%lu", (unsigned long)chTimeNow());
shellPrintLine(chp, buf);
}
/**
* @brief Array of the default commands.
*/
static ShellCommand local_commands[] = {
{"info", cmd_info},
{"systime", cmd_systime},
{NULL, NULL}
};
static bool_t cmdexec(const ShellCommand *scp, BaseChannel *chp,
char *name, int argc, char *argv[]) {
while (scp->sc_name != NULL) {
if (strcasecmp(scp->sc_name, name) == 0) {
scp->sc_function(chp, argc, argv);
return FALSE;
}
scp++;
}
return TRUE;
}
/**
* @brief Shell thread function.
*
* @param[in] p pointer to a @p BaseChannel object
* @return Termination reason.
* @retval RDY_OK terminated by command.
* @retval RDY_RESET terminated by reset condition on the I/O channel.
*/
static msg_t shell_thread(void *p) {
int n;
msg_t msg = RDY_OK;
BaseChannel *chp = ((ShellConfig *)p)->sc_channel;
const ShellCommand *scp = ((ShellConfig *)p)->sc_commands;
char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH];
char *args[SHELL_MAX_ARGUMENTS + 1];
shellPrintLine(chp, "");
shellPrintLine(chp, "ChibiOS/RT Shell");
while (TRUE) {
shellPrint(chp, "ch> ");
if (shellGetLine(chp, line, sizeof(line))) {
shellPrint(chp, "\nlogout");
break;
}
lp = strtok_r(line, " \009", &tokp);
cmd = lp;
n = 0;
while ((lp = strtok_r(NULL, " \009", &tokp)) != NULL) {
if (n >= SHELL_MAX_ARGUMENTS) {
shellPrintLine(chp, "too many arguments");
cmd = NULL;
break;
}
args[n++] = lp;
}
args[n] = NULL;
if (cmd != NULL) {
if (strcasecmp(cmd, "exit") == 0) {
if (n > 0)
usage(chp, "exit");
break;
}
else if (strcasecmp(cmd, "help") == 0) {
if (n > 0)
usage(chp, "help");
shellPrint(chp, "Commands: help exit ");
list_commands(chp, local_commands);
if (scp != NULL)
list_commands(chp, scp);
shellPrintLine(chp, "");
}
else if (cmdexec(local_commands, chp, cmd, n, args) &&
((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) {
shellPrint(chp, cmd);
shellPrintLine(chp, " ?");
}
}
}
chSysLock();
chEvtBroadcastI(&shell_terminated);
return msg;
}
/**
* @brief Shell manager initialization.
*/
void shellInit(void) {
chEvtInit(&shell_terminated);
}
/**
* @brief Spawns a new shell.
*
* @param[in] scp pointer to a @p ShellConfig object
* @param[in] size size of the shell working area to be allocated
* @param[in] prio the priority level for the new shell
*
* @return A pointer to the shell thread.
* @retval NULL thread creation failed because memory allocation.
*/
Thread *shellCreate(const ShellConfig *scp, size_t size, tprio_t prio) {
return chThdCreateFromHeap(NULL, size, prio, shell_thread, (void *)scp);
}
/**
* @brief Prints a string.
*
* @param[in] chp pointer to a @p BaseChannel object
* @param[in] msg pointer to the string
*/
void shellPrint(BaseChannel *chp, const char *msg) {
while (*msg)
chIOPut(chp, *msg++);
}
/**
* @brief Prints a string with a final newline.
*
* @param[in] chp pointer to a @p BaseChannel object
* @param[in] msg pointer to the string
*/
void shellPrintLine(BaseChannel *chp, const char *msg) {
shellPrint(chp, msg);
shellPrint(chp, "\r\n");
}
/**
* @brief Reads a whole line from the input channel.
*
* @param[in] chp pointer to a @p BaseChannel object
* @param[in] line pointer to the line buffer
* @param[in] size buffer maximum length
*
* @return The operation status.
* @retval TRUE the channel was reset or CTRL-D pressed.
* @retval FALSE operation successful.
*/
bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size) {
char *p = line;
while (TRUE) {
short c = (short)chIOGet(chp);
if (c < 0)
return TRUE;
if (c == 4) {
shellPrintLine(chp, "^D");
return TRUE;
}
if (c == 8) {
if (p != line) {
chIOPut(chp, (uint8_t)c);
chIOPut(chp, 0x20);
chIOPut(chp, (uint8_t)c);
p--;
}
continue;
}
if (c == '\r') {
shellPrintLine(chp, "");
*p = 0;
return FALSE;
}
if (c < 0x20)
continue;
if (p < line + size - 1) {
chIOPut(chp, (uint8_t)c);
*p++ = (char)c;
}
}
}
/** @} */

View File

@@ -0,0 +1,97 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file shell.h
* @brief Simple CLI shell header.
* @addtogroup SHELL
* @{
*/
#ifndef _SHELL_H_
#define _SHELL_H_
/**
* @brief Shell maximum input line length.
*/
#if !defined(SHELL_MAX_LINE_LENGTH) || defined(__DOXYGEN__)
#define SHELL_MAX_LINE_LENGTH 64
#endif
/**
* @brief Shell maximum arguments per command.
*/
#if !defined(SHELL_MAX_ARGUMENTS) || defined(__DOXYGEN__)
#define SHELL_MAX_ARGUMENTS 4
#endif
/**
* @brief Enforces the use of iprintf() on newlib.
*/
#if !defined(SHELL_USE_IPRINTF) || defined(__DOXYGEN__)
#define SHELL_USE_IPRINTF TRUE
#endif
/**
* @brief Command handler function type.
*/
typedef void (*shellcmd_t)(BaseChannel *chp, int argc, char *argv[]);
/**
* @brief Custom command entry type.
*/
typedef struct {
const char *sc_name; /**< @brief Command name. */
shellcmd_t sc_function; /**< @brief Command function. */
} ShellCommand;
/**
* @brief Shell descriptor type.
*/
typedef struct {
BaseChannel *sc_channel; /**< @brief I/O channel associated
to the shell. */
const ShellCommand *sc_commands; /**< @brief Shell extra commands
table. */
} ShellConfig;
extern EventSource shell_terminated;
#ifdef __cplusplus
extern "C" {
#endif
void shellInit(void);
Thread *shellCreate(const ShellConfig *scp, size_t size, tprio_t prio);
void shellPrint(BaseChannel *chp, const char *msg);
void shellPrintLine(BaseChannel *chp, const char *msg);
bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size);
#ifdef __cplusplus
}
#endif
#endif /* _SHELL_H_ */
/** @} */

View File

@@ -0,0 +1,177 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/*
* **** This file incorporates work covered by the following copyright and ****
* **** permission notice: ****
*
* Copyright (c) 2009 by Michael Fischer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************
* History:
*
* 28.03.09 mifi First Version, based on the original syscall.c from
* newlib version 1.17.0
* 17.08.09 gdisirio Modified the file for use under ChibiOS/RT
* 15.11.09 gdisirio Added read and write handling
****************************************************************************/
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "ch.h"
#if defined(STDOUT_SD) || defined(STDIN_SD)
#include "hal.h"
#endif
/***************************************************************************/
int _read_r(struct _reent *r, int file, char * ptr, int len)
{
(void)r;
#if defined(STDIN_SD)
if (!len || (file != 0)) {
__errno_r(r) = EINVAL;
return -1;
}
len = sdRead(&STDIN_SD, (uint8_t *)ptr, (size_t)len);
return len;
#else
(void)file;
(void)ptr;
(void)len;
__errno_r(r) = EINVAL;
return -1;
#endif
}
/***************************************************************************/
int _lseek_r(struct _reent *r, int file, int ptr, int dir)
{
(void)r;
(void)file;
(void)ptr;
(void)dir;
return 0;
}
/***************************************************************************/
int _write_r(struct _reent *r, int file, char * ptr, int len)
{
(void)r;
(void)file;
(void)ptr;
#if defined(STDOUT_SD)
if (file != 1) {
__errno_r(r) = EINVAL;
return -1;
}
sdWrite(&STDOUT_SD, (uint8_t *)ptr, (size_t)len);
#endif
return len;
}
/***************************************************************************/
int _close_r(struct _reent *r, int file)
{
(void)r;
(void)file;
return 0;
}
/***************************************************************************/
caddr_t _sbrk_r(struct _reent *r, int incr)
{
void *p;
chDbgCheck(incr > 0, "_sbrk_r");
(void)r;
p = chCoreAlloc((size_t)incr);
if (p == NULL) {
__errno_r(r) = ENOMEM;
return (caddr_t)-1;
}
return (caddr_t)p;
}
/***************************************************************************/
int _fstat_r(struct _reent *r, int file, struct stat * st)
{
(void)r;
(void)file;
memset(st, 0, sizeof(*st));
st->st_mode = S_IFCHR;
return 0;
}
/***************************************************************************/
int _isatty_r(struct _reent *r, int fd)
{
(void)r;
(void)fd;
return 1;
}
/*** EOF ***/

View File

@@ -0,0 +1,75 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup various Various
* @brief Utilities Library.
* @details This is a collection of useful library code that is not part of
* the base kernel services.
* <h2>Notes</h2>
* The library code does not follow the same naming convention of the
* system APIs in order to make very clear that it is not "core" code.<br>
* The main difference is that library code is not formally tested in the
* test suite but through usage in the various demo applications.
*/
/**
* @defgroup cpp_library C++ Wrapper
* @brief C++ wrapper module.
* @details This module allows to use the ChibiOS/RT functionalities
* from C++ as classes and objects rather the traditional "C" APIs.
*
* @ingroup various
*/
/**
* @defgroup memory_streams Memory Streams
* @brief Memory Streams.
* @details This module allows to use a memory area (RAM or ROM) using a
* @ref data_streams interface.
*
* @ingroup various
*/
/**
* @defgroup event_timer Periodic Events Timer
* @brief Periodic Event Timer.
* @details This timer generates an event at regular intervals. The
* listening threads can use the event to perform time related activities.
* Multiple threads can listen to the same timer.
*
* @ingroup various
*/
/**
* @defgroup SHELL Command Shell
* @brief Small extendible command line shell.
* @details This module implements a generic extendible command line interface.
* The CLI just requires an I/O channel (@p BaseChannel), more commands can be
* added to the shell using the configuration structure.
*
* @ingroup various
*/