ChibiOS/RT Architecture - Reference Manual - Guides |
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:
#include <ch.h> 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); ... }
The resulting ASM code for the thread function would be something like this:
MyThread: stmfd sp!, {r4, r5, r6, lr} ... ldmfd sp!, {r4, r5, r6, pc}
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:
#include <ch.h> 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); ... }
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.