Electronics > Microcontrollers

STM 32F4 FPU registers and main() gotcha

<< < (13/22) > >>

wek:

--- Quote from: westfw on August 05, 2024, 08:04:47 pm ---

--- Quote ---Would the toolmakers' attitude be "here's a description of each step of startup process, together with explanation and reasoning behind the individual steps"
--- End quote ---

avr-gcc's documentation of the nine (!) different initialization steps that happen before main is pretty nice.

--- End quote ---
Indeed it is.  But that's the exception, result of enthusiasm and also a certain amount of luck.

I believe you can name all major contributors to the avr-gcc/avr-libc project. This and the state of documentation are no coincidence: they put their names behind their work, and they were willing to publicly discuss it. That's not the norm in the world of "professionally" made tools (and make no mistake, gcc as such is *not* an enthusiasts-driven project).

JW

Nominal Animal:
Give me a specific version of newlibc and a gcc on a specific architecture compatible with those, and I can describe the entire C runtime and initialization scheme.  Especially so if you use an official ARM GNU Toolchain.  I've found that most work is mapping all the debugging options and their effects; for a single version, single set of compilation options, single target architecture, it isn't too painful..

I fully understand wek's issues when trying to do that in a wholly version-agnostic way, because there is so much configurable stuff in the target machine definition compiled to gcc, and all of it interacts with newlib – just see the macros controlling gcc/libgcc/crtstuff.c (which ends up compiled to most of the C runtime).  I've considered sketching it out using Graphviz as a directed graph starting from the hardware reset vector, but it is a lot of work; way too much for a generic directed graph!

For a specific version of the ARM GNU toolchain on a specific architecture (say, ARMv7e-M for Cortex-M4 and -M7), it's not too bad.  The toolchain release notes even include the build instructions (using Linaro ABE manifest.txt files).

What simply fucks all that up, is vendors like STMicroelectronics who package their own toolchains without documenting how to rebuild that toolchain (to distributed binaries differing only in timestamps and such).  Users are told "it's gcc and newlib", but that's less precise than saying "Euler angles (there being only 12 different incompatible ways of defining Euler angles; or 24, if you consider intrinsic and extrinsic rotations separately).

langwadt:

--- Quote from: Nominal Animal on August 06, 2024, 10:01:57 am ---Give me a specific version of newlibc and a gcc on a specific architecture compatible with those, and I can describe the entire C runtime and initialization scheme.  Especially so if you use an official ARM GNU Toolchain.  I've found that most work is mapping all the debugging options and their effects; for a single version, single set of compilation options, single target architecture, it isn't too painful..

I fully understand wek's issues when trying to do that in a wholly version-agnostic way, because there is so much configurable stuff in the target machine definition compiled to gcc, and all of it interacts with newlib – just see the macros controlling gcc/libgcc/crtstuff.c (which ends up compiled to most of the C runtime).  I've considered sketching it out using Graphviz as a directed graph starting from the hardware reset vector, but it is a lot of work; way too much for a generic directed graph!

For a specific version of the ARM GNU toolchain on a specific architecture (say, ARMv7e-M for Cortex-M4 and -M7), it's not too bad.  The toolchain release notes even include the build instructions (using Linaro ABE manifest.txt files).

What simply fucks all that up, is vendors like STMicroelectronics who package their own toolchains without documenting how to rebuild that toolchain (to distributed binaries differing only in timestamps and such).  Users are told "it's gcc and newlib", but that's less precise than saying "Euler angles (there being only 12 different incompatible ways of defining Euler angles; or 24, if you consider intrinsic and extrinsic rotations separately).

--- End quote ---


https://github.com/STMicroelectronics/gnu-tools-for-stm32 ?

Nominal Animal:

--- Quote from: langwadt on August 06, 2024, 12:53:52 pm ---https://github.com/STMicroelectronics/gnu-tools-for-stm32 ?
--- End quote ---
Having build scripts is nice, but not nearly as nice as a description of how to reproduce the distributed binaries (ignoring irrelevant differences like timestamps, function order, and so on).

peter-h:
Getting back to this FPU topic, and referring to this post
https://www.eevblog.com/forum/microcontrollers/for-more-memory-check-this-out/msg5633683/#msg5633683

I am a bit confused. That implies that you need to a float operation before interrupts are enabled.

I am enabling the FPU in startup.s


--- Code: ---/* Start FPU, to avoid this problem */
/* [url]https://www.eevblog.com/forum/microcontrollers/stm-32f4-fpu-registers-and-main()-gotcha/[/url] */

ldr.w r0, =0xE000ED88        /* The FPU enable bits are in the CPACR. */
ldr r1, [r0]
orr r1, r1, #( 0xf << 20 )    /* Enable CP10 and CP11 coprocessors, then save back. */
str r1, [r0]
--- End code ---

but I am not doing a float operation before FreeRTOS is started near the end of main(). After that various RTOS tasks do float ops, but I wonder if I should do one early in main(). There is currently a printf there which goes to the SWV ITM console output (which is harmless if a debugger is not connected) and I could output a float via that, which would not get optimised-out.

Or perhaps the other way is to enable the lazy stacking bit (somewhere??) right after the FPU is enabled. I read that FR handles the FPU issues internally when switching tasks and maybe it sets that bit.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod