I am using FreeRTOS on a ARM Cortex M7, a STM32H7.
To save energy I want to turn off floating point unit. Now I see this part in port.c:
/* Ensure the VFP is enabled - it should be anyway. */
vPortEnableVFP();
Also there is configENABLE_FPU which is set to 1 by default
I don’t understand why it is needed. Does FreeRTOS do some floating point calculations?
I searched for quite a while now but could not find clear explanations.
Is it possible to run FreeRTOS without having FPU enabled and which steps do I need to take esp in case of ARM Cortex M7?
Thanks for any help
To disable the FPU, you need to make sure that ALL the code you are using has been compiled with a configuration that avoids using any of the FPU registers, ever. The problem is that some of the simple library operations, like memcpy, can sometimes use the FPU to make the copy faster, so you need to make sure you avoid that. This is error prone enough that it isn’t built into the basic port.
I seem to remember that for an M4, if you were not using the FPU, and took the needed precautions, you just used the M3 port. I don’t know if that would work for the M7 too.
You’ll need to understand the ABI option which you can provide to your compiler, you can find more on this here. In short the -mfloat-abi=soft compiler option will tell the compiler not to use the FPU. You’ll also need any libraries to be compiled against the non-FPU ABI setting.
Once you have done this you should be able to modify the kernel to no longer make use of the FPU. “Should” being the keyword. Real world testing may prove it is still in use, however unlikely.
I think it should work. Try CM3 port and let us know if you face any problem. The major caveat here to ensure that FPU is not used at all.
Thanks for your answers.
is that summary correct: ?
FreeRTOS by itself does not use any floating point operations. But as tasks might it has to take precautions to make these operations safe in case of task switches right in the middle of some FPU access. So for any port that is made for HW with FPU these precautions are built in by default and cannot be disabled with just a config setting. So if one wants no FPU support it is best to use a port for a HW without FPU.
Is that right so?
Which are the precautions? Does FreeRTOS save and restore the FPU registers with any task switch?
Thanks for any help.
Since most of the FreeRTOS code is just C code (except some low-level, port-specific functions) it’s up to the compiler settings to generate FPU instructions or not. Also for the FreeRTOS scheduler and all other features there is no real use of floating point calculations.
FreeRTOS with FPU support (by port+config) of course handles save/restore of FPU registers. That’s also the drawback of it because it takes a bit more RAM (on stack) and processor cycles to do so. That’s a bit more overhead on task context switch.
On the other hand if the application needs performance critical floating point calculations it might be worth to enable it. Also the compiler can use FPU instructions as part of its code optimizations even for ‘normal’ code because it can use more (fast) registers etc. if configured accordingly by compiler flags.
For example for Cortex-M3 vs M4F vs M7 ports you can/should just use the CM3 port if you don’t want to use the FPU. With the proper compiler flags, as mentioned before.
Thanks for the clear answers.
It seems to be a bit larger project, so I can’t go for it now. I’ll keep things in mind…