Hello, I've been trying to enable the FPU on a SAMV71Q21 (on the ATSAMV71-XULT devkit).
I followed the instructions of the AN_44047 Application note (which seems a bit outdated), and changed my compiler flags from:
-mfloat-abi=softfp -mfpu=fpv4-sp-d16 to -mfloat-abi=hard -mfpu=fpv5-d16
I added the -mfloat-abi=hard to the linker flags as well as I got a compiler error that the object files and the .ELF file was not using the same instruction set. After this the code compiled. However, it ran into a runtime error immediately upon execution. Even before I got the chance to set up the UsageFault_Handler. This problem was caused by the AtmelSTART generated ASF4 code, which implements and calls the fpu_enable function that is describd in the AN above
in the _init_chip() function that is (in heavy cascade through a bunch of other init functions) called from the main() function. This is of course way too late, since the first floating point instructions are being executed in the Reset_Handler() interrupt callback from the file "startup_samv71q21b.c" by the function "__libc_init_array();".
So I moved the _fpu_enable(); to execute before the libc_init and now the code finally run.
However, I'm still uncertain if I missed something, and if I have all functionality that's provided by the FPU (I have also included arm_math.h and the CMSIS DSP library in the project). So does anyone have any comments to add to this? Are there any other registers or Handlers that should be configured in order to put the FPU to it's full use? I've been trying to read the ARM documentation, but to an unexperienced embedded programmer, such as myself, that documentation feels like a jigsaw-puzzle suspended in a massive spider-web. Bits and pieces of relevant and irrelevant information spread across hundreds of documents and thousands of small 20-line pages that is sometimes aimed towards ASIC designers and sometimes towards programmers.
Anyway, this brings me to my second problem (which is related to the above):
Using floats where I previously used integers as placeholders gave me problems with freeing up dynamically allocated memory because of "unalignment". Now, let's temporarily ignore the fact that I probably shouldn't use the malloc() family at all in an embedded system (as I've learned debugging this problem), because the problem seems to be related to the way that floats are stored in the memory and that I just randomly happened to observe it in a call of the "free()" function. I don't fully understand how ARM processors handle alignment (or even how alignment works in the first place), but from what I've been able to figure out it seems like the core expects 4-byte aligned input values to the LDM, STM, LDRD, and STRD instructions (ref: ARM docs ). I've noticed that my code crashes upon "lds" instructions when looking at the disassembly, which I guess is what ARM calls LDM (?). I've also seen mentions in the ARM docs that most ARM processors don't even have capability to store unaligned data, so that this shouldn't really be an issue - but as I'm seeing this error I suppose that the SAMV71 implementation allows for that, and utilizes it during float operations. Can anyone comment on whether this is true? I can't find much information about the FPU in the datasheet. And if this is the case: how can I make sure that the floats are aligned in memory?
Finally: quickly back to the dynamic allocation that we ignored above. If the malloc() family is a nono, how am I supposed to store a local array that contains a few hundred ADC readings, performs a few float operations on them and overflows the stack?