Documentation improvements, renamed some event APIs.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2179 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
fb439b48b9
commit
9ffea7e261
|
@ -50,7 +50,7 @@
|
|||
#ifndef _CHBSEM_H_
|
||||
#define _CHBSEM_H_
|
||||
|
||||
#if CH_USE_SEMAPHORES
|
||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @extends Semaphore
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#ifndef _CHCOND_H_
|
||||
#define _CHCOND_H_
|
||||
|
||||
#if CH_USE_CONDVARS
|
||||
#if CH_USE_CONDVARS || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
|
|
|
@ -82,7 +82,7 @@ typedef struct {
|
|||
|
||||
#define __QUOTE_THIS(p) #p
|
||||
|
||||
#if CH_DBG_ENABLE_CHECKS
|
||||
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Function parameter check.
|
||||
* @details If the condition check fails then the kernel panics and halts.
|
||||
|
@ -102,7 +102,7 @@ typedef struct {
|
|||
}
|
||||
#endif /* !CH_DBG_ENABLE_CHECKS */
|
||||
|
||||
#if CH_DBG_ENABLE_ASSERTS
|
||||
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Condition assertion.
|
||||
* @details If the condition check fails then the kernel panics with the
|
||||
|
@ -144,7 +144,7 @@ typedef struct {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if CH_DBG_ENABLE_TRACE
|
||||
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
|
||||
extern TraceBuffer trace_buffer;
|
||||
void trace_init(void);
|
||||
void chDbgTrace(Thread *otp);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHEVENTS_H_
|
||||
#define _CHEVENTS_H_
|
||||
|
||||
#if CH_USE_EVENTS
|
||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||
|
||||
typedef struct EventListener EventListener;
|
||||
|
||||
|
@ -91,16 +91,18 @@ typedef struct EventSource {
|
|||
* The value must range between zero and the size, in bit,
|
||||
* of the @p eventid_t type minus one.
|
||||
*/
|
||||
#define chEvtRegister(esp, elp, eid) chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
|
||||
#define chEvtRegister(esp, elp, eid) \
|
||||
chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
|
||||
|
||||
/**
|
||||
* @brief Initializes an Event Source.
|
||||
* @note Can be used with interrupts disabled or enabled.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p EventSource structure.
|
||||
*
|
||||
* @param[in] esp pointer to the @p EventSource structure
|
||||
*/
|
||||
#define chEvtInit(esp) \
|
||||
((esp)->es_next = (EventListener *)(void *)(esp))
|
||||
((esp)->es_next = (EventListener *)(void *)(esp))
|
||||
|
||||
/**
|
||||
* @brief Verifies if there is at least one @p EventListener registered.
|
||||
|
@ -109,7 +111,7 @@ typedef struct EventSource {
|
|||
* @param[in] esp pointer to the @p EventSource structure
|
||||
*/
|
||||
#define chEvtIsListening(esp) \
|
||||
((void *)(esp) != (void *)(esp)->es_next)
|
||||
((void *)(esp) != (void *)(esp)->es_next)
|
||||
|
||||
/**
|
||||
* @brief Event Handler callback function.
|
||||
|
@ -123,8 +125,8 @@ extern "C" {
|
|||
EventListener *elp,
|
||||
eventmask_t mask);
|
||||
void chEvtUnregister(EventSource *esp, EventListener *elp);
|
||||
eventmask_t chEvtClear(eventmask_t mask);
|
||||
eventmask_t chEvtPend(eventmask_t mask);
|
||||
eventmask_t chEvtClearFlags(eventmask_t mask);
|
||||
eventmask_t chEvtAddFlags(eventmask_t mask);
|
||||
void chEvtSignal(Thread *tp, eventmask_t mask);
|
||||
void chEvtSignalI(Thread *tp, eventmask_t mask);
|
||||
void chEvtBroadcast(EventSource *esp);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHHEAP_H_
|
||||
#define _CHHEAP_H_
|
||||
|
||||
#if CH_USE_HEAP
|
||||
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHMBOXES_H_
|
||||
#define _CHMBOXES_H_
|
||||
|
||||
#if CH_USE_MAILBOXES
|
||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
|
@ -37,6 +37,9 @@
|
|||
#error "CH_USE_MAILBOXES requires CH_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Structure representing a mailbox object.
|
||||
*/
|
||||
typedef struct {
|
||||
msg_t *mb_buffer; /**< @brief Pointer to the mailbox
|
||||
buffer. */
|
||||
|
@ -99,10 +102,10 @@ extern "C" {
|
|||
|
||||
/**
|
||||
* @brief Returns the next message in the queue without removing it.
|
||||
* @note A message must be waiting in the queue for this function to work or
|
||||
* it would return garbage. The correct way to use this macro is to
|
||||
* use @p chMBGetFull() and then use this macro, all within a lock
|
||||
* state.
|
||||
* @pre A message must be waiting in the queue for this function to work
|
||||
* or it would return garbage. The correct way to use this macro is
|
||||
* to use @p chMBGetFull() and then use this macro, all within a
|
||||
* lock state.
|
||||
*/
|
||||
#define chMBPeek(mbp) (*(mbp)->mb_rdptr)
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef void *(*memgetfunc_t)(size_t size);
|
|||
*/
|
||||
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
|
||||
|
||||
#if CH_USE_MEMCORE
|
||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHMEMPOOLS_H_
|
||||
#define _CHMEMPOOLS_H_
|
||||
|
||||
#if CH_USE_MEMPOOLS
|
||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Memory pool free object header.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHMSG_H_
|
||||
#define _CHMSG_H_
|
||||
|
||||
#if CH_USE_MESSAGES
|
||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Evaluates to TRUE if the thread has pending messages.
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#ifndef _CHMTX_H_
|
||||
#define _CHMTX_H_
|
||||
|
||||
#if CH_USE_MUTEXES
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Mutex structure.
|
||||
* @brief Mutex structure.
|
||||
*/
|
||||
typedef struct Mutex {
|
||||
ThreadsQueue m_queue; /**< @brief Queue of the threads sleeping
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHQUEUES_H_
|
||||
#define _CHQUEUES_H_
|
||||
|
||||
#if CH_USE_QUEUES
|
||||
#if CH_USE_QUEUES || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHREGISTRY_H_
|
||||
#define _CHREGISTRY_H_
|
||||
|
||||
#if CH_USE_REGISTRY
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Removes a thread from the registry list.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef _CHSEM_H_
|
||||
#define _CHSEM_H_
|
||||
|
||||
#if CH_USE_SEMAPHORES
|
||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Semaphore structure.
|
||||
|
|
|
@ -31,21 +31,20 @@
|
|||
* <h2>Operation mode</h2>
|
||||
* The condition variable is a synchronization object meant to be
|
||||
* used inside a zone protected by a @p Mutex. Mutexes and CondVars
|
||||
* together can implement a Monitor construct.<br>
|
||||
* In order to use the Condition Variables APIs the @p CH_USE_CONDVARS
|
||||
* together can implement a Monitor construct.
|
||||
* @pre In order to use the condition variable APIs the @p CH_USE_CONDVARS
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_CONDVARS && CH_USE_MUTEXES
|
||||
#if (CH_USE_CONDVARS && CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Initializes s @p CondVar structure.
|
||||
* @note This function can be invoked from within an interrupt handler even
|
||||
* if it is not an I-Class API because it does not touch any critical
|
||||
* kernel data structure.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p CondVar structure.
|
||||
*
|
||||
* @param[out] cp pointer to a @p CondVar structure
|
||||
*/
|
||||
|
@ -73,6 +72,10 @@ void chCondSignal(CondVar *cp) {
|
|||
|
||||
/**
|
||||
* @brief Signals one thread that is waiting on the condition variable.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
*/
|
||||
|
@ -99,6 +102,10 @@ void chCondBroadcast(CondVar *cp) {
|
|||
|
||||
/**
|
||||
* @brief Signals all threads that are waiting on the condition variable.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
*/
|
||||
|
@ -118,13 +125,15 @@ void chCondBroadcastI(CondVar *cp) {
|
|||
* @details Releases the currently owned mutex, waits on the condition
|
||||
* variable, and finally acquires the mutex again. All the sequence
|
||||
* is performed atomically.
|
||||
* @note The invoking thread <b>must</b> have at least one owned mutex on
|
||||
* entry.
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
* @return The wakep mode.
|
||||
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the condition variable.
|
||||
* @retval RDY_OK if the condvar has been signaled using
|
||||
* @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar has been signaled using
|
||||
* @p chCondBroadcast().
|
||||
*/
|
||||
msg_t chCondWait(CondVar *cp) {
|
||||
msg_t msg;
|
||||
|
@ -140,13 +149,15 @@ msg_t chCondWait(CondVar *cp) {
|
|||
* @details Releases the currently owned mutex, waits on the condition
|
||||
* variable, and finally acquires the mutex again. All the sequence
|
||||
* is performed atomically.
|
||||
* @note The invoking thread <b>must</b> have at least one owned mutex on
|
||||
* entry.
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
* @return The wakep mode.
|
||||
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the condition variable.
|
||||
* @retval RDY_OK if the condvar has been signaled using
|
||||
* @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar has been signaled using
|
||||
* @p chCondBroadcast().
|
||||
*/
|
||||
msg_t chCondWaitS(CondVar *cp) {
|
||||
Thread *ctp = currp;
|
||||
|
@ -167,15 +178,16 @@ msg_t chCondWaitS(CondVar *cp) {
|
|||
return msg;
|
||||
}
|
||||
|
||||
#if CH_USE_CONDVARS_TIMEOUT
|
||||
#if CH_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waits on the condition variable releasing the mutex lock.
|
||||
* @details Releases the currently owned mutex, waits on the condition
|
||||
* variable, and finally acquires the mutex again. All the sequence
|
||||
* is performed atomically.
|
||||
* @note The invoking thread <b>must</b> have at least one owned mutex on
|
||||
* entry.
|
||||
* @note Exiting the function because a timeout does not re-acquire the
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
* @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled
|
||||
* in order to use this function.
|
||||
* @post Exiting the function because a timeout does not re-acquire the
|
||||
* mutex, the mutex ownership is lost.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
|
@ -184,11 +196,14 @@ msg_t chCondWaitS(CondVar *cp) {
|
|||
* It is not possible to specify zero @p TIME_IMMEDIATE
|
||||
* as timeout specification because it would make no sense
|
||||
* in this function.
|
||||
* @return The wakep mode.
|
||||
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
|
||||
* @retval RDY_TIMEOUT if the condvar was not signaled @p within the specified
|
||||
* timeout.
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the condition variable.
|
||||
* @retval RDY_OK if the condvar has been signaled using
|
||||
* @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar has been signaled using
|
||||
* @p chCondBroadcast().
|
||||
* @retval RDY_TIMEOUT if the condvar has not been signaled within the
|
||||
* specified timeout.
|
||||
*/
|
||||
msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
|
||||
msg_t msg;
|
||||
|
@ -204,9 +219,10 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
|
|||
* @details Releases the currently owned mutex, waits on the condition
|
||||
* variable, and finally acquires the mutex again. All the sequence
|
||||
* is performed atomically.
|
||||
* @note The invoking thread <b>must</b> have at least one owned mutex on
|
||||
* entry.
|
||||
* @note Exiting the function because a timeout does not re-acquire the
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
* @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled
|
||||
* in order to use this function.
|
||||
* @post Exiting the function because a timeout does not re-acquire the
|
||||
* mutex, the mutex ownership is lost.
|
||||
*
|
||||
* @param[in] cp pointer to the @p CondVar structure
|
||||
|
@ -215,11 +231,14 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
|
|||
* It is not possible to specify zero @p TIME_IMMEDIATE
|
||||
* as timeout specification because it would make no sense
|
||||
* in this function.
|
||||
* @return The wakep mode.
|
||||
* @retval RDY_OK if the condvar was signaled using @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast().
|
||||
* @retval RDY_TIMEOUT if the condvar was not signaled within the specified
|
||||
* timeout.
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the condition variable.
|
||||
* @retval RDY_OK if the condvar has been signaled using
|
||||
* @p chCondSignal().
|
||||
* @retval RDY_RESET if the condvar has been signaled using
|
||||
* @p chCondBroadcast().
|
||||
* @retval RDY_TIMEOUT if the condvar has not been signaled within the
|
||||
* specified timeout.
|
||||
*/
|
||||
msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
|
||||
Mutex *mp;
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
* - Parameters check.
|
||||
* - Kernel assertions.
|
||||
* .
|
||||
* @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE,
|
||||
* @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must
|
||||
* be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_DBG_ENABLE_TRACE
|
||||
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Public trace buffer.
|
||||
*/
|
||||
|
@ -40,6 +43,7 @@ TraceBuffer trace_buffer;
|
|||
|
||||
/**
|
||||
* @brief Trace circular buffer subsystem initialization.
|
||||
* @note Internal use only.
|
||||
*/
|
||||
void trace_init(void) {
|
||||
|
||||
|
@ -63,7 +67,8 @@ void chDbgTrace(Thread *otp) {
|
|||
}
|
||||
#endif /* CH_DBG_ENABLE_TRACE */
|
||||
|
||||
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
|
||||
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
|
||||
CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pointer to the panic message.
|
||||
* @details This pointer is meant to be accessed through the debugger, it is
|
||||
|
|
|
@ -46,22 +46,27 @@
|
|||
* Event Source will be signaled with an events mask.<br>
|
||||
* An unlimited number of Event Sources can exists in a system and
|
||||
* each thread can be listening on an unlimited number of
|
||||
* them.<br><br>
|
||||
* In order to use the Events APIs the @p CH_USE_EVENTS option must be
|
||||
* them.
|
||||
* @pre In order to use the Events APIs the @p CH_USE_EVENTS option must be
|
||||
* enabled in @p chconf.h.
|
||||
* @post Enabling events requires 1-4 (depending on the architecture)
|
||||
* extra bytes in the @p Thread structure.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_EVENTS
|
||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Registers an Event Listener on an Event Source.
|
||||
* @note Multiple Event Listeners can specify the same bits to be pended.
|
||||
* @details Once a thread has registered as listener on an event source it
|
||||
* will be notified of all events broadcasted there.
|
||||
* @note Multiple Event Listeners can specify the same bits to be ORed to
|
||||
* different threads.
|
||||
*
|
||||
* @param[in] esp pointer to the @p EventSource structure
|
||||
* @param[in] elp pointer to the @p EventListener structure
|
||||
* @param[in] mask the mask of event flags to be pended to the thread when
|
||||
* @param[in] mask the mask of event flags to be ORed to the thread when
|
||||
* the event source is broadcasted
|
||||
*/
|
||||
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) {
|
||||
|
@ -110,7 +115,7 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) {
|
|||
* @param[in] mask the events to be cleared
|
||||
* @return The pending events that were cleared.
|
||||
*/
|
||||
eventmask_t chEvtClear(eventmask_t mask) {
|
||||
eventmask_t chEvtClearFlags(eventmask_t mask) {
|
||||
eventmask_t m;
|
||||
|
||||
chSysLock();
|
||||
|
@ -123,13 +128,13 @@ eventmask_t chEvtClear(eventmask_t mask) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Pends a set of event flags on the current thread, this is @b much
|
||||
* faster than using @p chEvtBroadcast() or @p chEvtSignal().
|
||||
* @brief Adds (OR) a set of event flags on the current thread, this is
|
||||
* @b much faster than using @p chEvtBroadcast() or @p chEvtSignal().
|
||||
*
|
||||
* @param[in] mask the events to be pended
|
||||
* @param[in] mask the event flags to be ORed
|
||||
* @return The current pending events mask.
|
||||
*/
|
||||
eventmask_t chEvtPend(eventmask_t mask) {
|
||||
eventmask_t chEvtAddFlags(eventmask_t mask) {
|
||||
|
||||
chSysLock();
|
||||
|
||||
|
@ -140,10 +145,10 @@ eventmask_t chEvtPend(eventmask_t mask) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Pends a set of event flags on the specified @p Thread.
|
||||
* @brief Adds (OR) a set of event flags on the specified @p Thread.
|
||||
*
|
||||
* @param[in] tp the thread to be signaled
|
||||
* @param[in] mask the event flags set to be pended
|
||||
* @param[in] mask the event flags set to be ORed
|
||||
*/
|
||||
void chEvtSignal(Thread *tp, eventmask_t mask) {
|
||||
|
||||
|
@ -156,10 +161,14 @@ void chEvtSignal(Thread *tp, eventmask_t mask) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Pends a set of event flags on the specified @p Thread.
|
||||
* @brief Adds (OR) a set of event flags on the specified @p Thread.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] tp the thread to be signaled
|
||||
* @param[in] mask the event flags set to be pended
|
||||
* @param[in] mask the event flags set to be ORed
|
||||
*/
|
||||
void chEvtSignalI(Thread *tp, eventmask_t mask) {
|
||||
|
||||
|
@ -191,6 +200,10 @@ void chEvtBroadcast(EventSource *esp) {
|
|||
/**
|
||||
* @brief Signals all the Event Listeners registered on the specified Event
|
||||
* Source.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] esp pointer to the @p EventSource structure
|
||||
*/
|
||||
|
@ -209,7 +222,7 @@ void chEvtBroadcastI(EventSource *esp) {
|
|||
/**
|
||||
* @brief Invokes the event handlers associated to an event flags mask.
|
||||
*
|
||||
* @param[in] mask mask of the events to be dispatched
|
||||
* @param[in] mask mask of the event flags to be dispatched
|
||||
* @param[in] handlers an array of @p evhandler_t. The array must have size
|
||||
* equal to the number of bits in eventmask_t.
|
||||
*/
|
||||
|
@ -242,8 +255,8 @@ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) {
|
|||
* This means that Event Listeners with a lower event identifier have
|
||||
* an higher priority.
|
||||
*
|
||||
* @param[in] mask mask of the events that the function should wait for,
|
||||
* @p ALL_EVENTS enables all the events
|
||||
* @param[in] mask mask of the event flags that the function should wait
|
||||
* for, @p ALL_EVENTS enables all the events
|
||||
* @return The mask of the lowest id served and cleared event.
|
||||
*/
|
||||
eventmask_t chEvtWaitOne(eventmask_t mask) {
|
||||
|
@ -269,8 +282,8 @@ eventmask_t chEvtWaitOne(eventmask_t mask) {
|
|||
* @details The function waits for any event among those specified in
|
||||
* @p mask to become pending then the events are cleared and returned.
|
||||
*
|
||||
* @param[in] mask mask of the events that the function should wait for,
|
||||
* @p ALL_EVENTS enables all the events
|
||||
* @param[in] mask mask of the event flags that the function should wait
|
||||
* for, @p ALL_EVENTS enables all the events
|
||||
* @return The mask of the served and cleared events.
|
||||
*/
|
||||
eventmask_t chEvtWaitAny(eventmask_t mask) {
|
||||
|
@ -295,7 +308,8 @@ eventmask_t chEvtWaitAny(eventmask_t mask) {
|
|||
* @details The function waits for all the events specified in @p mask to
|
||||
* become pending then the events are cleared and returned.
|
||||
*
|
||||
* @param[in] mask mask of the event ids that the function should wait for
|
||||
* @param[in] mask mask of the event flags that the function should wait
|
||||
* for, @p ALL_EVENTS requires all the events
|
||||
* @return The mask of the served and cleared events.
|
||||
*/
|
||||
eventmask_t chEvtWaitAll(eventmask_t mask) {
|
||||
|
@ -314,7 +328,7 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
|
|||
}
|
||||
#endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */
|
||||
|
||||
#if CH_USE_EVENTS_TIMEOUT
|
||||
#if CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waits for exactly one of the specified events.
|
||||
* @details The function waits for one event among those specified in
|
||||
|
@ -325,15 +339,15 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
|
|||
* This means that Event Listeners with a lower event identifier have
|
||||
* an higher priority.
|
||||
*
|
||||
* @param[in] mask mask of the events that the function should wait for,
|
||||
* @p ALL_EVENTS enables all the events
|
||||
* @param[in] mask mask of the event flagss that the function should wait
|
||||
* for, @p ALL_EVENTS enables all the events
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The mask of the lowest id served and cleared event.
|
||||
* @retval 0 if the specified timeout expired.
|
||||
* @retval 0 if the operation has timed out.
|
||||
*/
|
||||
eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) {
|
||||
Thread *ctp = currp;
|
||||
|
@ -362,15 +376,15 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) {
|
|||
* @p mask to become pending then the events are cleared and
|
||||
* returned.
|
||||
*
|
||||
* @param[in] mask mask of the events that the function should wait for,
|
||||
* @p ALL_EVENTS enables all the events
|
||||
* @param[in] mask mask of the event flags that the function should wait
|
||||
* for, @p ALL_EVENTS enables all the events
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The mask of the served and cleared events.
|
||||
* @retval 0 if the specified timeout expired.
|
||||
* @retval 0 if the operation has timed out.
|
||||
*/
|
||||
eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) {
|
||||
Thread *ctp = currp;
|
||||
|
@ -397,14 +411,15 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) {
|
|||
* @details The function waits for all the events specified in @p mask to
|
||||
* become pending then the events are cleared and returned.
|
||||
*
|
||||
* @param[in] mask mask of the event ids that the function should wait for
|
||||
* @param[in] mask mask of the event flags that the function should wait
|
||||
* for, @p ALL_EVENTS requires all the events
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The mask of the served and cleared events.
|
||||
* @retval 0 if the specified timeout expired.
|
||||
* @retval 0 if the operation has timed out.
|
||||
*/
|
||||
eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) {
|
||||
Thread *ctp = currp;
|
||||
|
|
|
@ -31,22 +31,22 @@
|
|||
* By enabling the @p CH_USE_MALLOC_HEAP option the heap manager
|
||||
* will use the runtime-provided @p malloc() and @p free() as
|
||||
* backend for the heap APIs instead of the system provided
|
||||
* allocator.<br>
|
||||
* In order to use the heap APIs the @p CH_USE_HEAP option must
|
||||
* allocator.
|
||||
* @pre In order to use the heap APIs the @p CH_USE_HEAP option must
|
||||
* be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_HEAP
|
||||
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
||||
|
||||
#if !CH_USE_MALLOC_HEAP
|
||||
#if !CH_USE_MALLOC_HEAP || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Defaults on the best synchronization mechanism available.
|
||||
*/
|
||||
#if CH_USE_MUTEXES
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
#define H_LOCK(h) chMtxLock(&(h)->h_mtx)
|
||||
#define H_UNLOCK(h) chMtxUnlock()
|
||||
#else
|
||||
|
@ -67,7 +67,7 @@ void heap_init(void) {
|
|||
default_heap.h_provider = chCoreAlloc;
|
||||
default_heap.h_free.h.u.next = (union heap_header *)NULL;
|
||||
default_heap.h_free.h.size = 0;
|
||||
#if CH_USE_MUTEXES
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
chMtxInit(&default_heap.h_mtx);
|
||||
#else
|
||||
chSemInit(&default_heap.h_sem, 1);
|
||||
|
@ -76,8 +76,8 @@ void heap_init(void) {
|
|||
|
||||
/**
|
||||
* @brief Initializes a memory heap from a static memory area.
|
||||
* @note Both the heap buffer base and the heap size must be aligned to
|
||||
* the @p align_t type size.
|
||||
* @pre Both the heap buffer base and the heap size must be aligned to
|
||||
* the @p stkalign_t type size.
|
||||
*
|
||||
* @param[out] heapp pointer to the memory heap descriptor to be initialized
|
||||
* @param[in] buf heap buffer base
|
||||
|
@ -93,7 +93,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
|
|||
heapp->h_free.h.size = 0;
|
||||
hp->h.u.next = NULL;
|
||||
hp->h.size = size - sizeof(union heap_header);
|
||||
#if CH_USE_MUTEXES
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
chMtxInit(&heapp->h_mtx);
|
||||
#else
|
||||
chSemInit(&heapp->h_sem, 1);
|
||||
|
@ -104,7 +104,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
|
|||
* @brief Allocates a block of memory from the heap by using the first-fit
|
||||
* algorithm.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type (@p align_t).
|
||||
* pointer data type (@p stkalign_t).
|
||||
*
|
||||
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
||||
* access the default heap.
|
||||
|
|
|
@ -43,17 +43,19 @@
|
|||
* possible approach is to allocate memory (from a memory pool as
|
||||
* example) from the posting side and free it on the fetching side.
|
||||
* Another approach is to set a "done" flag into the structure pointed
|
||||
* by the message.<br>
|
||||
* In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option
|
||||
* by the message.
|
||||
* @pre In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_MAILBOXES
|
||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Initializes a Mailbox object.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p Mailbox structure.
|
||||
*
|
||||
* @param[out] mbp the pointer to the Mailbox structure to be initialized
|
||||
* @param[in] buf the circular messages buffer
|
||||
|
@ -101,9 +103,9 @@ void chMBReset(Mailbox *mbp) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the message was correctly posted.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly posted.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
@ -127,9 +129,9 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the message was correctly posted.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly posted.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
@ -160,9 +162,9 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the message was correctly posted.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly posted.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
@ -186,9 +188,9 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the message was correctly posted.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly posted.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
@ -219,9 +221,9 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if a message was correctly fetched.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly fetched.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
@ -245,9 +247,9 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
|||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if a message was correctly fetched.
|
||||
* @retval RDY_RESET if the mailbox was reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation timed out.
|
||||
* @retval RDY_OK if a message has been correctly fetched.
|
||||
* @retval RDY_RESET if the mailbox has been reset while waiting.
|
||||
* @retval RDY_TIMEOUT if the operation has timed out.
|
||||
*/
|
||||
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||
msg_t rdymsg;
|
||||
|
|
|
@ -35,15 +35,15 @@
|
|||
* By having a centralized memory provider the various allocators can
|
||||
* coexist and share the main memory.<br>
|
||||
* This allocator, alone, is also useful for very simple applications
|
||||
* that just require a simple way to get memory blocks.<br>
|
||||
* In order to use the core memory manager APIs the @p CH_USE_MEMCORE
|
||||
* that just require a simple way to get memory blocks.
|
||||
* @pre In order to use the core memory manager APIs the @p CH_USE_MEMCORE
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_MEMCORE
|
||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||
|
||||
static uint8_t *nextmem;
|
||||
static uint8_t *endmem;
|
||||
|
@ -73,7 +73,6 @@ void core_init(void) {
|
|||
* type @p stkalign_t so it is not possible to allocate less
|
||||
* than <code>sizeof(stkalign_t)</code>.
|
||||
*
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
|
|
|
@ -26,19 +26,21 @@
|
|||
* <h2>Operation mode</h2>
|
||||
* The Memory Pools APIs allow to allocate/free fixed size objects in
|
||||
* <b>constant time</b> and reliably without memory fragmentation
|
||||
* problems.<br>
|
||||
* In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option
|
||||
* problems.
|
||||
* @pre In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_MEMPOOLS
|
||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Initializes an empty memory pool.
|
||||
* @note The size is internally aligned to be a multiple of the @p align_t
|
||||
* type size.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p MemoryPool structure.
|
||||
* @note The size is internally aligned to be a multiple of the
|
||||
* @p stkalign_t type size.
|
||||
*
|
||||
* @param[out] mp pointer to a @p MemoryPool structure
|
||||
* @param[in] size the size of the objects contained in this memory pool,
|
||||
|
@ -96,10 +98,10 @@ void *chPoolAlloc(MemoryPool *mp) {
|
|||
|
||||
/**
|
||||
* @brief Releases (or adds) an object into (to) a memory pool.
|
||||
* @note The object is assumed to be of the right size for the specified
|
||||
* @pre The freed object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @note The object is assumed to be memory aligned to the size of @p align_t
|
||||
* type.
|
||||
* @pre The freed object must be memory aligned to the size of
|
||||
* @p stkalign_t type.
|
||||
*
|
||||
* @param[in] mp pointer to a @p MemoryPool structure
|
||||
* @param[in] objp the pointer to the object to be released or added
|
||||
|
@ -116,8 +118,10 @@ void chPoolFreeI(MemoryPool *mp, void *objp) {
|
|||
|
||||
/**
|
||||
* @brief Releases (or adds) an object into (to) a memory pool.
|
||||
* @note The object is assumed to be of the right size for the specified
|
||||
* @pre The freed object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @pre The freed object must be memory aligned to the size of
|
||||
* @p stkalign_t type.
|
||||
*
|
||||
* @param[in] mp pointer to a @p MemoryPool structure
|
||||
* @param[in] objp the pointer to the object to be released or added
|
||||
|
|
|
@ -30,20 +30,22 @@
|
|||
* that messages are not copied between the client and server threads
|
||||
* but just a pointer passed so the exchange is very time
|
||||
* efficient.<br>
|
||||
* Messages are scalar data types of type @p msg_t that are guaranteed
|
||||
* to be size compatible with data pointers. Note that on some
|
||||
* architectures function pointers can be larger that @p msg_t.<br>
|
||||
* Messages are usually processed in FIFO order but it is possible to
|
||||
* process them in priority order by enabling the
|
||||
* @p CH_USE_MESSAGES_PRIORITY option in @p chconf.h.<br>
|
||||
* Applications do not need to allocate buffers for synchronous
|
||||
* message queues, the mechanism just requires two extra pointers in
|
||||
* the @p Thread structure (the message queue header).<br>
|
||||
* In order to use the Messages APIs the @p CH_USE_MESSAGES option
|
||||
* @pre In order to use the message APIs the @p CH_USE_MESSAGES option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @post Enabling messages requires 6-12 (depending on the architecture)
|
||||
* extra bytes in the @p Thread structure.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_MESSAGES
|
||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||
|
||||
#if CH_USE_MESSAGES_PRIORITY
|
||||
#define msg_insert(tp, qp) prio_insert(tp, qp)
|
||||
|
@ -79,13 +81,13 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
|
|||
|
||||
/**
|
||||
* @brief Suspends the thread and waits for an incoming message.
|
||||
* @note You can assume that the data contained in the message is stable
|
||||
* until you invoke @p chMsgRelease() because the sending thread is
|
||||
* suspended until then.
|
||||
* @post After receiving a message the function @p chMsgRelease() must be
|
||||
* invoked in order to acknowledge the reception and send the answer.
|
||||
* @note If the message is a pointer then you can assume that the data
|
||||
* pointed by the message is stable until you invoke @p chMsgRelease()
|
||||
* because the sending thread is suspended until then.
|
||||
*
|
||||
* @return The pointer to the message structure. Note, it is
|
||||
* always the message associated to the thread on the
|
||||
* top of the messages queue.
|
||||
* @return The message.
|
||||
*/
|
||||
msg_t chMsgWait(void) {
|
||||
msg_t msg;
|
||||
|
@ -104,16 +106,14 @@ msg_t chMsgWait(void) {
|
|||
|
||||
/**
|
||||
* @brief Returns the next message in the queue.
|
||||
* @note You can assume that the data pointed by the message is stable until
|
||||
* you invoke @p chMsgRelease() because the sending thread is
|
||||
* suspended until then. Always remember that the message data is not
|
||||
* copied between the sender and the receiver, just a pointer is
|
||||
* passed.
|
||||
* @post After receiving a message the function @p chMsgRelease() must be
|
||||
* invoked in order to acknowledge the reception and send the answer.
|
||||
* @note If the message is a pointer then you can assume that the data
|
||||
* pointed by the message is stable until you invoke @p chMsgRelease()
|
||||
* because the sending thread is suspended until then.
|
||||
*
|
||||
* @return The pointer to the message structure. Note, it is
|
||||
* always the message associated to the thread on the
|
||||
* top of the messages queue.
|
||||
* @retval NULL if the queue is empty.
|
||||
* @return The message.
|
||||
* @retval 0 if the queue is empty.
|
||||
*/
|
||||
msg_t chMsgGet(void) {
|
||||
msg_t msg;
|
||||
|
@ -126,12 +126,8 @@ msg_t chMsgGet(void) {
|
|||
|
||||
/**
|
||||
* @brief Releases the thread waiting on top of the messages queue.
|
||||
* @note You can call this function only if there is a message already in
|
||||
* the queue else the result will be unpredictable (a crash most likely).
|
||||
* Exiting from the @p chMsgWait() ensures you have at least one
|
||||
* message in the queue so it is not a big deal.<br>
|
||||
* The condition is only tested in debug mode in order to make this
|
||||
* code as fast as possible.
|
||||
* @pre Invoke this function only after a message has been received
|
||||
* using @p chMsgWait() or @p chMsgGet().
|
||||
*
|
||||
* @param[in] msg the message returned to the message sender
|
||||
*/
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
* <h2>Operation mode</h2>
|
||||
* A mutex is a threads synchronization object that can be in two
|
||||
* distinct states:
|
||||
* - Not owned.
|
||||
* - Owned by a thread.
|
||||
* - Not owned (unlocked).
|
||||
* - Owned by a thread (locked).
|
||||
* .
|
||||
* Operations defined for mutexes:
|
||||
* - <b>Lock</b>: The mutex is checked, if the mutex is not owned by
|
||||
|
@ -39,8 +39,6 @@
|
|||
* priority thread waiting in the queue, if any, is resumed and made
|
||||
* owner of the mutex.
|
||||
* .
|
||||
* In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must
|
||||
* be enabled in @p chconf.h.
|
||||
* <h2>Constraints</h2>
|
||||
* In ChibiOS/RT the Unlock operations are always performed in
|
||||
* lock-reverse order. The unlock API does not even have a parameter,
|
||||
|
@ -59,15 +57,21 @@
|
|||
* The mechanism works with any number of nested mutexes and any
|
||||
* number of involved threads. The algorithm complexity (worst case)
|
||||
* is N with N equal to the number of nested mutexes.
|
||||
* @pre In order to use the mutex APIs the @p CH_USE_MUTEXES option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @post Enabling mutexes requires 5-12 (depending on the architecture)
|
||||
* extra bytes in the @p Thread structure.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_MUTEXES
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Initializes s @p Mutex structure.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p Mutex structure.
|
||||
*
|
||||
* @param[out] mp pointer to a @p Mutex structure
|
||||
*/
|
||||
|
@ -81,6 +85,8 @@ void chMtxInit(Mutex *mp) {
|
|||
|
||||
/**
|
||||
* @brief Locks the specified mutex.
|
||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||
* mutexes.
|
||||
*
|
||||
* @param[in] mp pointer to the @p Mutex structure
|
||||
*/
|
||||
|
@ -95,6 +101,8 @@ void chMtxLock(Mutex *mp) {
|
|||
|
||||
/**
|
||||
* @brief Locks the specified mutex.
|
||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||
* mutexes.
|
||||
*
|
||||
* @param[in] mp pointer to the @p Mutex structure
|
||||
*/
|
||||
|
@ -164,12 +172,17 @@ void chMtxLockS(Mutex *mp) {
|
|||
|
||||
/**
|
||||
* @brief Tries to lock a mutex.
|
||||
* @details This function does not have any overhead related to
|
||||
* the priority inheritance mechanism because it does not try to
|
||||
* enter a sleep state on the mutex.
|
||||
* @details This function attempts to lock a mutex, if the mutex is already
|
||||
* locked by another thread then the function exits without waiting.
|
||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||
* mutexes.
|
||||
* @note This function does not have any overhead related to the
|
||||
* priority inheritance mechanism because it does not try to
|
||||
* enter a sleep state.
|
||||
*
|
||||
* @param[in] mp pointer to the @p Mutex structure
|
||||
* @retval TRUE if the mutex was successfully acquired
|
||||
* @return The operation status.
|
||||
* @retval TRUE if the mutex has been successfully acquired
|
||||
* @retval FALSE if the lock attempt failed.
|
||||
*/
|
||||
bool_t chMtxTryLock(Mutex *mp) {
|
||||
|
@ -185,12 +198,17 @@ bool_t chMtxTryLock(Mutex *mp) {
|
|||
|
||||
/**
|
||||
* @brief Tries to lock a mutex.
|
||||
* @details This function does not have any overhead related to
|
||||
* the priority inheritance mechanism because it does not try to
|
||||
* enter a sleep state on the mutex.
|
||||
* @details This function attempts to lock a mutex, if the mutex is already
|
||||
* taken by another thread then the function exits without waiting.
|
||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||
* mutexes.
|
||||
* @note This function does not have any overhead related to the
|
||||
* priority inheritance mechanism because it does not try to
|
||||
* enter a sleep state.
|
||||
*
|
||||
* @param[in] mp pointer to the @p Mutex structure
|
||||
* @retval TRUE if the mutex was successfully acquired
|
||||
* @return The operation status.
|
||||
* @retval TRUE if the mutex has been successfully acquired
|
||||
* @retval FALSE if the lock attempt failed.
|
||||
*/
|
||||
bool_t chMtxTryLockS(Mutex *mp) {
|
||||
|
@ -207,8 +225,11 @@ bool_t chMtxTryLockS(Mutex *mp) {
|
|||
|
||||
/**
|
||||
* @brief Unlocks the next owned mutex in reverse lock order.
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
* @post The mutex is unlocked and removed from the per-thread stack of
|
||||
* owned mutexes.
|
||||
*
|
||||
* @return The pointer to the unlocked mutex.
|
||||
* @return A pointer to the unlocked mutex.
|
||||
*/
|
||||
Mutex *chMtxUnlock(void) {
|
||||
Thread *ctp = currp;
|
||||
|
@ -260,9 +281,13 @@ Mutex *chMtxUnlock(void) {
|
|||
|
||||
/**
|
||||
* @brief Unlocks the next owned mutex in reverse lock order.
|
||||
* @note This function does not reschedule internally.
|
||||
* @pre The invoking thread <b>must</b> have at least one owned mutex.
|
||||
* @post The mutex is unlocked and removed from the per-thread stack of
|
||||
* owned mutexes.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel.
|
||||
*
|
||||
* @return The pointer to the unlocked mutex.
|
||||
* @return A pointer to the unlocked mutex.
|
||||
*/
|
||||
Mutex *chMtxUnlockS(void) {
|
||||
Thread *ctp = currp;
|
||||
|
@ -311,7 +336,9 @@ Mutex *chMtxUnlockS(void) {
|
|||
|
||||
/**
|
||||
* @brief Unlocks all the mutexes owned by the invoking thread.
|
||||
* @details This function is <b>MUCH MORE</b> efficient than releasing the
|
||||
* @post The stack of owned mutexes is emptied and all the found
|
||||
* mutexes are unlocked.
|
||||
* @note This function is <b>MUCH MORE</b> efficient than releasing the
|
||||
* mutexes one by one and not just because the call overhead,
|
||||
* this function does not have any overhead related to the priority
|
||||
* inheritance mechanism.
|
||||
|
|
|
@ -35,21 +35,23 @@
|
|||
* are implemented by pairing an input queue and an output queue
|
||||
* together.
|
||||
* .
|
||||
* In order to use the I/O queues the @p CH_USE_QUEUES option must
|
||||
* be enabled in @p chconf.h.<br>
|
||||
* I/O queues are usually used as an implementation layer for the I/O
|
||||
* channels interface, also see @ref io_channels.
|
||||
* @pre In order to use the I/O queues the @p CH_USE_QUEUES option must
|
||||
* be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_QUEUES
|
||||
#if CH_USE_QUEUES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Initializes an input queue.
|
||||
* @details A Semaphore is internally initialized and works as a counter of
|
||||
* the bytes contained in the queue.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p InputQueue structure.
|
||||
* @note The callback is invoked from within the S-Locked system state,
|
||||
* see @ref system_states.
|
||||
*
|
||||
|
@ -88,7 +90,7 @@ void chIQResetI(InputQueue *iqp) {
|
|||
*
|
||||
* @param[in] iqp pointer to an @p InputQueue structure
|
||||
* @param[in] b the byte value to be written in the queue
|
||||
* @return The operation status, it can be one of:
|
||||
* @return The operation status.
|
||||
* @retval Q_OK if the operation has been completed with success.
|
||||
* @retval Q_FULL if the queue is full and the operation cannot be
|
||||
* completed.
|
||||
|
@ -117,7 +119,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
|
|||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return A byte value from the queue or:
|
||||
* @return A byte value from the queue.
|
||||
* @retval Q_TIMEOUT if the specified time expired.
|
||||
* @retval Q_RESET if the queue was reset.
|
||||
*/
|
||||
|
@ -205,6 +207,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
|
|||
* @brief Initializes an output queue.
|
||||
* @details A Semaphore is internally initialized and works as a counter of
|
||||
* the free bytes in the queue.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p OutputQueue structure.
|
||||
* @note The callback is invoked from within the S-Locked system state,
|
||||
* see @ref system_states.
|
||||
*
|
||||
|
@ -250,7 +254,7 @@ void chOQResetI(OutputQueue *oqp) {
|
|||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status:
|
||||
* @return The operation status.
|
||||
* @retval Q_OK if the operation succeeded.
|
||||
* @retval Q_TIMEOUT if the specified time expired.
|
||||
* @retval Q_RESET if the queue was reset.
|
||||
|
@ -279,7 +283,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) {
|
|||
* @details A byte value is read from the low end of an output queue.
|
||||
*
|
||||
* @param[in] oqp pointer to an @p OutputQueue structure
|
||||
* @return The byte value from the queue or:
|
||||
* @return The byte value from the queue.
|
||||
* @retval Q_EMPTY if the queue is empty.
|
||||
*/
|
||||
msg_t chOQGetI(OutputQueue *oqp) {
|
||||
|
|
|
@ -40,25 +40,24 @@
|
|||
* Another possible use is for centralized threads memory management,
|
||||
* terminating threads can pulse an event source and an event handler
|
||||
* can perform a scansion of the registry in order to recover the
|
||||
* memory.<br>
|
||||
* In order to use the threads registry the @p CH_USE_REGISTRY option
|
||||
* memory.
|
||||
* @pre In order to use the threads registry the @p CH_USE_REGISTRY option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_REGISTRY
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Returns the first thread in the system.
|
||||
* @details Returns the most ancient thread in the system, usually this is
|
||||
* the main thread unless it terminated.
|
||||
* @note A reference is added to the returned thread in order to make sure
|
||||
* it status is not lost.
|
||||
* the main thread unless it terminated. A reference is added to the
|
||||
* returned thread in order to make sure its status is not lost.
|
||||
* @note This function cannot return @p NULL because there is always at
|
||||
* least one thread in the system.
|
||||
*
|
||||
* @return A reference to the first thread.
|
||||
* @return A reference to the most ancient thread.
|
||||
*/
|
||||
Thread *chRegFirstThread(void) {
|
||||
Thread *tp;
|
||||
|
|
|
@ -57,11 +57,15 @@ void scheduler_init(void) {
|
|||
|
||||
/**
|
||||
* @brief Inserts a thread in the Ready List.
|
||||
* @note The function does not reschedule, the @p chSchRescheduleS() should
|
||||
* be called soon after.
|
||||
* @pre The thread must not be already inserted in any list through its
|
||||
* @p p_next and @p p_prev or list corruption would occur.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] tp the Thread to be made ready
|
||||
* @return The Thread pointer.
|
||||
* @param[in] tp the thread to be made ready
|
||||
* @return The thread pointer.
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__)
|
||||
#if CH_OPTIMIZE_SPEED
|
||||
|
@ -93,8 +97,8 @@ Thread *chSchReadyI(Thread *tp) {
|
|||
|
||||
/**
|
||||
* @brief Puts the current thread to sleep into the specified state.
|
||||
* @details The thread goes into a sleeping state. The @ref thread_states are
|
||||
* described into @p threads.h.
|
||||
* @details The thread goes into a sleeping state. The possible
|
||||
* @ref thread_states are defined into @p threads.h.
|
||||
*
|
||||
* @param[in] newstate the new thread state
|
||||
*/
|
||||
|
@ -144,8 +148,8 @@ static void wakeup(void *p) {
|
|||
* timeout specification.
|
||||
* @details The thread goes into a sleeping state, if it is not awakened
|
||||
* explicitly within the specified timeout then it is forcibly
|
||||
* awakened with a @p RDY_TIMEOUT low level message. The @ref
|
||||
* thread_states are described into @p threads.h.
|
||||
* awakened with a @p RDY_TIMEOUT low level message. The possible
|
||||
* @ref thread_states are defined into @p threads.h.
|
||||
*
|
||||
* @param[in] newstate the new thread state
|
||||
* @param[in] time the number of ticks before the operation timeouts, the
|
||||
|
@ -181,6 +185,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
|
|||
* @details The thread is inserted into the ready list or immediately made
|
||||
* running depending on its relative priority compared to the current
|
||||
* thread.
|
||||
* @pre The thread must not be already inserted in any list through its
|
||||
* @p p_next and @p p_prev or list corruption would occur.
|
||||
* @note It is equivalent to a @p chSchReadyI() followed by a
|
||||
* @p chSchRescheduleS() but much more efficient.
|
||||
* @note The function assumes that the current thread has the highest
|
||||
|
|
|
@ -50,15 +50,15 @@
|
|||
* also have other uses, queues guards and counters as example.<br>
|
||||
* Semaphores usually use a FIFO queuing strategy but it is possible
|
||||
* to make them order threads by priority by enabling
|
||||
* @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.<br>
|
||||
* In order to use the Semaphores APIs the @p CH_USE_SEMAPHORES
|
||||
* @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.
|
||||
* @pre In order to use the semaphore APIs the @p CH_USE_SEMAPHORES
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if CH_USE_SEMAPHORES
|
||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||
|
||||
#if CH_USE_SEMAPHORES_PRIORITY
|
||||
#define sem_insert(tp, qp) prio_insert(tp, qp)
|
||||
|
@ -68,6 +68,8 @@
|
|||
|
||||
/**
|
||||
* @brief Initializes a semaphore with the specified counter value.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p Semaphore structure.
|
||||
*
|
||||
* @param[out] sp pointer to a @p Semaphore structure
|
||||
* @param[in] n initial value of the semaphore counter. Must be
|
||||
|
@ -83,6 +85,9 @@ void chSemInit(Semaphore *sp, cnt_t n) {
|
|||
|
||||
/**
|
||||
* @brief Performs a reset operation on the semaphore.
|
||||
* @post After invoking this function all the threads waiting on the
|
||||
* semaphore, if any, are released and the semaphore counter is set
|
||||
* to the specified, non negative, value.
|
||||
* @note The released threads can recognize they were waked up by a reset
|
||||
* rather than a signal because the @p chSemWait() will return
|
||||
* @p RDY_RESET instead of @p RDY_OK.
|
||||
|
@ -101,10 +106,16 @@ void chSemReset(Semaphore *sp, cnt_t n) {
|
|||
|
||||
/**
|
||||
* @brief Performs a reset operation on the semaphore.
|
||||
* @post After invoking this function all the threads waiting on the
|
||||
* semaphore, if any, are released and the semaphore counter is set
|
||||
* to the specified, non negative, value.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
* @note The released threads can recognize they were waked up by a reset
|
||||
* rather than a signal because the @p chSemWait() will return
|
||||
* @p RDY_RESET instead of @p RDY_OK.
|
||||
* @note This function does not reschedule.
|
||||
*
|
||||
* @param[in] sp pointer to a @p Semaphore structure
|
||||
* @param[in] n the new value of the semaphore counter. The value must
|
||||
|
@ -130,8 +141,11 @@ void chSemResetI(Semaphore *sp, cnt_t n) {
|
|||
* @brief Performs a wait operation on a semaphore.
|
||||
*
|
||||
* @param[in] sp pointer to a @p Semaphore structure
|
||||
* @retval RDY_OK if the semaphore was signaled or not taken.
|
||||
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval RDY_OK if the thread has not stopped on the semaphore or the
|
||||
* semaphore has been signaled.
|
||||
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
|
||||
*/
|
||||
msg_t chSemWait(Semaphore *sp) {
|
||||
msg_t msg;
|
||||
|
@ -146,8 +160,11 @@ msg_t chSemWait(Semaphore *sp) {
|
|||
* @brief Performs a wait operation on a semaphore.
|
||||
*
|
||||
* @param[in] sp pointer to a @p Semaphore structure
|
||||
* @retval RDY_OK if the semaphore was signaled or not taken.
|
||||
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval RDY_OK if the thread has not stopped on the semaphore or the
|
||||
* semaphore has been signaled.
|
||||
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
|
||||
*/
|
||||
msg_t chSemWaitS(Semaphore *sp) {
|
||||
|
||||
|
@ -176,10 +193,13 @@ msg_t chSemWaitS(Semaphore *sp) {
|
|||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @retval RDY_OK if the semaphore was signaled or not taken.
|
||||
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
|
||||
* @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the
|
||||
* specified timeout.
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval RDY_OK if the thread has not stopped on the semaphore or the
|
||||
* semaphore has been signaled.
|
||||
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
|
||||
* @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within
|
||||
* the specified timeout.
|
||||
*/
|
||||
msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
|
||||
msg_t msg;
|
||||
|
@ -199,10 +219,13 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
|
|||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @retval RDY_OK if the semaphore was signaled or not taken.
|
||||
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
|
||||
* @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the
|
||||
* specified timeout.
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval RDY_OK if the thread has not stopped on the semaphore or the
|
||||
* semaphore has been signaled.
|
||||
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
|
||||
* @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within
|
||||
* the specified timeout.
|
||||
*/
|
||||
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
|
||||
|
||||
|
@ -247,7 +270,10 @@ void chSemSignal(Semaphore *sp) {
|
|||
|
||||
/**
|
||||
* @brief Performs a signal operation on a semaphore.
|
||||
* @note This function does not reschedule.
|
||||
* @post This function does not reschedule so a call to a rescheduling
|
||||
* function must be performed before unlocking the kernel. Note that
|
||||
* interrupt handlers always reschedule on exit so an explicit
|
||||
* reschedule must not be performed in ISRs.
|
||||
*
|
||||
* @param[in] sp pointer to a @p Semaphore structure
|
||||
*/
|
||||
|
@ -272,13 +298,16 @@ void chSemSignalI(Semaphore *sp) {
|
|||
#if CH_USE_SEMSW
|
||||
/**
|
||||
* @brief Performs atomic signal and wait operations on two semaphores.
|
||||
* @note The function is available only if the @p CH_USE_SEMSW
|
||||
* option is enabled in @p chconf.h.
|
||||
* @pre The configuration option @p CH_USE_SEMSW must be enabled in order
|
||||
* to use this function.
|
||||
*
|
||||
* @param[in] sps pointer to a @p Semaphore structure to be signaled
|
||||
* @param[in] spw pointer to a @p Semaphore structure to be wait on
|
||||
* @retval RDY_OK if the semaphore was signaled or not taken.
|
||||
* @retval RDY_RESET if the semaphore was reset using @p chSemReset().
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval RDY_OK if the thread has not stopped on the semaphore or the
|
||||
* semaphore has been signaled.
|
||||
* @retval RDY_RESET if the semaphore has been reset using @p chSemReset().
|
||||
*/
|
||||
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
|
||||
msg_t msg;
|
||||
|
|
|
@ -63,9 +63,9 @@ void _idle_thread(void *p) {
|
|||
* @brief ChibiOS/RT initialization.
|
||||
* @details After executing this function the current instructions stream
|
||||
* becomes the main thread.
|
||||
* @note Interrupts should be still disabled when @p chSysInit() is invoked
|
||||
* @pre Interrupts must be still disabled when @p chSysInit() is invoked
|
||||
* and are internally enabled.
|
||||
* @note The main thread is created with priority @p NORMALPRIO.
|
||||
* @post The main thread is created with priority @p NORMALPRIO.
|
||||
*/
|
||||
void chSysInit(void) {
|
||||
static Thread mainthread;
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
|
||||
/**
|
||||
* @brief Initializes a thread structure.
|
||||
* @note This is an internal functions, do not use it in application code.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
* @param[in] prio the priority level for the new thread
|
||||
|
@ -112,6 +113,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
|
|||
* @brief Initializes a new thread.
|
||||
* @details The new thread is initialized but not inserted in the ready list,
|
||||
* the initial state is @p THD_STATE_SUSPENDED.
|
||||
* @post The initialized thread can be subsequently started by invoking
|
||||
* @p chThdResume().
|
||||
* @note A thread can terminate by calling @p chThdExit() or by simply
|
||||
* returning from its main function.
|
||||
* @note This function can be invoked from within an interrupt handler
|
||||
|
@ -166,13 +169,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
|
|||
#if CH_USE_DYNAMIC && CH_USE_HEAP
|
||||
/**
|
||||
* @brief Creates a new thread allocating the memory from the heap.
|
||||
* @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP
|
||||
* must be enabled in order to use this function.
|
||||
* @note A thread can terminate by calling @p chThdExit() or by simply
|
||||
* returning from its main function.
|
||||
* @note The memory allocated for the thread is not released when the thread
|
||||
* terminates but when a @p chThdWait() is performed.
|
||||
* @note The function is available only if the @p CH_USE_DYNAMIC,
|
||||
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
|
||||
* in @p chconf.h.
|
||||
*
|
||||
* @param[in] heapp heap from which allocate the memory or @p NULL for the
|
||||
* default heap
|
||||
|
@ -202,14 +204,13 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
|||
#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
|
||||
/**
|
||||
* @brief Creates a new thread allocating the memory from the specified
|
||||
* Memory Pool.
|
||||
* memory pool.
|
||||
* @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS
|
||||
* must be enabled in order to use this function.
|
||||
* @note A thread can terminate by calling @p chThdExit() or by simply
|
||||
* returning from its main function.
|
||||
* @note The memory allocated for the thread is not released when the thread
|
||||
* terminates but when a @p chThdWait() is performed.
|
||||
* @note The function is available only if the @p CH_USE_DYNAMIC,
|
||||
* @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled
|
||||
* in @p chconf.h.
|
||||
*
|
||||
* @param[in] mp pointer to the memory pool object
|
||||
* @param[in] prio the priority level for the new thread
|
||||
|
@ -270,7 +271,11 @@ tprio_t chThdSetPriority(tprio_t newprio) {
|
|||
|
||||
/**
|
||||
* @brief Resumes a suspended thread.
|
||||
* @note Use this function to resume threads created with @p chThdInit().
|
||||
* @pre The specified thread pointer must refer to an initialized thread
|
||||
* in the @p THD_STATE_SUSPENDED state.
|
||||
* @post The specified thread is immediately started or put in the ready
|
||||
* list depending on the relative priority levels.
|
||||
* @note Use this function to start threads created with @p chThdInit().
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
* @return The pointer to the thread.
|
||||
|
@ -288,9 +293,11 @@ Thread *chThdResume(Thread *tp) {
|
|||
|
||||
/**
|
||||
* @brief Requests a thread termination.
|
||||
* @note The thread is not terminated but a termination request is added to
|
||||
* its @p p_flags field. The thread can read this status by
|
||||
* invoking @p chThdShouldTerminate() and then terminate cleanly.
|
||||
* @pre The target thread must be written to invoke periodically
|
||||
* @p chThdShouldTerminate() and terminate cleanly if it returns
|
||||
* @p TRUE.
|
||||
* @post The specified thread will terminate after detecting the termination
|
||||
* condition.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
*/
|
||||
|
@ -349,10 +356,14 @@ void chThdYield(void) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Terminates the current thread by specifying an exit status code.
|
||||
* @brief Terminates the current thread.
|
||||
* @details The thread goes in the @p THD_STATE_FINAL state holding the
|
||||
* specified exit status code, other threads can retrieve the
|
||||
* exit status code by invoking the function @p chThdWait().
|
||||
* @post Eventual code after this function will never be executed,
|
||||
* this function never returns.
|
||||
*
|
||||
* @param[in] msg thread exit code. The code can be retrieved by using
|
||||
* @p chThdWait().
|
||||
* @param[in] msg thread exit code
|
||||
*/
|
||||
void chThdExit(msg_t msg) {
|
||||
Thread *tp = currp;
|
||||
|
@ -375,6 +386,8 @@ void chThdExit(msg_t msg) {
|
|||
#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Adds a reference to a thread object.
|
||||
* @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order
|
||||
* to use this function.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
* @return The same thread pointer passed as parameter
|
||||
|
@ -394,6 +407,8 @@ Thread *chThdAddRef(Thread *tp) {
|
|||
* @details If the references counter reaches zero <b>and</b> the thread
|
||||
* is in the @p THD_STATE_FINAL state then the thread's memory is
|
||||
* returned to the proper allocator.
|
||||
* @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order
|
||||
* to use this function.
|
||||
* @note Static threads are not affected.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
|
@ -444,10 +459,10 @@ void chThdRelease(Thread *tp) {
|
|||
* then the working area is returned to the owning memory pool.
|
||||
* .
|
||||
* Please read the @ref article_lifecycle article for more details.
|
||||
* @note After invoking @p chThdWait() the thread pointer becomes invalid
|
||||
* @pre The configuration option @p CH_USE_WAITEXIT must be enabled in
|
||||
* order to use this function.
|
||||
* @post After invoking @p chThdWait() the thread pointer becomes invalid
|
||||
* and must not be used as parameter for further system calls.
|
||||
* @note The function is available only if the @p CH_USE_WAITEXIT
|
||||
* option is enabled in @p chconf.h.
|
||||
* @note If @p CH_USE_DYNAMIC is not specified this function just waits for
|
||||
* the thread termination, no memory allocators are involved.
|
||||
*
|
||||
|
|
|
@ -108,6 +108,9 @@
|
|||
the ARM7 port.
|
||||
- OPT: Speed optimizations of the STM32 SPI driver, improved latency.
|
||||
- OPT: Speed optimizations of the STM32 ADC driver.
|
||||
- CHANGE: The event APIs chEvtPend() and chEvtClear() have been renamed
|
||||
to chEvtAddFlags() and chEvtClearFlags() for consistency and correct
|
||||
English (which I am famous for...).
|
||||
- CHANGE: Added a parameter to the UART driver callbacks, the pointer to the
|
||||
driver itself.
|
||||
- CHANGE: In the UART driver now an error does not automatically brings the
|
||||
|
|
|
@ -77,7 +77,7 @@ static EVENTSOURCE_DECL(es2);
|
|||
|
||||
static void evt1_setup(void) {
|
||||
|
||||
chEvtClear(ALL_EVENTS);
|
||||
chEvtClearFlags(ALL_EVENTS);
|
||||
}
|
||||
|
||||
static void h1(eventid_t id) {(void)id;test_emit_token('A');}
|
||||
|
@ -130,7 +130,7 @@ ROMCONST struct testcase testevt1 = {
|
|||
|
||||
static void evt2_setup(void) {
|
||||
|
||||
chEvtClear(ALL_EVENTS);
|
||||
chEvtClearFlags(ALL_EVENTS);
|
||||
}
|
||||
|
||||
static msg_t thread1(void *p) {
|
||||
|
@ -157,12 +157,12 @@ static void evt2_execute(void) {
|
|||
/*
|
||||
* Test on chEvtWaitOne() without wait.
|
||||
*/
|
||||
chEvtPend(5);
|
||||
chEvtAddFlags(5);
|
||||
m = chEvtWaitOne(ALL_EVENTS);
|
||||
test_assert(1, m == 1, "single event error");
|
||||
m = chEvtWaitOne(ALL_EVENTS);
|
||||
test_assert(2, m == 4, "single event error");
|
||||
m = chEvtClear(ALL_EVENTS);
|
||||
m = chEvtClearFlags(ALL_EVENTS);
|
||||
test_assert(3, m == 0, "stuck event");
|
||||
|
||||
/*
|
||||
|
@ -175,17 +175,17 @@ static void evt2_execute(void) {
|
|||
m = chEvtWaitOne(ALL_EVENTS);
|
||||
test_assert_time_window(4, target_time, target_time + ALLOWED_DELAY);
|
||||
test_assert(5, m == 1, "single event error");
|
||||
m = chEvtClear(ALL_EVENTS);
|
||||
m = chEvtClearFlags(ALL_EVENTS);
|
||||
test_assert(6, m == 0, "stuck event");
|
||||
test_wait_threads();
|
||||
|
||||
/*
|
||||
* Test on chEvtWaitAny() without wait.
|
||||
*/
|
||||
chEvtPend(5);
|
||||
chEvtAddFlags(5);
|
||||
m = chEvtWaitAny(ALL_EVENTS);
|
||||
test_assert(7, m == 5, "unexpected pending bit");
|
||||
m = chEvtClear(ALL_EVENTS);
|
||||
m = chEvtClearFlags(ALL_EVENTS);
|
||||
test_assert(8, m == 0, "stuck event");
|
||||
|
||||
/*
|
||||
|
@ -198,7 +198,7 @@ static void evt2_execute(void) {
|
|||
m = chEvtWaitAny(ALL_EVENTS);
|
||||
test_assert_time_window(9, target_time, target_time + ALLOWED_DELAY);
|
||||
test_assert(10, m == 1, "single event error");
|
||||
m = chEvtClear(ALL_EVENTS);
|
||||
m = chEvtClearFlags(ALL_EVENTS);
|
||||
test_assert(11, m == 0, "stuck event");
|
||||
test_wait_threads();
|
||||
|
||||
|
@ -215,7 +215,7 @@ static void evt2_execute(void) {
|
|||
thread2, "A");
|
||||
m = chEvtWaitAll(5);
|
||||
test_assert_time_window(12, target_time, target_time + ALLOWED_DELAY);
|
||||
m = chEvtClear(ALL_EVENTS);
|
||||
m = chEvtClearFlags(ALL_EVENTS);
|
||||
test_assert(13, m == 0, "stuck event");
|
||||
test_wait_threads();
|
||||
chEvtUnregister(&es1, &el1);
|
||||
|
@ -249,7 +249,7 @@ ROMCONST struct testcase testevt2 = {
|
|||
|
||||
static void evt3_setup(void) {
|
||||
|
||||
chEvtClear(ALL_EVENTS);
|
||||
chEvtClearFlags(ALL_EVENTS);
|
||||
}
|
||||
|
||||
static void evt3_execute(void) {
|
||||
|
|
Loading…
Reference in New Issue