Kernel headers cleanup.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1568 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2010-02-06 12:31:09 +00:00
parent f17db1931e
commit 8e428dbd1a
20 changed files with 758 additions and 602 deletions

View File

@ -20,6 +20,8 @@
/** /**
* @file channels.h * @file channels.h
* @brief I/O channels. * @brief I/O channels.
* @details This header defines abstract interfaces useful to access generic
* I/O resources in a standardized way.
* *
* @addtogroup io_channels * @addtogroup io_channels
* @{ * @{
@ -29,7 +31,7 @@
#define _CHANNELS_H_ #define _CHANNELS_H_
/** /**
* @brief @p BaseChannel specific methods. * @brief @p BaseChannel specific methods.
*/ */
#define _base_channel_methods \ #define _base_channel_methods \
_base_sequental_stream_methods \ _base_sequental_stream_methods \
@ -48,15 +50,15 @@
size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time); size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time);
/** /**
* @brief @p BaseChannel specific data. * @brief @p BaseChannel specific data.
* @note It is empty because @p BaseChannel is only an interface without * @note It is empty because @p BaseChannel is only an interface without
* implementation. * implementation.
*/ */
#define _base_channel_data \ #define _base_channel_data \
_base_sequental_stream_data _base_sequental_stream_data
/** /**
* @brief @p BaseChannel virtual methods table. * @brief @p BaseChannel virtual methods table.
*/ */
struct BaseChannelVMT { \ struct BaseChannelVMT { \
_base_channel_methods \ _base_channel_methods \
@ -65,149 +67,149 @@ struct BaseChannelVMT { \
/** /**
* @extends BaseSequentialStream * @extends BaseSequentialStream
* *
* @brief Base channel class. * @brief Base channel class.
* @details This class represents a generic, byte-wide, I/O channel. This class * @details This class represents a generic, byte-wide, I/O channel. This class
* introduces generic I/O primitives with timeout specification. * introduces generic I/O primitives with timeout specification.
*/ */
typedef struct { typedef struct {
/** /** @brief Virtual Methods Table.*/
* Virtual Methods Table.
*/
const struct BaseChannelVMT *vmt; const struct BaseChannelVMT *vmt;
_base_channel_data _base_channel_data
} BaseChannel; } BaseChannel;
/** /**
* @brief Channel output check. * @brief Channel output check.
* @details This function verifies if a subsequent put/write operation would * @details This function verifies if a subsequent put/write operation would
* block. * block.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @return The output queue status: * @return The output queue status:
* @retval FALSE if the output queue has space and would not block a write * @retval FALSE if the output queue has space and would not block a
* operation. * write operation.
* @retval TRUE if the output queue is full and would block a write operation. * @retval TRUE if the output queue is full and would block a write
* operation.
*/ */
#define chIOPutWouldBlock(ip) ((ip)->vmt->putwouldblock(ip)) #define chIOPutWouldBlock(ip) ((ip)->vmt->putwouldblock(ip))
/** /**
* @brief Channel input check. * @brief Channel input check.
* @details This function verifies if a subsequent get/read operation would * @details This function verifies if a subsequent get/read operation would
* block. * block.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @return The input queue status: * @return The input queue status:
* @retval FALSE if the input queue contains data and would not block a read * @retval FALSE if the input queue contains data and would not block a
* operation. * read operation.
* @retval TRUE if the input queue is empty and would block a read operation. * @retval TRUE if the input queue is empty and would block a read
* operation.
*/ */
#define chIOGetWouldBlock(ip) ((ip)->vmt->getwouldblock(ip)) #define chIOGetWouldBlock(ip) ((ip)->vmt->getwouldblock(ip))
/** /**
* @brief Channel blocking byte write. * @brief Channel blocking byte write.
* @details This function writes a byte value to a channel. If the channel * @details This function writes a byte value to a channel. If the channel
* is not ready to accept data then the calling thread is suspended. * is not ready to accept data then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @param[in] b the byte value to be written to the channel * @param[in] b the byte value to be written to the channel
* @return The operation status: * @return The operation status:
* @retval Q_OK if the operation succeeded. * @retval Q_OK if the operation succeeded.
* @retval Q_RESET if the channel associated queue (if any) was reset. * @retval Q_RESET if the channel associated queue (if any) was reset.
*/ */
#define chIOPut(ip, b) ((ip)->vmt->put(ip, b, TIME_INFINITE)) #define chIOPut(ip, b) ((ip)->vmt->put(ip, b, TIME_INFINITE))
/** /**
* @brief Channel blocking byte write with timeout. * @brief Channel blocking byte write with timeout.
* @details This function writes a byte value to a channel. If the channel * @details This function writes a byte value to a channel. If the channel
* is not ready to accept data then the calling thread is suspended. * is not ready to accept data then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @param[in] b the byte value to be written to the channel * @param[in] b the byte value to be written to the channel
* @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.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return The operation status: * @return The operation status:
* @retval Q_OK if the operation succeeded. * @retval Q_OK if the operation succeeded.
* @retval Q_TIMEOUT if the specified time expired. * @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the channel associated queue (if any) was reset. * @retval Q_RESET if the channel associated queue (if any) was reset.
*/ */
#define chIOPutTimeout(ip, b, time) ((ip)->vmt->put(ip, b, time)) #define chIOPutTimeout(ip, b, time) ((ip)->vmt->put(ip, b, time))
/** /**
* @brief Channel blocking byte read. * @brief Channel blocking byte read.
* @details This function reads a byte value from a channel. If the data * @details This function reads a byte value from a channel. If the data
* is not available then the calling thread is suspended. * is not available then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @return A byte value from the queue or: * @return A byte value from the queue or:
* @retval Q_RESET if the channel associated queue (if any) was reset. * @retval Q_RESET if the channel associated queue (if any) was reset.
*/ */
#define chIOGet(ip) ((ip)->vmt->get(ip, TIME_INFINITE)) #define chIOGet(ip) ((ip)->vmt->get(ip, TIME_INFINITE))
/** /**
* @brief Channel blocking byte read with timeout. * @brief Channel blocking byte read with timeout.
* @details This function reads a byte value from a channel. If the data * @details This function reads a byte value from a channel. If the data
* is not available then the calling thread is suspended. * is not available then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @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.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return A byte value from the queue or: * @return A byte value from the queue or:
* @retval Q_TIMEOUT if the specified time expired. * @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the channel associated queue (if any) was reset. * @retval Q_RESET if the channel associated queue (if any) was reset.
*/ */
#define chIOGetTimeout(ip, time) ((ip)->vmt->get(ip, time)) #define chIOGetTimeout(ip, time) ((ip)->vmt->get(ip, time))
/** /**
* @brief Channel blocking write with timeout. * @brief Channel blocking write with timeout.
* @details The function writes data from a buffer to a channel. If the channel * @details The function writes data from a buffer to a channel. If the channel
* is not ready to accept data then the calling thread is suspended. * is not ready to accept data then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @param[out] bp pointer to the data buffer * @param[out] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred * @param[in] n the maximum amount of data to be transferred
* @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.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return The number of bytes transferred. * @return The number of bytes transferred.
*/ */
#define chIOWriteTimeout(ip, bp, n, time) \ #define chIOWriteTimeout(ip, bp, n, time) \
((ip)->vmt->write(ip, bp, n, time)) ((ip)->vmt->write(ip, bp, n, time))
/** /**
* @brief Channel blocking read with timeout. * @brief Channel blocking read with timeout.
* @details The function reads data from a channel into a buffer. If the data * @details The function reads data from a channel into a buffer. If the data
* is not available then the calling thread is suspended. * is not available then the calling thread is suspended.
* *
* @param[in] ip pointer to a @p BaseChannel or derived class * @param[in] ip pointer to a @p BaseChannel or derived class
* @param[in] bp pointer to the data buffer * @param[in] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred * @param[in] n the maximum amount of data to be transferred
* @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.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return The number of bytes transferred. * @return The number of bytes transferred.
*/ */
#define chIOReadTimeout(ip, bp, n, time) \ #define chIOReadTimeout(ip, bp, n, time) \
((ip)->vmt->read(ip, bp, n, time)) ((ip)->vmt->read(ip, bp, n, time))
#if CH_USE_EVENTS #if CH_USE_EVENTS
/** /**
* @brief @p BaseAsynchronousChannel specific methods. * @brief @p BaseAsynchronousChannel specific methods.
*/ */
#define _base_asynchronous_channel_methods \ #define _base_asynchronous_channel_methods \
_base_channel_methods _base_channel_methods
/** /**
* @brief @p BaseAsynchronousChannel specific data. * @brief @p BaseAsynchronousChannel specific data.
*/ */
#define _base_asynchronous_channel_data \ #define _base_asynchronous_channel_data \
_base_channel_data \ _base_channel_data \
@ -217,7 +219,7 @@ typedef struct {
EventSource oevent; EventSource oevent;
/** /**
* @brief @p BaseAsynchronousChannel virtual methods table. * @brief @p BaseAsynchronousChannel virtual methods table.
*/ */
struct BaseAsynchronousChannelVMT { struct BaseAsynchronousChannelVMT {
_base_asynchronous_channel_methods _base_asynchronous_channel_methods
@ -226,35 +228,37 @@ struct BaseAsynchronousChannelVMT {
/** /**
* @extends BaseChannel * @extends BaseChannel
* *
* @brief Base asynchronous channel class. * @brief Base asynchronous channel class.
* @details This class extends @p BaseChannel by adding event sources fields * @details This class extends @p BaseChannel by adding event sources fields
* for asynchronous I/O for use in an event-driven environment. * for asynchronous I/O for use in an event-driven environment.
*/ */
typedef struct { typedef struct {
/** /** @brief Virtual Methods Table.*/
* Virtual Methods Table.
*/
const struct BaseAsynchronousChannelVMT *vmt; const struct BaseAsynchronousChannelVMT *vmt;
_base_asynchronous_channel_data _base_asynchronous_channel_data
} BaseAsynchronousChannel; } BaseAsynchronousChannel;
/** /**
* @brief Returns the write event source. * @brief Returns the write event source.
* @details The write event source is broadcasted when the channel is ready * @details The write event source is broadcasted when the channel is ready
* for write operations. This usually happens when the internal * for write operations. This usually happens when the internal
* output queue becomes empty. * output queue becomes empty.
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class *
* @return A pointer to an @p EventSource object. * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
* class
* @return A pointer to an @p EventSource object.
*/ */
#define chIOGetWriteEventSource(ip) (&((ip)->vmt->oevent)) #define chIOGetWriteEventSource(ip) (&((ip)->vmt->oevent))
/** /**
* @brief Returns the read event source. * @brief Returns the read event source.
* @details The read event source is broadcasted when the channel is ready * @details The read event source is broadcasted when the channel is ready
* for read operations. This usually happens when the internal * for read operations. This usually happens when the internal
* input queue becomes non-empty. * input queue becomes non-empty.
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class *
* @return A pointer to an @p EventSource object. * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
* class
* @return A pointer to an @p EventSource object.
*/ */
#define chIOGetReadEventSource(ip) (&((ip)->vmt->ievent)) #define chIOGetReadEventSource(ip) (&((ip)->vmt->ievent))

View File

@ -22,8 +22,9 @@
*/ */
/** /**
* @file condvars.h * @file condvars.h
* @brief Condition Variables macros and structures. * @brief Condition Variables macros and structures.
*
* @addtogroup condvars * @addtogroup condvars
* @{ * @{
*/ */
@ -41,10 +42,10 @@
#endif #endif
/** /**
* @brief CondVar structure. * @brief CondVar structure.
*/ */
typedef struct CondVar { typedef struct CondVar {
ThreadsQueue c_queue; /**< CondVar threads queue.*/ ThreadsQueue c_queue; /**< @brief CondVar threads queue.*/
} CondVar; } CondVar;
#ifdef __cplusplus #ifdef __cplusplus
@ -69,6 +70,8 @@ extern "C" {
* @brief Data part of a static condition variable initializer. * @brief Data part of a static condition variable initializer.
* @details This macro should be used when statically initializing a condition * @details This macro should be used when statically initializing a condition
* variable that is part of a bigger structure. * variable that is part of a bigger structure.
*
* @param[in] name the name of the condition variable
*/ */
#define _CONDVAR_DATA(name) {_THREADSQUEUE_DATA(name.c_queue)} #define _CONDVAR_DATA(name) {_THREADSQUEUE_DATA(name.c_queue)}
@ -76,7 +79,8 @@ extern "C" {
* @brief Static condition variable initializer. * @brief Static condition variable initializer.
* @details Statically initialized condition variables require no explicit * @details Statically initialized condition variables require no explicit
* initialization using @p chCondInit(). * initialization using @p chCondInit().
* @param name the name of the condition variable *
* @param[in] name the name of the condition variable
*/ */
#define CONDVAR_DECL(name) CondVar name = _CONDVAR_DATA(name) #define CONDVAR_DECL(name) CondVar name = _CONDVAR_DATA(name)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file debug.h * @file debug.h
* @brief Debug macros and structures. * @brief Debug macros and structures.
*
* @addtogroup debug * @addtogroup debug
* @{ * @{
*/ */
@ -31,56 +32,63 @@
* @brief Trace buffer entries. * @brief Trace buffer entries.
*/ */
#ifndef TRACE_BUFFER_SIZE #ifndef TRACE_BUFFER_SIZE
#define TRACE_BUFFER_SIZE 64 #define TRACE_BUFFER_SIZE 64
#endif #endif
/** /**
* @brief Fill value for thread stack area in debug mode. * @brief Fill value for thread stack area in debug mode.
*/ */
#ifndef STACK_FILL_VALUE #ifndef STACK_FILL_VALUE
#define STACK_FILL_VALUE 0x55 #define STACK_FILL_VALUE 0x55
#endif #endif
/** /**
* @brief Fill value for thread area in debug mode. * @brief Fill value for thread area in debug mode.
* @note The chosen default value is 0xFF in order to make evident which * @note The chosen default value is 0xFF in order to make evident which
* thread fields were not initialized when inspecting the memory with * thread fields were not initialized when inspecting the memory with
* a debugger. A uninitialized field is not an error in itself but it * a debugger. A uninitialized field is not an error in itself but it
* better to know it. * better to know it.
*/ */
#ifndef THREAD_FILL_VALUE #ifndef THREAD_FILL_VALUE
#define THREAD_FILL_VALUE 0xFF #define THREAD_FILL_VALUE 0xFF
#endif #endif
/** /**
* @brief Trace buffer record. * @brief Trace buffer record.
*/ */
typedef struct { typedef struct {
void *cse_wtobjp; /**< Object where going to sleep.*/ void *cse_wtobjp; /**< @brief Object where going to
systime_t cse_time; /**< Time of the switch event.*/ sleep. */
uint16_t cse_state: 4; /**< Switched out thread state.*/ systime_t cse_time; /**< @brief Time of the switch
uint16_t cse_tid: 12; /**< Switched in thdread id.*/ event. */
uint16_t cse_state: 4; /**< @brief Switched out thread
state. */
uint16_t cse_tid: 12; /**< @brief Switched in thread id. */
} CtxSwcEvent; } CtxSwcEvent;
/** /**
* @brief Trace buffer header. * @brief Trace buffer header.
*/ */
typedef struct { typedef struct {
unsigned tb_size; /**< Trace buffer size (records).*/ unsigned tb_size; /**< @brief Trace buffer size
CtxSwcEvent *tb_ptr; /**< Pointer to the ring buffer front.*/ (entries). */
CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/ CtxSwcEvent *tb_ptr; /**< @brief Pointer to the ring buffer
front. */
/** @brief Ring buffer.*/
CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE];
} TraceBuffer; } TraceBuffer;
#define __QUOTE_THIS(p) #p #define __QUOTE_THIS(p) #p
#if CH_DBG_ENABLE_CHECKS #if CH_DBG_ENABLE_CHECKS
/** /**
* Function parameter check, if the condition check fails then the kernel * @brief Function parameter check.
* panics. * @details If the condition check fails then the kernel panics and halts.
* @param c the condition to be verified to be true * @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch
* @param func the undecorated function name * is specified in @p chconf.h else the macro does nothing.
* @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch is *
* specified in @p chconf.h else the macro does nothing. * @param[in] c the condition to be verified to be true
* @param[in] func the undecorated function name
*/ */
#define chDbgCheck(c, func) { \ #define chDbgCheck(c, func) { \
if (!(c)) \ if (!(c)) \
@ -94,17 +102,19 @@ typedef struct {
#if CH_DBG_ENABLE_ASSERTS #if CH_DBG_ENABLE_ASSERTS
/** /**
* Condition assertion, if the condition check fails then the kernel panics * @brief Condition assertion.
* with the specified message. * @details If the condition check fails then the kernel panics with the
* @param c the condition to be verified to be true * specified message and halts.
* @param m the text message * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch
* @param r a remark string * is specified in @p chconf.h else the macro does nothing.
* @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch is * @note The convention for the message is the following:<br>
* specified in @p chconf.h else the macro does nothing. * @<function_name@>(), #@<assert_number@>
* @note The convention for the message is the following:<br> * @note The remark string is not currently used except for putting a
* @<function_name@>(), #@<assert_number@> * comment in the code about the assertion.
* @note The remark string is not currently used except for putting a comment *
* in the code about the assert. * @param[in] c the condition to be verified to be true
* @param[in] m the text message
* @param[in] r a remark string
*/ */
#define chDbgAssert(c, m, r) { \ #define chDbgAssert(c, m, r) { \
if (!(c)) \ if (!(c)) \
@ -114,15 +124,17 @@ typedef struct {
#define chDbgAssert(c, m, r) {(void)(c);} #define chDbgAssert(c, m, r) {(void)(c);}
#endif /* !CH_DBG_ENABLE_ASSERTS */ #endif /* !CH_DBG_ENABLE_ASSERTS */
#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)
/* When the debug features are disabled this function is replaced by an empty /* When the debug features are disabled this function is replaced by an empty
* macro.*/ macro.*/
#define chDbgPanic(msg) {} #define chDbgPanic(msg) {}
#endif #endif
#if !CH_DBG_ENABLE_TRACE #if !CH_DBG_ENABLE_TRACE
/* When the trace feature is disabled this function is replaced by an empty /* When the trace feature is disabled this function is replaced by an empty
* macro.*/ macro.*/
#define chDbgTrace(otp, ntp) {} #define chDbgTrace(otp, ntp) {}
#endif #endif

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file events.h * @file events.h
* @brief Events macros and structures. * @brief Events macros and structures.
*
* @addtogroup events * @addtogroup events
* @{ * @{
*/ */
@ -32,27 +33,30 @@
typedef struct EventListener EventListener; typedef struct EventListener EventListener;
/** /**
* @brief Event Listener structure. * @brief Event Listener structure.
*/ */
struct EventListener { struct EventListener {
EventListener *el_next; /**< Next Event Listener registered on EventListener *el_next; /**< @brief Next Event Listener
the Event Source.*/ registered on the Event
Thread *el_listener; /**< Thread interested in the Event Source. */
Source.*/ Thread *el_listener; /**< @brief Thread interested in the
eventmask_t el_mask; /**< Event flags mask associated by the Event Source. */
thread to the Event Source.*/ eventmask_t el_mask; /**< @brief Event flags mask associated
by the thread to the Event
Source. */
}; };
/** /**
* @brief Event Source structure. * @brief Event Source structure.
*/ */
typedef struct EventSource { typedef struct EventSource {
EventListener *es_next; /**< First Event Listener registered on EventListener *es_next; /**< @brief First Event Listener
the Event Source.*/ registered on the Event
Source. */
} EventSource; } EventSource;
/** /**
* @brief Data part of a static event source initializer. * @brief Data part of a static event source initializer.
* @details This macro should be used when statically initializing an event * @details This macro should be used when statically initializing an event
* source that is part of a bigger structure. * source that is part of a bigger structure.
* @param name the name of the event source variable * @param name the name of the event source variable
@ -60,10 +64,11 @@ typedef struct EventSource {
#define _EVENTSOURCE_DATA(name) {(void *)(&name)} #define _EVENTSOURCE_DATA(name) {(void *)(&name)}
/** /**
* @brief Static event source initializer. * @brief Static event source initializer.
* @details Statically initialized event sources require no explicit * @details Statically initialized event sources require no explicit
* initialization using @p chEvtInit(). * initialization using @p chEvtInit().
* @param name the name of the event source variable *
* @param name the name of the event source variable
*/ */
#define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name) #define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
@ -74,36 +79,41 @@ typedef struct EventSource {
#define EVENT_MASK(eid) (1 << (eid)) #define EVENT_MASK(eid) (1 << (eid))
/** /**
* Registers an Event Listener on an Event Source. * @brief Registers an Event Listener on an Event Source.
* @param esp pointer to the @p EventSource structure * @note Multiple Event Listeners can use the same event identifier, the
* @param elp pointer to the @p EventListener structure * listener will share the callback function.
* @param eid numeric identifier assigned to the Event Listener. The identifier *
* is used as index for the event callback function. * @param[in] esp pointer to the @p EventSource structure
* The value must range between zero and the size, in bit, of the * @param[out] elp pointer to the @p EventListener structure
* @p eventid_t type minus one. * @param[in] eid numeric identifier assigned to the Event Listener. The
* @note Multiple Event Listeners can use the same event identifier, the * identifier is used as index for the event callback
* listener will share the callback function. * function.
* 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))
/** /**
* Initializes an Event Source. * @brief Initializes an Event Source.
* @param esp pointer to the @p EventSource structure * @note Can be used with interrupts disabled or enabled.
* @note Can be called with interrupts disabled or enabled. *
* @param[in] esp pointer to the @p EventSource structure
*/ */
#define chEvtInit(esp) \ #define chEvtInit(esp) \
((esp)->es_next = (EventListener *)(void *)(esp)) ((esp)->es_next = (EventListener *)(void *)(esp))
/** /**
* Verifies if there is at least one @p EventListener registered on the * @brief Verifies if there is at least one @p EventListener registered.
* @p EventSource. * @note Can be called with interrupts disabled or enabled.
* @param esp pointer to the @p EventSource structure *
* @note Can be called with interrupts disabled or enabled. * @param[in] esp pointer to the @p EventSource structure
*/ */
#define chEvtIsListening(esp) \ #define chEvtIsListening(esp) \
((void *)(esp) != (void *)(esp)->es_next) ((void *)(esp) != (void *)(esp)->es_next)
/** Event Handler callback function.*/ /**
* @brief Event Handler callback function.
*/
typedef void (*evhandler_t)(eventid_t); typedef void (*evhandler_t)(eventid_t);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -21,15 +21,12 @@
#define _INLINE_H_ #define _INLINE_H_
/** /**
* @file inline.h * @file inline.h
* @brief kernel inlined functions. * @brief Kernel inlined functions.
* @details In this file there are a set of inlined functions if the
* @p CH_OPTIMIZE_SPEED is enabled.
*/ */
/*
* Inlined functions if CH_OPTIMIZE_SPEED is enabled.
* Note: static inlined functions do not duplicate the code in every module
* this is true for GCC, not sure about other compilers.
*/
#if CH_OPTIMIZE_SPEED #if CH_OPTIMIZE_SPEED
static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) { static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) {

View File

@ -18,8 +18,12 @@
*/ */
/** /**
* @file lists.h * @file lists.h
* @brief Thread queues/lists macros and structures. * @brief Thread queues/lists macros and structures.
* @note All the macros present in this module, while public, are not
* an OS API and should not be directly used in the user applications
* code.
*
* @addtogroup internals * @addtogroup internals
* @{ * @{
*/ */
@ -30,46 +34,49 @@
typedef struct Thread Thread; typedef struct Thread Thread;
/** /**
* @brief Threads queue initialization. * @brief Threads queue initialization.
*/ */
#define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp)); #define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp));
/** /**
* @brief Threads list initialization. * @brief Threads list initialization.
*/ */
#define list_init(tlp) ((tlp)->p_next = (Thread *)(tlp)) #define list_init(tlp) ((tlp)->p_next = (Thread *)(tlp))
/** /**
* @brief Evaluates to @p TRUE if the specified threads queue or list is * @brief Evaluates to @p TRUE if the specified threads queue or list is
* empty. * empty.
*/ */
#define isempty(p) ((p)->p_next == (Thread *)(p)) #define isempty(p) ((p)->p_next == (Thread *)(p))
/** /**
* @brief Evaluates to @p TRUE if the specified threads queue or list is * @brief Evaluates to @p TRUE if the specified threads queue or list is
* not empty. * not empty.
*/ */
#define notempty(p) ((p)->p_next != (Thread *)(p)) #define notempty(p) ((p)->p_next != (Thread *)(p))
/** /**
* @brief Data part of a static threads queue initializer. * @brief Data part of a static threads queue initializer.
* @details This macro should be used when statically initializing a threads * @details This macro should be used when statically initializing a threads
* queue that is part of a bigger structure. * queue that is part of a bigger structure.
* @param name the name of the threads queue variable *
* @param[in] name the name of the threads queue variable
*/ */
#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name} #define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name}
/** /**
* @brief Static threads queue initializer. * @brief Static threads queue initializer.
* @details Statically initialized threads queues require no explicit * @details Statically initialized threads queues require no explicit
* initialization using @p queue_init(). * initialization using @p queue_init().
* @param name the name of the threads queue variable *
* @param[in] name the name of the threads queue variable
*/ */
#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name) #define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name)
/** /**
* @brief Generic threads bidirectional linked list header and element.
* @extends ThreadsList * @extends ThreadsList
*
* @brief Generic threads bidirectional linked list header and element.
*/ */
typedef struct { typedef struct {
Thread *p_next; /**< First @p Thread in the queue, or Thread *p_next; /**< First @p Thread in the queue, or
@ -79,7 +86,7 @@ typedef struct {
} ThreadsQueue; } ThreadsQueue;
/** /**
* @brief Generic threads single link list, it works like a stack. * @brief Generic threads single link list, it works like a stack.
*/ */
typedef struct { typedef struct {

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file mailboxes.h * @file mailboxes.h
* @brief Mailboxes macros and structures. * @brief Mailboxes macros and structures.
*
* @addtogroup mailboxes * @addtogroup mailboxes
* @{ * @{
*/ */
@ -37,13 +38,16 @@
#endif #endif
typedef struct { typedef struct {
msg_t *mb_buffer; /**< Pointer to the mailbox buffer.*/ msg_t *mb_buffer; /**< @brief Pointer to the mailbox
msg_t *mb_top; /**< Pointer to the first location buffer. */
after the buffer.*/ msg_t *mb_top; /**< @brief Pointer to the location
msg_t *mb_wrptr; /**< Write pointer.*/ after the buffer. */
msg_t *mb_rdptr; /**< Read pointer.*/ msg_t *mb_wrptr; /**< @brief Write pointer. */
Semaphore mb_fullsem; /**< Full counter @p Semaphore.*/ msg_t *mb_rdptr; /**< @brief Read pointer. */
Semaphore mb_emptysem; /**< Empty counter @p Semaphore.*/ Semaphore mb_fullsem; /**< @brief Full counter
@p Semaphore. */
Semaphore mb_emptysem; /**< @brief Empty counter
@p Semaphore. */
} Mailbox; } Mailbox;
#ifdef __cplusplus #ifdef __cplusplus
@ -62,49 +66,54 @@ extern "C" {
#endif #endif
/** /**
* Returns the mailbox buffer size. * @brief Returns the mailbox buffer size.
* @param[in] mbp the pointer to an initialized Mailbox object *
* @param[in] mbp the pointer to an initialized Mailbox object
*/ */
#define chMBSize(mbp) \ #define chMBSize(mbp) \
((mbp)->mb_top - (mbp)->mb_buffer) ((mbp)->mb_top - (mbp)->mb_buffer)
/** /**
* Returns the free space into the mailbox. * @brief Returns the free space into the mailbox.
* @param[in] mbp the pointer to an initialized Mailbox object * @note Can be invoked in any system state but if invoked out of a locked
* @return The number of empty message slots. * state then the returned value may change after reading.
* @note Can be invoked in any system state but if invoked out of a locked * @note The returned value can be less than zero when there are waiting
* state then the returned value may change after reading. * threads on the internal semaphore.
* @note The returned value can be less than zero when there are waiting *
* threads on the internal semaphore. * @param[in] mbp the pointer to an initialized Mailbox object
* @return The number of empty message slots.
*/ */
#define chMBGetEmpty(mbp) chSemGetCounterI(&(mbp)->mb_emptysem) #define chMBGetEmpty(mbp) chSemGetCounterI(&(mbp)->mb_emptysem)
/** /**
* Returns the number of messages into the mailbox. * @brief Returns the number of messages into the mailbox.
* @param[in] mbp the pointer to an initialized Mailbox object * @note Can be invoked in any system state but if invoked out of a locked
* @return The number of queued messages. * state then the returned value may change after reading.
* @note Can be invoked in any system state but if invoked out of a locked * @note The returned value can be less than zero when there are waiting
* state then the returned value may change after reading. * threads on the internal semaphore.
* @note The returned value can be less than zero when there are waiting *
* threads on the internal semaphore. * @param[in] mbp the pointer to an initialized Mailbox object
* @return The number of queued messages.
*/ */
#define chMBGetFull(mbp) chSemGetCounterI(&(mbp)->mb_fullsem) #define chMBGetFull(mbp) chSemGetCounterI(&(mbp)->mb_fullsem)
/** /**
* Returns the next message in the queue without removing it. * @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 * @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 * 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. * use @p chMBGetFull() and then use this macro, all within a lock
* state.
*/ */
#define chMBPeek(mbp) (*(mbp)->mb_rdptr) #define chMBPeek(mbp) (*(mbp)->mb_rdptr)
/** /**
* @brief Data part of a static mailbox initializer. * @brief Data part of a static mailbox initializer.
* @details This macro should be used when statically initializing a * @details This macro should be used when statically initializing a
* mailbox that is part of a bigger structure. * mailbox that is part of a bigger structure.
* @param name the name of the mailbox variable *
* @param buffer pointer to the mailbox buffer area * @param[in] name the name of the mailbox variable
* @param size size of the mailbox buffer area * @param[in] buffer pointer to the mailbox buffer area
* @param[in] size size of the mailbox buffer area
*/ */
#define _MAILBOX_DATA(name, buffer, size) { \ #define _MAILBOX_DATA(name, buffer, size) { \
(msg_t *)(buffer), \ (msg_t *)(buffer), \
@ -116,12 +125,13 @@ extern "C" {
} }
/** /**
* @brief Static mailbox initializer. * @brief Static mailbox initializer.
* @details Statically initialized mailboxes require no explicit * @details Statically initialized mailboxes require no explicit
* initialization using @p chMBInit(). * initialization using @p chMBInit().
* @param name the name of the mailbox variable *
* @param buffer pointer to the mailbox buffer area * @param[in] name the name of the mailbox variable
* @param size size of the mailbox buffer area * @param[in] buffer pointer to the mailbox buffer area
* @param[in] size size of the mailbox buffer area
*/ */
#define MAILBOX_DECL(name, buffer, size) \ #define MAILBOX_DECL(name, buffer, size) \
Mailbox name = _MAILBOX_DATA(name, buffer, size) Mailbox name = _MAILBOX_DATA(name, buffer, size)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file memcore.h * @file memcore.h
* @brief Core memory manager macros and structures. * @brief Core memory manager macros and structures.
*
* @addtogroup memcore * @addtogroup memcore
* @{ * @{
*/ */
@ -28,31 +29,30 @@
#define _MEMCORE_H_ #define _MEMCORE_H_
/** /**
* @brief Memory alignment type. * @brief Memory alignment type.
*/ */
typedef void *align_t; typedef void *align_t;
/** /**
* @brief Memory get function. * @brief Memory get function.
* * @note This type must be assignment compatible with the @p chMemAlloc()
* @note This type must be assignment compatible with the @p chMemAlloc() * function.
* function.
*/ */
typedef void *(*memgetfunc_t)(size_t size); typedef void *(*memgetfunc_t)(size_t size);
/** /**
* @brief Alignment mask constant. * @brief Alignment mask constant.
*/ */
#define MEM_ALIGN_MASK (sizeof(align_t) - 1) #define MEM_ALIGN_MASK (sizeof(align_t) - 1)
/** /**
* @brief Alignment helper macro. * @brief Alignment helper macro.
*/ */
#define MEM_ALIGN_SIZE(p) (((size_t)(p) + MEM_ALIGN_MASK) & ~MEM_ALIGN_MASK) #define MEM_ALIGN_SIZE(p) (((size_t)(p) + MEM_ALIGN_MASK) & ~MEM_ALIGN_MASK)
/** /**
* @brief Returns whatever a pointer or memory size is aligned to * @brief Returns whatever a pointer or memory size is aligned to
* the type @p align_t. * the type @p align_t.
*/ */
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0) #define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file mempools.h * @file mempools.h
* @brief Memory Pools macros and structures. * @brief Memory Pools macros and structures.
*
* @addtogroup pools * @addtogroup pools
* @{ * @{
*/ */
@ -30,14 +31,15 @@
#if CH_USE_MEMPOOLS #if CH_USE_MEMPOOLS
/** /**
* @brief Memory pool free object header. * @brief Memory pool free object header.
*/ */
struct pool_header { struct pool_header {
struct pool_header *ph_next; struct pool_header *ph_next; /**< @brief Pointer to the next pool
header in the list. */
}; };
/** /**
* @brief Memory pool descriptor. * @brief Memory pool descriptor.
*/ */
typedef struct { typedef struct {
struct pool_header *mp_next; /**< @brief Pointer to the header. */ struct pool_header *mp_next; /**< @brief Pointer to the header. */
@ -48,13 +50,13 @@ typedef struct {
} MemoryPool; } MemoryPool;
/** /**
* @brief Data part of a static memory pool initializer. * @brief Data part of a static memory pool initializer.
* @details This macro should be used when statically initializing a * @details This macro should be used when statically initializing a
* memory pool that is part of a bigger structure. * memory pool that is part of a bigger structure.
* *
* @param[in] name the name of the memory pool variable * @param[in] name the name of the memory pool variable
* @param[in] size size of the memory pool contained objects * @param[in] size size of the memory pool contained objects
* @param[in] provider memory provider function for the memory pool * @param[in] provider memory provider function for the memory pool
*/ */
#define _MEMORYPOOL_DATA(name, size, provider) \ #define _MEMORYPOOL_DATA(name, size, provider) \
{NULL, MEM_ALIGN_SIZE(size), provider} {NULL, MEM_ALIGN_SIZE(size), provider}

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file messages.h * @file messages.h
* @brief Messages macros and structures. * @brief Messages macros and structures.
*
* @addtogroup messages * @addtogroup messages
* @{ * @{
*/ */
@ -30,13 +31,13 @@
#if CH_USE_MESSAGES #if CH_USE_MESSAGES
/** /**
* Evaluates to TRUE if the thread has pending messages. * @brief Evaluates to TRUE if the thread has pending messages.
*/ */
#define chMsgIsPendingI(tp) \ #define chMsgIsPendingI(tp) \
((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue) ((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue)
/** /**
* Returns the first message in the queue. * @brief Returns the first message in the queue.
*/ */
#define chMsgGetI(tp) \ #define chMsgGetI(tp) \
((tp)->p_msgqueue.p_next->p_msg) ((tp)->p_msgqueue.p_next->p_msg)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file mutexes.h * @file mutexes.h
* @brief Mutexes macros and structures. * @brief Mutexes macros and structures.
*
* @addtogroup mutexes * @addtogroup mutexes
* @{ * @{
*/ */
@ -33,12 +34,12 @@
* @brief Mutex structure. * @brief Mutex structure.
*/ */
typedef struct Mutex { typedef struct Mutex {
ThreadsQueue m_queue; /**< Queue of the threads sleeping on ThreadsQueue m_queue; /**< @brief Queue of the threads sleeping
this Mutex.*/ on this Mutex. */
Thread *m_owner; /**< Owner @p Thread pointer or Thread *m_owner; /**< @brief Owner @p Thread pointer or
@p NULL.*/ @p NULL. */
struct Mutex *m_next; /**< Next @p Mutex into an owner-list struct Mutex *m_next; /**< @brief Next @p Mutex into an
or @p NULL.*/ owner-list or @p NULL. */
} Mutex; } Mutex;
#ifdef __cplusplus #ifdef __cplusplus
@ -57,23 +58,26 @@ extern "C" {
#endif #endif
/** /**
* @brief Data part of a static mutex initializer. * @brief Data part of a static mutex initializer.
* @details This macro should be used when statically initializing a mutex * @details This macro should be used when statically initializing a mutex
* that is part of a bigger structure. * that is part of a bigger structure.
* @param name the name of the mutex variable *
* @param[in] name the name of the mutex variable
*/ */
#define _MUTEX_DATA(name) {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL} #define _MUTEX_DATA(name) {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL}
/** /**
* @brief Static mutex initializer. * @brief Static mutex initializer.
* @details Statically initialized mutexes require no explicit initialization * @details Statically initialized mutexes require no explicit initialization
* using @p chMtxInit(). * using @p chMtxInit().
* @param name the name of the mutex variable *
* @param[in] name the name of the mutex variable
*/ */
#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name) #define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name)
/** /**
* Returns @p TRUE if the mutex queue contains at least a waiting thread. * @brief Returns @p TRUE if the mutex queue contains at least a waiting
* thread.
*/ */
#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue) #define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file queues.h I/O * @file queues.h I/O
* @brief Queues macros and structures. * @brief Queues macros and structures.
*
* @addtogroup io_queues * @addtogroup io_queues
* @{ * @{
*/ */
@ -36,22 +37,22 @@
#error "CH_USE_QUEUES requires CH_USE_SEMAPHORES" #error "CH_USE_QUEUES requires CH_USE_SEMAPHORES"
#endif #endif
/** Queue notification callback type. */ /** @brief Queue notification callback type.*/
typedef void (*qnotify_t)(void); typedef void (*qnotify_t)(void);
/** Returned by the queue functions if the operation is successful. */ /** @brief Returned by the queue functions if the operation is successful.*/
#define Q_OK RDY_OK #define Q_OK RDY_OK
/** Returned by the queue functions if a timeout occurs. */ /** @brief Returned by the queue functions if a timeout occurs.*/
#define Q_TIMEOUT RDY_TIMEOUT #define Q_TIMEOUT RDY_TIMEOUT
/** Returned by the queue functions if the queue is reset. */ /** @brief Returned by the queue functions if the queue is reset.*/
#define Q_RESET RDY_RESET #define Q_RESET RDY_RESET
/** Returned by the queue functions if the queue is empty. */ /** @brief Returned by the queue functions if the queue is empty.*/
#define Q_EMPTY -3 #define Q_EMPTY -3
/** Returned by the queue functions if the queue is full. */ /** @brief Returned by the queue functions if the queue is full.*/
#define Q_FULL -4 #define Q_FULL -4
/** /**
* @brief Generic I/O queue structure. * @brief Generic I/O queue structure.
* @details This structure represents a generic Input or Output asymmetrical * @details This structure represents a generic Input or Output asymmetrical
* queue. The queue is asymmetrical because one end is meant to be * queue. The queue is asymmetrical because one end is meant to be
* accessed from a thread context, and thus can be blocking, the other * accessed from a thread context, and thus can be blocking, the other
@ -60,64 +61,69 @@ typedef void (*qnotify_t)(void);
* @ref system_states) and is non-blocking. * @ref system_states) and is non-blocking.
*/ */
typedef struct { typedef struct {
uint8_t *q_buffer; /**< Pointer to the queue buffer.*/ uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/
uint8_t *q_top; /**< Pointer to the first location uint8_t *q_top; /**< @brief Pointer to the first location
after the buffer.*/ after the buffer. */
uint8_t *q_wrptr; /**< Write pointer.*/ uint8_t *q_wrptr; /**< @brief Write pointer. */
uint8_t *q_rdptr; /**< Read pointer.*/ uint8_t *q_rdptr; /**< @brief Read pointer. */
Semaphore q_sem; /**< Counter @p Semaphore.*/ Semaphore q_sem; /**< @brief Counter @p Semaphore. */
qnotify_t q_notify; /**< Data notification callback.*/ qnotify_t q_notify; /**< @brief Data notification callback. */
} GenericQueue; } GenericQueue;
/** Returns the queue's buffer size. */ /**
* @brief Returns the queue's buffer size.
*/
#define chQSize(q) ((q)->q_top - (q)->q_buffer) #define chQSize(q) ((q)->q_top - (q)->q_buffer)
/** /**
* Returns the used space if used on an Input Queue and the empty space if * @brief Queue space.
* used on an Output Queue. * @details Returns the used space if used on an Input Queue and the empty
* @note The returned value can be less than zero when there are waiting * space if used on an Output Queue.
* threads on the internal semaphore. * @note The returned value can be less than zero when there are waiting
* threads on the internal semaphore.
*/ */
#define chQSpace(q) chSemGetCounterI(&(q)->q_sem) #define chQSpace(q) chSemGetCounterI(&(q)->q_sem)
/** /**
* @brief Input queue structure. * @extends GenericQueue
*
* @brief Input queue structure.
* @details This structure represents a generic asymmetrical input queue. * @details This structure represents a generic asymmetrical input queue.
* Writing in the queue is non-blocking and can be performed from * Writing in the queue is non-blocking and can be performed from
* interrupt handlers or from within a kernel lock zone (see * interrupt handlers or from within a kernel lock zone (see
* <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states). * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
* Reading the queue can be a blocking operation and is supposed to * Reading the queue can be a blocking operation and is supposed to
* be performed by a system thread. * be performed by a system thread.
* @extends GenericQueue
*/ */
typedef GenericQueue InputQueue; typedef GenericQueue InputQueue;
/** Evaluates to @p TRUE if the specified Input Queue is empty. */ /** @brief Evaluates to @p TRUE if the specified Input Queue is empty.*/
#define chIQIsEmpty(q) (chQSpace(q) <= 0) #define chIQIsEmpty(q) (chQSpace(q) <= 0)
/** Evaluates to @p TRUE if the specified Input Queue is full. */ /** @brief Evaluates to @p TRUE if the specified Input Queue is full.*/
#define chIQIsFull(q) (chQSpace(q) >= chQSize(q)) #define chIQIsFull(q) (chQSpace(q) >= chQSize(q))
/** /**
* @brief Input queue read. * @brief Input queue read.
* @details This function reads a byte value from an input queue. If the queue * @details This function reads a byte value from an input queue. If the queue
* is empty then the calling thread is suspended until a byte arrives * is empty then the calling thread is suspended until a byte arrives
* in the queue. * in the queue.
* *
* @param[in] iqp pointer to an @p InputQueue structure * @param[in] iqp pointer to an @p InputQueue structure
* @return A byte value from the queue or: * @return A byte value from the queue or:
* @retval Q_RESET if the queue was reset. * @retval Q_RESET if the queue was reset.
*/ */
#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE) #define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE)
/** /**
* @brief Data part of a static input queue initializer. * @brief Data part of a static input queue initializer.
* @details This macro should be used when statically initializing an * @details This macro should be used when statically initializing an
* input queue that is part of a bigger structure. * input queue that is part of a bigger structure.
* @param name the name of the input queue variable *
* @param buffer pointer to the queue buffer area * @param[in] name the name of the input queue variable
* @param size size of the queue buffer area * @param[in] buffer pointer to the queue buffer area
* @param inotify input notification callback pointer * @param[in] size size of the queue buffer area
* @param[in] inotify input notification callback pointer
*/ */
#define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \ #define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \
(uint8_t *)(buffer), \ (uint8_t *)(buffer), \
@ -129,57 +135,64 @@ typedef GenericQueue InputQueue;
} }
/** /**
* @brief Static input queue initializer. * @brief Static input queue initializer.
* @details Statically initialized input queues require no explicit * @details Statically initialized input queues require no explicit
* initialization using @p chIQInit(). * initialization using @p chIQInit().
* @param name the name of the input queue variable *
* @param buffer pointer to the queue buffer area * @param[in] name the name of the input queue variable
* @param size size of the queue buffer area * @param[in] buffer pointer to the queue buffer area
* @param inotify input notification callback pointer * @param[in] size size of the queue buffer area
* @param[in] inotify input notification callback pointer
*/ */
#define INPUTQUEUE_DECL(name, buffer, size, inotify) \ #define INPUTQUEUE_DECL(name, buffer, size, inotify) \
InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify) InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify)
/** /**
* @brief Output queue structure. * @extends GenericQueue
*
* @brief Output queue structure.
* @details This structure represents a generic asymmetrical output queue. * @details This structure represents a generic asymmetrical output queue.
* Reading from the queue is non-blocking and can be performed from * Reading from the queue is non-blocking and can be performed from
* interrupt handlers or from within a kernel lock zone (see * interrupt handlers or from within a kernel lock zone (see
* <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states). * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
* Writing the queue can be a blocking operation and is supposed to * Writing the queue can be a blocking operation and is supposed to
* be performed by a system thread. * be performed by a system thread.
* @extends GenericQueue
*/ */
typedef GenericQueue OutputQueue; typedef GenericQueue OutputQueue;
/** Evaluates to @p TRUE if the specified Output Queue is empty. */ /**
* @brief Evaluates to @p TRUE if the specified Output Queue is empty.
*/
#define chOQIsEmpty(q) (chQSpace(q) >= chQSize(q)) #define chOQIsEmpty(q) (chQSpace(q) >= chQSize(q))
/** Evaluates to @p TRUE if the specified Output Queue is full. */ /**
* @brief Evaluates to @p TRUE if the specified Output Queue is full.
*/
#define chOQIsFull(q) (chQSpace(q) <= 0) #define chOQIsFull(q) (chQSpace(q) <= 0)
/** /**
* @brief Output queue write. * @brief Output queue write.
* @details This function writes a byte value to an output queue. If the queue * @details This function writes a byte value to an output queue. If the queue
* is full then the calling thread is suspended until there is space * is full then the calling thread is suspended until there is space
* in the queue. * in the queue.
* *
* @param[in] oqp pointer to an @p OutputQueue structure * @param[in] oqp pointer to an @p OutputQueue structure
* @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: * @return The operation status:
* @retval Q_OK if the operation succeeded. * @retval Q_OK if the operation succeeded.
* @retval Q_RESET if the queue was reset. * @retval Q_RESET if the queue was reset.
*/ */
#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE) #define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE)
/** /**
* @brief Data part of a static output queue initializer. * @brief Data part of a static output queue initializer.
* @details This macro should be used when statically initializing an * @details This macro should be used when statically initializing an
* output queue that is part of a bigger structure. * output queue that is part of a bigger structure.
* @param name the name of the output queue variable. *
* @param buffer pointer to the queue buffer area * @param[in] name the name of the output queue variable.
* @param size size of the queue buffer area * @param[in] buffer pointer to the queue buffer area
* @param onotify output notification callback pointer * @param[in] size size of the queue buffer area
* @param[in] onotify output notification callback pointer
*/ */
#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \ #define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \
(uint8_t *)(buffer), \ (uint8_t *)(buffer), \
@ -194,10 +207,11 @@ typedef GenericQueue OutputQueue;
* @brief Static output queue initializer. * @brief Static output queue initializer.
* @details Statically initialized output queues require no explicit * @details Statically initialized output queues require no explicit
* initialization using @p chOQInit(). * initialization using @p chOQInit().
* @param name the name of the output queue variable *
* @param buffer pointer to the queue buffer area * @param[in] name the name of the output queue variable
* @param size size of the queue buffer area * @param[in] buffer pointer to the queue buffer area
* @param onotify output notification callback pointer * @param[in] size size of the queue buffer area
* @param[in] onotify output notification callback pointer
*/ */
#define OUTPUTQUEUE_DECL(name, buffer, size, onotify) \ #define OUTPUTQUEUE_DECL(name, buffer, size, onotify) \
InputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify) InputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file registry.h * @file registry.h
* @brief Threads registry macros and structures. * @brief Threads registry macros and structures.
*
* @addtogroup registry * @addtogroup registry
* @{ * @{
*/ */
@ -32,6 +33,8 @@
/** /**
* @brief Removes a thread from the registry list. * @brief Removes a thread from the registry list.
* @note This macro is not meant for use in application code. * @note This macro is not meant for use in application code.
*
* @param[in] tp thread to remove from the registry
*/ */
#define REG_REMOVE(tp) { \ #define REG_REMOVE(tp) { \
(tp)->p_older->p_newer = (tp)->p_newer; \ (tp)->p_older->p_newer = (tp)->p_newer; \
@ -41,6 +44,8 @@
/** /**
* @brief Adds a thread to the registry list. * @brief Adds a thread to the registry list.
* @note This macro is not meant for use in application code. * @note This macro is not meant for use in application code.
*
* @param[in] tp thread to add to the registry
*/ */
#define REG_INSERT(tp) { \ #define REG_INSERT(tp) { \
(tp)->p_newer = (Thread *)&rlist; \ (tp)->p_newer = (Thread *)&rlist; \

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file scheduler.h * @file scheduler.h
* @brief Scheduler macros and structures. * @brief Scheduler macros and structures.
*
* @addtogroup scheduler * @addtogroup scheduler
* @{ * @{
*/ */
@ -27,58 +28,61 @@
#ifndef _SCHEDULER_H_ #ifndef _SCHEDULER_H_
#define _SCHEDULER_H_ #define _SCHEDULER_H_
/** Default thread wakeup low level message. */ /** @brief Default thread wakeup low level message.*/
#define RDY_OK 0 #define RDY_OK 0
/** Low level message sent to a thread awakened by a timeout. */ /** @brief Low level message sent to a thread awakened by a timeout.*/
#define RDY_TIMEOUT -1 #define RDY_TIMEOUT -1
/** Low level message sent to a thread awakened by a reset operation. */ /** @brief Low level message sent to a thread awakened by a reset operation.*/
#define RDY_RESET -2 #define RDY_RESET -2
#define NOPRIO 0 /**< Ready list header priority.*/ #define NOPRIO 0 /**< @brief Ready list header priority. */
#define IDLEPRIO 1 /**< Idle thread priority.*/ #define IDLEPRIO 1 /**< @brief Idle thread priority. */
#define LOWPRIO 2 /**< Lowest user priority.*/ #define LOWPRIO 2 /**< @brief Lowest user priority. */
#define NORMALPRIO 64 /**< Normal user priority.*/ #define NORMALPRIO 64 /**< @brief Normal user priority. */
#define HIGHPRIO 127 /**< Highest user priority.*/ #define HIGHPRIO 127 /**< @brief Highest user priority. */
#define ABSPRIO 255 /**< Greatest possible priority.*/ #define ABSPRIO 255 /**< @brief Greatest possible priority. */
/** /**
* Zero time specification for some syscalls with a timeout * @brief Zero time specification for some syscalls with a timeout
* specification. * specification.
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
* see the specific function documentation. * see the specific function documentation.
*/ */
#define TIME_IMMEDIATE ((systime_t)-1) #define TIME_IMMEDIATE ((systime_t)-1)
/** /**
* Infinite time specification for all the syscalls with a timeout * @brief Infinite time specification for all the syscalls with a timeout
* specification. * specification.
*/ */
#define TIME_INFINITE ((systime_t)0) #define TIME_INFINITE ((systime_t)0)
/** The priority of the first thread on the given ready list. */ /**
* @brief Returns the priority of the first thread on the given ready list.
*/
#define firstprio(rlp) ((rlp)->p_next->p_prio) #define firstprio(rlp) ((rlp)->p_next->p_prio)
/** /**
* @brief Ready list header.
*
* @extends ThreadsQueue * @extends ThreadsQueue
*
* @brief Ready list header.
*/ */
typedef struct { typedef struct {
ThreadsQueue r_queue; /**< Threads queue. */ ThreadsQueue r_queue; /**< @brief Threads queue. */
tprio_t r_prio; /**< This field must be initialized to tprio_t r_prio; /**< @brief This field must be
zero. */ initialized to zero. */
struct context p_ctx; /**< Not used, present because struct context p_ctx; /**< @brief Not used, present because
offsets. */ offsets. */
#if CH_USE_REGISTRY #if CH_USE_REGISTRY
Thread *p_newer; /**< Newer registry element. */ Thread *p_newer; /**< @brief Newer registry element. */
Thread *p_older; /**< Older registry element. */ Thread *p_older; /**< @brief Older registry element. */
#endif #endif
/* End of the fields shared with the Thread structure.*/ /* End of the fields shared with the Thread structure.*/
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
cnt_t r_preempt; /**< Round robin counter. */ cnt_t r_preempt; /**< @brief Round robin counter. */
#endif #endif
#ifndef CH_CURRP_REGISTER_CACHE #ifndef CH_CURRP_REGISTER_CACHE
Thread *r_current; /**< The currently running thread. */ Thread *r_current; /**< @brief The currently running
thread. */
#endif #endif
} ReadyList; } ReadyList;
@ -112,14 +116,14 @@ extern "C" {
#endif #endif
/** /**
* @brief Determines if yielding is possible. * @brief Determines if yielding is possible.
* @details This function returns @p TRUE if there is a ready thread with * @details This function returns @p TRUE if there is a ready thread with
* equal or higher priority. * equal or higher priority.
*/ */
#define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio) #define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio)
/** /**
* @brief Determines if the current thread must reschedule. * @brief Determines if the current thread must reschedule.
* @details This function returns @p TRUE if there is a ready thread with * @details This function returns @p TRUE if there is a ready thread with
* higher priority. * higher priority.
*/ */

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file semaphores.h * @file semaphores.h
* @brief Semaphores macros and structures. * @brief Semaphores macros and structures.
*
* @addtogroup semaphores * @addtogroup semaphores
* @{ * @{
*/ */
@ -30,12 +31,12 @@
#if CH_USE_SEMAPHORES #if CH_USE_SEMAPHORES
/** /**
* @brief Semaphore structure. * @brief Semaphore structure.
*/ */
typedef struct Semaphore { typedef struct Semaphore {
ThreadsQueue s_queue; /**< Queue of the threads sleeping on ThreadsQueue s_queue; /**< @brief Queue of the threads sleeping
this semaphore.*/ on this semaphore. */
cnt_t s_cnt; /**< The semaphore counter.*/ cnt_t s_cnt; /**< @brief The semaphore counter. */
} Semaphore; } Semaphore;
#ifdef __cplusplus #ifdef __cplusplus
@ -58,37 +59,41 @@ extern "C" {
#endif #endif
/** /**
* @brief Data part of a static semaphore initializer. * @brief Data part of a static semaphore initializer.
* @details This macro should be used when statically initializing a semaphore * @details This macro should be used when statically initializing a semaphore
* that is part of a bigger structure. * that is part of a bigger structure.
* @param name the name of the semaphore variable *
* @param n the counter initial value, this value must be non-negative * @param[in] name the name of the semaphore variable
* @param[in] n the counter initial value, this value must be
* non-negative
*/ */
#define _SEMAPHORE_DATA(name, n) {_THREADSQUEUE_DATA(name.s_queue), n} #define _SEMAPHORE_DATA(name, n) {_THREADSQUEUE_DATA(name.s_queue), n}
/** /**
* @brief Static semaphore initializer. * @brief Static semaphore initializer.
* @details Statically initialized semaphores require no explicit initialization * @details Statically initialized semaphores require no explicit
* using @p chSemInit(). * initialization using @p chSemInit().
* @param name the name of the semaphore variable *
* @param n the counter initial value, this value must be non-negative * @param[in] name the name of the semaphore variable
* @param[in] n the counter initial value, this value must be
* non-negative
*/ */
#define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n) #define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n)
/** /**
* Decreases the semaphore counter, this macro can be used when it is ensured * @brief Decreases the semaphore counter.
* that the counter would not become negative. * @details This macro can be used when the counter is known to be positive.
*/ */
#define chSemFastWaitI(sp) ((sp)->s_cnt--) #define chSemFastWaitI(sp) ((sp)->s_cnt--)
/** /**
* Increases the semaphore counter, this macro can be used when the counter is * @brief Increases the semaphore counter.
* not negative. * @details This macro can be used when the counter is known to be not negative.
*/ */
#define chSemFastSignalI(sp) ((sp)->s_cnt++) #define chSemFastSignalI(sp) ((sp)->s_cnt++)
/** /**
* Returns the semaphore counter current value. * @brief Returns the semaphore counter current value.
*/ */
#define chSemGetCounterI(sp) ((sp)->s_cnt) #define chSemGetCounterI(sp) ((sp)->s_cnt)

View File

@ -18,8 +18,11 @@
*/ */
/** /**
* @file streams.h * @file streams.h
* @brief Data streams. * @brief Data streams.
* @details This header defines abstract interfaces useful to access generic
* data streams in a standardized way.
*
* @addtogroup data_streams * @addtogroup data_streams
* @{ * @{
*/ */
@ -28,7 +31,7 @@
#define _STREAMS_H_ #define _STREAMS_H_
/** /**
* @brief BaseSequentialStream specific methods. * @brief BaseSequentialStream specific methods.
*/ */
#define _base_sequental_stream_methods \ #define _base_sequental_stream_methods \
/* Stream write buffer method.*/ \ /* Stream write buffer method.*/ \
@ -37,55 +40,54 @@
size_t (*read)(void *instance, uint8_t *bp, size_t n); size_t (*read)(void *instance, uint8_t *bp, size_t n);
/** /**
* @brief @p BaseSequentialStream specific data. * @brief @p BaseSequentialStream specific data.
* @note It is empty because @p BaseSequentialStream is only an interface * @note It is empty because @p BaseSequentialStream is only an interface
* without implementation. * without implementation.
*/ */
#define _base_sequental_stream_data #define _base_sequental_stream_data
/** /**
* @brief @p BaseSequentialStream virtual methods table. * @brief @p BaseSequentialStream virtual methods table.
*/ */
struct BaseSequentialStreamVMT { struct BaseSequentialStreamVMT {
_base_sequental_stream_methods _base_sequental_stream_methods
}; };
/** /**
* @brief Base stream class. * @brief Base stream class.
* @details This class represents a generic blocking unbuffered sequential * @details This class represents a generic blocking unbuffered sequential
* data stream. * data stream.
*/ */
typedef struct { typedef struct {
/** /** @brief Virtual Methods Table.*/
* Virtual Methods Table.
*/
const struct BaseSequentialStreamVMT *vmt; const struct BaseSequentialStreamVMT *vmt;
_base_sequental_stream_data _base_sequental_stream_data
} BaseSequentialStream; } BaseSequentialStream;
/** /**
* @brief Sequential Stream write. * @brief Sequential Stream write.
* @details The function writes data from a buffer to a stream. * @details The function writes data from a buffer to a stream.
* *
* @param[in] ip pointer to a @p BaseSequentialStream or derived class * @param[in] ip pointer to a @p BaseSequentialStream or derived class
* @param[in] bp pointer to the data buffer * @param[in] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred * @param[in] n the maximum amount of data to be transferred
* @return The number of bytes transferred. The return value can be less * @return The number of bytes transferred. The return value can
* than the specified number of bytes if the stream reaches a * be less than the specified number of bytes if the
* physical end of file and cannot be extended. * stream reaches a physical end of file and cannot be
* extended.
*/ */
#define chSequentialStreamWrite(ip, bp, n) ((ip)->vmt->write(ip, bp, n)) #define chSequentialStreamWrite(ip, bp, n) ((ip)->vmt->write(ip, bp, n))
/** /**
* @brief Sequential Stream read. * @brief Sequential Stream read.
* @details The function reads data from a stream into a buffer. * @details The function reads data from a stream into a buffer.
* *
* @param[in] ip pointer to a @p BaseSequentialStream or derived class * @param[in] ip pointer to a @p BaseSequentialStream or derived class
* @param[out] bp pointer to the data buffer * @param[out] bp pointer to the data buffer
* @param[in] n the maximum amount of data to be transferred * @param[in] n the maximum amount of data to be transferred
* @return The number of bytes transferred. The return value can be less * @return The number of bytes transferred. The return value can
* than the specified number of bytes if the stream reaches the end * be less than the specified number of bytes if the
* of the available data. * stream reaches the end of the available data.
*/ */
#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n)) #define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file sys.h * @file sys.h
* @brief System related macros and structures. * @brief System related macros and structures.
*
* @addtogroup system * @addtogroup system
* @{ * @{
*/ */
@ -28,63 +29,61 @@
#define _SYS_H_ #define _SYS_H_
/** /**
* @brief Halts the system. * @brief Halts the system.
* @details This function is invoked by the operating system when an * @details This function is invoked by the operating system when an
* unrecoverable error is detected (as example because a programming error in * unrecoverable error is detected, as example because a programming
* the application code that triggers an assertion while in debug mode). * error in the application code that triggers an assertion while
* in debug mode.
*/ */
#define chSysHalt() port_halt() #define chSysHalt() port_halt()
/** /**
* @brief Performs a context switch. * @brief Performs a context switch.
* *
* @param otp the thread to be switched out * @param[in] otp the thread to be switched out
* @param ntp the thread to be switched in * @param[in] ntp the thread to be switched in
*/ */
#define chSysSwitchI(otp, ntp) port_switch(otp, ntp) #define chSysSwitchI(otp, ntp) port_switch(otp, ntp)
/** /**
* @brief Raises the system interrupt priority mask to the maximum level. * @brief Raises the system interrupt priority mask to the maximum level.
* @details All the maskable interrupt sources are disabled regardless their * @details All the maskable interrupt sources are disabled regardless their
* hardware priority. * hardware priority.
* * @note The implementation is architecture dependent, it may just disable
* @note The implementation is architecture dependent, it may just disable the * the interrupts or be exactly equivalent to @p chSysDisable().
* interrupts or be exactly equivalent to @p chSysDisable(). * @note Do not invoke this API from within a kernel lock.
* @note Do not invoke this API from within a kernel lock.
*/ */
#define chSysDisable() port_disable() #define chSysDisable() port_disable()
/** /**
* @brief Raises the system interrupt priority mask to system level. * @brief Raises the system interrupt priority mask to system level.
* @details The interrupt sources that should not be able to preempt the kernel * @details The interrupt sources that should not be able to preempt the kernel
* are disabled, interrupt sources with higher priority are still enabled. * are disabled, interrupt sources with higher priority are still
* * enabled.
* @note The implementation is architecture dependent, it may just disable the * @note The implementation is architecture dependent, it may just disable
* interrupts. * the interrupts.
* @note Do not invoke this API from within a kernel lock. * @note Do not invoke this API from within a kernel lock.
* @note This API is no replacement for @p chSysLock(), the @p chSysLock() * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
* could do more than just disable the interrupts. * could do more than just disable the interrupts.
*/ */
#define chSysSuspend() port_suspend() #define chSysSuspend() port_suspend()
/** /**
* @brief Lowers the system interrupt priority mask to user level. * @brief Lowers the system interrupt priority mask to user level.
* @details All the interrupt sources are enabled. * @details All the interrupt sources are enabled.
* * @note The implementation is architecture dependent, it may just enable
* @note The implementation is architecture dependent, it may just enable the * the interrupts.
* interrupts. * @note Do not invoke this API from within a kernel lock.
* @note Do not invoke this API from within a kernel lock. * @note This API is no replacement for @p chSysUnlock(), the
* @note This API is no replacement for @p chSysUnlock(), the @p chSysUnlock() * @p chSysUnlock() could do more than just enable the interrupts.
* could do more than just enable the interrupts.
*/ */
#define chSysEnable() port_enable() #define chSysEnable() port_enable()
/** /**
* @brief Enters the kernel lock mode. * @brief Enters the kernel lock mode.
* * @note The use of kernel lock mode is not recommended in the user code,
* @note The use of kernel lock mode is not recommended in the user code, it is * it is a better idea to use the semaphores or mutexes instead.
* a better idea to use the semaphores or mutexes instead. * @see CH_USE_NESTED_LOCKS
* @see CH_USE_NESTED_LOCKS
*/ */
#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__) #if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) #if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
@ -98,11 +97,10 @@
#endif /* !CH_USE_NESTED_LOCKS */ #endif /* !CH_USE_NESTED_LOCKS */
/** /**
* @brief Leaves the kernel lock mode. * @brief Leaves the kernel lock mode.
* * @note The use of kernel lock mode is not recommended in the user code,
* @note The use of kernel lock mode is not recommended in the user code, it is * it is a better idea to use the semaphores or mutexes instead.
* a better idea to use the semaphores or mutexes instead. * @see CH_USE_NESTED_LOCKS
* @see CH_USE_NESTED_LOCKS
*/ */
#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__) #if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) #if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
@ -116,53 +114,49 @@
#endif /* !CH_USE_NESTED_LOCKS */ #endif /* !CH_USE_NESTED_LOCKS */
/** /**
* @brief Enters the kernel lock mode from within an interrupt handler. * @brief Enters the kernel lock mode from within an interrupt handler.
* * @note This API may do nothing on some architectures, it is required
* @note This API may do nothing on some architectures, it is required because * because on ports that support preemptable interrupt handlers
* on ports that support preemptable interrupt handlers it is required to * it is required to raise the interrupt mask to the same level of
* raise the interrupt mask to the same level of the system mutual * the system mutual exclusion zone.<br>
* exclusion zone.<br> * It is good practice to invoke this API before invoking any I-class
* It is good practice to invoke this API before invoking any I-class * syscall from an interrupt handler.
* syscall from an interrupt handler. * @note This API must be invoked exclusively from interrupt handlers.
* @note This API must be invoked exclusively from interrupt handlers.
*/ */
#define chSysLockFromIsr() port_lock_from_isr() #define chSysLockFromIsr() port_lock_from_isr()
/** /**
* @brief Leaves the kernel lock mode from within an interrupt handler. * @brief Leaves the kernel lock mode from within an interrupt handler.
* *
* @note This API may do nothing on some architectures, it is required because * @note This API may do nothing on some architectures, it is required
* on ports that support preemptable interrupt handlers it is required to * because on ports that support preemptable interrupt handlers
* raise the interrupt mask to the same level of the system mutual * it is required to raise the interrupt mask to the same level of
* exclusion zone.<br> * the system mutual exclusion zone.<br>
* It is good practice to invoke this API after invoking any I-class * It is good practice to invoke this API after invoking any I-class
* syscall from an interrupt handler. * syscall from an interrupt handler.
* @note This API must be invoked exclusively from interrupt handlers. * @note This API must be invoked exclusively from interrupt handlers.
*/ */
#define chSysUnlockFromIsr() port_unlock_from_isr() #define chSysUnlockFromIsr() port_unlock_from_isr()
/** /**
* @brief IRQ handler enter code. * @brief IRQ handler enter code.
* * @note Usually IRQ handlers functions are also declared naked.
* @note Usually IRQ handlers functions are also declared naked. * @note On some architectures this macro can be empty.
* @note On some architectures this macro can be empty.
*/ */
#define CH_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE() #define CH_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
/** /**
* @brief IRQ handler exit code. * @brief IRQ handler exit code.
* * @note Usually IRQ handlers function are also declared naked.
* @note Usually IRQ handlers function are also declared naked. * @note This macro usually performs the final reschedulation by using
* @note This macro usually performs the final reschedulation by using * @p chSchRescRequiredI() and @p chSchDoRescheduleI().
* @p chSchRescRequiredI() and @p chSchDoRescheduleI().
*/ */
#define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE() #define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
/** /**
* @brief Standard IRQ handler declaration. * @brief Standard IRQ handler declaration.
* * @note @p id can be a function name or a vector number depending on the
* @note @p id can be a function name or a vector number depending on the * port implementation.
* port implementation.
*/ */
#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file threads.h * @file threads.h
* @brief Threads macros and structures. * @brief Threads macros and structures.
*
* @addtogroup threads * @addtogroup threads
* @{ * @{
*/ */
@ -38,115 +39,168 @@
#endif #endif
/** /**
* @brief Structure representing a thread.
*
* @extends ThreadsQueue * @extends ThreadsQueue
* @note Not all the listed fields are always needed, by switching off some *
* not needed ChibiOS/RT subsystems it is possible to save RAM space by * @brief Structure representing a thread.
* shrinking the @p Thread structure. * @note Not all the listed fields are always needed, by switching off some
* not needed ChibiOS/RT subsystems it is possible to save RAM space
* by shrinking the @p Thread structure.
*/ */
struct Thread { struct Thread {
Thread *p_next; /**< Next @p Thread in the threads Thread *p_next; /**< @brief Next in the list/queue. */
list/queue. */
/* End of the fields shared with the ThreadsList structure. */ /* End of the fields shared with the ThreadsList structure. */
Thread *p_prev; /**< Previous @p Thread in the threads Thread *p_prev; /**< @brief Previous in the queue. */
queue. */
/* End of the fields shared with the ThreadsQueue structure. */ /* End of the fields shared with the ThreadsQueue structure. */
tprio_t p_prio; /**< Thread priority. */ tprio_t p_prio; /**< @brief Thread priority. */
struct context p_ctx; /**< Processor context. */ struct context p_ctx; /**< @brief Processor context. */
#if CH_USE_REGISTRY #if CH_USE_REGISTRY
Thread *p_newer; /**< Newer registry element. */ Thread *p_newer; /**< @brief Newer registry element. */
Thread *p_older; /**< Older registry element. */ Thread *p_older; /**< @brief Older registry element. */
#endif #endif
/* End of the fields shared with the ReadyList structure. */ /* End of the fields shared with the ReadyList structure. */
/**
* @brief Current thread state.
*/
tstate_t p_state;
/**
* @brief Various thread flags.
*/
tmode_t p_flags;
#if CH_USE_DYNAMIC #if CH_USE_DYNAMIC
trefs_t p_refs; /**< References to this thread. */ /**
* @brief References to this thread.
*/
trefs_t p_refs;
#endif #endif
tstate_t p_state; /**< Current thread state. */
tmode_t p_flags; /**< Various thread flags. */
#if CH_USE_NESTED_LOCKS #if CH_USE_NESTED_LOCKS
cnt_t p_locks; /**< Number of nested locks. */ /**
* @brief Number of nested locks.
*/
cnt_t p_locks;
#endif #endif
#if CH_DBG_THREADS_PROFILING #if CH_DBG_THREADS_PROFILING
volatile systime_t p_time; /**< Thread consumed time in ticks. /**
@note This field can overflow. */ * @brief Thread consumed time in ticks.
* @note This field can overflow.
*/
volatile systime_t p_time;
#endif #endif
/**
* @brief State-specific fields.
* @note All the fields declared in this union are only valid in the
* specified state or condition and are thus volatile.
*/
union { union {
msg_t rdymsg; /**< Thread wakeup code. */ /**
msg_t exitcode; /**< The thread exit code * @brief Thread wakeup code.
(@p THD_STATE_FINAL state). */ * @note This field contains the low level message sent to the thread
void *wtobjp; /**< Generic kernel object pointer. */ * by the waking thread or interrupt handler. The value is valid
* after exiting the @p chSchWakeupS() function.
*/
msg_t rdymsg;
/**
* @brief Thread exit code.
* @note The thread termination code is stored in this field in order
* to be retrieved by the thread performing a @p chThdWait() on
* this thread.
*/
msg_t exitcode;
/**
* @brief Pointer to a generic "wait" object.
* @note This field is used to get a generic pointer to a synchronization
* object and is valid when the thread is in one of the wait
* states.
*/
void *wtobjp;
#if CH_USE_EVENTS #if CH_USE_EVENTS
eventmask_t ewmask; /**< Enabled events mask /**
(@p THD_STATE_WTOREVT or * @brief Enabled events mask.
@p THD_STATE_WTANDEVT states). */ * @note This field is only valied while the thread is in the
* @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states.
*/
eventmask_t ewmask;
#endif #endif
} p_u; /**< State-specific fields. */ } p_u;
#if CH_USE_WAITEXIT #if CH_USE_WAITEXIT
ThreadsList p_waiting; /**< Termination waiting list. */ /**
* @brief Termination waiting list.
*/
ThreadsList p_waiting;
#endif #endif
#if CH_USE_MESSAGES #if CH_USE_MESSAGES
ThreadsQueue p_msgqueue; /**< Messages queue. */ /**
msg_t p_msg; /**< Thread message. */ * @brief Messages queue.
*/
ThreadsQueue p_msgqueue;
/**
* @brief Thread message.
*/
msg_t p_msg;
#endif #endif
#if CH_USE_EVENTS #if CH_USE_EVENTS
eventmask_t p_epending; /**< Pending events mask. */ /**
* @brief Pending events mask.
*/
eventmask_t p_epending;
#endif #endif
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
Mutex *p_mtxlist; /**< List of the mutexes owned by this /**
thread, @p NULL terminated. */ * @brief List of the mutexes owned by this thread.
tprio_t p_realprio; /**< Thread's own, non-inherited, * @note The list is terminated by a @p NULL in this field.
priority. */ */
Mutex *p_mtxlist;
/**
* @brief Thread's own, non-inherited, priority.
*/
tprio_t p_realprio;
#endif #endif
#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
void *p_mpool; /**< Memory Pool where the thread /**
workspace is returned. */ * @brief Memory Pool where the thread workspace is returned.
*/
void *p_mpool;
#endif #endif
/* Extra fields defined in chconf.h */ /* Extra fields defined in chconf.h.*/
THREAD_EXT_FIELDS THREAD_EXT_FIELDS
}; };
/** Thread state: Ready to run, waiting on the ready list.*/ /** @brief Thread state: Ready to run, waiting on the ready list.*/
#define THD_STATE_READY 0 #define THD_STATE_READY 0
/** Thread state: Currently running.*/ /** @brief Thread state: Currently running.*/
#define THD_STATE_CURRENT 1 #define THD_STATE_CURRENT 1
/** Thread state: Thread created in suspended state.*/ /** @brief Thread state: Thread created in suspended state.*/
#define THD_STATE_SUSPENDED 2 #define THD_STATE_SUSPENDED 2
/** Thread state: Waiting on a semaphore.*/ /** @brief Thread state: Waiting on a semaphore.*/
#define THD_STATE_WTSEM 3 #define THD_STATE_WTSEM 3
/** Thread state: Waiting on a mutex.*/ /** @brief Thread state: Waiting on a mutex.*/
#define THD_STATE_WTMTX 4 #define THD_STATE_WTMTX 4
/** Thread state: Waiting in @p chCondWait().*/ /** @brief Thread state: Waiting in @p chCondWait().*/
#define THD_STATE_WTCOND 5 #define THD_STATE_WTCOND 5
/** Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/ /** @brief Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/
#define THD_STATE_SLEEPING 6 #define THD_STATE_SLEEPING 6
/** Thread state: Waiting in @p chThdWait().*/ /** @brief Thread state: Waiting in @p chThdWait().*/
#define THD_STATE_WTEXIT 7 #define THD_STATE_WTEXIT 7
/** Thread state: Waiting in @p chEvtWaitOneTimeout() or /** @brief Thread state: Waiting in @p chEvtWaitXXX().*/
@p chEvtWaitAnyTimeout().*/ #define THD_STATE_WTOREVT 8
#define THD_STATE_WTOREVT 8 /** @brief Thread state: Waiting in @p chEvtWaitAllTimeout().*/
/** Thread state: Waiting in @p chEvtWaitAllTimeout().*/ #define THD_STATE_WTANDEVT 9
#define THD_STATE_WTANDEVT 9 /** @brief Thread state: Waiting in @p chMsgSend().*/
/** Thread state: Waiting in @p chMsgSend().*/ #define THD_STATE_SNDMSG 10
#define THD_STATE_SNDMSG 10 /** @brief Thread state: Waiting in @p chMsgWait().*/
/** Thread state: Waiting in @p chMsgWait().*/ #define THD_STATE_WTMSG 11
#define THD_STATE_WTMSG 11 /** @brief Thread state: After termination.*/
/** Thread state: After termination.*/ #define THD_STATE_FINAL 12
#define THD_STATE_FINAL 12
/* /*
* Various flags into the thread p_flags field. * Various flags into the thread p_flags field.
*/ */
#define THD_MEM_MODE_MASK 3 /**< Thread memory mode mask. */ #define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */
#define THD_MEM_MODE_STATIC 0 /**< Thread memory mode: static.*/ #define THD_MEM_MODE_STATIC 0 /**< @brief Thread memory mode: static. */
#define THD_MEM_MODE_HEAP 1 /**< Thread memory mode: heap. */ #define THD_MEM_MODE_HEAP 1 /**< @brief Thread memory mode: heap. */
#define THD_MEM_MODE_MEMPOOL 2 /**< Thread memory mode: pool. */ #define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread memory mode: pool. */
#define THD_TERMINATE 4 /**< Termination requested. */ #define THD_TERMINATE 4 /**< @brief Termination requested. */
/* Not an API, don't use into the application code.*/ /** @brief Thread function.*/
Thread *init_thread(Thread *tp, tprio_t prio);
/** Thread function.*/
typedef msg_t (*tfunc_t)(void *); typedef msg_t (*tfunc_t)(void *);
/* /*
@ -155,6 +209,7 @@ typedef msg_t (*tfunc_t)(void *);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
Thread *init_thread(Thread *tp, tprio_t prio);
Thread *chThdInit(void *wsp, size_t size, Thread *chThdInit(void *wsp, size_t size,
tprio_t prio, tfunc_t pf, void *arg); tprio_t prio, tfunc_t pf, void *arg);
Thread *chThdCreateStatic(void *wsp, size_t size, Thread *chThdCreateStatic(void *wsp, size_t size,
@ -186,85 +241,87 @@ extern "C" {
#endif #endif
/** /**
* Returns a pointer to the current @p Thread. * @brief Returns a pointer to the current @p Thread.
*/ */
#define chThdSelf() currp #define chThdSelf() currp
/** /**
* Returns the current thread priority. * @brief Returns the current thread priority.
*/ */
#define chThdGetPriority() (currp->p_prio) #define chThdGetPriority() (currp->p_prio)
/** /**
* Returns the pointer to the @p Thread local storage area, if any. * @brief Returns the pointer to the @p Thread local storage area, if any.
*/ */
#define chThdLS() (void *)(currp + 1) #define chThdLS() (void *)(currp + 1)
/** /**
* Verifies if the specified thread is in the @p THD_STATE_FINAL state. * @brief Verifies if the specified thread is in the @p THD_STATE_FINAL state.
* *
* @param[in] tp the pointer to the thread * @param[in] tp the pointer to the thread
* @retval TRUE thread terminated. * @retval TRUE thread terminated.
* @retval FALSE thread not terminated. * @retval FALSE thread not terminated.
*/ */
#define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL) #define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL)
/** /**
* Verifies if the current thread has a termination request pending. * @brief Verifies if the current thread has a termination request pending.
* *
* @retval TRUE termination request pended. * @retval TRUE termination request pended.
* @retval FALSE termination request not pended. * @retval FALSE termination request not pended.
*/ */
#define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE) #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE)
/** /**
* Resumes a thread created with @p chThdInit(). * @brief Resumes a thread created with @p chThdInit().
* *
* @param[in] tp the pointer to the thread * @param[in] tp the pointer to the thread
*/ */
#define chThdResumeI(tp) chSchReadyI(tp) #define chThdResumeI(tp) chSchReadyI(tp)
/** /**
* 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 as * @param[in] time the delay in system ticks, the special values are
* 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 timeout * interpreted as a normal time specification not as
* specification. * an immediate timeout specification.
* . * .
*/ */
#define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time) #define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time)
/** /**
* Delays the invoking thread for the specified number of seconds. * @brief Delays the invoking thread for the specified number of seconds.
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
* *
* @param[in] sec the time in seconds * @param[in] sec the time in seconds
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
*/ */
#define chThdSleepSeconds(sec) chThdSleep(S2ST(sec)) #define chThdSleepSeconds(sec) chThdSleep(S2ST(sec))
/** /**
* Delays the invoking thread for the specified number of milliseconds. * @brief Delays the invoking thread for the specified number of
* milliseconds.
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
* *
* @param[in] msec the time in milliseconds * @param[in] msec the time in milliseconds
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
*/ */
#define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec)) #define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec))
/** /**
* Delays the invoking thread for the specified number of microseconds. * @brief Delays the invoking thread for the specified number of
* microseconds.
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
* *
* @param[in] usec the time in microseconds * @param[in] usec the time in microseconds
* @note The specified time is rounded up to a value allowed by the real
* system clock.
* @note The maximum specified value is implementation dependent.
*/ */
#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))

View File

@ -18,8 +18,9 @@
*/ */
/** /**
* @file vt.h * @file vt.h
* @brief Time macros and structures. * @brief Time macros and structures.
*
* @addtogroup time * @addtogroup time
* @{ * @{
*/ */
@ -28,58 +29,73 @@
#define _VT_H_ #define _VT_H_
/** /**
* Time conversion utility. Converts from seconds to system ticks number. * @brief Time conversion utility.
* @details Converts from seconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
*/ */
#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY)) #define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY))
/** /**
* Time conversion utility. Converts from milliseconds to system ticks number. * @brief Time conversion utility.
* @note The result is rounded upward to the next tick boundary. * @details Converts from milliseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
*/ */
#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L)) #define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L))
/** /**
* Time conversion utility. Converts from microseconds to system ticks number. * @brief Time conversion utility.
* @note The result is rounded upward to the next tick boundary. * @details Converts from microseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
*/ */
#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L)) #define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L))
/** Virtual Timer callback function.*/ /**
* @brief Virtual Timer callback function.
*/
typedef void (*vtfunc_t)(void *); typedef void (*vtfunc_t)(void *);
/**
* @brief Virtual Timer structure type.
*/
typedef struct VirtualTimer VirtualTimer; typedef struct VirtualTimer VirtualTimer;
/** /**
* @brief Virtual Timer descriptor structure.
* @extends DeltaList * @extends DeltaList
*
* @brief Virtual Timer descriptor structure.
*/ */
struct VirtualTimer { struct VirtualTimer {
VirtualTimer *vt_next; /**< Next timer in the delta list.*/ VirtualTimer *vt_next; /**< @brief Next timer in the delta
VirtualTimer *vt_prev; /**< Previous timer in the delta list.*/ list. */
systime_t vt_time; /**< Time delta before timeout.*/ VirtualTimer *vt_prev; /**< @brief Previous timer in the delta
vtfunc_t vt_func; /**< Timer callback function pointer. list. */
The pointer is reset to zero after systime_t vt_time; /**< @brief Time delta before timeout. */
the callback is invoked.*/ vtfunc_t vt_func; /**< @brief Timer callback function
void *vt_par; /**< Timer callback function pointer. */
parameter.*/ void *vt_par; /**< @brief Timer callback function
parameter. */
}; };
/** /**
* @brief Virtual timers list header. * @brief Virtual timers list header.
* @note The delta list is implemented as a double link bidirectional list in * @note The delta list is implemented as a double link bidirectional list
* order to make the unlink time constant, the reset of a virtual timer * in order to make the unlink time constant, the reset of a virtual
* is often used in the code. * timer is often used in the code.
*/ */
typedef struct { typedef struct {
VirtualTimer *vt_next; /**< Next timer in the delta list (the VirtualTimer *vt_next; /**< @brief Next timer in the delta
one that will be triggered next).*/ list. */
VirtualTimer *vt_prev; /**< Last timer in the delta list.*/ VirtualTimer *vt_prev; /**< @brief Last timer in the delta
systime_t vt_time; /**< Must be initialized to -1.*/ list. */
volatile systime_t vt_systime; /**< System Time counter.*/ systime_t vt_time; /**< @brief Must be initialized to -1. */
volatile systime_t vt_systime; /**< @brief System Time counter. */
} VTList; } VTList;
extern VTList vtlist; extern VTList vtlist;
/**
* @brief Virtual timers sticker.
*/
#define chVTDoTickI() { \ #define chVTDoTickI() { \
vtlist.vt_systime++; \ vtlist.vt_systime++; \
if (&vtlist != (VTList *)vtlist.vt_next) { \ if (&vtlist != (VTList *)vtlist.vt_next) { \
@ -110,14 +126,19 @@ extern "C" {
} }
#endif #endif
/** Returns TRUE if the speciified timer is armed.*/ /**
* @brief Returns TRUE if the speciified timer is armed.
*/
#define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL) #define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL)
/** /**
* Returns the number of system ticks since the @p chSysInit() invocation. * @brief Current system time.
* @return the system ticks number * @details Returns the number of system ticks since the @p chSysInit()
* @note The counter can reach its maximum and then returns to zero. * invocation.
* @note This function is designed to work with the @p chThdSleepUntil(). * @note The counter can reach its maximum and then restart from zero.
* @note This function is designed to work with the @p chThdSleepUntil().
*
* @return The system time in ticks.r
*/ */
#define chTimeNow() (vtlist.vt_systime) #define chTimeNow() (vtlist.vt_systime)

View File

@ -20,6 +20,9 @@
/** /**
* @file chlists.c * @file chlists.c
* @brief Thread queues/lists code. * @brief Thread queues/lists code.
* @note All the functions present in this module, while public, are not
* an OS API and should not be directly used in the user applications
* code.
* *
* @addtogroup internals * @addtogroup internals
* @{ * @{