From 89788b3234417d8aea3d5e34d78bf24c4e1da444 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 11 Mar 2009 14:24:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@831 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/src/articles.dox | 1 + docs/src/design.dox | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ readme.txt | 4 +- src/chschd.c | 14 ++++--- src/chsys.c | 1 - src/chthreads.c | 35 ++++++++-------- src/include/threads.h | 35 +++++++++++++--- 7 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 docs/src/design.dox diff --git a/docs/src/articles.dox b/docs/src/articles.dox index a0426f41c..66268f9d7 100644 --- a/docs/src/articles.dox +++ b/docs/src/articles.dox @@ -29,6 +29,7 @@ * - @subpage article_jitter * - @subpage article_timing * - @subpage article_portguide + * - @subpage article_design * . */ /** @} */ diff --git a/docs/src/design.dox b/docs/src/design.dox new file mode 100644 index 000000000..4b6780a7a --- /dev/null +++ b/docs/src/design.dox @@ -0,0 +1,112 @@ +/* + 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 . +*/ + +/** + * @page article_design Designing an embedded application + * @{ + * ChibiOS/RT offers a variety of mechanisms and primitives, often it is + * better to focus on a single approach for the system design and use only + * part of the available subsystems.
+ * When designing your application you may choose among several design + * alternatives: + * - @ref nothreads + * - @ref messpass + * - @ref thdshared + * - @ref thdmixed + * . + * @section nothreads Single threaded superloop + * Correct, single thread, it is not mandatory to use the multithreading + * features of the OS. You may choose to implements everything as a complex + * state machine handled in the main thread alone. In this scenario the OS + * still offers a variety of useful mechanisms: + * - Interrupt handling. + * - Virtual Timers, very useful in state machines in order to handle time + * triggered state transitions. + * - Power management. + * - Event Flags and/or Semaphores as communication mechanism between + * interrupt handlers and the main. + * - I/O queues. + * - Memory allocation. + * - System time. + * . + * In this configuration the kernel size is really minimal, everything else + * is disabled and takes no space. You always have the option to use more + * threads at a later time in order to perform separate tasks. + * + * @section messpass Message Passing + * In this scenario there are multiple threads in the system that never + * share data, everything is done by exchanging messages. Each thread + * represents a service, the other threads can request the service by sending + * a message.
+ * In this scenario the following subsystems can be used: + * - Synchronous Messages. + * - Mailboxes (asynchronous message queues). + * . + * The advantage of this approach is to not have to deal with mutual exclusion, + * each functionality is encapsulated into a server thread that sequentially + * serves all the requests. As example, you can have the following scenario: + * - A buffers allocator server. + * - A disk driver server. + * - A file system server. + * - One or more client threads. + * . + * Example: + *

+ * @dot + digraph example { + rankdir="RL"; + node [shape=rectangle, fontname=Helvetica, fontsize=8, fixedsize="true", + width="1.2", height="0.75"]; + edge [fontname=Helvetica, fontsize=8]; + disk [label="Server Thread\nDisk Driver"]; + buf [label="Server Thread\nBuffers Allocator"]; + fs [label="Client&Server Thread\nFile System"]; + cl1 [label="Client Thread"]; + cl2 [label="Client Thread"]; + cl3 [label="Client Thread"]; + fs -> disk [label="I/O request", constraint=false]; + disk -> fs [label="status", style="dotted", constraint=false]; + fs -> buf [label="buffer request"]; + buf -> fs [label="buffer", style="dotted"]; + cl1 -> fs [label="FS transaction"]; + fs -> cl1 [label="result", style="dotted"]; + cl2 -> fs [label="FS transaction"]; + fs -> cl2 [label="result", style="dotted"]; + cl3 -> fs [label="FS transaction"]; + fs -> cl3 [label="result", style="dotted"]; + } + * @enddot + *

+ * Note that the threads should not exchange complex messages but just + * pointers to data structures in order to optimize the performance. + * Also note that a thread can be both client and server at the same + * time, the FS service in the previous scenario as example. + * + * @section thdshared Threads sharing data + * This is the most common scenario, several threads have access to both their + * private data and shared data. Synchronization happens with one of the + * mechanisms described in the @ref article_mutual_exclusion article.
+ * + * @section thdmixed Mixed + * All the above approaches can be freely mixed in a single application but + * usually I prefer to choose a way and consistently design the system around + * it. The OS is a toolbox that offers a lot of tools but you don't have + * to use them all necessarily. + */ +/** @} */ diff --git a/readme.txt b/readme.txt index c938f3dff..9902c263f 100644 --- a/readme.txt +++ b/readme.txt @@ -77,7 +77,8 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, added a specific test case to the test suite (backported in stable branch). - FIX: Fixed a problem in time ranges (bug 2680425)(backported in stable branch). -- FIX: Fixed a wrong parameter check in chVTSetI() (bug 2679155). +- FIX: Fixed a wrong parameter check in chVTSetI() and chThdSleep() + (bug 2679155). - FIX: Build error with options CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED (bug 2678928). - FIX: Removed unused chSysPuts() macro (bug 2672678). @@ -88,6 +89,7 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, - Removed testcond.c|h and moved the test cases into testmtx.c. Mutexes and condvars have to be tested together. - Added architecture diagram to the documentation. +- Removed from the documentation some references to long gone functions... *** 1.1.1unstable *** - FIX: Fixed a problem into the STACK_ALIGN() macro (backported in stable diff --git a/src/chschd.c b/src/chschd.c index b246d8f57..23b9871f9 100644 --- a/src/chschd.c +++ b/src/chschd.c @@ -122,11 +122,15 @@ static void wakeup(void *p) { * to sleep is awakened after the specified time has elapsed. * * @param[in] newstate the new thread state - * @param[in] time the number of ticks before the operation timeouts, - * the special value @p TIME_INFINITE is allowed. - * It is not possible to specify @p TIME_IMMEDIATE as timeout - * specification, it is interpreted as a normal time - * specification. + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state, this is equivalent to invoking @p chSchGoSleepS() + * but, of course, less efficient. + * - @a TIME_IMMEDIATE this value is accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. * @note The function must be called in the system mutex zone. diff --git a/src/chsys.c b/src/chsys.c index cedd3d28b..217e2f2da 100644 --- a/src/chsys.c +++ b/src/chsys.c @@ -75,7 +75,6 @@ void chSysInit(void) { chSysEnable(); /* - * The idle thread is created using the port-provided implementation. * This thread has the lowest priority in the system, its role is just to * serve interrupts in its context while keeping the lowest energy saving * mode compatible with the system status. diff --git a/src/chthreads.c b/src/chthreads.c index 70db14130..5a7a98943 100644 --- a/src/chthreads.c +++ b/src/chthreads.c @@ -73,10 +73,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * * @param[out] workspace pointer to a working area dedicated to the thread * stack - * @param[in] wsize size of the working area. - * @param[in] prio the priority level for the new thread. Usually the threads - * are created with priority @p NORMALPRIO, priorities - * can range from @p LOWPRIO to @p HIGHPRIO. + * @param[in] wsize size of the working area + * @param[in] prio the priority level for the new thread * @param[in] pf the thread function * @param[in] arg an argument passed to the thread function. It can be @p NULL. * @return The pointer to the @p Thread structure allocated for the @@ -112,10 +110,8 @@ Thread *chThdInit(void *workspace, size_t wsize, * * @param[out] workspace pointer to a working area dedicated to the thread * stack - * @param[in] wsize size of the working area. - * @param[in] prio the priority level for the new thread. Usually the threads - * are created with priority @p NORMALPRIO, priorities - * can range from @p LOWPRIO to @p HIGHPRIO. + * @param[in] wsize size of the working area + * @param[in] prio the priority level for the new thread * @param[in] pf the thread function * @param[in] arg an argument passed to the thread function. It can be @p NULL. * @return The pointer to the @p Thread structure allocated for the @@ -134,9 +130,7 @@ Thread *chThdCreateStatic(void *workspace, size_t wsize, * @brief Creates a new thread allocating the memory from the heap. * * @param[in] wsize size of the working area to be allocated - * @param[in] prio the priority level for the new thread. Usually the threads - * are created with priority @p NORMALPRIO, priorities - * can range from @p LOWPRIO to @p HIGHPRIO. + * @param[in] prio the priority level for the new thread * @param[in] pf the thread function * @param[in] arg an argument passed to the thread function. It can be @p NULL. * @return The pointer to the @p Thread structure allocated for the @@ -168,9 +162,7 @@ Thread *chThdCreateFromHeap(size_t wsize, tprio_t prio, * Pool. * * @param[in] mp the memory pool - * @param[in] prio the priority level for the new thread. Usually the threads - * are created with priority @p NORMALPRIO, priorities - * can range from @p LOWPRIO to @p HIGHPRIO. + * @param[in] prio the priority level for the new thread * @param[in] pf the thread function * @param[in] arg an argument passed to the thread function. It can be @p NULL. * @return The pointer to the @p Thread structure allocated for the @@ -207,7 +199,7 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, * @param[in] newprio the new priority level of the running thread * @return The old priority level. * @note The function returns the real thread priority regardless of the - * actual priority that could be higher than the real priority because + * current priority that could be higher than the real priority because * the priority inheritance mechanism. */ tprio_t chThdSetPriority(tprio_t newprio) { @@ -268,13 +260,18 @@ void chThdTerminate(Thread *tp) { /** * @brief Suspends the invoking thread for the specified time. * - * @param[in] time the delay in system ticks, the values @p TIME_IMMEDIATE and - * @p TIME_INFINITE are not allowed + * @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 accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . */ void chThdSleep(systime_t time) { - chDbgCheck((time != TIME_IMMEDIATE) && (time != TIME_INFINITE), - "chThdSleep"); + chDbgCheck(time != TIME_INFINITE, "chThdSleep"); chSysLock(); chThdSleepS(time); diff --git a/src/include/threads.h b/src/include/threads.h index 961ef5b0b..e7c56d3c7 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -190,35 +190,54 @@ extern "C" { /** Returns the pointer to the @p Thread currently in execution.*/ #define chThdSelf() currp -/** Returns the thread priority.*/ +/** Returns the current thread priority.*/ #define chThdGetPriority() (currp->p_prio) /** Returns the pointer to the @p Thread local storage area, if any.*/ #define chThdLS() (void *)(currp + 1) -/** Verifies if the specified thread is in the @p PREXIT state.*/ +/** + * Verifies if the specified thread is in the @p PREXIT state. + * + * @param[in] tp the pointer to the thread + * @retval TRUE thread terminated. + * @retval FALSE thread not terminated. + */ #define chThdTerminated(tp) ((tp)->p_state == PREXIT) /** * Verifies if the current thread has a termination request pending. + * + * @retval TRUE termination request pended. + * @retval FALSE termination request not pended. */ #define chThdShouldTerminate() (currp->p_flags & P_TERMINATE) /** - * Resumes a thread created with the @p P_SUSPENDED option or suspended with - * @p chThdSuspend(). - * @param tp the pointer to the thread + * Resumes a thread created with @p chThdInit(). + * + * @param[in] tp the pointer to the thread */ #define chThdResumeI(tp) chSchReadyI(tp) /** * Suspends the invoking thread for the specified time. - * @param time the delay in 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 accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . */ #define chThdSleepS(time) chSchGoSleepTimeoutS(PRSLEEP, time) /** * Delays the invoking thread for the specified number of seconds. + * + * @param[in] sec the time in seconds * @note The specified time is rounded up to a value allowed by the real * system clock. * @note The maximum specified value is implementation dependent. @@ -227,6 +246,8 @@ extern "C" { /** * Delays the invoking thread for the specified number of milliseconds. + * + * @param[in] msec the time in milliseconds * @note The specified time is rounded up to a value allowed by the real * system clock. * @note The maximum specified value is implementation dependent. @@ -235,6 +256,8 @@ extern "C" { /** * Delays the invoking thread for the specified number of microseconds. + * + * @param[in] usec the time in microseconds * @note The specified time is rounded up to a value allowed by the real * system clock. * @note The maximum specified value is implementation dependent. -- cgit v1.2.3