From c1ef5c1ac7c65f7d9ffbafea09c0516e7ec632f3 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 29 Jan 2009 18:43:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@681 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/src/concepts.dox | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 docs/src/concepts.dox (limited to 'docs/src/concepts.dox') diff --git a/docs/src/concepts.dox b/docs/src/concepts.dox new file mode 100644 index 000000000..cfa5bfbc3 --- /dev/null +++ b/docs/src/concepts.dox @@ -0,0 +1,240 @@ +/* + 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 . +*/ + +/** + * @page Concepts Concepts + * @{ + * @brief ChibiOS/RT Concepts and Architecture + * @section naming Naming Conventions + * ChibiOS/RT APIs are all named following this convention: + * @a ch\\\(). + * The possible groups are: @a Sys, @a Sch, @a VT, @a Thd, @a Sem, @a Mtx, + * @a Cond, @a Evt, @a Msg, @a IQ, @a OQ, @a HQ, @a FDD, @a HDD, @a Dbg, + * @a Heap, @a Pool. + * + * @section api_suffixes API Names 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. + * - "I", I-Class APIs are invokable only from the I-Locked or + * S-Locked states. See @ref system_states. + * - "S", S-Class APIs are invokable only from the S-Locked + * state. See @ref system_states. + * 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 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 @ref System APIs group and + * @ref article_interrupts. + * - 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 @ref article_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. S-Class and I-Class APIs are + * invokable in this state. + * - I-Locked. Kernel locked and regular interrupt sources disabled. + * 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 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 state 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: + * + * @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()"]; + 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 + * Note, the SFI, Halted and SNMI 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 *"]; + 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 + * @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.

+ * @image html readylist.png + * 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 Threads States + * The image shows how threads can change their state in ChibiOS/RT.
+ * @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="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 + * + * @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.

+ * @image html workspace.png + *
+ * 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 @ref Core documentation for details, the area may change on + * the various ports and some structures may not be present (or be zero-sized). + */ +/** @} */ -- cgit v1.2.3