diff options
-rw-r--r-- | docs/src/articles.dox | 3 | ||||
-rw-r--r-- | docs/src/concepts.dox | 4 | ||||
-rw-r--r-- | docs/src/goals.dox | 4 | ||||
-rw-r--r-- | docs/src/main.dox | 4 | ||||
-rw-r--r-- | docs/src/memory.dox | 2 | ||||
-rw-r--r-- | docs/src/wakeup.dox | 148 | ||||
-rw-r--r-- | os/kernel/include/threads.h | 7 | ||||
-rw-r--r-- | os/kernel/templates/chconf.h | 2 | ||||
-rw-r--r-- | readme.txt | 1 | ||||
-rw-r--r-- | test/test.dox | 2 |
10 files changed, 167 insertions, 10 deletions
diff --git a/docs/src/articles.dox b/docs/src/articles.dox index ca35c3f14..caf332d32 100644 --- a/docs/src/articles.dox +++ b/docs/src/articles.dox @@ -20,8 +20,9 @@ /**
* @page articles Articles and Code Samples
* ChibiOS/RT Articles and Code Examples:
- * - @subpage article_interrupts
* - @subpage article_create_thread
+ * - @subpage article_interrupts
+ * - @subpage article_wakeup
* - @subpage article_manage_memory
* - @subpage article_stacks
* - @subpage article_mutual_exclusion
diff --git a/docs/src/concepts.dox b/docs/src/concepts.dox index d6364513b..49c96b2c8 100644 --- a/docs/src/concepts.dox +++ b/docs/src/concepts.dox @@ -34,8 +34,8 @@ * ChibiOS/RT APIs are all named following this convention:
* @a ch\<group\>\<action\>\<suffix\>().
* The possible groups are: @a Sys, @a Sch, @a Time, @a VT, @a Thd, @a Sem,
- * @a Mtx, @a Cond, @a Evt, @a Msg, @a Stream, @a IO, @a IQ, @a OQ, @a Dbg,
- * @a Core, @a Heap, @a Pool.
+ * @a Mtx, @a Cond, @a Evt, @a Msg, @a SequentialStream, @a IO, @a IQ, @a OQ,
+ * @a Dbg, @a Core, @a Heap, @a Pool.
*
* @section api_suffixes API Names Suffixes
* The suffix can be one of the following:
diff --git a/docs/src/goals.dox b/docs/src/goals.dox index bcce60922..e312b526a 100644 --- a/docs/src/goals.dox +++ b/docs/src/goals.dox @@ -42,7 +42,7 @@ *
* <h3>Static design</h3>
* Everything in the kernel is static, nowhere memory is allocated or freed,
- * there are two allocator subsystems but those are options and not part of
+ * there are three allocator subsystems but those are options and not part of
* core OS. Safety is something you design in, not something you can add later.
*
* <h3>No tables, arrays or other fixed structures</h3>
@@ -84,5 +84,5 @@ * committing to use it. Test results on all the supported platforms and
* performance metrics are included in each ChibiOS/RT release. The test
* code is released as well, all the included demos are capable of executing
- * the test suite and the OS benchmarks.
+ * the test suite and the OS benchmarks, see @ref testsuite.
*/
diff --git a/docs/src/main.dox b/docs/src/main.dox index 4ce9b64b1..ddf608c3f 100644 --- a/docs/src/main.dox +++ b/docs/src/main.dox @@ -42,8 +42,8 @@ * number of all the above objects.
* - PC simulator target included, the development can be done on a PC
* under Linux or Windows.<br>
- * Timers, I/O channels and other HW resources are simulated in a
- * Win32 process and the application code does not need to be aware of it.
+ * Timers, I/O channels and other HW resources are simulated in a guest OS
+ * process and the application code does not need to be aware of it.
* - No *need* for a memory allocator, all the kernel structures are static
* and declaratively allocated.
* - Optional, thread safe, Heap Allocator subsystem.
diff --git a/docs/src/memory.dox b/docs/src/memory.dox index 727a95b2b..cf8495bcc 100644 --- a/docs/src/memory.dox +++ b/docs/src/memory.dox @@ -35,7 +35,7 @@ *
* <h2>The three subsystems</h2>
* This is a small comparison table regarding the three subsystems, C-runtime
- * and static objects are thrown there for comparison:<br><br>
+ * and static objects are thrown in there for comparison:<br><br>
* <table style="text-align: center; width: 95%;"
* align="center" border="1" cellpadding="2" cellspacing="0">
* <tr>
diff --git a/docs/src/wakeup.dox b/docs/src/wakeup.dox new file mode 100644 index 000000000..82766932b --- /dev/null +++ b/docs/src/wakeup.dox @@ -0,0 +1,148 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @page article_wakeup How to wake up a thread from an interrupt handler
+ * Waking up a thread after an hardware event is one of the most common tasks
+ * that an RTOS must be able to perform efficiently. In ChibiOS/RT there are
+ * several mechanisms that can be used, often each mechanism is best suited
+ * in a specific scenario.
+ *
+ * <h2>Synchronously waking up a specific thread</h2>
+ * A common situation is to have to synchronously wake up a specific thread.
+ * This can be accomplished without the use of any specific synchronization
+ * primitive, it uses the very efficient low level scheduler APIs, note that
+ * you can also optionally send a simple message from the IRQ handler to
+ * the thread.
+ * @code
+static Thread *tp = NULL;
+
+void mythread(void *p) {
+
+ while (TRUE) {
+ msg_t msg;
+
+ // Waiting for the IRQ to happen.
+ chSysLock();
+ tp = chThdSelf();
+ chSchGoSleepS(PRSUSPENDED);
+ msg = chThdSelf()->p_rdymsg; // Retrieving the message, optional
+ chSysUnlock();
+ // Perform processing here.
+ }
+}
+
+CH_IRQ_HANDLER(myIRQ) {
+ CH_IRQ_PROLOGUE();
+
+ // Wakes up the thread.
+ chSysLockFromIsr();
+ if (tp != NULL) {
+ tp->p_rdymsg = (msg_t)55; // Sending the message, optional
+ chSchReadyI(tp);
+ tp = NULL;
+ }
+ chSysUnlockFromIsr().
+
+ CH_IRQ_EPILOGUE();
+}
+ * @endcode
+ *
+ * <h2>Synchronously waking up one of the waiting threads</h2>
+ * Lets assume you have a queue of waiting threads, you want to wake up
+ * the threads one by one in FIFO order, if there are no waiting threads
+ * then nothing happens.<br>
+ * This can be accomplished using a @p Semaphore object initialized to zero:
+ * @code
+CH_IRQ_HANDLER(myIRQ) {
+ CH_IRQ_PROLOGUE();
+
+ // If there is at least one waiting thread then signal it.
+ chSysLockFromIsr();
+ if (chSemGetCounterI(&mysem) < 0)
+ chSemSignalI(&mysem);
+ chSysUnlockFromIsr().
+
+ CH_IRQ_EPILOGUE();
+}
+ * @endcode
+ *
+ * <h2>Synchronously waking up all the waiting threads</h2>
+ * In this scenario you want to synchronously wake up all the waiting threads,
+ * if there are no waiting threads then nothing happens.<br>
+ * This can be accomplished using a @p Semaphore object initialized to zero:
+ * @code
+CH_IRQ_HANDLER(myIRQ) {
+ CH_IRQ_PROLOGUE();
+
+ // Wakes up all the threads waiting on the semaphore.
+ chSysLockFromIsr();
+ chSemResetI(&mysem);
+ chSysUnlockFromIsr().
+
+ CH_IRQ_EPILOGUE();
+}
+ * @endcode
+ *
+ * <h2>Asynchronously waking up a specific thread</h2>
+ * If you have to asynchronously wake up a specific thread then a simple
+ * event flags can be used.
+ * @code
+static Thread *tp;
+
+void mythread(void *p) {
+
+ tp = chThdSelf();
+ while (TRUE) {
+ // Checks if an IRQ happened else wait.
+ chEvtWaitAny((eventmask_t)1);
+ // Perform processing here.
+ }
+}
+
+CH_IRQ_HANDLER(myIRQ) {
+ CH_IRQ_PROLOGUE();
+
+ // Wakes up the thread.
+ chSysLockFromIsr();
+ chEvtSignalI(tp, (eventmask_t)1);
+ chSysUnlockFromIsr().
+
+ CH_IRQ_EPILOGUE();
+}
+ * @endcode
+ *
+ * <h2>Asynchronously waking up one or more threads</h2>
+ * By using event sources it is possible to asynchronously wake up one or more
+ * listener threads. The mechanism requires a single initialized
+ * @p EventSource object, all the threads registered as listeners on the
+ * event source will be broadcasted.
+ * @code
+CH_IRQ_HANDLER(myIRQ) {
+ CH_IRQ_PROLOGUE();
+
+ // Pends an event flag on all the listening threads.
+ chSysLockFromIsr();
+ chEvtBroadcastI(&my_event_source);
+ chSysUnlockFromIsr().
+
+ CH_IRQ_EPILOGUE();
+}
+ * @endcode
+ */
diff --git a/os/kernel/include/threads.h b/os/kernel/include/threads.h index edcf1f42a..1468b0f5a 100644 --- a/os/kernel/include/threads.h +++ b/os/kernel/include/threads.h @@ -27,6 +27,13 @@ #ifndef _THREADS_H_ #define _THREADS_H_ +/* + * Module dependencies check. + */ +#if CH_USE_DYNAMIC && !CH_USE_WAITEXIT +#error "CH_USE_DYNAMIC requires CH_USE_WAITEXIT" +#endif + /** * @brief Structure representing a thread. * diff --git a/os/kernel/templates/chconf.h b/os/kernel/templates/chconf.h index eeb35e4d4..5b42d3c9c 100644 --- a/os/kernel/templates/chconf.h +++ b/os/kernel/templates/chconf.h @@ -160,7 +160,7 @@ /**
* @brief Atomic semaphore API.
- * @details If enabled then the semaphores the @p chSemWaitSignal() API
+ * @details If enabled then the semaphores the @p chSemSignalWait() API
* is included in the kernel.
*
* @note The default is @p TRUE.
diff --git a/readme.txt b/readme.txt index f2a35cabe..b91f389cf 100644 --- a/readme.txt +++ b/readme.txt @@ -70,6 +70,7 @@ FIFO preload feature. Setting LPC214x_UART_FIFO_PRELOAD to 1 results in
the same behavior.
- Documentation fixes and improvements, testing strategy explained.
+- Added article about waking up threads from IRQ handlers.
*** 1.3.7 ***
- FIX: Fixed duplicated definition of SPI_USE_MUTUAL_EXCLUSION (bug 2922495).
diff --git a/test/test.dox b/test/test.dox index 75a46366e..9e83c095d 100644 --- a/test/test.dox +++ b/test/test.dox @@ -24,7 +24,7 @@ * order to verify the proper working of the kernel, the port and the demo
* itself.
*
- * <h2>Strategy by Components</h2>
+ * <h2>Strategy by Component</h2>
* The OS components are tested in various modes depending on their importance:
* - <b>Kernel</b>. The kernel code is subject to rigorous testing. The test
* suite aims to test <b>all</b> the kernel code and reach a code coverage
|