Reformatted doxygen tags into the kernel sources to make them more readable.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1567 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2010-02-06 10:55:53 +00:00
parent 6f7c30adff
commit f17db1931e
21 changed files with 817 additions and 828 deletions

View File

@ -19,7 +19,10 @@
/** /**
* @file ch.h * @file ch.h
* @brief ChibiOS/RT main include file, it includes everything else. * @brief ChibiOS/RT main include file.
* @details This header includes all the required kernel headers so it is the
* only kernel header you usually want to include in your application.
*
* @addtogroup kernel_info * @addtogroup kernel_info
* @{ * @{
*/ */
@ -28,27 +31,27 @@
#define _CH_H_ #define _CH_H_
/** /**
* ChibiOS/RT identification macro. * @brief ChibiOS/RT identification macro.
*/ */
#define _CHIBIOS_RT_ #define _CHIBIOS_RT_
/** /**
* Kernel version string. * @brief Kernel version string.
*/ */
#define CH_KERNEL_VERSION "1.5.1unstable" #define CH_KERNEL_VERSION "1.5.1unstable"
/** /**
* Kernel version major number. * @brief Kernel version major number.
*/ */
#define CH_KERNEL_MAJOR 1 #define CH_KERNEL_MAJOR 1
/** /**
* Kernel version minor number. * @brief Kernel version minor number.
*/ */
#define CH_KERNEL_MINOR 5 #define CH_KERNEL_MINOR 5
/** /**
* Kernel version patch number. * @brief Kernel version patch number.
*/ */
#define CH_KERNEL_PATCH 1 #define CH_KERNEL_PATCH 1

View File

@ -20,6 +20,7 @@
/** /**
* @file channels.h * @file channels.h
* @brief I/O channels. * @brief I/O channels.
*
* @addtogroup io_channels * @addtogroup io_channels
* @{ * @{
*/ */

View File

@ -109,7 +109,9 @@ typedef void (*evhandler_t)(eventid_t);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask); void chEvtRegisterMask(EventSource *esp,
EventListener *elp,
eventmask_t mask);
void chEvtUnregister(EventSource *esp, EventListener *elp); void chEvtUnregister(EventSource *esp, EventListener *elp);
eventmask_t chEvtClear(eventmask_t mask); eventmask_t chEvtClear(eventmask_t mask);
eventmask_t chEvtPend(eventmask_t mask); eventmask_t chEvtPend(eventmask_t mask);
@ -119,23 +121,23 @@ extern "C" {
void chEvtBroadcastI(EventSource *esp); void chEvtBroadcastI(EventSource *esp);
void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask); void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask);
#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT #if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
eventmask_t chEvtWaitOne(eventmask_t ewmask); eventmask_t chEvtWaitOne(eventmask_t mask);
eventmask_t chEvtWaitAny(eventmask_t ewmask); eventmask_t chEvtWaitAny(eventmask_t mask);
eventmask_t chEvtWaitAll(eventmask_t ewmask); eventmask_t chEvtWaitAll(eventmask_t mask);
#endif #endif
#if CH_USE_EVENTS_TIMEOUT #if CH_USE_EVENTS_TIMEOUT
eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time); eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time);
eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time); eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time);
eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time); eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT #if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT
#define chEvtWaitOne(ewmask) chEvtWaitOneTimeout(ewmask, TIME_INFINITE) #define chEvtWaitOne(ewmask) chEvtWaitOneTimeout(emask, TIME_INFINITE)
#define chEvtWaitAny(ewmask) chEvtWaitAnyTimeout(ewmask, TIME_INFINITE) #define chEvtWaitAny(ewmask) chEvtWaitAnyTimeout(emask, TIME_INFINITE)
#define chEvtWaitAll(ewmask) chEvtWaitAllTimeout(ewmask, TIME_INFINITE) #define chEvtWaitAll(ewmask) chEvtWaitAllTimeout(emask, TIME_INFINITE)
#endif #endif
#endif /* CH_USE_EVENTS */ #endif /* CH_USE_EVENTS */

View File

@ -20,6 +20,7 @@
/** /**
* @file heap.h * @file heap.h
* @brief Heaps macros and structures. * @brief Heaps macros and structures.
*
* @addtogroup heaps * @addtogroup heaps
* @{ * @{
*/ */

View File

@ -24,6 +24,7 @@
/** /**
* @file chcond.c * @file chcond.c
* @brief Condition Variables code. * @brief Condition Variables code.
*
* @addtogroup condvars Condition Variables * @addtogroup condvars Condition Variables
* @{ * @{
*/ */
@ -34,11 +35,11 @@
/** /**
* @brief Initializes s @p CondVar structure. * @brief Initializes s @p CondVar structure.
* @note This function can be invoked from within an interrupt handler even
* if it is not an I-Class API because it does not touch any critical
* kernel data structure.
* *
* @param[out] cp pointer to a @p CondVar structure * @param[out] cp pointer to a @p CondVar structure
* @note This function can be invoked from within an interrupt handler even if
* it is not an I-Class API because it does not touch any critical kernel
* data structure.
*/ */
void chCondInit(CondVar *cp) { void chCondInit(CondVar *cp) {
@ -57,7 +58,7 @@ void chCondSignal(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondSignal"); chDbgCheck(cp != NULL, "chCondSignal");
chSysLock(); chSysLock();
if (notempty(&cp->c_queue)) /* any thread ? */ if (notempty(&cp->c_queue))
chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK);
chSysUnlock(); chSysUnlock();
} }
@ -71,7 +72,7 @@ void chCondSignalI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondSignalI"); chDbgCheck(cp != NULL, "chCondSignalI");
if (notempty(&cp->c_queue)) /* any thread ? */ if (notempty(&cp->c_queue))
chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK; chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK;
} }
@ -98,8 +99,8 @@ void chCondBroadcastI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondBroadcastI"); chDbgCheck(cp != NULL, "chCondBroadcastI");
/* Empties the condition variable queue and inserts all the Threads into the /* Empties the condition variable queue and inserts all the Threads into the
* ready list in FIFO order. The wakeup message is set to @p RDY_RESET in ready list in FIFO order. The wakeup message is set to @p RDY_RESET in
* order to make a chCondBroadcast() detectable from a chCondSignal().*/ order to make a chCondBroadcast() detectable from a chCondSignal().*/
while (cp->c_queue.p_next != (void *)&cp->c_queue) while (cp->c_queue.p_next != (void *)&cp->c_queue)
chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET; chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET;
} }
@ -108,13 +109,13 @@ void chCondBroadcastI(CondVar *cp) {
* @brief Waits on the condition variable releasing the mutex lock. * @brief Waits on the condition variable releasing the mutex lock.
* @details Releases the mutex, waits on the condition variable, and finally * @details Releases the mutex, waits on the condition variable, and finally
* acquires the mutex again. This is done atomically. * acquires the mutex again. This is done atomically.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWait().
* *
* @param[in] cp pointer to the @p CondVar structure * @param[in] cp pointer to the @p CondVar structure
* @return The wakep mode. * @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @note The thread MUST already have locked the mutex when calling
* @p chCondWait().
*/ */
msg_t chCondWait(CondVar *cp) { msg_t chCondWait(CondVar *cp) {
msg_t msg; msg_t msg;
@ -129,13 +130,13 @@ msg_t chCondWait(CondVar *cp) {
* @brief Waits on the condition variable releasing the mutex lock. * @brief Waits on the condition variable releasing the mutex lock.
* @details Releases the mutex, waits on the condition variable, and finally * @details Releases the mutex, waits on the condition variable, and finally
* acquires the mutex again. This is done atomically. * acquires the mutex again. This is done atomically.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitS().
* *
* @param[in] cp pointer to the @p CondVar structure * @param[in] cp pointer to the @p CondVar structure
* @return The wakep mode. * @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitS().
*/ */
msg_t chCondWaitS(CondVar *cp) { msg_t chCondWaitS(CondVar *cp) {
Thread *ctp = currp; Thread *ctp = currp;
@ -161,6 +162,8 @@ msg_t chCondWaitS(CondVar *cp) {
* @brief Waits on the condition variable releasing the mutex lock. * @brief Waits on the condition variable releasing the mutex lock.
* @details Releases the mutex, waits on the condition variable, and finally * @details Releases the mutex, waits on the condition variable, and finally
* acquires the mutex again. This is done atomically. * acquires the mutex again. This is done atomically.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitTimeout().
* *
* @param[in] cp pointer to the @p CondVar structure * @param[in] cp pointer to the @p CondVar structure
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
@ -169,12 +172,10 @@ msg_t chCondWaitS(CondVar *cp) {
* as timeout specification because it would make no sense * as timeout specification because it would make no sense
* in this function. * in this function.
* @return The wakep mode. * @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar was not signaled within the specified * @retval RDY_TIMEOUT if the condvar was not signaled @p within the specified
* timeout. * timeout.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitTimeout().
*/ */
msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
msg_t msg; msg_t msg;
@ -189,6 +190,8 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
* @brief Waits on the condition variable releasing the mutex lock. * @brief Waits on the condition variable releasing the mutex lock.
* @details Releases the mutex, waits on the condition variable, and finally * @details Releases the mutex, waits on the condition variable, and finally
* acquires the mutex again. This is done atomically. * acquires the mutex again. This is done atomically.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitTimeoutS().
* *
* @param[in] cp pointer to the @p CondVar structure * @param[in] cp pointer to the @p CondVar structure
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
@ -197,12 +200,10 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
* as timeout specification because it would make no sense * as timeout specification because it would make no sense
* in this function. * in this function.
* @return The wakep mode. * @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar was not signaled within the specified * @retval RDY_TIMEOUT if the condvar was not signaled within the specified
* timeout. * timeout.
* @note The thread MUST already have locked the mutex when calling
* @p chCondWaitTimeoutS().
*/ */
msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
Thread *ctp = currp; Thread *ctp = currp;

View File

@ -20,6 +20,7 @@
/** /**
* @file chdebug.c * @file chdebug.c
* @brief ChibiOS/RT Debug code. * @brief ChibiOS/RT Debug code.
*
* @addtogroup debug * @addtogroup debug
* @{ * @{
*/ */

View File

@ -20,6 +20,7 @@
/** /**
* @file chevents.c * @file chevents.c
* @brief Events code. * @brief Events code.
*
* @addtogroup events * @addtogroup events
* @{ * @{
*/ */
@ -28,14 +29,14 @@
#if CH_USE_EVENTS #if CH_USE_EVENTS
/** /**
* @brief Registers an Event Listener on an Event Source. * @brief Registers an Event Listener on an Event Source.
* @note Multiple Event Listeners can specify the same bits to be pended.
* *
* @param[in] esp pointer to the @p EventSource structure * @param[in] esp pointer to the @p EventSource structure
* @param[in] elp pointer to the @p EventListener structure * @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 * @param[in] mask the mask of event flags to be pended to the thread when
* event source is broadcasted * the event source is broadcasted
* @note Multiple Event Listeners can specify the same bits to be pended.
*/ */
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) { void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) {
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask"); chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
@ -43,20 +44,20 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask)
elp->el_next = esp->es_next; elp->el_next = esp->es_next;
esp->es_next = elp; esp->es_next = elp;
elp->el_listener = currp; elp->el_listener = currp;
elp->el_mask = emask; elp->el_mask = mask;
chSysUnlock(); chSysUnlock();
} }
/** /**
* @brief Unregisters an Event Listener from its Event Source. * @brief Unregisters an Event Listener from its Event Source.
* @note If the event listener is not registered on the specified event
* source then the function does nothing.
* @note For optimal performance it is better to perform the unregister
* operations in inverse order of the register operations (elements
* are found on top of the list).
* *
* @param[in] esp pointer to the @p EventSource structure * @param[in] esp pointer to the @p EventSource structure
* @param[in] elp pointer to the @p EventListener structure * @param[in] elp pointer to the @p EventListener structure
* @note If the event listener is not registered on the specified event source
* then the function does nothing.
* @note For optimal performance it is better to perform the unregister
* operations in inverse order of the register operations (elements are
* found on top of the list).
*/ */
void chEvtUnregister(EventSource *esp, EventListener *elp) { void chEvtUnregister(EventSource *esp, EventListener *elp) {
EventListener *p; EventListener *p;
@ -205,27 +206,27 @@ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) {
/** /**
* @brief Waits for exactly one of the specified events. * @brief Waits for exactly one of the specified events.
* @details The function waits for one event among those specified in * @details The function waits for one event among those specified in
* @p ewmask to become pending then the event is cleared and returned. * @p mask to become pending then the event is 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 lowest id served and cleared event.
* @note One and only one event is served in the function, the one with the * @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 * lowest event id. The function is meant to be invoked into a loop in
* order to serve all the pending events.<br> * order to serve all the pending events.<br>
* This means that Event Listeners with a lower event identifier have * This means that Event Listeners with a lower event identifier have
* an higher priority. * an higher priority.
*
* @param[in] mask 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.
*/ */
eventmask_t chEvtWaitOne(eventmask_t ewmask) { eventmask_t chEvtWaitOne(eventmask_t mask) {
Thread *ctp = currp; Thread *ctp = currp;
eventmask_t m; eventmask_t m;
chSysLock(); chSysLock();
if ((m = (ctp->p_epending & ewmask)) == 0) { if ((m = (ctp->p_epending & mask)) == 0) {
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
chSchGoSleepS(THD_STATE_WTOREVT); chSchGoSleepS(THD_STATE_WTOREVT);
m = ctp->p_epending & ewmask; m = ctp->p_epending & mask;
} }
m &= -m; m &= -m;
ctp->p_epending &= ~m; ctp->p_epending &= ~m;
@ -237,22 +238,22 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) {
/** /**
* @brief Waits for any of the specified events. * @brief Waits for any of the specified events.
* @details The function waits for any event among those specified in * @details The function waits for any event among those specified in
* @p ewmask to become pending then the events are cleared and returned. * @p mask to become pending then the events are cleared and returned.
* *
* @param[in] ewmask mask of the events that the function should wait for, * @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events * @p ALL_EVENTS enables all the events
* @return The mask of the served and cleared events. * @return The mask of the served and cleared events.
*/ */
eventmask_t chEvtWaitAny(eventmask_t ewmask) { eventmask_t chEvtWaitAny(eventmask_t mask) {
Thread *ctp = currp; Thread *ctp = currp;
eventmask_t m; eventmask_t m;
chSysLock(); chSysLock();
if ((m = (ctp->p_epending & ewmask)) == 0) { if ((m = (ctp->p_epending & mask)) == 0) {
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
chSchGoSleepS(THD_STATE_WTOREVT); chSchGoSleepS(THD_STATE_WTOREVT);
m = ctp->p_epending & ewmask; m = ctp->p_epending & mask;
} }
ctp->p_epending &= ~m; ctp->p_epending &= ~m;
@ -262,25 +263,25 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) {
/** /**
* @brief Waits for all the specified events. * @brief Waits for all the specified events.
* @details The function waits for all the events specified in @p ewmask to * @details The function waits for all the events specified in @p mask to
* become pending then the events are cleared and returned. * 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] mask mask of the event ids that the function should wait for
* @return The mask of the served and cleared events. * @return The mask of the served and cleared events.
*/ */
eventmask_t chEvtWaitAll(eventmask_t ewmask) { eventmask_t chEvtWaitAll(eventmask_t mask) {
Thread *ctp = currp; Thread *ctp = currp;
chSysLock(); chSysLock();
if ((ctp->p_epending & ewmask) != ewmask) { if ((ctp->p_epending & mask) != mask) {
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
chSchGoSleepS(THD_STATE_WTANDEVT); chSchGoSleepS(THD_STATE_WTANDEVT);
} }
ctp->p_epending &= ~ewmask; ctp->p_epending &= ~mask;
chSysUnlock(); chSysUnlock();
return ewmask; return mask;
} }
#endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */ #endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */
@ -288,9 +289,14 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) {
/** /**
* @brief Waits for exactly one of the specified events. * @brief Waits for exactly one of the specified events.
* @details The function waits for one event among those specified in * @details The function waits for one event among those specified in
* @p ewmask to become pending then the event is cleared and returned. * @p mask to become pending then the event is cleared and 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.<br>
* 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, * @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events * @p ALL_EVENTS enables all the events
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed: * the following special values are allowed:
@ -299,25 +305,20 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) {
* . * .
* @return The mask of the lowest id served and cleared event. * @return The mask of the lowest id served and cleared event.
* @retval 0 if the specified timeout expired. * @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.
*/ */
eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp; Thread *ctp = currp;
eventmask_t m; eventmask_t m;
chSysLock(); chSysLock();
if ((m = (ctp->p_epending & ewmask)) == 0) { if ((m = (ctp->p_epending & mask)) == 0) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
m = ctp->p_epending & ewmask; m = ctp->p_epending & mask;
} }
m &= -m; m &= -m;
ctp->p_epending &= ~m; ctp->p_epending &= ~m;
@ -329,10 +330,10 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) {
/** /**
* @brief Waits for any of the specified events. * @brief Waits for any of the specified events.
* @details The function waits for any event among those specified in * @details The function waits for any event among those specified in
* @p ewmask to become pending then the events are cleared and * @p mask to become pending then the events are cleared and
* returned. * returned.
* *
* @param[in] ewmask mask of the events that the function should wait for, * @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events * @p ALL_EVENTS enables all the events
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed: * the following special values are allowed:
@ -342,19 +343,19 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) {
* @return The mask of the served and cleared events. * @return The mask of the served and cleared events.
* @retval 0 if the specified timeout expired. * @retval 0 if the specified timeout expired.
*/ */
eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp; Thread *ctp = currp;
eventmask_t m; eventmask_t m;
chSysLock(); chSysLock();
if ((m = (ctp->p_epending & ewmask)) == 0) { if ((m = (ctp->p_epending & mask)) == 0) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
m = ctp->p_epending & ewmask; m = ctp->p_epending & mask;
} }
ctp->p_epending &= ~m; ctp->p_epending &= ~m;
@ -364,10 +365,10 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) {
/** /**
* @brief Waits for all the specified events. * @brief Waits for all the specified events.
* @details The function waits for all the events specified in @p ewmask to * @details The function waits for all the events specified in @p mask to
* become pending then the events are cleared and returned. * 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] mask mask of the event ids that the function should wait for
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed: * the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_IMMEDIATE immediate timeout.
@ -376,22 +377,22 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) {
* @return The mask of the served and cleared events. * @return The mask of the served and cleared events.
* @retval 0 if the specified timeout expired. * @retval 0 if the specified timeout expired.
*/ */
eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp; Thread *ctp = currp;
chSysLock(); chSysLock();
if ((ctp->p_epending & ewmask) != ewmask) { if ((ctp->p_epending & mask) != mask) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
ctp->p_u.ewmask = ewmask; ctp->p_u.ewmask = mask;
if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
} }
ctp->p_epending &= ~ewmask; ctp->p_epending &= ~mask;
chSysUnlock(); chSysUnlock();
return ewmask; return mask;
} }
#endif /* CH_USE_EVENTS_TIMEOUT */ #endif /* CH_USE_EVENTS_TIMEOUT */

View File

@ -20,6 +20,7 @@
/** /**
* @file chheap.c * @file chheap.c
* @brief Heaps code. * @brief Heaps code.
*
* @addtogroup heaps * @addtogroup heaps
* @{ * @{
*/ */
@ -48,7 +49,6 @@ static MemoryHeap default_heap;
/** /**
* @brief Initializes the default heap. * @brief Initializes the default heap.
*
* @note Internal use only. * @note Internal use only.
*/ */
void heap_init(void) { void heap_init(void) {
@ -64,13 +64,12 @@ void heap_init(void) {
/** /**
* @brief Initializes a memory heap from a static memory area. * @brief Initializes a memory heap from a static memory area.
*
* @param[out] heapp pointer to a memory heap descriptor to be initialized
* @param[in] buf heap buffer base
* @param[in] size heap size
*
* @note Both the heap buffer base and the heap size must be aligned to * @note Both the heap buffer base and the heap size must be aligned to
* the @p align_t type size. * the @p align_t type size.
*
* @param[out] heapp pointer to the memory heap descriptor to be initialized
* @param[in] buf heap buffer base
* @param[in] size heap size
*/ */
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
struct heap_header *hp; struct heap_header *hp;
@ -95,8 +94,8 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
* @details The allocated block is guaranteed to be properly aligned for a * @details The allocated block is guaranteed to be properly aligned for a
* pointer data type (@p align_t). * pointer data type (@p align_t).
* *
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to access * @param[in] heapp pointer to a heap descriptor or @p NULL in order to
* the default heap. * access the default heap.
* @param[in] size the size of the block to be allocated. Note that the * @param[in] size the size of the block to be allocated. Note that the
* allocated block may be a bit bigger than the requested * allocated block may be a bit bigger than the requested
* size for alignment and fragmentation reasons. * size for alignment and fragmentation reasons.
@ -117,17 +116,13 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
hp = qp->h_u.next; hp = qp->h_u.next;
if (hp->h_size >= size) { if (hp->h_size >= size) {
if (hp->h_size < size + sizeof(struct heap_header)) { if (hp->h_size < size + sizeof(struct heap_header)) {
/* /* Gets the whole block even if it is slightly bigger than the
* Gets the whole block even if it is slightly bigger than the requested size because the fragment would be too small to be
* requested size because the fragment would be too small to be useful.*/
* useful.
*/
qp->h_u.next = hp->h_u.next; qp->h_u.next = hp->h_u.next;
} }
else { else {
/* /* Block bigger enough, must split it.*/
* Block bigger enough, must split it.
*/
fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size);
fp->h_u.next = hp->h_u.next; fp->h_u.next = hp->h_u.next;
fp->h_size = hp->h_size - sizeof(struct heap_header) - size; fp->h_size = hp->h_size - sizeof(struct heap_header) - size;
@ -144,9 +139,8 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
H_UNLOCK(heapp); H_UNLOCK(heapp);
/* /* More memory is required, tries to get it from the associated provider
* More memory is required, tries to get it from the associated provider. else fails.*/
*/
if (heapp->h_provider) { if (heapp->h_provider) {
hp = heapp->h_provider(size + sizeof(struct heap_header)); hp = heapp->h_provider(size + sizeof(struct heap_header));
if (hp != NULL) { if (hp != NULL) {
@ -166,7 +160,7 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
/** /**
* @brief Frees a previously allocated memory block. * @brief Frees a previously allocated memory block.
* *
* @param[in] p the memory block pointer * @param[in] p pointer to the memory block to be freed
*/ */
void chHeapFree(void *p) { void chHeapFree(void *p) {
struct heap_header *qp, *hp; struct heap_header *qp, *hp;
@ -186,25 +180,17 @@ void chHeapFree(void *p) {
if (((qp == &heapp->h_free) || (hp > qp)) && if (((qp == &heapp->h_free) || (hp > qp)) &&
((qp->h_u.next == NULL) || (hp < qp->h_u.next))) { ((qp->h_u.next == NULL) || (hp < qp->h_u.next))) {
/* /* Insertion after qp.*/
* Insertion after qp.
*/
hp->h_u.next = qp->h_u.next; hp->h_u.next = qp->h_u.next;
qp->h_u.next = hp; qp->h_u.next = hp;
/* /* Verifies if the newly inserted block should be merged.*/
* Verifies if the newly inserted block should be merged.
*/
if (LIMIT(hp) == hp->h_u.next) { if (LIMIT(hp) == hp->h_u.next) {
/* /* Merge with the next block.*/
* Merge with the next block.
*/
hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header); hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header);
hp->h_u.next = hp->h_u.next->h_u.next; hp->h_u.next = hp->h_u.next->h_u.next;
} }
if ((LIMIT(qp) == hp)) { if ((LIMIT(qp) == hp)) {
/* /* Merge with the previous block.*/
* Merge with the previous block.
*/
qp->h_size += hp->h_size + sizeof(struct heap_header); qp->h_size += hp->h_size + sizeof(struct heap_header);
qp->h_u.next = hp->h_u.next; qp->h_u.next = hp->h_u.next;
} }
@ -219,16 +205,16 @@ void chHeapFree(void *p) {
/** /**
* @brief Reports the heap status. * @brief Reports the heap status.
* @note This function is meant to be used in the test suite, it should
* not be really useful for the application code.
* @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
* configuration option is used (it always returns zero).
* *
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to access * @param[in] heapp pointer to a heap descriptor or @p NULL in order to
* the default heap. * access the default heap.
* @param[in] sizep pointer to a variable that will receive the total * @param[in] sizep pointer to a variable that will receive the total
* fragmented free space * fragmented free space
* @return The number of fragments in the heap. * @return The number of fragments in the heap.
* @note This function is meant to be used in the test suite, it should not be
* really useful for the application code.
* @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
* configuration option is used (it always returns zero).
*/ */
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
struct heap_header *qp; struct heap_header *qp;

View File

@ -20,6 +20,7 @@
/** /**
* @file chlists.c * @file chlists.c
* @brief Thread queues/lists code. * @brief Thread queues/lists code.
*
* @addtogroup internals * @addtogroup internals
* @{ * @{
*/ */
@ -37,16 +38,16 @@
*/ */
void prio_insert(Thread *tp, ThreadsQueue *tqp) { void prio_insert(Thread *tp, ThreadsQueue *tqp) {
/* cp iterates over the queue */ /* cp iterates over the queue.*/
Thread *cp = (Thread *)tqp; Thread *cp = (Thread *)tqp;
do { do {
/* iterate to next thread in queue */ /* Iterate to next thread in queue.*/
cp = cp->p_next; cp = cp->p_next;
/* not end of queue? and cp has equal or higher priority than tp? */ /* Not end of queue? and cp has equal or higher priority than tp?.*/
} while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)); } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio));
/* insert before cp, point tp to next and prev in queue */ /* Insert before cp, point tp to next and prev in queue.*/
tp->p_prev = (tp->p_next = cp)->p_prev; tp->p_prev = (tp->p_next = cp)->p_prev;
/* make prev point to tp, and cp point back to tp */ /* Make prev point to tp, and cp point back to tp.*/
tp->p_prev->p_next = cp->p_prev = tp; tp->p_prev->p_next = cp->p_prev = tp;
} }

View File

@ -20,6 +20,7 @@
/** /**
* @file chmboxes.c * @file chmboxes.c
* @brief Mailboxes code. * @brief Mailboxes code.
*
* @addtogroup mailboxes * @addtogroup mailboxes
* @{ * @{
*/ */

View File

@ -20,6 +20,7 @@
/** /**
* @file chmemcore.c * @file chmemcore.c
* @brief Core memory manager code. * @brief Core memory manager code.
*
* @addtogroup memcore * @addtogroup memcore
* @{ * @{
*/ */

View File

@ -20,6 +20,7 @@
/** /**
* @file chmempools.c * @file chmempools.c
* @brief Memory Pools code. * @brief Memory Pools code.
*
* @addtogroup pools * @addtogroup pools
* @{ * @{
*/ */
@ -29,15 +30,16 @@
#if CH_USE_MEMPOOLS #if CH_USE_MEMPOOLS
/** /**
* @brief Initializes an empty memory pool. * @brief Initializes an empty memory pool.
* @note The size is internally aligned to be a multiple of the @p align_t
* type size.
* *
* @param[out] mp pointer to a @p MemoryPool structure * @param[out] mp pointer to a @p MemoryPool structure
* @param[in] size the size of the objects contained in this memory pool, * @param[in] size the size of the objects contained in this memory pool,
* the minimum accepted size is the size of a pointer to void. * the minimum accepted size is the size of a pointer to
* void.
* @param[in] provider memory provider function for the memory pool or * @param[in] provider memory provider function for the memory pool or
* @p NULL if the pool is not allowed to grow automatically * @p NULL if the pool is not allowed to grow
* * automatically
* @note The size is internally aligned to be a multiple of the @p align_t
* type size.
*/ */
void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) {
@ -87,14 +89,13 @@ void *chPoolAlloc(MemoryPool *mp) {
/** /**
* @brief Releases (or adds) an object into (to) a memory pool. * @brief Releases (or adds) an object into (to) a memory pool.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @param[in] objp the pointer to the object to be released or added
*
* @note The object is assumed to be of the right size for the specified * @note The object is assumed to be of the right size for the specified
* memory pool. * memory pool.
* @note The object is assumed to be memory aligned to the size of @p align_t * @note The object is assumed to be memory aligned to the size of @p align_t
* type. * type.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @param[in] objp the pointer to the object to be released or added
*/ */
void chPoolFreeI(MemoryPool *mp, void *objp) { void chPoolFreeI(MemoryPool *mp, void *objp) {
struct pool_header *php = objp; struct pool_header *php = objp;
@ -108,11 +109,11 @@ void chPoolFreeI(MemoryPool *mp, void *objp) {
/** /**
* @brief Releases (or adds) an object into (to) a memory pool. * @brief Releases (or adds) an object into (to) a memory pool.
* @note The object is assumed to be of the right size for the specified
* memory pool.
* *
* @param[in] mp pointer to a @p MemoryPool structure * @param[in] mp pointer to a @p MemoryPool structure
* @param[in] objp the pointer to the object to be released or added * @param[in] objp the pointer to the object to be released or added
* @note the object is assumed to be of the right size for the specified
* memory pool.
*/ */
void chPoolFree(MemoryPool *mp, void *objp) { void chPoolFree(MemoryPool *mp, void *objp) {

View File

@ -20,6 +20,7 @@
/** /**
* @file chmsg.c * @file chmsg.c
* @brief Messages code. * @brief Messages code.
*
* @addtogroup messages * @addtogroup messages
* @{ * @{
*/ */
@ -41,7 +42,7 @@
* *
* @param[in] tp the pointer to the thread * @param[in] tp the pointer to the thread
* @param[in] msg the message * @param[in] msg the message
* @return The return message from @p chMsgRelease(). * @return The answer message from @p chMsgRelease().
*/ */
msg_t chMsgSend(Thread *tp, msg_t msg) { msg_t chMsgSend(Thread *tp, msg_t msg) {
Thread *ctp = currp; Thread *ctp = currp;
@ -62,12 +63,13 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
/** /**
* @brief Suspends the thread and waits for an incoming message. * @brief Suspends the thread and waits for an incoming message.
* * @note You can assume that the data contained in the message is stable
* @return The pointer to the message structure. Note, it is always the * until you invoke @p chMsgRelease() because the sending thread is
* message associated to the thread on the top of the messages queue.
* @note You can assume that the data contained in the message is stable until
* you invoke @p chMsgRelease() because the sending thread is
* suspended until then. * suspended until then.
*
* @return The pointer to the message structure. Note, it is
* always the message associated to the thread on the
* top of the messages queue.
*/ */
msg_t chMsgWait(void) { msg_t chMsgWait(void) {
msg_t msg; msg_t msg;
@ -82,14 +84,16 @@ msg_t chMsgWait(void) {
/** /**
* @brief Returns the next message in the queue. * @brief Returns the next message in the queue.
*
* @return The pointer to the message structure. Note, it is always the
* message associated to the thread on the top of the messages queue.
* If the queue is empty then @p NULL is returned.
* @note You can assume that the data pointed by the message is stable until * @note You can assume that the data pointed by the message is stable until
* you invoke @p chMsgRelease() because the sending thread is * you invoke @p chMsgRelease() because the sending thread is
* suspended until then. Always remember that the message data is not * suspended until then. Always remember that the message data is not
* copied between the sender and the receiver, just a pointer is passed. * copied between the sender and the receiver, just a pointer is
* passed.
*
* @return The pointer to the message structure. Note, it is
* always the message associated to the thread on the
* top of the messages queue.
* @retval NULL if the queue is empty.
*/ */
msg_t chMsgGet(void) { msg_t chMsgGet(void) {
msg_t msg; msg_t msg;
@ -102,14 +106,14 @@ msg_t chMsgGet(void) {
/** /**
* @brief Releases the thread waiting on top of the messages queue. * @brief Releases the thread waiting on top of the messages queue.
* * @note You can call this function only if there is a message already in
* @param[in] msg the message returned to the message sender * the queue else the result will be unpredictable (a crash most likely).
* @note You can call this function only if there is a message already in the
* queue else the result will be unpredictable (a crash most likely).
* Exiting from the @p chMsgWait() ensures you have at least one * Exiting from the @p chMsgWait() ensures you have at least one
* message in the queue so it is not a big deal.<br> * message in the queue so it is not a big deal.<br>
* The condition is only tested in debug mode in order to make this code * The condition is only tested in debug mode in order to make this
* as fast as possible. * code as fast as possible.
*
* @param[in] msg the message returned to the message sender
*/ */
void chMsgRelease(msg_t msg) { void chMsgRelease(msg_t msg) {

View File

@ -20,6 +20,7 @@
/** /**
* @file chmtx.c * @file chmtx.c
* @brief Mutexes code. * @brief Mutexes code.
*
* @addtogroup mutexes * @addtogroup mutexes
* @{ * @{
*/ */
@ -32,9 +33,6 @@
* @brief Initializes s @p Mutex structure. * @brief Initializes s @p Mutex structure.
* *
* @param[out] mp pointer to a @p Mutex structure * @param[out] mp pointer to a @p Mutex structure
* @note This function can be invoked from within an interrupt handler even if
* it is not an I-Class API because it does not touch any critical kernel
* data structure.
*/ */
void chMtxInit(Mutex *mp) { void chMtxInit(Mutex *mp) {
@ -62,8 +60,6 @@ void chMtxLock(Mutex *mp) {
* @brief Locks the specified mutex. * @brief Locks the specified mutex.
* *
* @param[in] mp pointer to the @p Mutex structure * @param[in] mp pointer to the @p Mutex structure
* @note This function must be called within a @p chSysLock() / @p chSysUnlock()
* block.
*/ */
void chMtxLockS(Mutex *mp) { void chMtxLockS(Mutex *mp) {
Thread *ctp = currp; Thread *ctp = currp;
@ -146,11 +142,10 @@ bool_t chMtxTryLock(Mutex *mp) {
* @details This function does not have any overhead related to * @details This function does not have any overhead related to
* the priority inheritance mechanism because it does not try to * the priority inheritance mechanism because it does not try to
* enter a sleep state on the mutex. * enter a sleep state on the mutex.
*
* @param[in] mp pointer to the @p Mutex structure * @param[in] mp pointer to the @p Mutex structure
* @retval TRUE if the mutex was successfully acquired * @retval TRUE if the mutex was successfully acquired
* @retval FALSE if the lock attempt failed. * @retval FALSE if the lock attempt failed.
* @note This function must be called within a @p chSysLock() / @p chSysUnlock()
* block.
*/ */
bool_t chMtxTryLockS(Mutex *mp) { bool_t chMtxTryLockS(Mutex *mp) {
@ -211,11 +206,9 @@ Mutex *chMtxUnlock(void) {
/** /**
* @brief Unlocks the next owned mutex in reverse lock order. * @brief Unlocks the next owned mutex in reverse lock order.
* @note This function does not reschedule internally.
* *
* @return The pointer to the unlocked mutex. * @return The pointer to the unlocked mutex.
* @note This function must be called within a @p chSysLock() / @p chSysUnlock()
* block.
* @note This function does not reschedule internally.
*/ */
Mutex *chMtxUnlockS(void) { Mutex *chMtxUnlockS(void) {
Thread *ctp = currp; Thread *ctp = currp;

View File

@ -20,6 +20,7 @@
/** /**
* @file chqueues.c * @file chqueues.c
* @brief I/O Queues code. * @brief I/O Queues code.
*
* @addtogroup io_queues * @addtogroup io_queues
* @{ * @{
*/ */
@ -32,15 +33,14 @@
* @brief Initializes an input queue. * @brief Initializes an input queue.
* @details A Semaphore is internally initialized and works as a counter of * @details A Semaphore is internally initialized and works as a counter of
* the bytes contained in the queue. * the bytes contained in the queue.
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
* *
* @param[out] iqp pointer to an @p InputQueue structure * @param[out] iqp pointer to an @p InputQueue structure
* @param[in] bp pointer to a memory area allocated as queue buffer * @param[in] bp pointer to a memory area allocated as queue buffer
* @param[in] size size of the queue buffer * @param[in] size size of the queue buffer
* @param[in] infy pointer to a callback function that is invoked when * @param[in] infy pointer to a callback function that is invoked when
* data is read from the queue. The value can be @p NULL. * data is read from the queue. The value can be @p NULL.
*
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
*/ */
void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) {
@ -54,8 +54,8 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) {
* @brief Resets an input queue. * @brief Resets an input queue.
* @details All the data in the input queue is erased and lost, any waiting * @details All the data in the input queue is erased and lost, any waiting
* thread is resumed with status @p Q_RESET. * thread is resumed with status @p Q_RESET.
* @note A reset operation can be used by a low level driver in order to obtain * @note A reset operation can be used by a low level driver in order to
* immediate attention from the high level layers. * obtain immediate attention from the high level layers.
* *
* @param[in] iqp pointer to an @p InputQueue structure * @param[in] iqp pointer to an @p InputQueue structure
*/ */
@ -73,7 +73,8 @@ void chIQResetI(InputQueue *iqp) {
* @param[in] b the byte value to be written in the queue * @param[in] b the byte value to be written in the queue
* @return The operation status, it can be one of: * @return The operation status, it can be one of:
* @retval Q_OK if the operation has been completed with success. * @retval Q_OK if the operation has been completed with success.
* @retval Q_FULL if the queue is full and the operation cannot be completed. * @retval Q_FULL if the queue is full and the operation cannot be
* completed.
*/ */
msg_t chIQPutI(InputQueue *iqp, uint8_t b) { msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
@ -183,15 +184,14 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
* @brief Initializes an output queue. * @brief Initializes an output queue.
* @details A Semaphore is internally initialized and works as a counter of * @details A Semaphore is internally initialized and works as a counter of
* the free bytes in the queue. * the free bytes in the queue.
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
* *
* @param[out] oqp pointer to an @p OutputQueue structure * @param[out] oqp pointer to an @p OutputQueue structure
* @param[in] bp pointer to a memory area allocated as queue buffer * @param[in] bp pointer to a memory area allocated as queue buffer
* @param[in] size size of the queue buffer * @param[in] size size of the queue buffer
* @param[in] onfy pointer to a callback function that is invoked when * @param[in] onfy pointer to a callback function that is invoked when
* data is written to the queue. The value can be @p NULL. * data is written to the queue. The value can be @p NULL.
*
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
*/ */
void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) {
@ -205,11 +205,10 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) {
* @brief Resets an output queue. * @brief Resets an output queue.
* @details All the data in the output queue is erased and lost, any waiting * @details All the data in the output queue is erased and lost, any waiting
* thread is resumed with status @p Q_RESET. * thread is resumed with status @p Q_RESET.
* @note A reset operation can be used by a low level driver in order to
* obtain immediate attention from the high level layers.
* *
* @param[in] oqp pointer to an @p OutputQueue structure * @param[in] oqp pointer to an @p OutputQueue structure
*
* @note A reset operation can be used by a low level driver in order to obtain
* immediate attention from the high level layers.
*/ */
void chOQResetI(OutputQueue *oqp) { void chOQResetI(OutputQueue *oqp) {

View File

@ -20,6 +20,7 @@
/** /**
* @file chregistry.c * @file chregistry.c
* @brief Threads registry code. * @brief Threads registry code.
*
* @addtogroup registry * @addtogroup registry
* @{ * @{
*/ */

View File

@ -20,6 +20,7 @@
/** /**
* @file chschd.c * @file chschd.c
* @brief Scheduler code. * @brief Scheduler code.
*
* @addtogroup scheduler * @addtogroup scheduler
* @{ * @{
*/ */
@ -33,8 +34,7 @@ ReadyList rlist;
/** /**
* @brief Scheduler initialization. * @brief Scheduler initialization.
* * @note Internally invoked by the @p chSysInit(), not an API.
* @note Internally invoked by the @p chSysInit().
*/ */
void scheduler_init(void) { void scheduler_init(void) {
@ -50,11 +50,11 @@ void scheduler_init(void) {
/** /**
* @brief Inserts a thread in the Ready List. * @brief Inserts a thread in the Ready List.
* @note The function does not reschedule, the @p chSchRescheduleS() should
* be called soon after.
* *
* @param[in] tp the Thread to be made ready * @param[in] tp the Thread to be made ready
* @return The Thread pointer. * @return The Thread pointer.
* @note The function does not reschedule, the @p chSchRescheduleS() should
* be called soon after.
*/ */
#if CH_OPTIMIZE_SPEED #if CH_OPTIMIZE_SPEED
/* NOTE: it is inlined in this module only.*/ /* NOTE: it is inlined in this module only.*/
@ -132,11 +132,11 @@ static void wakeup(void *p) {
* @param[in] time the number of ticks before the operation timeouts, the * @param[in] time the number of ticks before the operation timeouts, the
* special values are handled as follow: * special values are handled as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep * - @a TIME_INFINITE the thread enters an infinite sleep
* state, this is equivalent to invoking @p chSchGoSleepS() * state, this is equivalent to invoking
* but, of course, less efficient. * @p chSchGoSleepS() but, of course, less efficient.
* - @a TIME_IMMEDIATE this value is accepted but interpreted * - @a TIME_IMMEDIATE this value is accepted but
* as a normal time specification not as an immediate timeout * interpreted as a normal time specification not as an
* specification. * immediate timeout specification.
* . * .
* @return The wakeup message. * @return The wakeup message.
* @retval RDY_TIMEOUT if a timeout occurs. * @retval RDY_TIMEOUT if a timeout occurs.
@ -161,20 +161,21 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
* @details The thread is inserted into the ready list or immediately made * @details The thread is inserted into the ready list or immediately made
* running depending on its relative priority compared to the current * running depending on its relative priority compared to the current
* thread. * thread.
* @note It is equivalent to a @p chSchReadyI() followed by a
* @p chSchRescheduleS() but much more efficient.
* @note The function assumes that the current thread has the highest
* priority.
* *
* @param[in] ntp the Thread to be made ready * @param[in] ntp the Thread to be made ready
* @param[in] msg message to the awakened thread * @param[in] msg message to the awakened thread
* @note It is equivalent to a @p chSchReadyI() followed by a
* @p chSchRescheduleS() but much more efficient.
* @note The function assumes that the current thread has the highest priority
*/ */
void chSchWakeupS(Thread *ntp, msg_t msg) { void chSchWakeupS(Thread *ntp, msg_t msg) {
ntp->p_u.rdymsg = msg; ntp->p_u.rdymsg = msg;
/* If the waken thread has a not-greater priority than the current /* If the waken thread has a not-greater priority than the current
* one then it is just inserted in the ready list else it made one then it is just inserted in the ready list else it made
* running immediately and the invoking thread goes in the ready running immediately and the invoking thread goes in the ready
* list instead.*/ list instead.*/
if (ntp->p_prio <= currp->p_prio) if (ntp->p_prio <= currp->p_prio)
chSchReadyI(ntp); chSchReadyI(ntp);
else { else {
@ -191,9 +192,8 @@ void chSchWakeupS(Thread *ntp, msg_t msg) {
/** /**
* @brief Switches to the first thread on the runnable queue. * @brief Switches to the first thread on the runnable queue.
* * @note It is intended to be called if @p chSchRescRequiredI() evaluates
* @note It is intended to be called if @p chSchRescRequiredI() evaluates to * to @p TRUE.
* @p TRUE.
*/ */
void chSchDoRescheduleI(void) { void chSchDoRescheduleI(void) {
@ -223,25 +223,24 @@ void chSchRescheduleS(void) {
* @brief Evaluates if a reschedulation is required. * @brief Evaluates if a reschedulation is required.
* @details The decision is taken by comparing the relative priorities and * @details The decision is taken by comparing the relative priorities and
* depending on the state of the round robin timeout counter. * depending on the state of the round robin timeout counter.
* @note This function is meant to be used in the timer interrupt handler
* where @p chVTDoTickI() is invoked.
* *
* @retval TRUE if there is a thread that should go in running state. * @retval TRUE if there is a thread that should go in running state.
* @retval FALSE if a reschedulation is not required. * @retval FALSE if a reschedulation is not required.
*
* @note This function is meant to be used in the timer interrupt handler
* where @p chVTDoTickI() is invoked.
*/ */
bool_t chSchIsRescRequiredExI(void) { bool_t chSchIsRescRequiredExI(void) {
tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p1 = firstprio(&rlist.r_queue);
tprio_t p2 = currp->p_prio; tprio_t p2 = currp->p_prio;
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
/* If the running thread has not reached its time quantum, reschedule only /* If the running thread has not reached its time quantum, reschedule only
* if the first thread on the ready queue has a higher priority. if the first thread on the ready queue has a higher priority.
* Otherwise, if the running thread has used up its time quantum, reschedule Otherwise, if the running thread has used up its time quantum, reschedule
* if the first thread on the ready queue has equal or higher priority.*/ if the first thread on the ready queue has equal or higher priority.*/
return rlist.r_preempt ? p1 > p2 : p1 >= p2; return rlist.r_preempt ? p1 > p2 : p1 >= p2;
#else #else
/* If the round robin feature is not enabled then performs a simpler /* If the round robin preemption feature is not enabled then performs a
* comparison.*/ simpler comparison.*/
return p1 > p2; return p1 > p2;
#endif #endif
} }
@ -257,11 +256,9 @@ void chSchDoYieldS(void) {
Thread *cp = (Thread *)&rlist.r_queue; Thread *cp = (Thread *)&rlist.r_queue;
Thread *otp = currp; Thread *otp = currp;
/* /* Note, the following insertion code works because we know that on the
* Note, the following insertion code works because we know that on the ready list there is at least one thread with priority equal or higher
* ready list there is at least one thread with priority equal or higher than the current one.*/
* than the current one.
*/
otp->p_state = THD_STATE_READY; otp->p_state = THD_STATE_READY;
do { do {
cp = cp->p_prev; cp = cp->p_prev;

View File

@ -20,6 +20,7 @@
/** /**
* @file chsem.c * @file chsem.c
* @brief Semaphores code. * @brief Semaphores code.
*
* @addtogroup semaphores * @addtogroup semaphores
* @{ * @{
*/ */
@ -38,10 +39,8 @@
* @brief Initializes a semaphore with the specified counter value. * @brief Initializes a semaphore with the specified counter value.
* *
* @param[out] sp pointer to a @p Semaphore structure * @param[out] sp pointer to a @p Semaphore structure
* @param[in] n initial value of the semaphore counter. Must be non-negative. * @param[in] n initial value of the semaphore counter. Must be
* @note This function can be invoked from within an interrupt handler even if * non-negative.
* it is not an I-Class API because it does not touch any critical kernel
* data structure.
*/ */
void chSemInit(Semaphore *sp, cnt_t n) { void chSemInit(Semaphore *sp, cnt_t n) {
@ -53,12 +52,13 @@ void chSemInit(Semaphore *sp, cnt_t n) {
/** /**
* @brief Performs a reset operation on the semaphore. * @brief Performs a reset operation on the semaphore.
* @note The released threads can recognize they were waked up by a reset
* rather than a signal because the @p chSemWait() will return
* @p RDY_RESET instead of @p RDY_OK.
* *
* @param[in] sp pointer to a @p Semaphore structure * @param[in] sp pointer to a @p Semaphore structure
* @param[in] n the new value of the semaphore counter. The value must be non-negative. * @param[in] n the new value of the semaphore counter. The value must
* @note The released threads can recognize they were waked up by a reset * be non-negative.
* instead than a signal because the @p chSemWait() will return
* @p RDY_RESET instead of @p RDY_OK.
*/ */
void chSemReset(Semaphore *sp, cnt_t n) { void chSemReset(Semaphore *sp, cnt_t n) {
@ -70,13 +70,14 @@ void chSemReset(Semaphore *sp, cnt_t n) {
/** /**
* @brief Performs a reset operation on the semaphore. * @brief Performs a reset operation on the semaphore.
*
* @param[in] sp pointer to a @p Semaphore structure
* @param[in] n the new value of the semaphore counter. The value must be non-negative.
* @note The released threads can recognize they were waked up by a reset * @note The released threads can recognize they were waked up by a reset
* instead than a signal because the @p chSemWait() will return * rather than a signal because the @p chSemWait() will return
* @p RDY_RESET instead of @p RDY_OK. * @p RDY_RESET instead of @p RDY_OK.
* @note This function does not reschedule. * @note This function does not reschedule.
*
* @param[in] sp pointer to a @p Semaphore structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
*/ */
void chSemResetI(Semaphore *sp, cnt_t n) { void chSemResetI(Semaphore *sp, cnt_t n) {
cnt_t cnt; cnt_t cnt;
@ -111,8 +112,6 @@ msg_t chSemWait(Semaphore *sp) {
* @param[in] sp pointer to a @p Semaphore structure * @param[in] sp pointer to a @p Semaphore structure
* @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @note This function must be called with interrupts disabled.
* @note This function cannot be called by an interrupt handler.
*/ */
msg_t chSemWaitS(Semaphore *sp) { msg_t chSemWaitS(Semaphore *sp) {
@ -161,8 +160,8 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
* . * .
* @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the specified * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the
* timeout. * specified timeout.
*/ */
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
@ -184,8 +183,6 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
* @brief Performs a signal operation on a semaphore. * @brief Performs a signal operation on a semaphore.
* *
* @param[in] sp pointer to a @p Semaphore structure * @param[in] sp pointer to a @p Semaphore structure
* @note The function is available only if the @p CH_USE_SEMAPHORES
* option is enabled in @p chconf.h.
*/ */
void chSemSignal(Semaphore *sp) { void chSemSignal(Semaphore *sp) {
@ -199,18 +196,16 @@ void chSemSignal(Semaphore *sp) {
/** /**
* @brief Performs a signal operation on a semaphore. * @brief Performs a signal operation on a semaphore.
* @note This function does not reschedule.
* *
* @param[in] sp pointer to a @p Semaphore structure * @param[in] sp pointer to a @p Semaphore structure
* @note The function is available only if the @p CH_USE_SEMAPHORES
* option is enabled in @p chconf.h.
* @note This function does not reschedule.
*/ */
void chSemSignalI(Semaphore *sp) { void chSemSignalI(Semaphore *sp) {
chDbgCheck(sp != NULL, "chSemSignalI"); chDbgCheck(sp != NULL, "chSemSignalI");
if (sp->s_cnt++ < 0) { if (sp->s_cnt++ < 0) {
/* NOTE: It is done this way in order to allow a tail call on /* note, it is done this way in order to allow a tail call on
chSchReadyI().*/ chSchReadyI().*/
Thread *tp = fifo_remove(&sp->s_queue); Thread *tp = fifo_remove(&sp->s_queue);
tp->p_u.rdymsg = RDY_OK; tp->p_u.rdymsg = RDY_OK;
@ -221,13 +216,13 @@ void chSemSignalI(Semaphore *sp) {
#if CH_USE_SEMSW #if CH_USE_SEMSW
/** /**
* @brief Performs atomic signal and wait operations on two semaphores. * @brief Performs atomic signal and wait operations on two semaphores.
* @note The function is available only if the @p CH_USE_SEMSW
* option is enabled in @p chconf.h.
* *
* @param[in] sps pointer to a @p Semaphore structure to be signaled * @param[in] sps pointer to a @p Semaphore structure to be signaled
* @param[in] spw pointer to a @p Semaphore structure to be wait on * @param[in] spw pointer to a @p Semaphore structure to be wait on
* @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @note The function is available only if the @p CH_USE_SEMSW
* option is enabled in @p chconf.h.
*/ */
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
msg_t msg; msg_t msg;

View File

@ -20,6 +20,7 @@
/** /**
* @file chsys.c * @file chsys.c
* @brief System related code. * @brief System related code.
*
* @addtogroup system * @addtogroup system
* @{ * @{
*/ */
@ -51,7 +52,6 @@ static void idle_thread(void *p) {
* @brief ChibiOS/RT initialization. * @brief ChibiOS/RT initialization.
* @details After executing this function the current instructions stream * @details After executing this function the current instructions stream
* becomes the main thread. * becomes the main thread.
*
* @note Interrupts should be still disabled when @p chSysInit() is invoked * @note Interrupts should be still disabled when @p chSysInit() is invoked
* and are internally enabled. * and are internally enabled.
* @note The main thread is created with priority @p NORMALPRIO. * @note The main thread is created with priority @p NORMALPRIO.
@ -72,17 +72,13 @@ void chSysInit(void) {
trace_init(); trace_init();
#endif #endif
/* /* Now this instructions flow becomes the main thread.*/
* Now this instructions flow becomes the main thread.
*/
(currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT;
chSysEnable(); chSysEnable();
/* /* This thread has the lowest priority in the system, its role is just to
* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving
* serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/
* mode compatible with the system status.
*/
chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO,
(tfunc_t)idle_thread, NULL); (tfunc_t)idle_thread, NULL);
} }
@ -93,8 +89,9 @@ void chSysInit(void) {
* and preempts it when the quantum is used up. Increments system * and preempts it when the quantum is used up. Increments system
* time and manages the timers. * time and manages the timers.
* *
* @note The frequency of the timer determines the system tick granularity and, * @note The frequency of the timer determines the system tick granularity
* together with the @p CH_TIME_QUANTUM macro, the round robin interval. * and, together with the @p CH_TIME_QUANTUM macro, the round robin
* interval.
*/ */
void chSysTimerHandlerI(void) { void chSysTimerHandlerI(void) {

View File

@ -20,6 +20,7 @@
/** /**
* @file chthreads.c * @file chthreads.c
* @brief Threads code. * @brief Threads code.
*
* @addtogroup threads * @addtogroup threads
* @{ * @{
*/ */
@ -31,7 +32,6 @@
* *
* @param[in] tp pointer to the thread * @param[in] tp pointer to the thread
* @param[in] prio the priority level for the new thread * @param[in] prio the priority level for the new thread
*
* @return The same thread pointer passed as parameter. * @return The same thread pointer passed as parameter.
*/ */
Thread *init_thread(Thread *tp, tprio_t prio) { Thread *init_thread(Thread *tp, tprio_t prio) {
@ -92,8 +92,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be * @param[in] arg an argument passed to the thread function. It can be
* @p NULL. * @p NULL.
* @return The pointer to the @p Thread structure allocated for the * @return The pointer to the @p Thread structure allocated for
* thread into the working space area. * the thread into the working space area.
*/ */
Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
/* Thread structure is layed out in the lower part of the thread workspace */ /* Thread structure is layed out in the lower part of the thread workspace */
@ -122,8 +122,8 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be * @param[in] arg an argument passed to the thread function. It can be
* @p NULL. * @p NULL.
* @return The pointer to the @p Thread structure allocated for the * @return The pointer to the @p Thread structure allocated for
* thread into the working space area. * the thread into the working space area.
*/ */
Thread *chThdCreateStatic(void *wsp, size_t size, Thread *chThdCreateStatic(void *wsp, size_t size,
tprio_t prio, tfunc_t pf, void *arg) { tprio_t prio, tfunc_t pf, void *arg) {
@ -149,8 +149,8 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be * @param[in] arg an argument passed to the thread function. It can be
* @p NULL. * @p NULL.
* @return The pointer to the @p Thread structure allocated for the * @return The pointer to the @p Thread structure allocated for
* thread into the working space area. * the thread into the working space area.
* @retval NULL if the memory cannot be allocated. * @retval NULL if the memory cannot be allocated.
*/ */
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
@ -184,9 +184,8 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be * @param[in] arg an argument passed to the thread function. It can be
* @p NULL. * @p NULL.
* @return The pointer to the @p Thread structure allocated for the * @return The pointer to the @p Thread structure allocated for
* thread into the working space area or @p NULL if the memory cannot * the thread into the working space area.
* be allocated.
* @retval NULL if the memory pool is empty. * @retval NULL if the memory pool is empty.
*/ */
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
@ -273,13 +272,13 @@ void chThdTerminate(Thread *tp) {
/** /**
* @brief Suspends the invoking thread for the specified time. * @brief Suspends the invoking thread for the specified time.
* *
* @param[in] time the delay in system ticks, the special values are handled * @param[in] time the delay in system ticks, the special values are
* as follow: * handled as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep * - @a TIME_INFINITE the thread enters an infinite sleep
* state. * state.
* - @a TIME_IMMEDIATE this value is accepted but interpreted * - @a TIME_IMMEDIATE this value is accepted but
* as a normal time specification not as an immediate * interpreted as a normal time specification not as an
* timeout specification. * immediate timeout specification.
* . * .
*/ */
void chThdSleep(systime_t time) { void chThdSleep(systime_t time) {
@ -322,7 +321,6 @@ void chThdYield(void) {
* *
* @param[in] msg thread exit code. The code can be retrieved by using * @param[in] msg thread exit code. The code can be retrieved by using
* @p chThdWait(). * @p chThdWait().
* @return The same thread pointer passed as parameter.
*/ */
void chThdExit(msg_t msg) { void chThdExit(msg_t msg) {
Thread *tp = currp; Thread *tp = currp;
@ -345,8 +343,8 @@ void chThdExit(msg_t msg) {
* @brief Adds a reference to a thread object. * @brief Adds a reference to a thread object.
* *
* @param[in] tp pointer to the thread * @param[in] tp pointer to the thread
* @return The same thread pointer passed as parameter representing the * @return The same thread pointer passed as parameter
* new reference. * representing the new reference.
*/ */
Thread *chThdAddRef(Thread *tp) { Thread *chThdAddRef(Thread *tp) {
@ -420,7 +418,7 @@ void chThdRelease(Thread *tp) {
* the thread termination, no memory allocators are involved. * the thread termination, no memory allocators are involved.
* *
* @param[in] tp pointer to the thread * @param[in] tp pointer to the thread
* @return The exit code from the terminated thread * @return The exit code from the terminated thread.
*/ */
msg_t chThdWait(Thread *tp) { msg_t chThdWait(Thread *tp) {
msg_t msg; msg_t msg;

View File

@ -20,17 +20,20 @@
/** /**
* @file chvt.c * @file chvt.c
* @brief Time and Virtual Timers related code. * @brief Time and Virtual Timers related code.
*
* @addtogroup time * @addtogroup time
* @{ * @{
*/ */
#include "ch.h" #include "ch.h"
/**
* @brief Virtual timers delta list header.
*/
VTList vtlist; VTList vtlist;
/** /**
* @brief Virtual Timers initialization. * @brief Virtual Timers initialization.
*
* @note Internal use only. * @note Internal use only.
*/ */
void vt_init(void) { void vt_init(void) {
@ -42,18 +45,19 @@ void vt_init(void) {
/** /**
* @brief Enables a virtual timer. * @brief Enables a virtual timer.
*
* @param[out] vtp the @p VirtualTimer structure pointer
* @param[in] time the number of time ticks, the value @p TIME_INFINITE is not
* allowed. The value @p TIME_IMMEDIATE is allowed but
* interpreted as a normal time specification not as an
* immediate timeout specification.
* @param[in] vtfunc the timer callback function. After invoking the callback
* the timer is disabled and the structure can be disposed or
* reused.
* @param[in] par a parameter that will be passed to the callback function
* @note The associated function is invoked by an interrupt handler within * @note The associated function is invoked by an interrupt handler within
* the I-Locked state, see @ref system_states. * the I-Locked state, see @ref system_states.
*
* @param[out] vtp the @p VirtualTimer structure pointer
* @param[in] time the number of time ticks, the value @p TIME_INFINITE
* is notallowed. The value @p TIME_IMMEDIATE is allowed
* but interpreted as a normal time specification not as
* an immediate timeout specification.
* @param[in] vtfunc the timer callback function. After invoking the
* callback the timer is disabled and the structure can
* be disposed or reused.
* @param[in] par a parameter that will be passed to the callback
* function
*/ */
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
VirtualTimer *p; VirtualTimer *p;
@ -78,9 +82,9 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
/** /**
* @brief Disables a Virtual Timer. * @brief Disables a Virtual Timer.
* @note The timer MUST be active when this function is invoked.
* *
* @param[in] vtp the @p VirtualTimer structure pointer * @param[in] vtp the @p VirtualTimer structure pointer
* @note The timer MUST be active when this function is invoked.
*/ */
void chVTResetI(VirtualTimer *vtp) { void chVTResetI(VirtualTimer *vtp) {
@ -97,14 +101,15 @@ void chVTResetI(VirtualTimer *vtp) {
} }
/** /**
* @brief Checks if the current system time is within the specified time window. * @brief Checks if the current system time is within the specified time
* window.
* @note When start==end then the function returns always true because the
* whole time range is specified.
* *
* @param[in] start the start of the time window (inclusive) * @param[in] start the start of the time window (inclusive)
* @param[in] end the end of the time window (non inclusive) * @param[in] end the end of the time window (non inclusive)
* @retval TRUE current time within the specified time window. * @retval TRUE current time within the specified time window.
* @retval FALSE current time not within the specified time window. * @retval FALSE current time not within the specified time window.
* @note When start==end then the function returns always true because the
* whole time range is specified.
*/ */
bool_t chTimeIsWithin(systime_t start, systime_t end) { bool_t chTimeIsWithin(systime_t start, systime_t end) {