git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@831 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
80a8621ec0
commit
89788b3234
|
@ -29,6 +29,7 @@
|
||||||
* - @subpage article_jitter
|
* - @subpage article_jitter
|
||||||
* - @subpage article_timing
|
* - @subpage article_timing
|
||||||
* - @subpage article_portguide
|
* - @subpage article_portguide
|
||||||
|
* - @subpage article_design
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.<br>
|
||||||
|
* 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.<br>
|
||||||
|
* 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:
|
||||||
|
* <br><br>
|
||||||
|
* @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
|
||||||
|
* <br><br>
|
||||||
|
* 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.<br>
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
/** @} */
|
|
@ -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).
|
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
|
- FIX: Fixed a problem in time ranges (bug 2680425)(backported in stable
|
||||||
branch).
|
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
|
- FIX: Build error with options CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
|
||||||
(bug 2678928).
|
(bug 2678928).
|
||||||
- FIX: Removed unused chSysPuts() macro (bug 2672678).
|
- 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
|
- Removed testcond.c|h and moved the test cases into testmtx.c. Mutexes and
|
||||||
condvars have to be tested together.
|
condvars have to be tested together.
|
||||||
- Added architecture diagram to the documentation.
|
- Added architecture diagram to the documentation.
|
||||||
|
- Removed from the documentation some references to long gone functions...
|
||||||
|
|
||||||
*** 1.1.1unstable ***
|
*** 1.1.1unstable ***
|
||||||
- FIX: Fixed a problem into the STACK_ALIGN() macro (backported in stable
|
- FIX: Fixed a problem into the STACK_ALIGN() macro (backported in stable
|
||||||
|
|
14
src/chschd.c
14
src/chschd.c
|
@ -122,11 +122,15 @@ static void wakeup(void *p) {
|
||||||
* to sleep is awakened after the specified time has elapsed.
|
* to sleep is awakened after the specified time has elapsed.
|
||||||
*
|
*
|
||||||
* @param[in] newstate the new thread state
|
* @param[in] newstate the new thread state
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts, the
|
||||||
* the special value @p TIME_INFINITE is allowed.
|
* special values are handled as follow:
|
||||||
* It is not possible to specify @p TIME_IMMEDIATE as timeout
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
* specification, it is interpreted as a normal time
|
* state, this is equivalent to invoking @p chSchGoSleepS()
|
||||||
* specification.
|
* 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.
|
* @return The wakeup message.
|
||||||
* @retval RDY_TIMEOUT if a timeout occurs.
|
* @retval RDY_TIMEOUT if a timeout occurs.
|
||||||
* @note The function must be called in the system mutex zone.
|
* @note The function must be called in the system mutex zone.
|
||||||
|
|
|
@ -75,7 +75,6 @@ void chSysInit(void) {
|
||||||
chSysEnable();
|
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
|
* 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
|
* serve interrupts in its context while keeping the lowest energy saving
|
||||||
* mode compatible with the system status.
|
* mode compatible with the system status.
|
||||||
|
|
|
@ -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
|
* @param[out] workspace pointer to a working area dedicated to the thread
|
||||||
* stack
|
* stack
|
||||||
* @param[in] wsize size of the working area.
|
* @param[in] wsize size of the working area
|
||||||
* @param[in] prio the priority level for the new thread. Usually the threads
|
* @param[in] prio the priority level for the new thread
|
||||||
* are created with priority @p NORMALPRIO, priorities
|
|
||||||
* can range from @p LOWPRIO to @p HIGHPRIO.
|
|
||||||
* @param[in] pf the thread function
|
* @param[in] pf the thread function
|
||||||
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
|
* @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
|
* @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
|
* @param[out] workspace pointer to a working area dedicated to the thread
|
||||||
* stack
|
* stack
|
||||||
* @param[in] wsize size of the working area.
|
* @param[in] wsize size of the working area
|
||||||
* @param[in] prio the priority level for the new thread. Usually the threads
|
* @param[in] prio the priority level for the new thread
|
||||||
* are created with priority @p NORMALPRIO, priorities
|
|
||||||
* can range from @p LOWPRIO to @p HIGHPRIO.
|
|
||||||
* @param[in] pf the thread function
|
* @param[in] pf the thread function
|
||||||
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
|
* @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
|
* @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.
|
* @brief Creates a new thread allocating the memory from the heap.
|
||||||
*
|
*
|
||||||
* @param[in] wsize size of the working area to be allocated
|
* @param[in] wsize size of the working area to be allocated
|
||||||
* @param[in] prio the priority level for the new thread. Usually the threads
|
* @param[in] prio the priority level for the new thread
|
||||||
* are created with priority @p NORMALPRIO, priorities
|
|
||||||
* can range from @p LOWPRIO to @p HIGHPRIO.
|
|
||||||
* @param[in] pf the thread function
|
* @param[in] pf the thread function
|
||||||
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
|
* @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
|
* @return The pointer to the @p Thread structure allocated for the
|
||||||
|
@ -168,9 +162,7 @@ Thread *chThdCreateFromHeap(size_t wsize, tprio_t prio,
|
||||||
* Pool.
|
* Pool.
|
||||||
*
|
*
|
||||||
* @param[in] mp the memory pool
|
* @param[in] mp the memory pool
|
||||||
* @param[in] prio the priority level for the new thread. Usually the threads
|
* @param[in] prio the priority level for the new thread
|
||||||
* are created with priority @p NORMALPRIO, priorities
|
|
||||||
* can range from @p LOWPRIO to @p HIGHPRIO.
|
|
||||||
* @param[in] pf the thread function
|
* @param[in] pf the thread function
|
||||||
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
|
* @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
|
* @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
|
* @param[in] newprio the new priority level of the running thread
|
||||||
* @return The old priority level.
|
* @return The old priority level.
|
||||||
* @note The function returns the real thread priority regardless of the
|
* @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.
|
* the priority inheritance mechanism.
|
||||||
*/
|
*/
|
||||||
tprio_t chThdSetPriority(tprio_t newprio) {
|
tprio_t chThdSetPriority(tprio_t newprio) {
|
||||||
|
@ -268,13 +260,18 @@ void chThdTerminate(Thread *tp) {
|
||||||
/**
|
/**
|
||||||
* @brief Suspends the invoking thread for the specified time.
|
* @brief Suspends the invoking thread for the specified time.
|
||||||
*
|
*
|
||||||
* @param[in] time the delay in system ticks, the values @p TIME_IMMEDIATE and
|
* @param[in] time the delay in system ticks, the special values are handled as
|
||||||
* @p TIME_INFINITE are not allowed
|
* 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) {
|
void chThdSleep(systime_t time) {
|
||||||
|
|
||||||
chDbgCheck((time != TIME_IMMEDIATE) && (time != TIME_INFINITE),
|
chDbgCheck(time != TIME_INFINITE, "chThdSleep");
|
||||||
"chThdSleep");
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chThdSleepS(time);
|
chThdSleepS(time);
|
||||||
|
|
|
@ -190,35 +190,54 @@ extern "C" {
|
||||||
/** Returns the pointer to the @p Thread currently in execution.*/
|
/** Returns the pointer to the @p Thread currently in execution.*/
|
||||||
#define chThdSelf() currp
|
#define chThdSelf() currp
|
||||||
|
|
||||||
/** Returns the thread priority.*/
|
/** Returns the current thread priority.*/
|
||||||
#define chThdGetPriority() (currp->p_prio)
|
#define chThdGetPriority() (currp->p_prio)
|
||||||
|
|
||||||
/** Returns the pointer to the @p Thread local storage area, if any.*/
|
/** Returns the pointer to the @p Thread local storage area, if any.*/
|
||||||
#define chThdLS() (void *)(currp + 1)
|
#define chThdLS() (void *)(currp + 1)
|
||||||
|
|
||||||
/** Verifies if the specified thread is in the @p 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)
|
#define chThdTerminated(tp) ((tp)->p_state == PREXIT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies if the current thread has a termination request pending.
|
* 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)
|
#define chThdShouldTerminate() (currp->p_flags & P_TERMINATE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resumes a thread created with the @p P_SUSPENDED option or suspended with
|
* Resumes a thread created with @p chThdInit().
|
||||||
* @p chThdSuspend().
|
*
|
||||||
* @param tp the pointer to the thread
|
* @param[in] tp the pointer to the thread
|
||||||
*/
|
*/
|
||||||
#define chThdResumeI(tp) chSchReadyI(tp)
|
#define chThdResumeI(tp) chSchReadyI(tp)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspends the invoking thread for the specified time.
|
* 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)
|
#define chThdSleepS(time) chSchGoSleepTimeoutS(PRSLEEP, time)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delays the invoking thread for the specified number of seconds.
|
* 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
|
* @note The specified time is rounded up to a value allowed by the real
|
||||||
* system clock.
|
* system clock.
|
||||||
* @note The maximum specified value is implementation dependent.
|
* @note The maximum specified value is implementation dependent.
|
||||||
|
@ -227,6 +246,8 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delays the invoking thread for the specified number of milliseconds.
|
* 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
|
* @note The specified time is rounded up to a value allowed by the real
|
||||||
* system clock.
|
* system clock.
|
||||||
* @note The maximum specified value is implementation dependent.
|
* @note The maximum specified value is implementation dependent.
|
||||||
|
@ -235,6 +256,8 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delays the invoking thread for the specified number of microseconds.
|
* 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
|
* @note The specified time is rounded up to a value allowed by the real
|
||||||
* system clock.
|
* system clock.
|
||||||
* @note The maximum specified value is implementation dependent.
|
* @note The maximum specified value is implementation dependent.
|
||||||
|
|
Loading…
Reference in New Issue