111 lines
4.7 KiB
Plaintext
111 lines
4.7 KiB
Plaintext
/*
|
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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.
|
|
*/
|