Building a bare-metal ARM hard-float compiler, what ABI?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Building a bare-metal ARM hard-float compiler, what ABI?

Stuart Longland-2
Hi all,

I'm trying to build firmware for Rowetel's SM1000 smart microphone,
which is based around the STM32F4 microcontroller.

http://www.rowetel.com/blog/?page_id=3902

The device is basically a digital voice modem for radio communications,
the firmware implements code that encodes and decodes audio into Codec2
format and modulating that for transmission via HF radio.  It needs
hardware floating point to work.

I *had* thought `crossdev -t arm-none-eabi` would be sufficient for
this, but imagine my surprise when I received this error:

> arm-none-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg   -c -o STM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.o STM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c
> arm-none-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg   -c -o STM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.o STM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c
> find STM32F4xx_DSP_StdPeriph_Lib -type f -name '*.o' -exec ar crs libstm32f4.a {} ";"
> arm-none-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg -DPROFILE src/codec2_profile.c src/gdb_stdio.c src/stm32f4_machdep.c src/startup_stm32f4xx.s src/init.c src/system_stm32f4xx.c ../src/lpc.c ../src/nlp.c ../src/postfilter.c ../src/sine.c ../src/codec2.c ../src/kiss_fft.c ../src/interp.c ../src/lsp.c ../src/phase.c ../src/quantise.c ../src/pack.c ../src/codebook.c ../
 s
rc/codebookd.c ../src/codebookjvm.c ../src/codebookge.c ../src/dump.c ../src/fdmdv.c ../src/freedv_api.c ../src/varicode.c ../src/golay23.c -o codec2_profile.elf  libstm32f4.a -lg -lnosys -lm

> ../src/freedv_api.c: In function ‘freedv_comptx’:
> ../src/freedv_api.c:260:46: warning: unused variable ‘nspare’ [-Wunused-variable]
>      int    data, codeword1, data_flag_index, nspare;
>                                               ^
> ../src/freedv_api.c:258:29: warning: unused variable ‘k’ [-Wunused-variable]
>      int    bit, byte, i, j, k;
>                              ^
> ../src/freedv_api.c: In function ‘freedv_comprx’:
> ../src/freedv_api.c:516:77: warning: unused variable ‘nspare’ [-Wunused-variable]
>      int                 recd_codeword, codeword1, data_flag_index, n_ascii, nspare;
>                                                                              ^
> ../src/freedv_api.c:515:58: warning: unused variable ‘k’ [-Wunused-variable]
>      int                 i, j, bit, byte, nin_prev, nout, k;
>                                                           ^
> /usr/libexec/gcc/arm-none-eabi/ld: error: codec2_profile.elf uses VFP register arguments, /usr/lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/libg.a(lib_a-assert.o) does not
> /usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /usr/lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/libg.a(lib_a-assert.o)
> /usr/libexec/gcc/arm-none-eabi/ld: error: codec2_profile.elf uses VFP register arguments, /usr/lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/libg.a(lib_a-exit.o) does not
> /usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /usr/lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/libg.a(lib_a-exit.o)

Okay, so I read that as "newlib has been built using softfloat".  No
matter.  I thought maybe I can coax a hardfloat toolchain out by
manipulation of the target.

When I try `crossdev -t arm-hardfloat-eabi` (as clearly "none" gave me a
softfloat one) I got this building gcc at stage 1.

> configure:3389: /tmp/portage/cross-arm-hardfloat-eabi/gcc-4.9.3/work/build/./gcc/xgcc -B/tmp/portage/cross-arm-hardfloat-eabi/gcc-4.9.3/work/build/./gcc/
>  -B/usr/arm-hardfloat-eabi/bin/ -B/usr/arm-hardfloat-eabi/lib/ -isystem /usr/arm-hardfloat-eabi/include -isystem /usr/arm-hardfloat-eabi/sys-include  -mt
> humb -o conftest -g -O2 -pipe   conftest.c  >&5
> conftest.c: In function 'main':
> conftest.c:12:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI
>  {

Now, there's an option to pass in ABIs to crossdev, and for the default
one to be identified.  Question is, where can I find what the ABIs are
called?
--
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Stuart Longland-2
On 05/09/15 14:59, Stuart Longland wrote:

>> arm-none-eabi-gcc … -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard …
> …
> When I try `crossdev -t arm-hardfloat-eabi` (as clearly "none" gave me a
> softfloat one) I got this building gcc at stage 1.
>
>> configure:3389: /tmp/portage/cross-arm-hardfloat-eabi/gcc-4.9.3/work/build/./gcc/xgcc -B/tmp/portage/cross-arm-hardfloat-eabi/gcc-4.9.3/work/build/./gcc/
>>  -B/usr/arm-hardfloat-eabi/bin/ -B/usr/arm-hardfloat-eabi/lib/ -isystem /usr/arm-hardfloat-eabi/include -isystem /usr/arm-hardfloat-eabi/sys-include  -mt
>> humb -o conftest -g -O2 -pipe   conftest.c  >&5
>> conftest.c: In function 'main':
>> conftest.c:12:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI
>
> Now, there's an option to pass in ABIs to crossdev, and for the default
> one to be identified.  Question is, where can I find what the ABIs are
> called?

Well, seems I'm possibly onto a different solution.  I noticed in the
toolchain eclass, some FPU options get set based on the target (apart
from using softfloat if "softfloat" is seen there).

>                 # Make default mode thumb for microcontroller classes #418209
>                 [[ ${arm_arch} == *-m ]] && confgcc+=( --with-mode=thumb )
>
>                 # Enable hardvfp
>                 if [[ $(tc-is-softfloat) == "no" ]] && \
>                    [[ ${CTARGET} == armv[67]* ]] && \
>                    tc_version_is_at_least 4.5
>                 then
>                         # Follow the new arm hardfp distro standard by default
>                         confgcc+=( --with-float=hard )
>                         case ${CTARGET} in
>                         armv6*) confgcc+=( --with-fpu=vfp ) ;;
>                         armv7*) confgcc+=( --with-fpu=vfpv3-d16 ) ;;
>                         esac
>                 fi

That got me thinking, I can pass parameters in using EXTRA_CONFIG and
--genv, maybe I can force things my way?  I figured this would generate
a toolchain that would be less generic, so I've altered my target to
mark it as a "Cortex M4" toolchain:

> crossdev -t arm-cortexm4-eabi -s4 --ex-gcc --genv 'EXTRA_CONF="--with-float=hard --with-fpu=fpv4-sp-d16"'

That got all the way to gcc stage 2, failing with:

> In file included from /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_internal_defs.h:14:0,
>                  from /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_flags.h:15,
>                  from /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_flags.cc:12:
> /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_platform.h:15:3: error: #error "This operating syst
> em is not supported"
>  # error "This operating system is not supported"
>    ^
> In file included from /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_libignore.cc:8:0:
> /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_platform.h:15:3: error: #error "This operating syst
> em is not supported"
>  # error "This operating system is not supported"
>    ^
> Makefile:416: recipe for target 'sanitizer_common_libcdep.lo' failed
> make[4]: *** [sanitizer_common_libcdep.lo] Error 1
> make[4]: *** Waiting for unfinished jobs....
> Makefile:416: recipe for target 'sanitizer_linux_libcdep.lo' failed
> make[4]: *** [sanitizer_linux_libcdep.lo] Error 1
> In file included from /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_linux.cc:13:0:
> /tmp/portage/cross-arm-cortexm4-eabi/gcc-4.9.3/work/gcc-4.9.3/libsanitizer/sanitizer_common/sanitizer_platform.h:15:3: error: #error "This operating syst
> em is not supported"
>  # error "This operating system is not supported"
>    ^
> Makefile:416: recipe for target 'sanitizer_linux.lo' failed

I'll keep plugging away at this, I'm close.
--
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Manuel Lauss-3
I use this with my Tegra toys:

EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
--with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
--with-little-endian" emerge --nodeps --quiet-build=y
=cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}

The resulting toolchain works very well.

      Manuel

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Stuart Longland-2
On 05/09/15 18:34, Manuel Lauss wrote:
> I use this with my Tegra toys:
>
> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
> --with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
> --with-little-endian" emerge --nodeps --quiet-build=y
> =cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}
                         ^^^^^^^^^^^
> The resulting toolchain works very well.

Sadly, it won't work very well at all on these:
http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252142?sc=internet/mcu/product/252142.jsp

Linux won't run in 192kB RAM, not even µCLinux

--
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Manuel Lauss-3
On Sat, Sep 5, 2015 at 10:43 AM, Stuart Longland
<[hidden email]> wrote:

> On 05/09/15 18:34, Manuel Lauss wrote:
>> I use this with my Tegra toys:
>>
>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
>> --with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
>> --with-little-endian" emerge --nodeps --quiet-build=y
>> =cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}
>                          ^^^^^^^^^^^
>> The resulting toolchain works very well.
>
> Sadly, it won't work very well at all on these:
> http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252142?sc=internet/mcu/product/252142.jsp
>
> Linux won't run in 192kB RAM, not even µCLinux

I agree, but I think you can tune your toolchain the same way:

EXTRA_ECONF="--disable-libcc1 --with-arch=armv7e-m
--with-tune=cortex-m4 --with-float-abi=hard" crossdev -t
armv7-hardfloat-eabi --stage1 --b 9999 --g 5.2.0

Manuel

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Manuel Lauss-3
On Sat, Sep 5, 2015 at 10:53 AM, Manuel Lauss <[hidden email]> wrote:

> On Sat, Sep 5, 2015 at 10:43 AM, Stuart Longland
> <[hidden email]> wrote:
>> On 05/09/15 18:34, Manuel Lauss wrote:
>>> I use this with my Tegra toys:
>>>
>>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
>>> --with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
>>> --with-little-endian" emerge --nodeps --quiet-build=y
>>> =cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}
>>                          ^^^^^^^^^^^
>>> The resulting toolchain works very well.
>>
>> Sadly, it won't work very well at all on these:
>> http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252142?sc=internet/mcu/product/252142.jsp
>>
>> Linux won't run in 192kB RAM, not even µCLinux
>
> I agree, but I think you can tune your toolchain the same way:
>
> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7e-m
> --with-tune=cortex-m4 --with-float-abi=hard" crossdev -t
> armv7-hardfloat-eabi --stage1 --b 9999 --g 5.2.0


This creates a working compiler:

USE="-*" EXTRA_ECONF="--disable-libcc1 --disable-libgcc
--with-arch=armv7e-m --with-tune=cortex-m4 --with-float-abi=hard
--with-mode=thumb" crossdev -t arm-none-eabi -v --b 9999 --g 5.2.0
--stage1

Had to disable libgcc since it apparently doesn't work with Thumb mode.

Manuel

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Stuart Longland-2
On 05/09/15 19:16, Manuel Lauss wrote:

> On Sat, Sep 5, 2015 at 10:53 AM, Manuel Lauss <[hidden email]> wrote:
>> On Sat, Sep 5, 2015 at 10:43 AM, Stuart Longland
>> <[hidden email]> wrote:
>>> On 05/09/15 18:34, Manuel Lauss wrote:
>>>> I use this with my Tegra toys:
>>>>
>>>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
>>>> --with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
>>>> --with-little-endian" emerge --nodeps --quiet-build=y
>>>> =cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}
>>>                          ^^^^^^^^^^^
>>>> The resulting toolchain works very well.
>>>
>>> Sadly, it won't work very well at all on these:
>>> http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252142?sc=internet/mcu/product/252142.jsp
>>>
>>> Linux won't run in 192kB RAM, not even µCLinux
>>
>> I agree, but I think you can tune your toolchain the same way:
>>
>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7e-m
>> --with-tune=cortex-m4 --with-float-abi=hard" crossdev -t
>> armv7-hardfloat-eabi --stage1 --b 9999 --g 5.2.0
>
>
> This creates a working compiler:
>
> USE="-*" EXTRA_ECONF="--disable-libcc1 --disable-libgcc
> --with-arch=armv7e-m --with-tune=cortex-m4 --with-float-abi=hard
> --with-mode=thumb" crossdev -t arm-none-eabi -v --b 9999 --g 5.2.0
> --stage1

Yeah, I found the same thing here.  In the end, I wound up with issues
once I got to building newlib:

> armv7-hardfloat-eabi-gcc -B/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/newlib/ -isystem /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/newlib/targ-include -isystem /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/include -B/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/libgloss/arm -L/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/libgloss/libnosys -L/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/libgloss/arm  -mfloat-abi=hard -DPACKAGE_NAME=\"newlib\" -DPACKAGE_TARNAME=\"newlib\" -DPACKAGE_VERSION=\"2.2.0\" -DPACKAGE_STRING=\"newlib\ 2.2.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -I. -I/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls -DARM_RDI_MONITOR -fno-builtin      -g -O2 -pipe  -mfloat-abi=hard -c -o lib_
 a
-sysgetpid.o `test -f 'sysgetpid.c' || echo '/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/'`sysgetpid.c

> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysclose.c:1:0: error: target CPU does not support ARM mode
>  /* connector for close */
>  ^
> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysfcntl.c:1:0: error: target CPU does not support ARM mode
>  /* connector for fcntl */
>  ^
> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysgetpid.c:1:0: error: target CPU does not support ARM mode
>  /* connector for getpid */
>  ^
> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysfstat.c:1:0: error: target CPU does not support ARM mode
>  /* connector for fstat */
>  ^
> Makefile:379: recipe for target 'lib_a-sysclose.o' failed

I was reluctant to try armv7 as I wasn't certain that a Cortex M4 was an
ARMv7, seems it is though, so all is well there. :-)

Interesting thing though.  I managed to build a C/C++ cross-compiler
using arm-cortexm4-eabi, and tried building my project again, got the
same linker errors with calls for VFP and non-VFP code being mixed up.

This was the gcc link command:
> RC=0 stuartl@vk4msl-mb ~/projects/sm1000/codec2/stm32 $ arm-cortexm4-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg -O3 src/sm1000_main.o src/sm1000_leds_switches.o ../src/fifo.o src/debugblinky.o src/system_stm32f4xx.o src/startup_stm32f4xx.s src/init.o ../src/lpc.o ../src/nlp.o ../src/postfilter.o ../src/sine.o ../src/codec2.o ../src/kiss_fft.o ../src/interp.o ../src/ls
 p
.o ../src/phase.o ../src/quantise.o ../src/pack.o ../src/codebook.o ../src/codebookd.o ../src/codebookjvm.o ../src/codebookge.o ../src/dump.o ../src/fdmdv.o ../src/freedv_api.o ../src/varicode.o ../src/golay23.o src/stm32f4_dac.o src/stm32f4_adc.o libstm32f4.a -o sm1000.elf  -lg -lnosys -lm
> /usr/libexec/gcc/arm-cortexm4-eabi/ld: error: sm1000.elf uses VFP register arguments, /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/libg.a(lib_a-assert.o) does not
> /usr/libexec/gcc/arm-cortexm4-eabi/ld: failed to merge target specific data of file /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/libg.a(lib_a-assert.o)

Now, I had a look in /usr/arm-cortexm4-eabi/lib/ and noticed it had an
FPU directory, so I tried:

> RC=0 stuartl@vk4msl-mb ~/projects/sm1000/codec2/stm32 $ arm-cortexm4-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg -O3 src/sm1000_main.o src/sm1000_leds_switches.o ../src/fifo.o src/debugblinky.o src/system_stm32f4xx.o src/startup_stm32f4xx.s src/init.o ../src/lpc.o ../src/nlp.o ../src/postfilter.o ../src/sine.o ../src/codec2.o ../src/kiss_fft.o ../src/interp.o ../src/ls
 p
.o ../src/phase.o ../src/quantise.o ../src/pack.o ../src/codebook.o ../src/codebookd.o ../src/codebookjvm.o ../src/codebookge.o ../src/dump.o ../src/fdmdv.o ../src/freedv_api.o ../src/varicode.o ../src/golay23.o src/stm32f4_dac.o src/stm32f4_adc.o libstm32f4.a -o sm1000.elf  -lg -lnosys -lm -L /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/fpu

It linked fine.  So it looks like the toolchain works, just that there's
some magic flag that gcc isn't passing to binutils to tell it that it
needs to look for the 'fpu' version of the library.

Looking around, I see my arm-none-eabi toolchain also has this 'fpu'
directory, and so maybe will work, if given the right arguments.

Alas, the manpage for gcc is not helpful here, as the only obvious
option, -mfpu, is given.  I've also tried -mhardfloat to no avail.

I don't believe for a minute that the Makefile is supposed to know where
gcc/newlib keep their libraries.
--
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.

Reply | Threaded
Open this post in threaded view
|

Re: Building a bare-metal ARM hard-float compiler, what ABI?

Stuart Longland-2
On 05/09/15 20:11, Stuart Longland wrote:

> On 05/09/15 19:16, Manuel Lauss wrote:
>> On Sat, Sep 5, 2015 at 10:53 AM, Manuel Lauss <[hidden email]> wrote:
>>> On Sat, Sep 5, 2015 at 10:43 AM, Stuart Longland
>>> <[hidden email]> wrote:
>>>> On 05/09/15 18:34, Manuel Lauss wrote:
>>>>> I use this with my Tegra toys:
>>>>>
>>>>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7-a
>>>>> --with-tune=cortex-a15 --with-fpu=neon-vfpv4 --with-float-abi=hard
>>>>> --with-little-endian" emerge --nodeps --quiet-build=y
>>>>> =cross-armv7a-hardfloat-linux-gnueabi/{binutils-9999,gcc-5.2.0,glibc-2.22}
>>>>                          ^^^^^^^^^^^
>>>>> The resulting toolchain works very well.
>>>>
>>>> Sadly, it won't work very well at all on these:
>>>> http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252142?sc=internet/mcu/product/252142.jsp
>>>>
>>>> Linux won't run in 192kB RAM, not even µCLinux
>>>
>>> I agree, but I think you can tune your toolchain the same way:
>>>
>>> EXTRA_ECONF="--disable-libcc1 --with-arch=armv7e-m
>>> --with-tune=cortex-m4 --with-float-abi=hard" crossdev -t
>>> armv7-hardfloat-eabi --stage1 --b 9999 --g 5.2.0
>>
>>
>> This creates a working compiler:
>>
>> USE="-*" EXTRA_ECONF="--disable-libcc1 --disable-libgcc
>> --with-arch=armv7e-m --with-tune=cortex-m4 --with-float-abi=hard
>> --with-mode=thumb" crossdev -t arm-none-eabi -v --b 9999 --g 5.2.0
>> --stage1
>
> Yeah, I found the same thing here.  In the end, I wound up with issues
> once I got to building newlib:
>
>> armv7-hardfloat-eabi-gcc -B/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/newlib/ -isystem /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/newlib/targ-include -isystem /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/include -B/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/libgloss/arm -L/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/build/armv7-hardfloat-eabi/fpu/libgloss/libnosys -L/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/libgloss/arm  -mfloat-abi=hard -DPACKAGE_NAME=\"newlib\" -DPACKAGE_TARNAME=\"newlib\" -DPACKAGE_VERSION=\"2.2.0\" -DPACKAGE_STRING=\"newlib\ 2.2.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -I. -I/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls -DARM_RDI_MONITOR -fno-builtin      -g -O2 -pipe  -mfloat-abi=hard -c -o lib
 _

>  a
> -sysgetpid.o `test -f 'sysgetpid.c' || echo '/tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/'`sysgetpid.c
>> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysclose.c:1:0: error: target CPU does not support ARM mode
>>  /* connector for close */
>>  ^
>> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysfcntl.c:1:0: error: target CPU does not support ARM mode
>>  /* connector for fcntl */
>>  ^
>> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysgetpid.c:1:0: error: target CPU does not support ARM mode
>>  /* connector for getpid */
>>  ^
>> /tmp/portage/cross-armv7-hardfloat-eabi/newlib-2.2.0/work/newlib-2.2.0/newlib/libc/syscalls/sysfstat.c:1:0: error: target CPU does not support ARM mode
>>  /* connector for fstat */
>>  ^
>> Makefile:379: recipe for target 'lib_a-sysclose.o' failed
>
> I was reluctant to try armv7 as I wasn't certain that a Cortex M4 was an
> ARMv7, seems it is though, so all is well there. :-)
>
> Interesting thing though.  I managed to build a C/C++ cross-compiler
> using arm-cortexm4-eabi, and tried building my project again, got the
> same linker errors with calls for VFP and non-VFP code being mixed up.
>
> This was the gcc link command:
>> RC=0 stuartl@vk4msl-mb ~/projects/sm1000/codec2/stm32 $ arm-cortexm4-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg -O3 src/sm1000_main.o src/sm1000_leds_switches.o ../src/fifo.o src/debugblinky.o src/system_stm32f4xx.o src/startup_stm32f4xx.s src/init.o ../src/lpc.o ../src/nlp.o ../src/postfilter.o ../src/sine.o ../src/codec2.o ../src/kiss_fft.o ../src/interp.o ../src/l
 s

>  p
> .o ../src/phase.o ../src/quantise.o ../src/pack.o ../src/codebook.o ../src/codebookd.o ../src/codebookjvm.o ../src/codebookge.o ../src/dump.o ../src/fdmdv.o ../src/freedv_api.o ../src/varicode.o ../src/golay23.o src/stm32f4_dac.o src/stm32f4_adc.o libstm32f4.a -o sm1000.elf  -lg -lnosys -lm
>> /usr/libexec/gcc/arm-cortexm4-eabi/ld: error: sm1000.elf uses VFP register arguments, /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/libg.a(lib_a-assert.o) does not
>> /usr/libexec/gcc/arm-cortexm4-eabi/ld: failed to merge target specific data of file /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/libg.a(lib_a-assert.o)
>
> Now, I had a look in /usr/arm-cortexm4-eabi/lib/ and noticed it had an
> FPU directory, so I tried:
>
>> RC=0 stuartl@vk4msl-mb ~/projects/sm1000/codec2/stm32 $ arm-cortexm4-eabi-gcc -std=gnu99 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_STDPERIPH_DRIVER -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc -ISTM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include -ISTM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include -DARM_MATH_CM4 -D__EMBEDDED__ -I../src -I../unittest -Iinc -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg -O3 src/sm1000_main.o src/sm1000_leds_switches.o ../src/fifo.o src/debugblinky.o src/system_stm32f4xx.o src/startup_stm32f4xx.s src/init.o ../src/lpc.o ../src/nlp.o ../src/postfilter.o ../src/sine.o ../src/codec2.o ../src/kiss_fft.o ../src/interp.o ../src/l
 s

>  p
> .o ../src/phase.o ../src/quantise.o ../src/pack.o ../src/codebook.o ../src/codebookd.o ../src/codebookjvm.o ../src/codebookge.o ../src/dump.o ../src/fdmdv.o ../src/freedv_api.o ../src/varicode.o ../src/golay23.o src/stm32f4_dac.o src/stm32f4_adc.o libstm32f4.a -o sm1000.elf  -lg -lnosys -lm -L /usr/lib/gcc/arm-cortexm4-eabi/4.9.3/../../../../arm-cortexm4-eabi/lib/fpu
>
> It linked fine.  So it looks like the toolchain works, just that there's
> some magic flag that gcc isn't passing to binutils to tell it that it
> needs to look for the 'fpu' version of the library.

And the winner is…

-mthumb specified during link.  That seems to throw the linker
off-course, and so it tries grabbing the softfloat version.

The Makefile tries to do compiles and links by specifying .c files to
the compiler.  So I better fix that problem, then things should work fine.
--
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.