From 819c02b8391e3cadcbe814c84c5c5f366ae41e03 Mon Sep 17 00:00:00 2001
From: gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>
Date: Fri, 23 Jan 2009 16:18:13 +0000
Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@669
 35acf78f-673a-0410-8e92-d51de3d6d3f4

---
 docs/ch.txt           | 85 ++++++++++++++++++++++++++++++---------------------
 docs/src/jitter.dox   | 81 ++++++++++++++++++++++++++++++++++++------------
 ports/ARM7/port.dox   |  4 +--
 ports/ARMCM3/port.dox |  4 +--
 ports/AVR/port.dox    |  4 +--
 ports/MSP430/port.dox |  4 +--
 6 files changed, 120 insertions(+), 62 deletions(-)

diff --git a/docs/ch.txt b/docs/ch.txt
index 416811dc8..aff84eff1 100644
--- a/docs/ch.txt
+++ b/docs/ch.txt
@@ -104,7 +104,7 @@
  * @section system_states System States
  * When using ChibiOS/RT the system can be in one of the following logical
  * 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
  *   any system API except @p chSysInit(). This state is entered after a
  *   physical reset.
@@ -146,7 +146,8 @@
   digraph example {
       rankdir="LR";
       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];
       susp [label="Suspended"];
       disab [label="Disabled"];
@@ -155,31 +156,46 @@
       slock [label="S-Locked"];
       sleep [label="Sleep"];
       sri [label="SRI"];
-      sfi [label="SFI"];
-      init -> norm [label="chSysInit()", fontname=Helvetica, fontsize=8];
-      norm -> slock [label="chSysLock()", fontname=Helvetica, fontsize=8, constraint=false];
-      slock -> norm [label="chSysUnlock()", fontname=Helvetica, fontsize=8];
-      norm -> susp [label="chSysSuspend()", fontname=Helvetica, fontsize=8];
-      susp -> disab [label="chSysDisable()", fontname=Helvetica, fontsize=8];
-      norm -> disab [label="chSysDisable()", fontname=Helvetica, fontsize=8];
-      susp -> norm [label="chSysEnable()", fontname=Helvetica, fontsize=8];
-      disab -> norm [label="chSysEnable()", fontname=Helvetica, fontsize=8];
-      slock -> ilock [dir="both", label="Context Switch", fontname=Helvetica, fontsize=8];
-      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];
+      init -> norm [label="chSysInit()"];
+      norm -> slock [label="chSysLock()", constraint=false];
+      slock -> norm [label="chSysUnlock()"];
+      norm -> susp [label="chSysSuspend()"];
+      susp -> disab [label="chSysDisable()"];
+      norm -> disab [label="chSysDisable()"];
+      susp -> norm [label="chSysEnable()"];
+      disab -> norm [label="chSysEnable()"];
+      slock -> ilock [label="Context Switch", dir="both"];
+      norm -> sri [label="Regular IRQ", style="dotted"];
       sri -> norm [label="Regular IRQ return", fontname=Helvetica, fontsize=8];
-      sfi -> norm [label="Fast IRQ return", fontname=Helvetica, fontsize=8];
-      sfi -> susp [label="Fast IRQ return", fontname=Helvetica, fontsize=8];
-      sri -> ilock [label="chSysLockI()", fontname=Helvetica, fontsize=8, constraint=false];
-      ilock -> sri [label="chSysUnlockI()", fontname=Helvetica, fontsize=8];
-      norm -> sleep [label="Idle Thread", fontname=Helvetica, fontsize=8];
-      sleep -> sri [style="dotted", label="Regular IRQ", fontname=Helvetica, fontsize=8];
-      sleep -> sfi [style="dotted", label="Fast IRQ", fontname=Helvetica, fontsize=8];
+      sri -> ilock [label="chSysLockI()", constraint=false];
+      ilock -> sri [label="chSysUnlockI()", fontsize=8];
+      norm -> sleep [label="Idle Thread"];
+      sleep -> sri [label="Regular IRQ", style="dotted"];
+  }
+ * @enddot
+ * 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
- * Note, the Halted and SNMI states can be reached from any state and are not
- * shown for simplicity.
  *
  * @section scheduling Scheduling
  * The strategy is very simple the currently ready thread with the highest
@@ -197,22 +213,23 @@
   digraph example {
       /*rankdir="LR";*/
       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"];
       run [label="Running"];
       ready [label="Ready"];
       suspend [label="Suspended"];
       sleep [label="Sleeping"];
       stop [label="Stop", style="bold"];
-      start -> suspend [label="chThdInit()", fontname=Helvetica, fontsize=8, constraint=false];
-      start -> run [label="chThdCreate()", fontname=Helvetica, fontsize=8];
-      start -> ready [label="chThdCreate()", fontname=Helvetica, fontsize=8];
-      run -> ready [dir="both", label="Reschedulation", fontname=Helvetica, fontsize=8];
-      suspend -> run [label="chThdResume()", fontname=Helvetica, fontsize=8];
-      suspend -> ready [label="chThdResume()", fontname=Helvetica, fontsize=8];
-      run -> sleep [label="chSchGoSleepS()", fontname=Helvetica, fontsize=8];
-      sleep -> run [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
-      sleep -> ready [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
-      run -> stop [label="chThdExit()", fontname=Helvetica, fontsize=8];
+      start -> suspend [label="chThdInit()", constraint=false];
+      start -> run [label="chThdCreate()"];
+      start -> ready [label="chThdCreate()"];
+      run -> ready [label="Reschedulation", dir="both"];
+      suspend -> run [label="chThdResume()"];
+      suspend -> ready [label="chThdResume()"];
+      run -> sleep [label="chSchGoSleepS()"];
+      sleep -> run [label="chSchWakepS()"];
+      sleep -> ready [label="chSchWakepS()"];
+      run -> stop [label="chThdExit()"];
   }
  * @enddot
  *
diff --git a/docs/src/jitter.dox b/docs/src/jitter.dox
index 4bbedd7b7..1b4220dd4 100644
--- a/docs/src/jitter.dox
+++ b/docs/src/jitter.dox
@@ -8,15 +8,61 @@
  * A good place to start is this
  * <a href="http://en.wikipedia.org/wiki/Jitter">Wikipedia article</a>.
  *
- * <h2>Jitter Sources</h2>
- * Under ChibiOS/RT (or any other similar RTOS) there are several possible
- * jitter sources:
- * -# Hardware interrupts latency.
- * -# Interrupts service time and priority.
- * -# Kernel lock zones.
- * -# Higher priority threads activity.
+ * <h2>Interrupt Response Time</h2>
+ * This is the time from an interrupt event and the execution of the handler
+ * code.
  *
- * <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
  * mitigation actions.
  *
@@ -26,7 +72,7 @@
  * architecture more efficient at interrupt handling, as example, the
  * 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:
  * - Fixed handler overhead, as example registers stacking/unstacking.
  * - 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
  * to handle the bulk of the work.<br>
  * 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>
- * 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>
  * The OS kernel protects some critical internal data structure by disabling
@@ -67,12 +105,15 @@
  *
  * <h3>Higher priority threads activity</h3>
  * 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
- * higher priority threads and contention on protected resources.<br>
+ * jitter, as seen in the previous subsections, but also by the activity of
+ * the higher priority threads and contention on protected resources.<br>
  * It is possible to improve the system overall response time and reduce jitter
  * by carefully assigning priorities to the various threads and carefully
  * designing mutual exclusion zones.<br>
  * The use of the proper synchronization mechanism (semaphores, mutexes, events,
  * 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.
  */
 /** @} */
diff --git a/ports/ARM7/port.dox b/ports/ARM7/port.dox
index fce2f9cd7..4efe06089 100644
--- a/ports/ARM7/port.dox
+++ b/ports/ARM7/port.dox
@@ -20,8 +20,8 @@
  * @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
  * port:
- * - <b>Initialization</b>. This state is represented by the startup code and
- *   the initialization code before @p chSysInit() is executed. It has not a
+ * - <b>Init</b>. This state is represented by the startup code and the
+ *   initialization code before @p chSysInit() is executed. It has not a
  *   special hardware state associated, usually the CPU goes through several
  *   hardware states during the startup phase.
  * - <b>Normal</b>. This is the state the system has after executing
diff --git a/ports/ARMCM3/port.dox b/ports/ARMCM3/port.dox
index 32f52337d..c1776669d 100644
--- a/ports/ARMCM3/port.dox
+++ b/ports/ARMCM3/port.dox
@@ -7,8 +7,8 @@
  * @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
  * Cortex-M3 port:
- * - <b>Initialization</b>. This state is represented by the startup code and
- *   the initialization code before @p chSysInit() is executed. It has not a
+ * - <b>Init</b>. This state is represented by the startup code and the
+ *   initialization code before @p chSysInit() is executed. It has not a
  *   special hardware state associated.
  * - <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
diff --git a/ports/AVR/port.dox b/ports/AVR/port.dox
index 8f455f208..817da5a64 100644
--- a/ports/AVR/port.dox
+++ b/ports/AVR/port.dox
@@ -7,8 +7,8 @@
  * @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
  * port:
- * - <b>Initialization</b>. This state is represented by the startup code and
- *   the initialization code before @p chSysInit() is executed. It has not a
+ * - <b>Init</b>. This state is represented by the startup code and the
+ *   initialization code before @p chSysInit() is executed. It has not a
  *   special hardware state associated.
  * - <b>Normal</b>. This is the state the system has after executing
  *   @p chSysInit(). Interrupts are enabled.
diff --git a/ports/MSP430/port.dox b/ports/MSP430/port.dox
index 108a44bd8..774098e3d 100644
--- a/ports/MSP430/port.dox
+++ b/ports/MSP430/port.dox
@@ -7,8 +7,8 @@
  * @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
  * port:
- * - <b>Initialization</b>. This state is represented by the startup code and
- *   the initialization code before @p chSysInit() is executed. It has not a
+ * - <b>Init</b>. This state is represented by the startup code and the
+ *   initialization code before @p chSysInit() is executed. It has not a
  *   special hardware state associated.
  * - <b>Normal</b>. This is the state the system has after executing
  *   @p chSysInit(). Interrupts are enabled.
-- 
cgit v1.2.3