ARM
This article is not about running Linux on ARM.
It is about 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.