/* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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_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(); ... chThdCreateStatic(waMyThread, sizeof(waMyThread), NORMALPRIO, MyThread, NULL); ... } * @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 WORKING_AREA(waMyThread, 64); __attribute__((noreturn)) static void MyThread(void *arg) { while (!chThdShoudTerminate()) { /* Do thread inner work */ } chThdExit(1); } main() { chSysInit(); ... chThdCreateStatic(waMyThread, sizeof(waMyThread), NORMALPRIO, (tfunc_t)MyThread, NULL); ... } * @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. */