ARM
This article is not about running Linux on ARM.
It is about [[Article description::compiling code for an ARM processor, taking advantage of its FPU.]]
Prepare the toolchain
Building with crossdev
If nanolib, hardfloat and C++ support are not important, you may proceed to building.
Enable C++ support
C++ support can be enabled with the cxx
USE flag in both cross-arm-hardfloat-eabi/binutils and cross-arm-hardfloat-eabi/gcc packages.
In order to override crossdev's USE flags, the custom ones must exist in a file with lower dictionary order like /etc/portage/package.use/cross-zzz.
Enable nanolib support
Support for the nano library exists as part of sys-libs/newlib since at least version 2.5.0
by use of the nano
USE flag.
Enable hardfloat support
This is a bit tricky. One way to enable it, supposing the target processor has an FPU unit, is the following.
root #
crossdev --stable -t arm-hardfloat-eabi --env \
'EXTRA_ECONF="--with-cpu=cortex-m4
--with-float-abi=hard
--with-mode=thumb"'
Analyzing the above command, the previous -none- part has been replaced with -hardfloat-.
As for the EXTRA_ECONF flags, they were copied from a readme.txt file found in the ARM toolchain source's root or the following path for the pre-built version: share/doc/gcc-arm-none-eabi/. Here are the contents of the readme.txt for convenience:
user $
cat readme.txt
-------------------------------------------------------------------------- | Arm core | Command Line Options | multilib | |------------|--------------------------------------------|--------------| | Cortex-M0+ | -mthumb -mcpu=cortex-m0plus | thumb | | Cortex-M0 | -mthumb -mcpu=cortex-m0 | /v6-m | | Cortex-M1 | -mthumb -mcpu=cortex-m1 | | |------------|--------------------------------------------|--------------| | Cortex-M3 | -mthumb -mcpu=cortex-m3 | thumb | | | | /v7-m | |------------|--------------------------------------------|--------------| | Cortex-M4 | -mthumb -mcpu=cortex-m4 | thumb | | (No FP) | | /v7e-m | |------------|--------------------------------------------|--------------| | Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | thumb | | (Soft FP) | | /v7e-m+fp | | | | /softfp | |------------|--------------------------------------------|--------------| | Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard | thumb | | (Hard FP) | | /v7e-m+fp | | | | /hard | |------------|--------------------------------------------|--------------| | Cortex-M7 | -mthumb -mcpu=cortex-m7 | thumb | | (No FP) | | /v7e-m | | | | /nofp | |------------|--------------------------------------------|--------------| | Cortex-M7 | -mthumb -mcpu=cortex-m7 -mfloat-abi=softfp | thumb | | (Soft FP) | | /v7e-m+dp | | | | /softfp | |------------|--------------------------------------------|--------------| | Cortex-M7 | -mthumb -mcpu=cortex-m7 -mfloat-abi=hard | thumb | | (Hard FP) | -mfpu=fpv5-sp-d16 | /v7e-m+dp | | | | /hard | |------------|--------------------------------------------|--------------| | Cortex-M23 | -mthumb -mcpu=cortex-m23 | thumb | | | | /v8-m.base | |------------|--------------------------------------------|--------------| | Cortex-M33 | -mthumb -mcpu=cortex-m33 | thumb | | (No FP) | | /v8-m.main | | | | /nofp | |------------|--------------------------------------------|--------------| | Cortex-M33 | -mthumb -mcpu-cortex-m33 | thumb | | (Soft FP) | -mfloat-abi=softfp | /v8-m.main+fp| | | | /softfp | |------------|--------------------------------------------|--------------| | Cortex-M33 | -mthumb -mcpu=cortex-m33 | thumb | | (Hard FP) | -mfloat-abi=hard | /v8-m.main+fp| | | | /hard | |------------|--------------------------------------------|--------------| | Cortex-R4 | [-mthumb] -mcpu=cortex-r? | thumb | | Cortex-R5 | | /v7 | | Cortex-R7 | | /nofp | | Cortex-R8 | | | | (No FP) | | | |------------|--------------------------------------------|--------------| | Cortex-R5 | [-mthumb] -mcpu=cortex-r? | thumb | | Cortex-R7 | -mfloat-abi=softfp | /v7+fp | | Cortex-R8 | | /softfp | | (Soft FP) | | | |------------|--------------------------------------------|--------------| | Cortex-R5 | [-mthumb] -mcpu=cortex-r? | thumb | | Cortex-R7 | -mfloat-abi=hard | /v7+fp | | Cortex-R8 | | /hard | | (Hard FP) | | | |------------|--------------------------------------------|--------------| | Cortex-R52 | [-mthumb] -mcpu=cortex-r52 | thumb | | (No FP) | | /v7 | | | | /nofp | |------------|--------------------------------------------|--------------| | Cortex-R52 | [-mthumb] -mcpu=cortex-r52 | thumb | | (Soft FP) | -mfloat-abi=softfp | /v7+fp | | | | /softfp | |------------|--------------------------------------------|--------------| | Cortex-R52 | [-mthumb] -mcpu=cortex-r52 | thumb | | (Soft FP) | -mfloat-abi=hard | /v7+fp | | | | /hard | |------------|--------------------------------------------|--------------| | Cortex-A* | [-mthumb] -mcpu=cortex-a* | thumb | | (No FP) | | /v7 | | | | /nofp | |------------|--------------------------------------------|--------------| | Cortex-A* | [-mthumb] -mcpu=cortex-a* | thumb | | (Soft FP) | -mfloat-abi=softfp | /v7+fp | | | | /softfp | |------------|--------------------------------------------|--------------| | Cortex-A* | [-mthumb] -mcpu=cortex-a* | thumb | | (Hard FP) | -mfloat-abi=hard | /v7+fp | | | | /hard | --------------------------------------------------------------------------
You may now proceed to writing code.
Building
The simplest command to build a toolchain is:
root #
crossdev --stable -t arm-none-eabi
Using the pre-built one
A pre-built toolchain is the GNU Arm Embedded Toolchain. Remember to update your PATH
by prepending the location of the toolchain's bin folder:
user $
export PATH="/path/to/toolchain/bin:$PATH"
Writing code
Error message: .... uses VFP register arguments ... does not
This probably means that some of the libraries being linked, were compiled with hardfloat
(-mfloat=hardfloat
) while others with floatfp
or float
. This can also happen when the compiler was compiled in an opposite to the code manner.
Error message: undefined reference to `__stack_chk_guard'
In the case of compilation errors like undefined reference to `__stack_chk_guard'
, make sure the ssp
USE flag was not enabled for cross-arm*/gcc.
Using Mbed
Mbed is an online platform for writing and compiling code for various boards. It has an export function that enables retrieving the said code including a Makefile and the imported libraries.
If arm-hardfloat-eabi or -mfloat=hard is used, the Makefile must be adapted since it uses arm-none-eabi and -march=floatfp.
If instead of the mbed-os library, the mbed one is included, being precompiled, it might not link against hardfloatly compiled code.
Missing mbed_config.h
If compilation fails with a missing mbed_config.h file, Makefile needs to be adapted with a point to the root folder's mbed_config.h file.
Using STM32CubeMX
STM32CubeMX can be used to initialize code. In provides a graphical user interface to choose pin modes and clocks.
Using pre-built toolchain's samples
The pre-built GNU Arm Embedded Toolchain, comes with code samples and Makefiles.
See also
External resources
- Embedded Artistry explains the difference between
hard
,softfp
andsoft
(the three ARM floating point compiler options). - Discussion on the problems enabling hardfloat.
- Another similar discussion in the Gentoo forums.