From c142399273babe2cb6c47ad714494fde77a22893 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 3 May 2018 12:52:11 +0000 Subject: Added builder for full RM manual including RT, NIL, HAL and EX in a single document. Separated documents will be phased out later. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11991 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- doc/full_rm/src/concepts.dox | 411 +++++++++++++++++++++++++++++++++++++++++++ doc/full_rm/src/main.dox | 48 +++++ 2 files changed, 459 insertions(+) create mode 100644 doc/full_rm/src/concepts.dox create mode 100644 doc/full_rm/src/main.dox (limited to 'doc/full_rm/src') diff --git a/doc/full_rm/src/concepts.dox b/doc/full_rm/src/concepts.dox new file mode 100644 index 000000000..9475a417e --- /dev/null +++ b/doc/full_rm/src/concepts.dox @@ -0,0 +1,411 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 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 concepts Kernel Concepts + * @brief ChibiOS Kernel Concepts + * This article applies to both RT and NIL kernels, many concepts are also + * applicable to HAL (states and API classes). + * + * - @ref naming + * - @ref api_suffixes + * - @ref interrupt_classes + * - @ref system_states + * - @ref scheduling + * - @ref thread_states + * - @ref priority + * - @ref warea + * . + * @section naming Naming Conventions + * ChibiOS/RT and ChibiOS/NIL APIs are named following this convention: + * @a ch\\\(). + * Examples of groups are: @a Sys, @a Sch, @a Time, @a VT, @a Thd, @a Sem, etc. + * + * @section api_suffixes API Name Suffixes + * The suffix can be one of the following: + * - None, APIs without any suffix can be invoked only from the user + * code in the Normal state unless differently specified. See + * @ref system_states. + * - @anchor I-Class "I", I-Class APIs are invokable only from the + * I-Locked or S-Locked states. See @ref system_states. + * - @anchor S-Class "S", S-Class APIs are invokable only from the + * S-Locked state. See @ref system_states. + * - @anchor X-Class "X", X-Class APIs are invokable from any context. + * . + * Examples: @p chThdCreateStatic(), @p chSemSignalI(), @p chIQGetTimeout(). + * + * @section interrupt_classes Interrupt Classes + * In ChibiOS/RT there are three logical interrupt classes: + * - Regular Interrupts. Maskable interrupt sources that cannot + * preempt (small parts of) the kernel code and are thus able to invoke + * operating system APIs from within their handlers. The interrupt handlers + * belonging to this class must be written following some rules. See the + * system APIs group and the web article + * + * How to write interrupt handlers. + * - Fast Interrupts. Maskable interrupt sources with the ability + * to preempt the kernel code and thus have a lower latency and are less + * subject to jitter, see the web article + * + * Response Time and Jitter. + * Such sources are not supported on all the architectures.
+ * Fast interrupts are not allowed to invoke any operating system API from + * within their handlers. Fast interrupt sources may, however, pend a lower + * priority regular interrupt where access to the operating system is + * possible. + * - Non Maskable Interrupts. Non maskable interrupt sources are + * totally out of the operating system control and have the lowest latency. + * Such sources are not supported on all the architectures. + * . + * The mapping of the above logical classes into physical interrupts priorities + * is, of course, port dependent. See the documentation of the various ports + * for details. + * + * @section system_states System States + * When using ChibiOS/RT the system can be in one of the following logical + * operating states: + * - Init. 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. + * - Normal. All the interrupt sources are enabled and the system APIs + * are accessible, threads are running. + * - Suspended. In this state the fast interrupt sources are enabled but + * the regular interrupt sources are not. In this state it is not possible + * to use any system API except @p chSysDisable() or @p chSysEnable() in + * order to change state. + * - Disabled. When the system is in this state both the maskable + * regular and fast interrupt sources are disabled. In this state it is not + * possible to use any system API except @p chSysSuspend() or + * @p chSysEnable() in order to change state. + * - Sleep. Architecture-dependent low power mode, the idle thread + * goes in this state and waits for interrupts, after servicing the interrupt + * the Normal state is restored and the scheduler has a chance to reschedule. + * - S-Locked. Kernel locked and regular interrupt sources disabled. + * Fast interrupt sources are enabled. @ref S-Class and @ref I-Class APIs are + * invokable in this state. + * - I-Locked. Kernel locked and regular interrupt sources disabled. + * @ref I-Class APIs are invokable from this state. + * - Serving Regular Interrupt. No system APIs are accessible but it is + * possible to switch to the I-Locked state using @p chSysLockFromIsr() and + * then invoke any @ref I-Class API. Interrupt handlers can be preemptable on + * some architectures thus is important to switch to I-Locked state before + * invoking system APIs. + * - Serving Fast Interrupt. System APIs are not accessible. + * - Serving Non-Maskable Interrupt. System APIs are not accessible. + * - Halted. All interrupt sources are disabled and system stopped into + * an infinite loop. This state can be reached if the debug mode is activated + * and an error is detected or after explicitly invoking + * @p chSysHalt(). + * . + * Note that the above states are just Logical States that may have no + * real associated machine state on some architectures. The following diagram + * shows the possible transitions between the states: + * + * @if LATEX_PDF + * @dot + digraph example { + size="5, 7"; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"]; + edge [fontname=Helvetica, fontsize=8]; + init [label="Init", style="bold"]; + norm [label="Normal", shape=doublecircle]; + susp [label="Suspended"]; + disab [label="Disabled"]; + slock [label="S-Locked"]; + ilock [label="I-Locked"]; + slock [label="S-Locked"]; + sleep [label="Sleep"]; + sri [label="SRI"]; + 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()"]; + disab -> susp [label="chSysSuspend()"]; + slock -> ilock [label="Context Switch", dir="both"]; + norm -> sri [label="Regular IRQ", style="dotted"]; + sri -> norm [label="Regular IRQ return", fontname=Helvetica, fontsize=8]; + sri -> ilock [label="chSysLockFromIsr()", constraint=false]; + ilock -> sri [label="chSysUnlockFromIsr()", fontsize=8]; + norm -> sleep [label="Idle Thread"]; + sleep -> sri [label="Regular IRQ", style="dotted"]; + } + * @enddot + * @else + * @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]; + init [label="Init", style="bold"]; + norm [label="Normal", shape=doublecircle]; + susp [label="Suspended"]; + disab [label="Disabled"]; + slock [label="S-Locked"]; + ilock [label="I-Locked"]; + slock [label="S-Locked"]; + sleep [label="Sleep"]; + sri [label="SRI"]; + 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()"]; + disab -> susp [label="chSysSuspend()"]; + slock -> ilock [label="Context Switch", dir="both"]; + norm -> sri [label="Regular IRQ", style="dotted"]; + sri -> norm [label="Regular IRQ return", fontname=Helvetica, fontsize=8]; + sri -> ilock [label="chSysLockFromIsr()", constraint=false]; + ilock -> sri [label="chSysUnlockFromIsr()", fontsize=8]; + norm -> sleep [label="Idle Thread"]; + sleep -> sri [label="Regular IRQ", style="dotted"]; + } + * @enddot + * @endif + * Note, the SFI, Halted and SNMI states were not shown + * because those are reachable from most states: + * + * @dot + digraph example { + size="5, 7"; + 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 *"]; + sfi [label="SFI"]; + any1 -> sfi [style="dotted", label="Fast IRQ"]; + sfi -> any1 [label="Fast IRQ return"]; + } + * @enddot + * @dot + digraph example { + size="5, 7"; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"]; + edge [fontname=Helvetica, fontsize=8]; + any2 [label="Any State"]; + halt [label="Halted"]; + SNMI [label="SNMI"]; + 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 + * @attention * except: Init, Halt, SNMI, Disabled. + * + * @section scheduling Scheduling + * The strategy is very simple the currently ready thread with the highest + * priority is executed. If more than one thread with equal priority are + * eligible for execution then they are executed in a round-robin way, the + * CPU time slice constant is configurable. The ready list is a double linked + * list of threads ordered by priority.

+ * @if LATEX_PDF + * @dot + digraph example { + size="5, 7"; + rankdir="LR"; + + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + edge [fontname=Helvetica, fontsize=8]; + + subgraph cluster_running { + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + currp [label="'currp'\npointer", style="bold"]; + T4 [label="Tuser(4)\nprio=100"]; + label = "Currently Running Thread"; + penwidth = 0; + } + + subgraph cluster_rlist { + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + rh [label="ready list\nheader\nprio=0", style="bold"]; + Ti [label="Tidle\nprio=1"]; + Tm [label="Tmain\nprio=64"]; + T1 [label="Tuser(1)\nprio=32"]; + T2 [label="Tuser(2)\nprio=32"]; + T3 [label="Tuser(3)\nprio=80"]; + label = "Threads Ready for Execution"; + penwidth = 0; + } + + currp -> T4 + rh -> Ti -> T1 -> T2 -> Tm -> T3 -> rh [label="p_next"]; + rh -> T3 -> Tm -> T2 -> T1 -> Ti -> rh [label="p_prev"]; + } + * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + edge [fontname=Helvetica, fontsize=8]; + + subgraph cluster_running { + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + currp [label="'currp'\npointer", style="bold"]; + T4 [label="Tuser(4)\nprio=100"]; + label = "Currently Running Thread"; + penwidth = 0; + } + + subgraph cluster_rlist { + node [shape=square, fontname=Helvetica, fontsize=8, + fixedsize="true", width="0.6", height="0.5"]; + rh [label="ready list\nheader\nprio=0", style="bold"]; + Ti [label="Tidle\nprio=1"]; + Tm [label="Tmain\nprio=64"]; + T1 [label="Tuser(1)\nprio=32"]; + T2 [label="Tuser(2)\nprio=32"]; + T3 [label="Tuser(3)\nprio=80"]; + label = "Threads Ready for Execution"; + penwidth = 0; + } + + currp -> T4 + rh -> Ti -> T1 -> T2 -> Tm -> T3 -> rh [label="p_next"]; + rh -> T3 -> Tm -> T2 -> T1 -> Ti -> rh [label="p_prev"]; + } + * @enddot + * @endif + *
+ * Note that the currently running thread is not in the ready list, the list + * only contains the threads ready to be executed but still actually waiting. + * + * @section thread_states Thread States + * The image shows how threads can change their state in ChibiOS/RT.
+ * @if LATEX_PDF + * @dot + digraph example { + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"]; + size="5, 7"; + + 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="\n chThdCreateI()", constraint=false, dir=back]; + start -> run [label="chThdCreate()"]; + start -> ready [label="chThdCreate()"]; + run -> ready [label="Reschedule", dir="both"]; + suspend -> run [label="chThdResume()"]; + suspend -> ready [label="chThdResume()"]; + run -> sleep [label="chSchGoSleepS()"]; + sleep -> run [label="chSchWakepuS()"]; + sleep -> ready [label="chSchWakepuS()"]; + run -> stop [label="chThdExit()"]; + } + * @enddot + * @else + * @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]; + 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="\n chThdCreateI()", constraint=false, dir=back]; + start -> run [label="chThdCreate()"]; + start -> ready [label="chThdCreate()"]; + run -> ready [label="Reschedule", dir="both"]; + suspend -> run [label="chThdResume()"]; + suspend -> ready [label="chThdResume()"]; + run -> sleep [label="chSchGoSleepS()"]; + sleep -> run [label="chSchWakepuS()"]; + sleep -> ready [label="chSchWakepuS()"]; + run -> stop [label="chThdExit()"]; + } + * @enddot + * @endif + * + * @section priority Priority Levels + * Priorities in ChibiOS/RT are a contiguous numerical range but the initial + * and final values are not enforced.
+ * The following table describes the various priority boundaries (from lowest + * to highest): + * - @p IDLEPRIO, this is the lowest priority level and is reserved for the + * idle thread, no other threads should share this priority level. This is + * the lowest numerical value of the priorities space. + * - @p LOWPRIO, the lowest priority level that can be assigned to an user + * thread. + * - @p NORMALPRIO, this is the central priority level for user threads. It is + * advisable to assign priorities to threads as values relative to + * @p NORMALPRIO, as example NORMALPRIO-1 or NORMALPRIO+4, this ensures the + * portability of code should the numerical range change in future + * implementations. + * - @p HIGHPRIO, the highest priority level that can be assigned to an user + * thread. + * - @p ABSPRO, absolute maximum software priority level, it can be higher than + * @p HIGHPRIO but the numerical values above @p HIGHPRIO up to @p ABSPRIO + * (inclusive) are reserved. This is the highest numerical value of the + * priorities space. + * . + * @section warea Thread Working Area + * Each thread has its own stack, a Thread structure and some preemption + * areas. All the structures are allocated into a "Thread Working Area", + * a thread private heap, usually statically declared in your code. + * Threads do not use any memory outside the allocated working area + * except when accessing static shared data.

+ * @if LATEX_PDF + * @image latex workspace.eps + * @else + * @image html workspace.png + * @endif + *
+ * Note that the preemption area is only present when the thread is not + * running (switched out), the context switching is done by pushing the + * registers on the stack of the switched-out thread and popping the registers + * of the switched-in thread from its stack. + * The preemption area can be divided in up to three structures: + * - External Context. + * - Interrupt Stack. + * - Internal Context. + * . + * See the port documentation for details, the area may change on + * the various ports and some structures may not be present (or be zero-sized). + */ diff --git a/doc/full_rm/src/main.dox b/doc/full_rm/src/main.dox new file mode 100644 index 000000000..7da6fadad --- /dev/null +++ b/doc/full_rm/src/main.dox @@ -0,0 +1,48 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 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 . +*/ + +/** + * @mainpage Introduction + * @author Giovanni Di Sirio (gdisirio@users.sourceforge.net). + * + *

Chibi ?

+ * I didn't want a serious name for this project. It is the Japanese word for + * small as in small child. So ChibiOS + * @htmlonly (ちびOS) @endhtmlonly + * means small Operating System. + * Source Wikipedia. + * + *

Features

+ * ChibiOS is composed by several subsystems that are part of the project or + * external software components. + * + *

Subsystems

+ * - RT, a full features RTOS. + * - NIL, another RTOS with a very reduced footprint. + * - OSLIB, a library of RTOS enhancements, it can be used on top of both RT + * NIL. + * - HAL, an abstraction layer for common MCU peripherals. + * - EX, abstraction for board-level devices, it sits on top of HAL. + * . + *

External Components

+ * - FatFS. + * - lwIP. + * - WolfSSL. + * . + */ -- cgit v1.2.3