diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c
index 10aee42d3..0ec331b41 100644
--- a/os/kernel/src/chsem.c
+++ b/os/kernel/src/chsem.c
@@ -347,7 +347,7 @@ void chSemAddCounterI(Semaphore *sp, cnt_t n) {
* 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
+ * @param[in] spw pointer to a @p Semaphore structure to wait on
* @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
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
index 0be671c16..0df804df7 100644
--- a/os/kernel/src/chthreads.c
+++ b/os/kernel/src/chthreads.c
@@ -233,7 +233,7 @@ tprio_t chThdSetPriority(tprio_t newprio) {
* 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().
+ * @note Use this function to start threads created with @p chThdCreateI().
*
* @param[in] tp pointer to the thread
* @return The pointer to the thread.
@@ -388,9 +388,9 @@ void chThdExitS(msg_t msg) {
* The memory used by the exited thread is handled in different ways
* depending on the API that spawned the thread:
* - If the thread was spawned by @p chThdCreateStatic() or by
- * @p chThdInit() then nothing happens and the thread working area
- * is not released or modified in any way. This is the default,
- * totally static, behavior.
+ * @p chThdCreateI() then nothing happens and the thread working
+ * area is not released or modified in any way. This is the
+ * default, totally static, behavior.
* - If the thread was spawned by @p chThdCreateFromHeap() then
* the working area is returned to the system heap.
* - If the thread was spawned by @p chThdCreateFromMemoryPool()
diff --git a/os/various/cpp_wrappers/ch.cpp b/os/various/cpp_wrappers/ch.cpp
index 5faf6d37c..d6dd61ff7 100644
--- a/os/various/cpp_wrappers/ch.cpp
+++ b/os/various/cpp_wrappers/ch.cpp
@@ -52,6 +52,11 @@ namespace chibios_rt {
return chTimeNow();
}
+ bool isTimeWithin(systime_t start, systime_t end) {
+
+ return (bool)chTimeIsWithin(start, end);
+ }
+
/*------------------------------------------------------------------------*
* chibios_rt::Timer *
*------------------------------------------------------------------------*/
@@ -209,6 +214,11 @@ namespace chibios_rt {
chThdExit(msg);
}
+ void BaseThread::exitS(msg_t msg) {
+
+ chThdExitS(msg);
+ }
+
bool BaseThread::shouldTerminate(void) {
return (bool)chThdShouldTerminate();
@@ -224,6 +234,11 @@ namespace chibios_rt {
chThdSleepUntil(time);
}
+ void BaseThread::yield(void) {
+
+ chThdYield();
+ }
+
#if CH_USE_MESSAGES
msg_t BaseThread::getMessage(ThreadReference* trp) {
@@ -289,6 +304,23 @@ namespace chibios_rt {
}
#endif /* CH_USE_EVENTS */
+#if CH_USE_MUTEXES
+ void BaseThread::unlockMutex(void) {
+
+ chMtxUnlock();
+ }
+
+ void BaseThread::unlockMutexS(void) {
+
+ chMtxUnlockS();
+ }
+
+ void BaseThread::unlockAllMutexes(void) {
+
+ chMtxUnlockAll();
+ }
+#endif /* CH_USE_MUTEXES */
+
#if CH_USE_SEMAPHORES
/*------------------------------------------------------------------------*
* chibios_rt::Semaphore *
@@ -349,7 +381,8 @@ namespace chibios_rt {
}
#if CH_USE_SEMSW
- msg_t Semaphore::signalWait(Semaphore *ssem, Semaphore *wsem) {
+ msg_t Semaphore::signalWait(chibios_rt::Semaphore *ssem,
+ chibios_rt::Semaphore *wsem) {
return chSemSignalWait(&ssem->sem, &wsem->sem);
}
@@ -370,19 +403,19 @@ namespace chibios_rt {
return chMtxTryLock(&mutex);
}
+ bool Mutex::tryLockS(void) {
+
+ return chMtxTryLockS(&mutex);
+ }
+
void Mutex::lock(void) {
chMtxLock(&mutex);
}
- void Mutex::unlock(void) {
+ void Mutex::lockS(void) {
- chMtxUnlock();
- }
-
- void Mutex::unlockAll(void) {
-
- chMtxUnlockAll();
+ chMtxLockS(&mutex);
}
#if CH_USE_CONDVARS
@@ -399,16 +432,31 @@ namespace chibios_rt {
chCondSignal(&condvar);
}
+ void CondVar::signalI(void) {
+
+ chCondSignalI(&condvar);
+ }
+
void CondVar::broadcast(void) {
chCondBroadcast(&condvar);
}
+ void CondVar::broadcastI(void) {
+
+ chCondBroadcastI(&condvar);
+ }
+
msg_t CondVar::wait(void) {
return chCondWait(&condvar);
}
+ msg_t CondVar::waitS(void) {
+
+ return chCondWaitS(&condvar);
+ }
+
#if CH_USE_CONDVARS_TIMEOUT
msg_t CondVar::waitTimeout(systime_t time) {
diff --git a/os/various/cpp_wrappers/ch.hpp b/os/various/cpp_wrappers/ch.hpp
index efcb49dba..a1928e852 100644
--- a/os/various/cpp_wrappers/ch.hpp
+++ b/os/various/cpp_wrappers/ch.hpp
@@ -43,27 +43,27 @@ namespace chibios_rt {
public:
/**
* @brief ChibiOS/RT initialization.
- * @details The system is initialized, the idle thread is spawned and the
- * current instruction flow becomes the main thread with priority
- * @p NORMALPRIO.
+ * @details After executing this function the current instructions stream
+ * becomes the main thread.
+ * @pre Interrupts must be still disabled when @p chSysInit() is invoked
+ * and are internally enabled.
+ * @post The main thread is created with priority @p NORMALPRIO.
+ * @note This function has special, architecture-dependent, requirements,
+ * see the notes into the various port reference manuals.
*
- * @api
+ * @special
*/
static void init(void);
/**
- * @brief Kernel lock.
- * @note On some ports it is faster to invoke chSysLock() directly
- * because inlining.
+ * @brief Enters the kernel lock mode.
*
* @special
*/
static void lock(void);
/**
- * @brief Kernel unlock.
- * @note On some ports it is faster to invoke chSysUnlock() directly
- * because inlining.
+ * @brief Leaves the kernel lock mode.
*
* @special
*/
@@ -78,6 +78,21 @@ namespace chibios_rt {
* @api
*/
static systime_t getTime(void);
+
+ /**
+ * @brief Checks if the current system time is within the specified time
+ * window.
+ * @note When start==end then the function returns always true because the
+ * whole time range is specified.
+ *
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @api
+ */
+ static bool isTimeWithin(systime_t start, systime_t end);
};
/*------------------------------------------------------------------------*
@@ -94,13 +109,20 @@ namespace chibios_rt {
struct ::VirtualTimer timer_ref;
/**
- * @brief Starts the timer.
- * @note It must be called with the interrupts disabled.
- * @note The associated function is invoked by an interrupt handler.
+ * @brief Enables a virtual timer.
+ * @note The associated function is invoked from interrupt context.
*
- * @param[in] time the time in system ticks
- * @param[in] vtfunc the timer callback function
- * @param[in] par the parameter for the callback function
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ * @param[in] vtfunc the timer callback function. After invoking the
+ * callback the timer is disabled and the structure can
+ * be disposed or reused.
+ * @param[in] par a parameter that will be passed to the callback
+ * function
*
* @iclass
*/
@@ -192,17 +214,46 @@ namespace chibios_rt {
void resumeI(msg_t msg);
/**
- * @brief Requests thread termination.
- * @details A termination flag is added to the thread, it is thread
- * responsibility to detect it and exit.
+ * @brief Requests a thread termination.
+ * @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.
+ *
+ * @api
*/
void requestTerminate(void);
#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
/**
- * @brief Synchronization on Thread exit.
+ * @brief Blocks the execution of the invoking thread until the specified
+ * thread terminates then the exit code is returned.
+ * @details This function waits for the specified thread to terminate then
+ * decrements its reference counter, if the counter reaches zero then
+ * the thread working area is returned to the proper allocator.
+ * The memory used by the exited thread is handled in different ways
+ * depending on the API that spawned the thread:
+ * - If the thread was spawned by @p chThdCreateStatic() or by
+ * @p chThdCreateI() then nothing happens and the thread working
+ * area is not released or modified in any way. This is the
+ * default, totally static, behavior.
+ * - If the thread was spawned by @p chThdCreateFromHeap() then
+ * the working area is returned to the system heap.
+ * - If the thread was spawned by @p chThdCreateFromMemoryPool()
+ * then the working area is returned to the owning memory pool.
+ * .
+ * @pre The configuration option @p CH_USE_WAITEXIT must be enabled in
+ * order to use this function.
+ * @post Enabling @p chThdWait() requires 2-4 (depending on the
+ * architecture) extra bytes in the @p Thread structure.
+ * @post After invoking @p chThdWait() the thread pointer becomes invalid
+ * and must not be used as parameter for further system calls.
+ * @note If @p CH_USE_DYNAMIC is not specified this function just waits for
+ * the thread termination, no memory allocators are involved.
*
- * @return The exit message from the thread.
+ * @param[in] tp pointer to the thread
+ * @return The exit code from the terminated thread.
*
* @api
*/
@@ -311,54 +362,95 @@ namespace chibios_rt {
static void setName(const char *tname);
/**
- * @brief Changes the current thread priority.
+ * @brief Changes the running thread priority level then reschedules if
+ * necessary.
+ * @note The function returns the real thread priority regardless of the
+ * current priority that could be higher than the real priority
+ * because the priority inheritance mechanism.
*
- * @param[in] newprio The new priority level
- * @return The old priority level.
+ * @param[in] newprio the new priority level of the running thread
+ * @return The old priority level.
*
* @api
*/
static tprio_t setPriority(tprio_t newprio);
/**
- * @brief Thread exit.
+ * @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. The compiler has no way to
+ * know this so do not assume that the compiler would remove
+ * the dead code.
*
- * @param[in] msg the exit message
+ * @param[in] msg thread exit code
*
* @api
*/
static void exit(msg_t msg);
/**
- * @brief Determines if there is a pending termination request.
+ * @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. The compiler has no way to
+ * know this so do not assume that the compiler would remove
+ * the dead code.
*
- * @return The termination status.
- * @retval false if there is no termination request pending.
- * @retval true if there is a termination request pending.
+ * @param[in] msg thread exit code
*
- * @api
+ * @sclass
+ */
+ static void exitS(msg_t msg);
+
+ /**
+ * @brief Verifies if the current thread has a termination request pending.
+ * @note Can be invoked in any context.
+ *
+ * @retval TRUE termination request pending.
+ * @retval FALSE termination request not pending.
+ *
+ * @special
*/
static bool shouldTerminate(void);
/**
- * @brief Suspends the thread execution for the specified number of
- * system ticks.
+ * @brief Suspends the invoking thread for the specified time.
*
- * @param[in] interval the number of system ticks
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
*
* @api
*/
static void sleep(systime_t interval);
/**
- * @brief Suspends the thread execution until the specified time arrives.
+ * @brief Suspends the invoking thread until the system time arrives to the
+ * specified value.
*
- * @param[in] time the system time
+ * @param[in] time absolute system time
*
* @api
*/
static void sleepUntil(systime_t time);
+ /**
+ * @brief Yields the time slot.
+ * @details Yields the CPU control to the next thread in the ready list with
+ * equal priority, if any.
+ *
+ * @api
+ */
+ static void yield(void);
+
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
/**
* @brief Waits for a message.
@@ -530,6 +622,47 @@ namespace chibios_rt {
static void dispatchEvents(const evhandler_t handlers[],
eventmask_t mask);
#endif /* CH_USE_EVENTS */
+
+#if CH_USE_MUTEXES || defined(__DOXYGEN__)
+ /**
+ * @brief Unlocks the next owned mutex in reverse lock order.
+ * @pre The invoking thread must have at least one owned mutex.
+ * @post The mutex is unlocked and removed from the per-thread stack of
+ * owned mutexes.
+ *
+ * @return A pointer to the unlocked mutex.
+ *
+ * @api
+ */
+ static void unlockMutex(void);
+
+ /**
+ * @brief Unlocks the next owned mutex in reverse lock order.
+ * @pre The invoking thread must 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 A pointer to the unlocked mutex.
+ *
+ * @sclass
+ */
+ static void unlockMutexS(void);
+
+ /**
+ * @brief Unlocks all the mutexes owned by the invoking thread.
+ * @post The stack of owned mutexes is emptied and all the found
+ * mutexes are unlocked.
+ * @note This function is MUCH MORE 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.
+ *
+ * @api
+ */
+ static void unlockAllMutexes(void);
+#endif /* CH_USE_MUTEXES */
};
/*------------------------------------------------------------------------*
@@ -745,14 +878,18 @@ namespace chibios_rt {
/**
* @brief Atomic signal and wait operations.
*
- * @param[in] ssem pointer to a @p Semaphore to be signaled
- * @param[in] wsem pointer to a @p Semaphore to be wait on
- * @retval RDY_OK if the semaphore was signaled or not taken.
- * @retval RDY_RESET if the semaphore was reset.
+ * @param[in] ssem @p Semaphore object to be signaled
+ * @param[in] wsem @p Semaphore object to wait on
+ * @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().
*
* @api
*/
- static msg_t signalWait(Semaphore *ssem, Semaphore *wsem);
+ static msg_t signalWait(chibios_rt::Semaphore *ssem,
+ chibios_rt::Semaphore *wsem);
#endif /* CH_USE_SEMSW */
};
#endif /* CH_USE_SEMAPHORES */
@@ -772,7 +909,7 @@ namespace chibios_rt {
struct ::Mutex mutex;
/**
- * @brief Mutex constructor.
+ * @brief Mutex object constructor.
* @details The embedded @p ::Mutex structure is initialized.
*
* @api
@@ -780,44 +917,58 @@ namespace chibios_rt {
Mutex(void);
/**
- * @brief Tries a lock operation on the mutex.
+ * @brief Tries to lock a 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.
*
- * @retval TRUE if the mutex was successfully acquired
- * @retval FALSE if the lock attempt failed.
+ * @return The operation status.
+ * @retval TRUE if the mutex has been successfully acquired
+ * @retval FALSE if the lock attempt failed.
*
* @api
*/
bool tryLock(void);
/**
- * @brief Locks the mutex.
- * @details Performs a lock operation on the mutex, if the mutex is
- * already locked then the thread enters the mutex priority
- * queue and waits.
+ * @brief Tries to lock a 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.
+ *
+ * @return The operation status.
+ * @retval TRUE if the mutex has been successfully acquired
+ * @retval FALSE if the lock attempt failed.
+ *
+ * @sclass
+ */
+ bool tryLockS(void);
+
+ /**
+ * @brief Locks the specified mutex.
+ * @post The mutex is locked and inserted in the per-thread stack of owned
+ * mutexes.
*
* @api
*/
void lock(void);
/**
- * @brief Unlocks the mutex.
- * @details Performs an unlock operation on the mutex, the next waiting
- * thread, if any, is resumed and locks the mutex.
+ * @brief Locks the specified mutex.
+ * @post The mutex is locked and inserted in the per-thread stack of owned
+ * mutexes.
*
- * @api
+ * @sclass
*/
- static void unlock(void);
-
- /**
- * @brief Unlocks all the mutexes owned by the invoking thread.
- * @details This operation is MUCH MORE 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.
- *
- * @api
- */
- static void unlockAll(void);
+ void lockS(void);
};
#if CH_USE_CONDVARS || defined(__DOXYGEN__)
@@ -835,7 +986,7 @@ namespace chibios_rt {
struct ::CondVar condvar;
/**
- * @brief CondVar constructor.
+ * @brief CondVar object constructor.
* @details The embedded @p ::CondVar structure is initialized.
*
* @api
@@ -843,34 +994,77 @@ namespace chibios_rt {
CondVar(void);
/**
- * @brief Signals the CondVar.
- * @details The next thread waiting on the @p CondVar, if any, is awakened.
+ * @brief Signals one thread that is waiting on the condition variable.
*
* @api
*/
void signal(void);
/**
- * @brief Broadcasts the CondVar.
- * @details All the threads waiting on the @p CondVar, if any, are awakened.
+ * @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.
+ *
+ * @iclass
+ */
+ void signalI(void);
+
+ /**
+ * @brief Signals all threads that are waiting on the condition variable.
*
* @api
*/
void broadcast(void);
/**
- * @brief Waits on the CondVar while releasing the controlling mutex.
+ * @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.
*
- * @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().
+ * @iclass
+ */
+ void broadcastI(void);
+
+ /**
+ * @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.
+ * @pre The invoking thread must have at least one owned mutex.
+ *
+ * @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().
*
* @api
*/
msg_t wait(void);
+ /**
+ * @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.
+ * @pre The invoking thread must have at least one owned mutex.
+ *
+ * @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().
+ *
+ * @sclass
+ */
+ msg_t waitS(void);
+
#if CH_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__)
/**
* @brief Waits on the CondVar while releasing the controlling mutex.