From e9274448e9058df5a32e43212ee9858006fe1c4d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 24 Feb 2009 16:07:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@802 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/src/articles.dox | 1 + docs/src/stacks.dox | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 docs/src/stacks.dox (limited to 'docs') diff --git a/docs/src/articles.dox b/docs/src/articles.dox index 590efdda7..a0426f41c 100644 --- a/docs/src/articles.dox +++ b/docs/src/articles.dox @@ -21,6 +21,7 @@ * @page articles Articles * @{ * ChibiOS/RT Articles and Code Examples: + * - @subpage article_stacks * - @subpage article_mutual_exclusion * - @subpage article_atomic * - @subpage article_saveram diff --git a/docs/src/stacks.dox b/docs/src/stacks.dox new file mode 100644 index 000000000..e824ea04a --- /dev/null +++ b/docs/src/stacks.dox @@ -0,0 +1,106 @@ +/* + 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 article_stacks Stacks and stack sizes + * @{ + * In a RTOS like ChibiOS/RT there are several dedicated stacks, each stack + * has a dedicated RAM space that must have a correctly sized assigned area. + *

The stacks

+ * There are several stacks in the systems, some are always present, some + * others are present only in some architectures: + * - Main stack, this stack is used by the @p main() function and the + * thread that execute it. It is not a normal thread stack because it is + * initialized in the startup code and its size is defined in a port + * dependent way. Details are in the various ports documentation. + * - Interrupt Stack, some architectures have a dedicated interrupt + * stack. This is an important feature in a multithreaded environment, + * without a dedicated interrupt stack each thread has to reserve + * enough space, for interrupts servicing, within its own stack. This space, + * multiplied by the total threads number, can be a significant RAM waste. + * - Thread Stack, each thread has a dedicated stack for its own + * execution and context switch. + * - Other Stacks, some architectures (ARM) can have other stacks but + * the OS does not directly use any of them. + * . + *

Risks

+ * The most critical thing when writing an embedded multithreaded application + * is to determine the correct stack size for main, threads and, when present, + * interrupts.
+ * Assign too much space to a stack wastes RAM, assign too little space + * leads to crashes or, worst scenario, hard to track instability. + * + *

Assign the correct size

+ * You may try to examine the asm listings in order to calculate the exact + * stack requirements but this requires much time, experience and patience.
+ * An alternative way is to use an interactive method. Follow this procedure + * for each thread in the system: + * - Enable the following debug options in the kernel: + * - @p CH_DBG_ENABLE_STACK_CHECK, this enables a stack check before any + * context switch. This option halts the system in @p chSysHalt() just + * before a stack overflow happens. + * - @p CH_DBG_FILL_THREADS, this option fills the threads working area + * with an easily recognizable pattern (0x55). + * - Assign a large and safe size to the thread stack, as example 256 bytes + * on 32 MCUs, 128 bytes on 8/16 bit MCUs. This is almost always too much + * for simple threads. + * - Run the application, if the application crashes or halts then increase + * the stack size and repeat (you know how to use the debugger right?). + * - Let the application run and make sure to trigger the thread in a way to + * make it follow most or all its code paths. If the application crashes or + * halts then increase the stack size and repeat. + * - Stop the application using the debugger and examine the thread working + * area (you know what a map file is, right?). You can see that the thread + * stack overwrote the fill pattern (0x55) from the top of the working area + * downward. You can estimate the excess stack by counting the untouched + * locations. + * - Trim down the stack size and repeat until the application still runs + * correctly and you have a decent margin in the stack. + * - Repeat for all the thread classes in the system. + * - Turn off the debug options. + * - Done. + * . + *

Final Notes

+ * Some useful info: + * - Stack overflows are the most common source of problems during development, + * when in trouble with crashes or anomalous behaviors always first verify + * stack sizes. + * - The required stack size can, and very often does change when changing + * compiler vendor, compiler version, compiler options, code type (ARM + * or THUMB as example). + * - Code compiled in THUMB mode uses more stack space compared to the + * same code compiled in ARM mode. In GCC this is related to lack of tail + * calls optimizations in THUMB mode, this is probably true also in other + * compilers. + * - Speed optimized code often requires less stack space compared to space + * optimized code. Be careful when changing optimizations. + * - The interrupts space overhead on the thread stacks (@p INT_REQUIRED_STACK + * defined in @p chcore.h) is included in the total working area size + * by the system macros @p THD_WA_SIZE() and @p WORKING_AREA().
+ * The correct way to reserve space into the thread stacks for interrupts + * processing is to override the @p INT_REQUIRED_STACK default value. + * Architectures with a dedicated interrupt stack do not require changes + * to this value. Resizing of the global interrupt stack may be required + * instead. + * - Often is a good idea to have some extra space in stacks unless you + * are really starved on RAM. Anyway optimize stack space at the very + * end of your development cycle. + * . + */ +/** @} */ -- cgit v1.2.3