From 0810f1daac3c33d194d573d82ec436021e3e7255 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 19 Jan 2009 13:31:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@643 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/src/saveram.dox | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 docs/src/saveram.dox (limited to 'docs/src/saveram.dox') diff --git a/docs/src/saveram.dox b/docs/src/saveram.dox new file mode 100644 index 000000000..fec810c81 --- /dev/null +++ b/docs/src/saveram.dox @@ -0,0 +1,66 @@ +/** + * @page article_saveram Saving RAM by declaring thread functions "noreturn" + * @{ + * One of the problems, when writing embedded multi-threaded applications, + * is that the thread functions do save the registers in the function + * entry code even if the system does not require it, exiting such + * a function would terminate the thread so there is no need to preserve + * the register values. This can waste tens of bytes for each thread.
+ * Consider the following code: + * @code +#include + +static WORKING_AREA(waMyThread, 64); + +static t_msg MyThread(void *arg) { + + while (!chThdShoudTerminate()) { + /* Do thread inner work */ + } + return 1; +} + +main() { + chSysInit(); + ... + chThdCreate(NORMALPRIO, 0, waMyThread, sizeof(waMyThread), MyThread, NULL); + ... + chSysPause(); +} + * @endcode + * The resulting ASM code for the thread function would be something like this: + * @code +MyThread: + stmfd sp!, {r4, r5, r6, lr} + ... + ldmfd sp!, {r4, r5, r6, pc} + * @endcode + * Being that function a thread there is no need to save those registers, in + * embedded applications often the RAM is a scarce resource. That space can be + * saved by modifying the code as follow, using some advanced GCC extensions: + * @code +#include + +static BYTE8 waMyThread[UserStackSize(64)]; + +__attribute__((noreturn)) void MyThread(void *arg) { + + while (!chThdShoudTerminate()) { + /* Do thread inner work */ + } + chThdExit(1); +} + +main() { + chSysInit(); + ... + chThdCreate(NORMALPRIO, 0, waMyThread, sizeof(waMyThread), (t_tfunc)MyThread, NULL); + ... + chSysPause(); +} + * @endcode + * This will make GCC believe that the function cannot return and there is no + * need to save registers. The code will be a bit less readable and less + * portable on other compilers however. + */ +/** @} */ -- cgit v1.2.3