Documentation improvements, renamed some event APIs.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2179 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2010-09-18 06:48:56 +00:00
parent fb439b48b9
commit 9ffea7e261
30 changed files with 377 additions and 249 deletions

View File

@ -50,7 +50,7 @@
#ifndef _CHBSEM_H_
#define _CHBSEM_H_
#if CH_USE_SEMAPHORES
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
/**
* @extends Semaphore

View File

@ -32,7 +32,7 @@
#ifndef _CHCOND_H_
#define _CHCOND_H_
#if CH_USE_CONDVARS
#if CH_USE_CONDVARS || defined(__DOXYGEN__)
/*
* Module dependencies check.

View File

@ -82,7 +82,7 @@ typedef struct {
#define __QUOTE_THIS(p) #p
#if CH_DBG_ENABLE_CHECKS
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
/**
* @brief Function parameter check.
* @details If the condition check fails then the kernel panics and halts.
@ -102,7 +102,7 @@ typedef struct {
}
#endif /* !CH_DBG_ENABLE_CHECKS */
#if CH_DBG_ENABLE_ASSERTS
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
/**
* @brief Condition assertion.
* @details If the condition check fails then the kernel panics with the
@ -144,7 +144,7 @@ typedef struct {
#ifdef __cplusplus
extern "C" {
#endif
#if CH_DBG_ENABLE_TRACE
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
extern TraceBuffer trace_buffer;
void trace_init(void);
void chDbgTrace(Thread *otp);

View File

@ -28,7 +28,7 @@
#ifndef _CHEVENTS_H_
#define _CHEVENTS_H_
#if CH_USE_EVENTS
#if CH_USE_EVENTS || defined(__DOXYGEN__)
typedef struct EventListener EventListener;
@ -91,16 +91,18 @@ typedef struct EventSource {
* The value must range between zero and the size, in bit,
* of the @p eventid_t type minus one.
*/
#define chEvtRegister(esp, elp, eid) chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
#define chEvtRegister(esp, elp, eid) \
chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
/**
* @brief Initializes an Event Source.
* @note Can be used with interrupts disabled or enabled.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p EventSource structure.
*
* @param[in] esp pointer to the @p EventSource structure
*/
#define chEvtInit(esp) \
((esp)->es_next = (EventListener *)(void *)(esp))
((esp)->es_next = (EventListener *)(void *)(esp))
/**
* @brief Verifies if there is at least one @p EventListener registered.
@ -109,7 +111,7 @@ typedef struct EventSource {
* @param[in] esp pointer to the @p EventSource structure
*/
#define chEvtIsListening(esp) \
((void *)(esp) != (void *)(esp)->es_next)
((void *)(esp) != (void *)(esp)->es_next)
/**
* @brief Event Handler callback function.
@ -123,8 +125,8 @@ extern "C" {
EventListener *elp,
eventmask_t mask);
void chEvtUnregister(EventSource *esp, EventListener *elp);
eventmask_t chEvtClear(eventmask_t mask);
eventmask_t chEvtPend(eventmask_t mask);
eventmask_t chEvtClearFlags(eventmask_t mask);
eventmask_t chEvtAddFlags(eventmask_t mask);
void chEvtSignal(Thread *tp, eventmask_t mask);
void chEvtSignalI(Thread *tp, eventmask_t mask);
void chEvtBroadcast(EventSource *esp);

View File

@ -28,7 +28,7 @@
#ifndef _CHHEAP_H_
#define _CHHEAP_H_
#if CH_USE_HEAP
#if CH_USE_HEAP || defined(__DOXYGEN__)
/*
* Module dependencies check.

View File

@ -28,7 +28,7 @@
#ifndef _CHMBOXES_H_
#define _CHMBOXES_H_
#if CH_USE_MAILBOXES
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
/*
* Module dependencies check.
@ -37,6 +37,9 @@
#error "CH_USE_MAILBOXES requires CH_USE_SEMAPHORES"
#endif
/**
* @brief Structure representing a mailbox object.
*/
typedef struct {
msg_t *mb_buffer; /**< @brief Pointer to the mailbox
buffer. */
@ -99,10 +102,10 @@ extern "C" {
/**
* @brief Returns the next message in the queue without removing it.
* @note A message must be waiting in the queue for this function to work or
* it would return garbage. The correct way to use this macro is to
* use @p chMBGetFull() and then use this macro, all within a lock
* state.
* @pre A message must be waiting in the queue for this function to work
* or it would return garbage. The correct way to use this macro is
* to use @p chMBGetFull() and then use this macro, all within a
* lock state.
*/
#define chMBPeek(mbp) (*(mbp)->mb_rdptr)

View File

@ -51,7 +51,7 @@ typedef void *(*memgetfunc_t)(size_t size);
*/
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
#if CH_USE_MEMCORE
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
#ifdef __cplusplus
extern "C" {

View File

@ -28,7 +28,7 @@
#ifndef _CHMEMPOOLS_H_
#define _CHMEMPOOLS_H_
#if CH_USE_MEMPOOLS
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
/**
* @brief Memory pool free object header.

View File

@ -28,7 +28,7 @@
#ifndef _CHMSG_H_
#define _CHMSG_H_
#if CH_USE_MESSAGES
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
/**
* @brief Evaluates to TRUE if the thread has pending messages.

View File

@ -28,10 +28,10 @@
#ifndef _CHMTX_H_
#define _CHMTX_H_
#if CH_USE_MUTEXES
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex structure.
* @brief Mutex structure.
*/
typedef struct Mutex {
ThreadsQueue m_queue; /**< @brief Queue of the threads sleeping

View File

@ -28,7 +28,7 @@
#ifndef _CHQUEUES_H_
#define _CHQUEUES_H_
#if CH_USE_QUEUES
#if CH_USE_QUEUES || defined(__DOXYGEN__)
/*
* Module dependencies check.

View File

@ -28,7 +28,7 @@
#ifndef _CHREGISTRY_H_
#define _CHREGISTRY_H_
#if CH_USE_REGISTRY
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
/**
* @brief Removes a thread from the registry list.

View File

@ -28,7 +28,7 @@
#ifndef _CHSEM_H_
#define _CHSEM_H_
#if CH_USE_SEMAPHORES
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
/**
* @brief Semaphore structure.

View File

@ -31,21 +31,20 @@
* <h2>Operation mode</h2>
* The condition variable is a synchronization object meant to be
* used inside a zone protected by a @p Mutex. Mutexes and CondVars
* together can implement a Monitor construct.<br>
* In order to use the Condition Variables APIs the @p CH_USE_CONDVARS
* together can implement a Monitor construct.
* @pre In order to use the condition variable APIs the @p CH_USE_CONDVARS
* option must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_CONDVARS && CH_USE_MUTEXES
#if (CH_USE_CONDVARS && CH_USE_MUTEXES) || defined(__DOXYGEN__)
/**
* @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.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p CondVar structure.
*
* @param[out] cp pointer to a @p CondVar structure
*/
@ -73,6 +72,10 @@ void chCondSignal(CondVar *cp) {
/**
* @brief Signals one thread that is waiting on the condition variable.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] cp pointer to the @p CondVar structure
*/
@ -99,6 +102,10 @@ void chCondBroadcast(CondVar *cp) {
/**
* @brief Signals all threads that are waiting on the condition variable.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] cp pointer to the @p CondVar structure
*/
@ -118,13 +125,15 @@ void chCondBroadcastI(CondVar *cp) {
* @details Releases the currently owned mutex, waits on the condition
* variable, and finally acquires the mutex again. All the sequence
* is performed atomically.
* @note The invoking thread <b>must</b> have at least one owned mutex on
* entry.
* @pre The invoking thread <b>must</b> have at least one owned mutex.
*
* @param[in] cp pointer to the @p CondVar structure
* @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
* @p chCondSignal().
* @retval RDY_RESET if the condvar has been signaled using
* @p chCondBroadcast().
*/
msg_t chCondWait(CondVar *cp) {
msg_t msg;
@ -140,13 +149,15 @@ msg_t chCondWait(CondVar *cp) {
* @details Releases the currently owned mutex, waits on the condition
* variable, and finally acquires the mutex again. All the sequence
* is performed atomically.
* @note The invoking thread <b>must</b> have at least one owned mutex on
* entry.
* @pre The invoking thread <b>must</b> have at least one owned mutex.
*
* @param[in] cp pointer to the @p CondVar structure
* @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
* @p chCondSignal().
* @retval RDY_RESET if the condvar has been signaled using
* @p chCondBroadcast().
*/
msg_t chCondWaitS(CondVar *cp) {
Thread *ctp = currp;
@ -167,15 +178,16 @@ msg_t chCondWaitS(CondVar *cp) {
return msg;
}
#if CH_USE_CONDVARS_TIMEOUT
#if CH_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__)
/**
* @brief Waits on the condition variable releasing the mutex lock.
* @details Releases the currently owned mutex, waits on the condition
* variable, and finally acquires the mutex again. All the sequence
* is performed atomically.
* @note The invoking thread <b>must</b> have at least one owned mutex on
* entry.
* @note Exiting the function because a timeout does not re-acquire the
* @pre The invoking thread <b>must</b> have at least one owned mutex.
* @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled
* in order to use this function.
* @post Exiting the function because a timeout does not re-acquire the
* mutex, the mutex ownership is lost.
*
* @param[in] cp pointer to the @p CondVar structure
@ -184,11 +196,14 @@ msg_t chCondWaitS(CondVar *cp) {
* It is not possible to specify zero @p TIME_IMMEDIATE
* as timeout specification because it would make no sense
* in this function.
* @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar was not signaled @p within the specified
* timeout.
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
* @p chCondSignal().
* @retval RDY_RESET if the condvar has been signaled using
* @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar has not been signaled within the
* specified timeout.
*/
msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
msg_t msg;
@ -204,9 +219,10 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
* @details Releases the currently owned mutex, waits on the condition
* variable, and finally acquires the mutex again. All the sequence
* is performed atomically.
* @note The invoking thread <b>must</b> have at least one owned mutex on
* entry.
* @note Exiting the function because a timeout does not re-acquire the
* @pre The invoking thread <b>must</b> have at least one owned mutex.
* @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled
* in order to use this function.
* @post Exiting the function because a timeout does not re-acquire the
* mutex, the mutex ownership is lost.
*
* @param[in] cp pointer to the @p CondVar structure
@ -215,11 +231,14 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
* It is not possible to specify zero @p TIME_IMMEDIATE
* as timeout specification because it would make no sense
* in this function.
* @return The wakep mode.
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar was not signaled within the specified
* timeout.
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
* @p chCondSignal().
* @retval RDY_RESET if the condvar has been signaled using
* @p chCondBroadcast().
* @retval RDY_TIMEOUT if the condvar has not been signaled within the
* specified timeout.
*/
msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
Mutex *mp;

View File

@ -27,12 +27,15 @@
* - Parameters check.
* - Kernel assertions.
* .
* @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE,
* @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must
* be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_DBG_ENABLE_TRACE
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
/**
* @brief Public trace buffer.
*/
@ -40,6 +43,7 @@ TraceBuffer trace_buffer;
/**
* @brief Trace circular buffer subsystem initialization.
* @note Internal use only.
*/
void trace_init(void) {
@ -63,7 +67,8 @@ void chDbgTrace(Thread *otp) {
}
#endif /* CH_DBG_ENABLE_TRACE */
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
/**
* @brief Pointer to the panic message.
* @details This pointer is meant to be accessed through the debugger, it is

View File

@ -46,22 +46,27 @@
* Event Source will be signaled with an events mask.<br>
* An unlimited number of Event Sources can exists in a system and
* each thread can be listening on an unlimited number of
* them.<br><br>
* In order to use the Events APIs the @p CH_USE_EVENTS option must be
* them.
* @pre In order to use the Events APIs the @p CH_USE_EVENTS option must be
* enabled in @p chconf.h.
* @post Enabling events requires 1-4 (depending on the architecture)
* extra bytes in the @p Thread structure.
* @{
*/
#include "ch.h"
#if CH_USE_EVENTS
#if CH_USE_EVENTS || defined(__DOXYGEN__)
/**
* @brief Registers an Event Listener on an Event Source.
* @note Multiple Event Listeners can specify the same bits to be pended.
* @details Once a thread has registered as listener on an event source it
* will be notified of all events broadcasted there.
* @note Multiple Event Listeners can specify the same bits to be ORed to
* different threads.
*
* @param[in] esp pointer to the @p EventSource structure
* @param[in] elp pointer to the @p EventListener structure
* @param[in] mask the mask of event flags to be pended to the thread when
* @param[in] mask the mask of event flags to be ORed to the thread when
* the event source is broadcasted
*/
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) {
@ -110,7 +115,7 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) {
* @param[in] mask the events to be cleared
* @return The pending events that were cleared.
*/
eventmask_t chEvtClear(eventmask_t mask) {
eventmask_t chEvtClearFlags(eventmask_t mask) {
eventmask_t m;
chSysLock();
@ -123,13 +128,13 @@ eventmask_t chEvtClear(eventmask_t mask) {
}
/**
* @brief Pends a set of event flags on the current thread, this is @b much
* faster than using @p chEvtBroadcast() or @p chEvtSignal().
* @brief Adds (OR) a set of event flags on the current thread, this is
* @b much faster than using @p chEvtBroadcast() or @p chEvtSignal().
*
* @param[in] mask the events to be pended
* @param[in] mask the event flags to be ORed
* @return The current pending events mask.
*/
eventmask_t chEvtPend(eventmask_t mask) {
eventmask_t chEvtAddFlags(eventmask_t mask) {
chSysLock();
@ -140,10 +145,10 @@ eventmask_t chEvtPend(eventmask_t mask) {
}
/**
* @brief Pends a set of event flags on the specified @p Thread.
* @brief Adds (OR) a set of event flags on the specified @p Thread.
*
* @param[in] tp the thread to be signaled
* @param[in] mask the event flags set to be pended
* @param[in] mask the event flags set to be ORed
*/
void chEvtSignal(Thread *tp, eventmask_t mask) {
@ -156,10 +161,14 @@ void chEvtSignal(Thread *tp, eventmask_t mask) {
}
/**
* @brief Pends a set of event flags on the specified @p Thread.
* @brief Adds (OR) a set of event flags on the specified @p Thread.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the thread to be signaled
* @param[in] mask the event flags set to be pended
* @param[in] mask the event flags set to be ORed
*/
void chEvtSignalI(Thread *tp, eventmask_t mask) {
@ -191,6 +200,10 @@ void chEvtBroadcast(EventSource *esp) {
/**
* @brief Signals all the Event Listeners registered on the specified Event
* Source.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] esp pointer to the @p EventSource structure
*/
@ -209,7 +222,7 @@ void chEvtBroadcastI(EventSource *esp) {
/**
* @brief Invokes the event handlers associated to an event flags mask.
*
* @param[in] mask mask of the events to be dispatched
* @param[in] mask mask of the event flags to be dispatched
* @param[in] handlers an array of @p evhandler_t. The array must have size
* equal to the number of bits in eventmask_t.
*/
@ -242,8 +255,8 @@ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) {
* This means that Event Listeners with a lower event identifier have
* an higher priority.
*
* @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param[in] mask mask of the event flags 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 mask) {
@ -269,8 +282,8 @@ eventmask_t chEvtWaitOne(eventmask_t mask) {
* @details The function waits for any event among those specified in
* @p mask to become pending then the events are cleared and returned.
*
* @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param[in] mask mask of the event flags that the function should wait
* for, @p ALL_EVENTS enables all the events
* @return The mask of the served and cleared events.
*/
eventmask_t chEvtWaitAny(eventmask_t mask) {
@ -295,7 +308,8 @@ eventmask_t chEvtWaitAny(eventmask_t mask) {
* @details The function waits for all the events specified in @p mask to
* become pending then the events are cleared and returned.
*
* @param[in] mask mask of the event ids that the function should wait for
* @param[in] mask mask of the event flags that the function should wait
* for, @p ALL_EVENTS requires all the events
* @return The mask of the served and cleared events.
*/
eventmask_t chEvtWaitAll(eventmask_t mask) {
@ -314,7 +328,7 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
}
#endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */
#if CH_USE_EVENTS_TIMEOUT
#if CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__)
/**
* @brief Waits for exactly one of the specified events.
* @details The function waits for one event among those specified in
@ -325,15 +339,15 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
* This means that Event Listeners with a lower event identifier have
* an higher priority.
*
* @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param[in] mask mask of the event flagss that the function should wait
* for, @p ALL_EVENTS enables all the events
* @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @return The mask of the lowest id served and cleared event.
* @retval 0 if the specified timeout expired.
* @retval 0 if the operation has timed out.
*/
eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp;
@ -362,15 +376,15 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) {
* @p mask to become pending then the events are cleared and
* returned.
*
* @param[in] mask mask of the events that the function should wait for,
* @p ALL_EVENTS enables all the events
* @param[in] mask mask of the event flags that the function should wait
* for, @p ALL_EVENTS enables all the events
* @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @return The mask of the served and cleared events.
* @retval 0 if the specified timeout expired.
* @retval 0 if the operation has timed out.
*/
eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp;
@ -397,14 +411,15 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) {
* @details The function waits for all the events specified in @p mask to
* become pending then the events are cleared and returned.
*
* @param[in] mask mask of the event ids that the function should wait for
* @param[in] mask mask of the event flags that the function should wait
* for, @p ALL_EVENTS requires all the events
* @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @return The mask of the served and cleared events.
* @retval 0 if the specified timeout expired.
* @retval 0 if the operation has timed out.
*/
eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) {
Thread *ctp = currp;

View File

@ -31,22 +31,22 @@
* By enabling the @p CH_USE_MALLOC_HEAP option the heap manager
* will use the runtime-provided @p malloc() and @p free() as
* backend for the heap APIs instead of the system provided
* allocator.<br>
* In order to use the heap APIs the @p CH_USE_HEAP option must
* allocator.
* @pre In order to use the heap APIs the @p CH_USE_HEAP option must
* be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_HEAP
#if CH_USE_HEAP || defined(__DOXYGEN__)
#if !CH_USE_MALLOC_HEAP
#if !CH_USE_MALLOC_HEAP || defined(__DOXYGEN__)
/*
* Defaults on the best synchronization mechanism available.
*/
#if CH_USE_MUTEXES
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
#define H_LOCK(h) chMtxLock(&(h)->h_mtx)
#define H_UNLOCK(h) chMtxUnlock()
#else
@ -67,7 +67,7 @@ void heap_init(void) {
default_heap.h_provider = chCoreAlloc;
default_heap.h_free.h.u.next = (union heap_header *)NULL;
default_heap.h_free.h.size = 0;
#if CH_USE_MUTEXES
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
chMtxInit(&default_heap.h_mtx);
#else
chSemInit(&default_heap.h_sem, 1);
@ -76,8 +76,8 @@ void heap_init(void) {
/**
* @brief Initializes a memory heap from a static memory area.
* @note Both the heap buffer base and the heap size must be aligned to
* the @p align_t type size.
* @pre Both the heap buffer base and the heap size must be aligned to
* the @p stkalign_t type size.
*
* @param[out] heapp pointer to the memory heap descriptor to be initialized
* @param[in] buf heap buffer base
@ -93,7 +93,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
heapp->h_free.h.size = 0;
hp->h.u.next = NULL;
hp->h.size = size - sizeof(union heap_header);
#if CH_USE_MUTEXES
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
chMtxInit(&heapp->h_mtx);
#else
chSemInit(&heapp->h_sem, 1);
@ -104,7 +104,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
* @brief Allocates a block of memory from the heap by using the first-fit
* algorithm.
* @details The allocated block is guaranteed to be properly aligned for a
* pointer data type (@p align_t).
* pointer data type (@p stkalign_t).
*
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
* access the default heap.

View File

@ -43,17 +43,19 @@
* possible approach is to allocate memory (from a memory pool as
* example) from the posting side and free it on the fetching side.
* Another approach is to set a "done" flag into the structure pointed
* by the message.<br>
* In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option
* by the message.
* @pre In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option
* must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_MAILBOXES
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
/**
* @brief Initializes a Mailbox object.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p Mailbox structure.
*
* @param[out] mbp the pointer to the Mailbox structure to be initialized
* @param[in] buf the circular messages buffer
@ -101,9 +103,9 @@ void chMBReset(Mailbox *mbp) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if the message was correctly posted.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly posted.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
@ -127,9 +129,9 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if the message was correctly posted.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly posted.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
@ -160,9 +162,9 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if the message was correctly posted.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly posted.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
@ -186,9 +188,9 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if the message was correctly posted.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly posted.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
msg_t rdymsg;
@ -219,9 +221,9 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if a message was correctly fetched.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly fetched.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
msg_t rdymsg;
@ -245,9 +247,9 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status.
* @retval RDY_OK if a message was correctly fetched.
* @retval RDY_RESET if the mailbox was reset while waiting.
* @retval RDY_TIMEOUT if the operation timed out.
* @retval RDY_OK if a message has been correctly fetched.
* @retval RDY_RESET if the mailbox has been reset while waiting.
* @retval RDY_TIMEOUT if the operation has timed out.
*/
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
msg_t rdymsg;

View File

@ -35,15 +35,15 @@
* By having a centralized memory provider the various allocators can
* coexist and share the main memory.<br>
* This allocator, alone, is also useful for very simple applications
* that just require a simple way to get memory blocks.<br>
* In order to use the core memory manager APIs the @p CH_USE_MEMCORE
* that just require a simple way to get memory blocks.
* @pre In order to use the core memory manager APIs the @p CH_USE_MEMCORE
* option must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_MEMCORE
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
static uint8_t *nextmem;
static uint8_t *endmem;
@ -73,7 +73,6 @@ void core_init(void) {
* type @p stkalign_t so it is not possible to allocate less
* than <code>sizeof(stkalign_t)</code>.
*
*
* @param[in] size the size of the block to be allocated
* @return A pointer to the allocated memory block.
* @retval NULL allocation failed, core memory exhausted.

View File

@ -26,19 +26,21 @@
* <h2>Operation mode</h2>
* The Memory Pools APIs allow to allocate/free fixed size objects in
* <b>constant time</b> and reliably without memory fragmentation
* problems.<br>
* In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option
* problems.
* @pre In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option
* must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_MEMPOOLS
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
/**
* @brief Initializes an empty memory pool.
* @note The size is internally aligned to be a multiple of the @p align_t
* type size.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p MemoryPool structure.
* @note The size is internally aligned to be a multiple of the
* @p stkalign_t type size.
*
* @param[out] mp pointer to a @p MemoryPool structure
* @param[in] size the size of the objects contained in this memory pool,
@ -96,10 +98,10 @@ void *chPoolAlloc(MemoryPool *mp) {
/**
* @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
* @pre The freed object must be of the right size for the specified
* memory pool.
* @note The object is assumed to be memory aligned to the size of @p align_t
* type.
* @pre The freed object must be memory aligned to the size of
* @p stkalign_t type.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @param[in] objp the pointer to the object to be released or added
@ -116,8 +118,10 @@ void chPoolFreeI(MemoryPool *mp, void *objp) {
/**
* @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
* @pre The freed object must be of the right size for the specified
* memory pool.
* @pre The freed object must be memory aligned to the size of
* @p stkalign_t type.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @param[in] objp the pointer to the object to be released or added

View File

@ -30,20 +30,22 @@
* that messages are not copied between the client and server threads
* but just a pointer passed so the exchange is very time
* efficient.<br>
* Messages are scalar data types of type @p msg_t that are guaranteed
* to be size compatible with data pointers. Note that on some
* architectures function pointers can be larger that @p msg_t.<br>
* Messages are usually processed in FIFO order but it is possible to
* process them in priority order by enabling the
* @p CH_USE_MESSAGES_PRIORITY option in @p chconf.h.<br>
* Applications do not need to allocate buffers for synchronous
* message queues, the mechanism just requires two extra pointers in
* the @p Thread structure (the message queue header).<br>
* In order to use the Messages APIs the @p CH_USE_MESSAGES option
* @pre In order to use the message APIs the @p CH_USE_MESSAGES option
* must be enabled in @p chconf.h.
* @post Enabling messages requires 6-12 (depending on the architecture)
* extra bytes in the @p Thread structure.
* @{
*/
#include "ch.h"
#if CH_USE_MESSAGES
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
#if CH_USE_MESSAGES_PRIORITY
#define msg_insert(tp, qp) prio_insert(tp, qp)
@ -79,13 +81,13 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
/**
* @brief Suspends the thread and waits for an incoming message.
* @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.
* @post After receiving a message the function @p chMsgRelease() must be
* invoked in order to acknowledge the reception and send the answer.
* @note If the message is a pointer then you can assume that the data
* pointed by the message is stable until you invoke @p chMsgRelease()
* because the sending thread is 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.
* @return The message.
*/
msg_t chMsgWait(void) {
msg_t msg;
@ -104,16 +106,14 @@ msg_t chMsgWait(void) {
/**
* @brief Returns the next message in the queue.
* @note You can assume that the data pointed by the message is stable until
* you invoke @p chMsgRelease() because the sending thread is
* suspended until then. Always remember that the message data is not
* copied between the sender and the receiver, just a pointer is
* passed.
* @post After receiving a message the function @p chMsgRelease() must be
* invoked in order to acknowledge the reception and send the answer.
* @note If the message is a pointer then you can assume that the data
* pointed by the message is stable until you invoke @p chMsgRelease()
* because the sending thread is 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.
* @retval NULL if the queue is empty.
* @return The message.
* @retval 0 if the queue is empty.
*/
msg_t chMsgGet(void) {
msg_t msg;
@ -126,12 +126,8 @@ msg_t chMsgGet(void) {
/**
* @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
* the queue else the result will be unpredictable (a crash most likely).
* Exiting from the @p chMsgWait() ensures you have at least one
* 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 as fast as possible.
* @pre Invoke this function only after a message has been received
* using @p chMsgWait() or @p chMsgGet().
*
* @param[in] msg the message returned to the message sender
*/

View File

@ -27,8 +27,8 @@
* <h2>Operation mode</h2>
* A mutex is a threads synchronization object that can be in two
* distinct states:
* - Not owned.
* - Owned by a thread.
* - Not owned (unlocked).
* - Owned by a thread (locked).
* .
* Operations defined for mutexes:
* - <b>Lock</b>: The mutex is checked, if the mutex is not owned by
@ -39,8 +39,6 @@
* priority thread waiting in the queue, if any, is resumed and made
* owner of the mutex.
* .
* In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must
* be enabled in @p chconf.h.
* <h2>Constraints</h2>
* In ChibiOS/RT the Unlock operations are always performed in
* lock-reverse order. The unlock API does not even have a parameter,
@ -59,15 +57,21 @@
* The mechanism works with any number of nested mutexes and any
* number of involved threads. The algorithm complexity (worst case)
* is N with N equal to the number of nested mutexes.
* @pre In order to use the mutex APIs the @p CH_USE_MUTEXES option
* must be enabled in @p chconf.h.
* @post Enabling mutexes requires 5-12 (depending on the architecture)
* extra bytes in the @p Thread structure.
* @{
*/
#include "ch.h"
#if CH_USE_MUTEXES
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Initializes s @p Mutex structure.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p Mutex structure.
*
* @param[out] mp pointer to a @p Mutex structure
*/
@ -81,6 +85,8 @@ void chMtxInit(Mutex *mp) {
/**
* @brief Locks the specified mutex.
* @post The mutex is locked and inserted in the per-thread stack of owned
* mutexes.
*
* @param[in] mp pointer to the @p Mutex structure
*/
@ -95,6 +101,8 @@ void chMtxLock(Mutex *mp) {
/**
* @brief Locks the specified mutex.
* @post The mutex is locked and inserted in the per-thread stack of owned
* mutexes.
*
* @param[in] mp pointer to the @p Mutex structure
*/
@ -164,12 +172,17 @@ void chMtxLockS(Mutex *mp) {
/**
* @brief Tries to lock a mutex.
* @details This function does not have any overhead related to
* the priority inheritance mechanism because it does not try to
* enter a sleep state on the mutex.
* @details This function attempts to lock a mutex, if the mutex is already
* locked by another thread then the function exits without waiting.
* @post The mutex is locked and inserted in the per-thread stack of owned
* mutexes.
* @note This function does not have any overhead related to the
* priority inheritance mechanism because it does not try to
* enter a sleep state.
*
* @param[in] mp pointer to the @p Mutex structure
* @retval TRUE if the mutex was successfully acquired
* @return The operation status.
* @retval TRUE if the mutex has been successfully acquired
* @retval FALSE if the lock attempt failed.
*/
bool_t chMtxTryLock(Mutex *mp) {
@ -185,12 +198,17 @@ bool_t chMtxTryLock(Mutex *mp) {
/**
* @brief Tries to lock a mutex.
* @details This function does not have any overhead related to
* the priority inheritance mechanism because it does not try to
* enter a sleep state on the mutex.
* @details This function attempts to lock a mutex, if the mutex is already
* taken by another thread then the function exits without waiting.
* @post The mutex is locked and inserted in the per-thread stack of owned
* mutexes.
* @note This function does not have any overhead related to the
* priority inheritance mechanism because it does not try to
* enter a sleep state.
*
* @param[in] mp pointer to the @p Mutex structure
* @retval TRUE if the mutex was successfully acquired
* @return The operation status.
* @retval TRUE if the mutex has been successfully acquired
* @retval FALSE if the lock attempt failed.
*/
bool_t chMtxTryLockS(Mutex *mp) {
@ -207,8 +225,11 @@ bool_t chMtxTryLockS(Mutex *mp) {
/**
* @brief Unlocks the next owned mutex in reverse lock order.
* @pre The invoking thread <b>must</b> have at least one owned mutex.
* @post The mutex is unlocked and removed from the per-thread stack of
* owned mutexes.
*
* @return The pointer to the unlocked mutex.
* @return A pointer to the unlocked mutex.
*/
Mutex *chMtxUnlock(void) {
Thread *ctp = currp;
@ -260,9 +281,13 @@ Mutex *chMtxUnlock(void) {
/**
* @brief Unlocks the next owned mutex in reverse lock order.
* @note This function does not reschedule internally.
* @pre The invoking thread <b>must</b> have at least one owned mutex.
* @post The mutex is unlocked and removed from the per-thread stack of
* owned mutexes.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel.
*
* @return The pointer to the unlocked mutex.
* @return A pointer to the unlocked mutex.
*/
Mutex *chMtxUnlockS(void) {
Thread *ctp = currp;
@ -311,7 +336,9 @@ Mutex *chMtxUnlockS(void) {
/**
* @brief Unlocks all the mutexes owned by the invoking thread.
* @details This function is <b>MUCH MORE</b> efficient than releasing the
* @post The stack of owned mutexes is emptied and all the found
* mutexes are unlocked.
* @note This function 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.

View File

@ -35,21 +35,23 @@
* are implemented by pairing an input queue and an output queue
* together.
* .
* In order to use the I/O queues the @p CH_USE_QUEUES option must
* be enabled in @p chconf.h.<br>
* I/O queues are usually used as an implementation layer for the I/O
* channels interface, also see @ref io_channels.
* @pre In order to use the I/O queues the @p CH_USE_QUEUES option must
* be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_QUEUES
#if CH_USE_QUEUES || defined(__DOXYGEN__)
/**
* @brief Initializes an input queue.
* @details A Semaphore is internally initialized and works as a counter of
* the bytes contained in the queue.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p InputQueue structure.
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
*
@ -88,7 +90,7 @@ void chIQResetI(InputQueue *iqp) {
*
* @param[in] iqp pointer to an @p InputQueue structure
* @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.
* @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.
@ -117,7 +119,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @return A byte value from the queue or:
* @return A byte value from the queue.
* @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the queue was reset.
*/
@ -205,6 +207,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
* @brief Initializes an output queue.
* @details A Semaphore is internally initialized and works as a counter of
* the free bytes in the queue.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p OutputQueue structure.
* @note The callback is invoked from within the S-Locked system state,
* see @ref system_states.
*
@ -250,7 +254,7 @@ void chOQResetI(OutputQueue *oqp) {
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @return The operation status:
* @return The operation status.
* @retval Q_OK if the operation succeeded.
* @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the queue was reset.
@ -279,7 +283,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) {
* @details A byte value is read from the low end of an output queue.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @return The byte value from the queue or:
* @return The byte value from the queue.
* @retval Q_EMPTY if the queue is empty.
*/
msg_t chOQGetI(OutputQueue *oqp) {

View File

@ -40,25 +40,24 @@
* Another possible use is for centralized threads memory management,
* terminating threads can pulse an event source and an event handler
* can perform a scansion of the registry in order to recover the
* memory.<br>
* In order to use the threads registry the @p CH_USE_REGISTRY option
* memory.
* @pre In order to use the threads registry the @p CH_USE_REGISTRY option
* must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_REGISTRY
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
/**
* @brief Returns the first thread in the system.
* @details Returns the most ancient thread in the system, usually this is
* the main thread unless it terminated.
* @note A reference is added to the returned thread in order to make sure
* it status is not lost.
* the main thread unless it terminated. A reference is added to the
* returned thread in order to make sure its status is not lost.
* @note This function cannot return @p NULL because there is always at
* least one thread in the system.
*
* @return A reference to the first thread.
* @return A reference to the most ancient thread.
*/
Thread *chRegFirstThread(void) {
Thread *tp;

View File

@ -57,11 +57,15 @@ void scheduler_init(void) {
/**
* @brief Inserts a thread in the Ready List.
* @note The function does not reschedule, the @p chSchRescheduleS() should
* be called soon after.
* @pre The thread must not be already inserted in any list through its
* @p p_next and @p p_prev or list corruption would occur.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the Thread to be made ready
* @return The Thread pointer.
* @param[in] tp the thread to be made ready
* @return The thread pointer.
*/
#if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__)
#if CH_OPTIMIZE_SPEED
@ -93,8 +97,8 @@ Thread *chSchReadyI(Thread *tp) {
/**
* @brief Puts the current thread to sleep into the specified state.
* @details The thread goes into a sleeping state. The @ref thread_states are
* described into @p threads.h.
* @details The thread goes into a sleeping state. The possible
* @ref thread_states are defined into @p threads.h.
*
* @param[in] newstate the new thread state
*/
@ -144,8 +148,8 @@ static void wakeup(void *p) {
* timeout specification.
* @details The thread goes into a sleeping state, if it is not awakened
* explicitly within the specified timeout then it is forcibly
* awakened with a @p RDY_TIMEOUT low level message. The @ref
* thread_states are described into @p threads.h.
* awakened with a @p RDY_TIMEOUT low level message. The possible
* @ref thread_states are defined into @p threads.h.
*
* @param[in] newstate the new thread state
* @param[in] time the number of ticks before the operation timeouts, the
@ -181,6 +185,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
* @details The thread is inserted into the ready list or immediately made
* running depending on its relative priority compared to the current
* thread.
* @pre The thread must not be already inserted in any list through its
* @p p_next and @p p_prev or list corruption would occur.
* @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

View File

@ -50,15 +50,15 @@
* also have other uses, queues guards and counters as example.<br>
* Semaphores usually use a FIFO queuing strategy but it is possible
* to make them order threads by priority by enabling
* @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.<br>
* In order to use the Semaphores APIs the @p CH_USE_SEMAPHORES
* @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.
* @pre In order to use the semaphore APIs the @p CH_USE_SEMAPHORES
* option must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
#if CH_USE_SEMAPHORES
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
#if CH_USE_SEMAPHORES_PRIORITY
#define sem_insert(tp, qp) prio_insert(tp, qp)
@ -68,6 +68,8 @@
/**
* @brief Initializes a semaphore with the specified counter value.
* @note This function can be invoked before the kernel is initialized
* because it just prepares a @p Semaphore structure.
*
* @param[out] sp pointer to a @p Semaphore structure
* @param[in] n initial value of the semaphore counter. Must be
@ -83,6 +85,9 @@ void chSemInit(Semaphore *sp, cnt_t n) {
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @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.
@ -101,10 +106,16 @@ void chSemReset(Semaphore *sp, cnt_t n) {
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
* @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.
* @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
@ -130,8 +141,11 @@ void chSemResetI(Semaphore *sp, cnt_t n) {
* @brief Performs a wait operation on a semaphore.
*
* @param[in] sp pointer to a @p Semaphore structure
* @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @return A message specifying how the invoking thread has been
* released from the semaphore.
* @retval RDY_OK if the thread has not stopped on the semaphore or the
* semaphore has been signaled.
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
*/
msg_t chSemWait(Semaphore *sp) {
msg_t msg;
@ -146,8 +160,11 @@ msg_t chSemWait(Semaphore *sp) {
* @brief Performs a wait operation on a semaphore.
*
* @param[in] sp pointer to a @p Semaphore structure
* @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @return A message specifying how the invoking thread has been
* released from the semaphore.
* @retval RDY_OK if the thread has not stopped on the semaphore or the
* semaphore has been signaled.
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
*/
msg_t chSemWaitS(Semaphore *sp) {
@ -176,10 +193,13 @@ msg_t chSemWaitS(Semaphore *sp) {
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @retval RDY_OK if the semaphore was signaled or not taken.
* @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 timeout.
* @return A message specifying how the invoking thread has been
* released from the semaphore.
* @retval RDY_OK if the thread has not stopped on the semaphore or the
* semaphore has been signaled.
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
* @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within
* the specified timeout.
*/
msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
msg_t msg;
@ -199,10 +219,13 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout.
* .
* @retval RDY_OK if the semaphore was signaled or not taken.
* @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 timeout.
* @return A message specifying how the invoking thread has been
* released from the semaphore.
* @retval RDY_OK if the thread has not stopped on the semaphore or the
* semaphore has been signaled.
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
* @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within
* the specified timeout.
*/
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
@ -247,7 +270,10 @@ void chSemSignal(Semaphore *sp) {
/**
* @brief Performs a signal operation on a semaphore.
* @note This function does not reschedule.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] sp pointer to a @p Semaphore structure
*/
@ -272,13 +298,16 @@ void chSemSignalI(Semaphore *sp) {
#if CH_USE_SEMSW
/**
* @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.
* @pre The configuration option @p CH_USE_SEMSW must be enabled in order
* to use this function.
*
* @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
* @retval RDY_OK if the semaphore was signaled or not taken.
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
* @return A message specifying how the invoking thread has been
* released from the semaphore.
* @retval RDY_OK if the thread has not stopped on the semaphore or the
* semaphore has been signaled.
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
*/
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
msg_t msg;

View File

@ -63,9 +63,9 @@ void _idle_thread(void *p) {
* @brief ChibiOS/RT initialization.
* @details After executing this function the current instructions stream
* becomes the main thread.
* @note Interrupts should be still disabled when @p chSysInit() is invoked
* @pre Interrupts must be still disabled when @p chSysInit() is invoked
* and are internally enabled.
* @note The main thread is created with priority @p NORMALPRIO.
* @post The main thread is created with priority @p NORMALPRIO.
*/
void chSysInit(void) {
static Thread mainthread;

View File

@ -59,6 +59,7 @@
/**
* @brief Initializes a thread structure.
* @note This is an internal functions, do not use it in application code.
*
* @param[in] tp pointer to the thread
* @param[in] prio the priority level for the new thread
@ -112,6 +113,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
* @brief Initializes a new thread.
* @details The new thread is initialized but not inserted in the ready list,
* the initial state is @p THD_STATE_SUSPENDED.
* @post The initialized thread can be subsequently started by invoking
* @p chThdResume().
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note This function can be invoked from within an interrupt handler
@ -166,13 +169,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
#if CH_USE_DYNAMIC && CH_USE_HEAP
/**
* @brief Creates a new thread allocating the memory from the heap.
* @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP
* must be enabled in order to use this function.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
*
* @param[in] heapp heap from which allocate the memory or @p NULL for the
* default heap
@ -202,14 +204,13 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
/**
* @brief Creates a new thread allocating the memory from the specified
* Memory Pool.
* memory pool.
* @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS
* must be enabled in order to use this function.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
*
* @param[in] mp pointer to the memory pool object
* @param[in] prio the priority level for the new thread
@ -270,7 +271,11 @@ tprio_t chThdSetPriority(tprio_t newprio) {
/**
* @brief Resumes a suspended thread.
* @note Use this function to resume threads created with @p chThdInit().
* @pre The specified thread pointer must refer to an initialized thread
* in the @p THD_STATE_SUSPENDED state.
* @post The specified thread is immediately started or put in the ready
* list depending on the relative priority levels.
* @note Use this function to start threads created with @p chThdInit().
*
* @param[in] tp pointer to the thread
* @return The pointer to the thread.
@ -288,9 +293,11 @@ Thread *chThdResume(Thread *tp) {
/**
* @brief Requests a thread termination.
* @note The thread is not terminated but a termination request is added to
* its @p p_flags field. The thread can read this status by
* invoking @p chThdShouldTerminate() and then terminate cleanly.
* @pre The target thread must be written to invoke periodically
* @p chThdShouldTerminate() and terminate cleanly if it returns
* @p TRUE.
* @post The specified thread will terminate after detecting the termination
* condition.
*
* @param[in] tp pointer to the thread
*/
@ -349,10 +356,14 @@ void chThdYield(void) {
}
/**
* @brief Terminates the current thread by specifying an exit status code.
* @brief Terminates the current thread.
* @details The thread goes in the @p THD_STATE_FINAL state holding the
* specified exit status code, other threads can retrieve the
* exit status code by invoking the function @p chThdWait().
* @post Eventual code after this function will never be executed,
* this function never returns.
*
* @param[in] msg thread exit code. The code can be retrieved by using
* @p chThdWait().
* @param[in] msg thread exit code
*/
void chThdExit(msg_t msg) {
Thread *tp = currp;
@ -375,6 +386,8 @@ void chThdExit(msg_t msg) {
#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
/**
* @brief Adds a reference to a thread object.
* @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order
* to use this function.
*
* @param[in] tp pointer to the thread
* @return The same thread pointer passed as parameter
@ -394,6 +407,8 @@ Thread *chThdAddRef(Thread *tp) {
* @details If the references counter reaches zero <b>and</b> the thread
* is in the @p THD_STATE_FINAL state then the thread's memory is
* returned to the proper allocator.
* @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order
* to use this function.
* @note Static threads are not affected.
*
* @param[in] tp pointer to the thread
@ -444,10 +459,10 @@ void chThdRelease(Thread *tp) {
* then the working area is returned to the owning memory pool.
* .
* Please read the @ref article_lifecycle article for more details.
* @note After invoking @p chThdWait() the thread pointer becomes invalid
* @pre The configuration option @p CH_USE_WAITEXIT must be enabled in
* order to use this function.
* @post After invoking @p chThdWait() the thread pointer becomes invalid
* and must not be used as parameter for further system calls.
* @note The function is available only if the @p CH_USE_WAITEXIT
* option is enabled in @p chconf.h.
* @note If @p CH_USE_DYNAMIC is not specified this function just waits for
* the thread termination, no memory allocators are involved.
*

View File

@ -108,6 +108,9 @@
the ARM7 port.
- OPT: Speed optimizations of the STM32 SPI driver, improved latency.
- OPT: Speed optimizations of the STM32 ADC driver.
- CHANGE: The event APIs chEvtPend() and chEvtClear() have been renamed
to chEvtAddFlags() and chEvtClearFlags() for consistency and correct
English (which I am famous for...).
- CHANGE: Added a parameter to the UART driver callbacks, the pointer to the
driver itself.
- CHANGE: In the UART driver now an error does not automatically brings the

View File

@ -77,7 +77,7 @@ static EVENTSOURCE_DECL(es2);
static void evt1_setup(void) {
chEvtClear(ALL_EVENTS);
chEvtClearFlags(ALL_EVENTS);
}
static void h1(eventid_t id) {(void)id;test_emit_token('A');}
@ -130,7 +130,7 @@ ROMCONST struct testcase testevt1 = {
static void evt2_setup(void) {
chEvtClear(ALL_EVENTS);
chEvtClearFlags(ALL_EVENTS);
}
static msg_t thread1(void *p) {
@ -157,12 +157,12 @@ static void evt2_execute(void) {
/*
* Test on chEvtWaitOne() without wait.
*/
chEvtPend(5);
chEvtAddFlags(5);
m = chEvtWaitOne(ALL_EVENTS);
test_assert(1, m == 1, "single event error");
m = chEvtWaitOne(ALL_EVENTS);
test_assert(2, m == 4, "single event error");
m = chEvtClear(ALL_EVENTS);
m = chEvtClearFlags(ALL_EVENTS);
test_assert(3, m == 0, "stuck event");
/*
@ -175,17 +175,17 @@ static void evt2_execute(void) {
m = chEvtWaitOne(ALL_EVENTS);
test_assert_time_window(4, target_time, target_time + ALLOWED_DELAY);
test_assert(5, m == 1, "single event error");
m = chEvtClear(ALL_EVENTS);
m = chEvtClearFlags(ALL_EVENTS);
test_assert(6, m == 0, "stuck event");
test_wait_threads();
/*
* Test on chEvtWaitAny() without wait.
*/
chEvtPend(5);
chEvtAddFlags(5);
m = chEvtWaitAny(ALL_EVENTS);
test_assert(7, m == 5, "unexpected pending bit");
m = chEvtClear(ALL_EVENTS);
m = chEvtClearFlags(ALL_EVENTS);
test_assert(8, m == 0, "stuck event");
/*
@ -198,7 +198,7 @@ static void evt2_execute(void) {
m = chEvtWaitAny(ALL_EVENTS);
test_assert_time_window(9, target_time, target_time + ALLOWED_DELAY);
test_assert(10, m == 1, "single event error");
m = chEvtClear(ALL_EVENTS);
m = chEvtClearFlags(ALL_EVENTS);
test_assert(11, m == 0, "stuck event");
test_wait_threads();
@ -215,7 +215,7 @@ static void evt2_execute(void) {
thread2, "A");
m = chEvtWaitAll(5);
test_assert_time_window(12, target_time, target_time + ALLOWED_DELAY);
m = chEvtClear(ALL_EVENTS);
m = chEvtClearFlags(ALL_EVENTS);
test_assert(13, m == 0, "stuck event");
test_wait_threads();
chEvtUnregister(&es1, &el1);
@ -249,7 +249,7 @@ ROMCONST struct testcase testevt2 = {
static void evt3_setup(void) {
chEvtClear(ALL_EVENTS);
chEvtClearFlags(ALL_EVENTS);
}
static void evt3_execute(void) {