git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@669 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
8d51d682db
commit
819c02b839
85
docs/ch.txt
85
docs/ch.txt
|
@ -104,7 +104,7 @@
|
||||||
* @section system_states System States
|
* @section system_states System States
|
||||||
* When using ChibiOS/RT the system can be in one of the following logical
|
* When using ChibiOS/RT the system can be in one of the following logical
|
||||||
* operating states:
|
* operating states:
|
||||||
* - <b>Initialization</b>. When the system is in this state all the maskable
|
* - <b>Init</b>. When the system is in this state all the maskable
|
||||||
* interrupt sources are disabled. In this state it is not possible to use
|
* interrupt sources are disabled. In this state it is not possible to use
|
||||||
* any system API except @p chSysInit(). This state is entered after a
|
* any system API except @p chSysInit(). This state is entered after a
|
||||||
* physical reset.
|
* physical reset.
|
||||||
|
@ -146,7 +146,8 @@
|
||||||
digraph example {
|
digraph example {
|
||||||
rankdir="LR";
|
rankdir="LR";
|
||||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||||
init [label="Initialization", style="bold"];
|
edge [fontname=Helvetica, fontsize=8];
|
||||||
|
init [label="Init", style="bold"];
|
||||||
norm [label="Normal", shape=doublecircle];
|
norm [label="Normal", shape=doublecircle];
|
||||||
susp [label="Suspended"];
|
susp [label="Suspended"];
|
||||||
disab [label="Disabled"];
|
disab [label="Disabled"];
|
||||||
|
@ -155,31 +156,46 @@
|
||||||
slock [label="S-Locked"];
|
slock [label="S-Locked"];
|
||||||
sleep [label="Sleep"];
|
sleep [label="Sleep"];
|
||||||
sri [label="SRI"];
|
sri [label="SRI"];
|
||||||
sfi [label="SFI"];
|
init -> norm [label="chSysInit()"];
|
||||||
init -> norm [label="chSysInit()", fontname=Helvetica, fontsize=8];
|
norm -> slock [label="chSysLock()", constraint=false];
|
||||||
norm -> slock [label="chSysLock()", fontname=Helvetica, fontsize=8, constraint=false];
|
slock -> norm [label="chSysUnlock()"];
|
||||||
slock -> norm [label="chSysUnlock()", fontname=Helvetica, fontsize=8];
|
norm -> susp [label="chSysSuspend()"];
|
||||||
norm -> susp [label="chSysSuspend()", fontname=Helvetica, fontsize=8];
|
susp -> disab [label="chSysDisable()"];
|
||||||
susp -> disab [label="chSysDisable()", fontname=Helvetica, fontsize=8];
|
norm -> disab [label="chSysDisable()"];
|
||||||
norm -> disab [label="chSysDisable()", fontname=Helvetica, fontsize=8];
|
susp -> norm [label="chSysEnable()"];
|
||||||
susp -> norm [label="chSysEnable()", fontname=Helvetica, fontsize=8];
|
disab -> norm [label="chSysEnable()"];
|
||||||
disab -> norm [label="chSysEnable()", fontname=Helvetica, fontsize=8];
|
slock -> ilock [label="Context Switch", dir="both"];
|
||||||
slock -> ilock [dir="both", label="Context Switch", fontname=Helvetica, fontsize=8];
|
norm -> sri [label="Regular IRQ", style="dotted"];
|
||||||
norm -> sri [style="dotted", label="Regular IRQ", fontname=Helvetica, fontsize=8];
|
|
||||||
norm -> sfi [style="dotted", label="Fast IRQ", fontname=Helvetica, fontsize=8];
|
|
||||||
susp -> sfi [style="dotted", label="Fast IRQ", fontname=Helvetica, fontsize=8];
|
|
||||||
sri -> norm [label="Regular IRQ return", fontname=Helvetica, fontsize=8];
|
sri -> norm [label="Regular IRQ return", fontname=Helvetica, fontsize=8];
|
||||||
sfi -> norm [label="Fast IRQ return", fontname=Helvetica, fontsize=8];
|
sri -> ilock [label="chSysLockI()", constraint=false];
|
||||||
sfi -> susp [label="Fast IRQ return", fontname=Helvetica, fontsize=8];
|
ilock -> sri [label="chSysUnlockI()", fontsize=8];
|
||||||
sri -> ilock [label="chSysLockI()", fontname=Helvetica, fontsize=8, constraint=false];
|
norm -> sleep [label="Idle Thread"];
|
||||||
ilock -> sri [label="chSysUnlockI()", fontname=Helvetica, fontsize=8];
|
sleep -> sri [label="Regular IRQ", style="dotted"];
|
||||||
norm -> sleep [label="Idle Thread", fontname=Helvetica, fontsize=8];
|
}
|
||||||
sleep -> sri [style="dotted", label="Regular IRQ", fontname=Helvetica, fontsize=8];
|
* @enddot
|
||||||
sleep -> sfi [style="dotted", label="Fast IRQ", fontname=Helvetica, fontsize=8];
|
* Note, the <b>SFI</b>, <b>Halted</b> and <b>SNMI</b> states were not shown
|
||||||
|
* because those are reachable from most states:
|
||||||
|
*
|
||||||
|
* @dot
|
||||||
|
digraph example {
|
||||||
|
rankdir="LR";
|
||||||
|
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||||
|
edge [fontname=Helvetica, fontsize=8];
|
||||||
|
any1 [label="Any State\nexcept\nDisabled\nand Init"];
|
||||||
|
any2 [label="Any State"];
|
||||||
|
sfi [label="SFI"];
|
||||||
|
halt [label="Halted"];
|
||||||
|
SNMI [label="SNMI"];
|
||||||
|
any1 -> sfi [style="dotted", label="Fast IRQ"];
|
||||||
|
sfi -> any1 [label="Fast IRQ return"];
|
||||||
|
any2 -> halt [label="chSysHalt()"];
|
||||||
|
any2 -> SNMI [label="Synchronous NMI"];
|
||||||
|
any2 -> SNMI [label="Asynchronous NMI", style="dotted"];
|
||||||
|
SNMI -> any2 [label="NMI return"];
|
||||||
|
halt -> SNMI [label="Asynchronous NMI", style="dotted"];
|
||||||
|
SNMI -> halt [label="NMI return"];
|
||||||
}
|
}
|
||||||
* @enddot
|
* @enddot
|
||||||
* Note, the Halted and SNMI states can be reached from any state and are not
|
|
||||||
* shown for simplicity.
|
|
||||||
*
|
*
|
||||||
* @section scheduling Scheduling
|
* @section scheduling Scheduling
|
||||||
* The strategy is very simple the currently ready thread with the highest
|
* The strategy is very simple the currently ready thread with the highest
|
||||||
|
@ -197,22 +213,23 @@
|
||||||
digraph example {
|
digraph example {
|
||||||
/*rankdir="LR";*/
|
/*rankdir="LR";*/
|
||||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||||
|
edge [fontname=Helvetica, fontsize=8];
|
||||||
start [label="Start", style="bold"];
|
start [label="Start", style="bold"];
|
||||||
run [label="Running"];
|
run [label="Running"];
|
||||||
ready [label="Ready"];
|
ready [label="Ready"];
|
||||||
suspend [label="Suspended"];
|
suspend [label="Suspended"];
|
||||||
sleep [label="Sleeping"];
|
sleep [label="Sleeping"];
|
||||||
stop [label="Stop", style="bold"];
|
stop [label="Stop", style="bold"];
|
||||||
start -> suspend [label="chThdInit()", fontname=Helvetica, fontsize=8, constraint=false];
|
start -> suspend [label="chThdInit()", constraint=false];
|
||||||
start -> run [label="chThdCreate()", fontname=Helvetica, fontsize=8];
|
start -> run [label="chThdCreate()"];
|
||||||
start -> ready [label="chThdCreate()", fontname=Helvetica, fontsize=8];
|
start -> ready [label="chThdCreate()"];
|
||||||
run -> ready [dir="both", label="Reschedulation", fontname=Helvetica, fontsize=8];
|
run -> ready [label="Reschedulation", dir="both"];
|
||||||
suspend -> run [label="chThdResume()", fontname=Helvetica, fontsize=8];
|
suspend -> run [label="chThdResume()"];
|
||||||
suspend -> ready [label="chThdResume()", fontname=Helvetica, fontsize=8];
|
suspend -> ready [label="chThdResume()"];
|
||||||
run -> sleep [label="chSchGoSleepS()", fontname=Helvetica, fontsize=8];
|
run -> sleep [label="chSchGoSleepS()"];
|
||||||
sleep -> run [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
|
sleep -> run [label="chSchWakepS()"];
|
||||||
sleep -> ready [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
|
sleep -> ready [label="chSchWakepS()"];
|
||||||
run -> stop [label="chThdExit()", fontname=Helvetica, fontsize=8];
|
run -> stop [label="chThdExit()"];
|
||||||
}
|
}
|
||||||
* @enddot
|
* @enddot
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,15 +8,61 @@
|
||||||
* A good place to start is this
|
* A good place to start is this
|
||||||
* <a href="http://en.wikipedia.org/wiki/Jitter">Wikipedia article</a>.
|
* <a href="http://en.wikipedia.org/wiki/Jitter">Wikipedia article</a>.
|
||||||
*
|
*
|
||||||
* <h2>Jitter Sources</h2>
|
* <h2>Interrupt Response Time</h2>
|
||||||
* Under ChibiOS/RT (or any other similar RTOS) there are several possible
|
* This is the time from an interrupt event and the execution of the handler
|
||||||
* jitter sources:
|
* code.
|
||||||
* -# Hardware interrupts latency.
|
|
||||||
* -# Interrupts service time and priority.
|
|
||||||
* -# Kernel lock zones.
|
|
||||||
* -# Higher priority threads activity.
|
|
||||||
*
|
*
|
||||||
* <h2>Jitter mitigation countermeasures</h2>
|
* @dot
|
||||||
|
digraph example {
|
||||||
|
rankdir="LR";
|
||||||
|
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||||
|
edge [fontname=Helvetica, fontsize=8];
|
||||||
|
int [label="Interrupt"];
|
||||||
|
busy [label="Busy"];
|
||||||
|
served [label="Interrupt\nServed"];
|
||||||
|
int -> served [label="Not Busy"];
|
||||||
|
int -> busy [label="Not Ready"];
|
||||||
|
busy -> busy [label="Still Busy\n(jitter)"];
|
||||||
|
busy -> served [label="Finally Ready"];
|
||||||
|
* @enddot
|
||||||
|
*
|
||||||
|
* <h3>Jitter Sources</h3>
|
||||||
|
* In this scenario the jitter (busy state) is represented by the sum of:
|
||||||
|
* - Higher or equal priority interrupt sources execution time combined.
|
||||||
|
* This time can go from zero to the maximum randomly. This value can be
|
||||||
|
* guaranteed to be zero only if the interrupt has the highest priority in
|
||||||
|
* the system.
|
||||||
|
* - Highest execution time among lower priority sources. This value is zero
|
||||||
|
* on those architectures (Cortex-M3 as example) where interrupt handlers
|
||||||
|
* can be preempted by higher priority sources.
|
||||||
|
* - Longest time in a kernel lock zone that can delay interrupt servicing.
|
||||||
|
* This value is zero for fast interrupt sources, see @ref system_states.
|
||||||
|
*
|
||||||
|
* <h2>Threads Flyback Time</h2>
|
||||||
|
* This is the time from an event, as example an interrupt, and the execution
|
||||||
|
* of a thread supposed to handle the event. Imagine the following graph as the
|
||||||
|
* continuation of the previous one.
|
||||||
|
*
|
||||||
|
* @dot
|
||||||
|
digraph example {
|
||||||
|
rankdir="LR";
|
||||||
|
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||||
|
edge [fontname=Helvetica, fontsize=8];
|
||||||
|
served [label="Interrupt\nServed"];
|
||||||
|
busy [label="Busy"];
|
||||||
|
thread [label="Thread\nAwakened"];
|
||||||
|
served -> busy [label="Not Highest Priority"];
|
||||||
|
busy -> busy [label="Other Threads\n(jitter)"];
|
||||||
|
busy -> thread [label="Highest Priority"];
|
||||||
|
served -> thread [label="Highest Priority"];
|
||||||
|
* @enddot
|
||||||
|
*
|
||||||
|
* <h3>Jitter Sources</h3>
|
||||||
|
* In this scenario all the jitter sources previously discussed are also
|
||||||
|
* present and there is the added jitter caused by the activity of the
|
||||||
|
* higher priority threads.
|
||||||
|
*
|
||||||
|
* <h2>Jitter Mitigation</h2>
|
||||||
* For each of the previously described jitter sources there are possible
|
* For each of the previously described jitter sources there are possible
|
||||||
* mitigation actions.
|
* mitigation actions.
|
||||||
*
|
*
|
||||||
|
@ -26,7 +72,7 @@
|
||||||
* architecture more efficient at interrupt handling, as example, the
|
* architecture more efficient at interrupt handling, as example, the
|
||||||
* ARM Cortex-M3 core present in the STM32 family is very efficient at that.
|
* ARM Cortex-M3 core present in the STM32 family is very efficient at that.
|
||||||
*
|
*
|
||||||
* <h3>Interrupts service time and priority</h3>
|
* <h3>Interrupts service time</h3>
|
||||||
* This is the execution time of interrupt handlers, this time includes:
|
* This is the execution time of interrupt handlers, this time includes:
|
||||||
* - Fixed handler overhead, as example registers stacking/unstacking.
|
* - Fixed handler overhead, as example registers stacking/unstacking.
|
||||||
* - Interrupt specific service time, as example, in a serial driver, this is
|
* - Interrupt specific service time, as example, in a serial driver, this is
|
||||||
|
@ -41,16 +87,8 @@
|
||||||
* An handler should serve the interrupt and wakeup a dedicated thread in order
|
* An handler should serve the interrupt and wakeup a dedicated thread in order
|
||||||
* to handle the bulk of the work.<br>
|
* to handle the bulk of the work.<br>
|
||||||
* Another possible mitigation action is to evaluate if a specific interrupt
|
* Another possible mitigation action is to evaluate if a specific interrupt
|
||||||
* handler really need to "speak" with the OS, if the handler uses full
|
* handler really needs to "speak" with the OS, if the handler uses full
|
||||||
* stand-alone code then it is possible to remove the OS related overhead.<br>
|
* stand-alone code then it is possible to remove the OS related overhead.<br>
|
||||||
* On some architecture it is also possible to give to interrupt sources a
|
|
||||||
* greater hardware priority than the kernel and not be affected by the
|
|
||||||
* jitter introduced by OS itself (see next subsection).<br>
|
|
||||||
* As example, in the ARM port, FIQ sources are not affected by the
|
|
||||||
* kernel-generated jitter. The Cortex-M3 port is even better thanks to its
|
|
||||||
* hardware-assisted interrupt architecture allowing handlers preemption,
|
|
||||||
* late arriving, tail chaining etc. See the notes about the various
|
|
||||||
* @ref Ports.
|
|
||||||
*
|
*
|
||||||
* <h3>Kernel lock zones</h3>
|
* <h3>Kernel lock zones</h3>
|
||||||
* The OS kernel protects some critical internal data structure by disabling
|
* The OS kernel protects some critical internal data structure by disabling
|
||||||
|
@ -67,12 +105,15 @@
|
||||||
*
|
*
|
||||||
* <h3>Higher priority threads activity</h3>
|
* <h3>Higher priority threads activity</h3>
|
||||||
* At thread level the response time is affected by the interrupt-related
|
* At thread level the response time is affected by the interrupt-related
|
||||||
* jitter as seen in the previous subsections but also by the activity of the
|
* jitter, as seen in the previous subsections, but also by the activity of
|
||||||
* higher priority threads and contention on protected resources.<br>
|
* the higher priority threads and contention on protected resources.<br>
|
||||||
* It is possible to improve the system overall response time and reduce jitter
|
* It is possible to improve the system overall response time and reduce jitter
|
||||||
* by carefully assigning priorities to the various threads and carefully
|
* by carefully assigning priorities to the various threads and carefully
|
||||||
* designing mutual exclusion zones.<br>
|
* designing mutual exclusion zones.<br>
|
||||||
* The use of the proper synchronization mechanism (semaphores, mutexes, events,
|
* The use of the proper synchronization mechanism (semaphores, mutexes, events,
|
||||||
* messages and so on) also helps to improve the overall system performance.
|
* messages and so on) also helps to improve the overall system performance.
|
||||||
|
* The use of the Priority Inheritance algorithm implemented in the mutexes
|
||||||
|
* subsystem can improve the overall response time and reduce jitter but it is
|
||||||
|
* not a magic wand, a proper system design comes first.
|
||||||
*/
|
*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
* @section ARM7_STATES Mapping of the System States in the ARM7 port
|
* @section ARM7_STATES Mapping of the System States in the ARM7 port
|
||||||
* The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM7
|
* The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM7
|
||||||
* port:
|
* port:
|
||||||
* - <b>Initialization</b>. This state is represented by the startup code and
|
* - <b>Init</b>. This state is represented by the startup code and the
|
||||||
* the initialization code before @p chSysInit() is executed. It has not a
|
* initialization code before @p chSysInit() is executed. It has not a
|
||||||
* special hardware state associated, usually the CPU goes through several
|
* special hardware state associated, usually the CPU goes through several
|
||||||
* hardware states during the startup phase.
|
* hardware states during the startup phase.
|
||||||
* - <b>Normal</b>. This is the state the system has after executing
|
* - <b>Normal</b>. This is the state the system has after executing
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
* @section ARMCM3_STATES Mapping of the System States in the ARM Cortex-M3 port
|
* @section ARMCM3_STATES Mapping of the System States in the ARM Cortex-M3 port
|
||||||
* The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
|
* The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
|
||||||
* Cortex-M3 port:
|
* Cortex-M3 port:
|
||||||
* - <b>Initialization</b>. This state is represented by the startup code and
|
* - <b>Init</b>. This state is represented by the startup code and the
|
||||||
* the initialization code before @p chSysInit() is executed. It has not a
|
* initialization code before @p chSysInit() is executed. It has not a
|
||||||
* special hardware state associated.
|
* special hardware state associated.
|
||||||
* - <b>Normal</b>. This is the state the system has after executing
|
* - <b>Normal</b>. This is the state the system has after executing
|
||||||
* @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
|
* @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
* @section AVR_STATES Mapping of the System States in the AVR port
|
* @section AVR_STATES Mapping of the System States in the AVR port
|
||||||
* The ChibiOS/RT logical @ref system_states are mapped as follow in the AVR
|
* The ChibiOS/RT logical @ref system_states are mapped as follow in the AVR
|
||||||
* port:
|
* port:
|
||||||
* - <b>Initialization</b>. This state is represented by the startup code and
|
* - <b>Init</b>. This state is represented by the startup code and the
|
||||||
* the initialization code before @p chSysInit() is executed. It has not a
|
* initialization code before @p chSysInit() is executed. It has not a
|
||||||
* special hardware state associated.
|
* special hardware state associated.
|
||||||
* - <b>Normal</b>. This is the state the system has after executing
|
* - <b>Normal</b>. This is the state the system has after executing
|
||||||
* @p chSysInit(). Interrupts are enabled.
|
* @p chSysInit(). Interrupts are enabled.
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
* @section MSP430_STATES Mapping of the System States in the MSP430 port
|
* @section MSP430_STATES Mapping of the System States in the MSP430 port
|
||||||
* The ChibiOS/RT logical @ref system_states are mapped as follow in the MSP430
|
* The ChibiOS/RT logical @ref system_states are mapped as follow in the MSP430
|
||||||
* port:
|
* port:
|
||||||
* - <b>Initialization</b>. This state is represented by the startup code and
|
* - <b>Init</b>. This state is represented by the startup code and the
|
||||||
* the initialization code before @p chSysInit() is executed. It has not a
|
* initialization code before @p chSysInit() is executed. It has not a
|
||||||
* special hardware state associated.
|
* special hardware state associated.
|
||||||
* - <b>Normal</b>. This is the state the system has after executing
|
* - <b>Normal</b>. This is the state the system has after executing
|
||||||
* @p chSysInit(). Interrupts are enabled.
|
* @p chSysInit(). Interrupts are enabled.
|
||||||
|
|
Loading…
Reference in New Issue