Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building apps with gcc flag '-mhard-float' ? #97

Open
JOE1994 opened this issue Jul 21, 2020 · 8 comments
Open

Building apps with gcc flag '-mhard-float' ? #97

JOE1994 opened this issue Jul 21, 2020 · 8 comments

Comments

@JOE1994
Copy link

JOE1994 commented Jul 21, 2020

Hello 🦀,

I measured the execution time of the same C nbody benchmark program on top of FreeRTOS & Tock.
(I only modified variable n in the main function to be const volatile int n = 50000;)
(Both cases were tested on NucleoF429ZI board)

  • nbody on FreeRTOS : 13.037325 seconds
  • nbody on Tock : 360.536 seconds

I found that Tock apps are currently built with gcc flag -mfloat-abi=soft

-mfloat-abi=soft\

I tried replacing the flag with -mfloat-abi=hard,
but I received the following error.

lonelyjoe@lonelyjoe-desktop:~/workspace/libtock-c/examples/n-body$ make
  CC        main.c
In file included from ./../../support/warning_header.h:6:0,
                 from <command-line>:0:
/usr/include/newlib/stdio.h: In function '__sputc_r':
/usr/include/newlib/stdio.h:671:39: sorry, unimplemented: Thumb-1 hard-float VFP ABI
 _ELIDABLE_INLINE int __sputc_r(struct _reent *_ptr, int _c, FILE *_p) {
                                       ^~~~~~

On Stm32CubeIDE which provides newlib-nano as the default runtime library,
I had no errors while building the same C program on top of FreeRTOS with the -mfloat-abi=hard configuration.
One thing I see is that the instruction set I used in stm32cubeide was Thumb-2,
while the error from building Tock tells me Thumb-1 hard-float VFP ABI is not implemented.

(below is an image of the build configuration I used for building nbody on FreeRTOS)
image

Is there a way to work around this error to build apps with flag -mfloat-abi=soft?
Or is it currently possible to use Thumb-2 instruction set instead of Thumb-1?

Thank you for checking out this issue 👍 👍

@ppannuto
Copy link
Member

I was lazy one upon a lifetime.

The newlib in libtock-c is built to support all cortex M's, which do not all have hard floating point support. The fix for this is to build multiple copies of newlib with varying features enabled and choose the one that matches the capabilities of the board. The libtock-c build system just doesn't have that intelligence implemented presently. The Stm32CubeIDE does this and ships with multiple copies of newlib (choosing the Mcu chooses the version of newlib to use).

I think the newlib build actually does this to an extent out of the box; if you build newlib locally you should get a version in /arm-none-eabi/thumb/v7+fp (<-- ish, I think that's how they named it) that will allow hard floating point.

I'm happy to add more newlib builds to Tock (we maybe should bump versions of newlib too.. we're using one from 2017 presently), but the logic to choose the right newlib is a bit trickier. Maybe less painful now with some of the logic @bradjc had to implement for Risc-V...

@ppannuto
Copy link
Member

This is a build for arm-none-eabi/thumb/v7e-m+fp/hard/newlib, which I think is correct for that core

newlib.zip

@JOE1994
Copy link
Author

JOE1994 commented Jul 23, 2020

This is a build for arm-none-eabi/thumb/v7e-m+fp/hard/newlib, which I think is correct for that core

newlib.zip

Thank you so much for the files!

I replaced libm.a & libc.a in libtock-c/newlib/cortex-m with new ones and naively tried a clean make,
but currently Make tries to build for all cortex-m cores (including cortex-m0 which doesn't have FPU),
the build gets stuck while trying to build for cortex-m0 😿
I'll try to find a workaround later..

  • shell output
lonelyjoe@lonelyjoe-desktop:~/workspace/libtock-c/examples/n-body$ make
 DIR        ../../libtock/build/cortex-m0
  CC        ../../libtock/internal/alarm_internal.c
In file included from ./../../support/warning_header.h:6:0,
                 from <command-line>:0:
/usr/include/newlib/stdio.h: In function '__sputc_r':
/usr/include/newlib/stdio.h:671:39: sorry, unimplemented: Thumb-1 hard-float VFP ABI
 _ELIDABLE_INLINE int __sputc_r(struct _reent *_ptr, int _c, FILE *_p) {
                                       ^~~~~~
../../TockLibrary.mk:147: recipe for target '../../libtock/build/cortex-m0/alarm_internal.o' failed
make: *** [../../libtock/build/cortex-m0/alarm_internal.o] Error 1

@ppannuto
Copy link
Member

try TOCK_TARGETS=cortex-m4 make, that'll just do the one

@JOE1994
Copy link
Author

JOE1994 commented Jul 24, 2020

try TOCK_TARGETS=cortex-m4 make, that'll just do the one

That worked! Thank you!
Now the last step: I'm trying to cross-compile gcc with FPU enabled..
I could try to add more newlib builds to Tock once I have this done 👍

lonelyjoe@lonelyjoe-desktop:~/workspace/libtock-c/examples/n-body$ TOCK_TARGETS=cortex-m4 make
  LD        build/cortex-m4/cortex-m4.elf
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: BFD (2.27-9ubuntu1+9) 2.27 assertion fail ../../binutils-2.27/bfd/elf32-arm.c:13082
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: BFD (2.27-9ubuntu1+9) 2.27 assertion fail ../../binutils-2.27/bfd/elf32-arm.c:13082
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(adddf3.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(adddf3.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(divdf3.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(divdf3.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(eqdf2.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(eqdf2.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(gedf2.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(gedf2.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(ledf2.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(ledf2.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(muldf3.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(muldf3.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(subdf3.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(subdf3.o)
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: error: build/cortex-m4/cortex-m4.elf uses VFP register arguments, ../../libc++/cortex-m/libgcc.a(unorddf2.o) does not
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file ../../libc++/cortex-m/libgcc.a(unorddf2.o)
collect2: error: ld returned 1 exit status
../../AppMakefile.mk:267: recipe for target 'build/cortex-m4/cortex-m4.elf' failed
make: *** [build/cortex-m4/cortex-m4.elf] Error 1
lonelyjoe@lonelyjoe-desktop:~/workspace/libtock-c/examples/n-body$ 

@ppannuto
Copy link
Member

You shouldn't need to cross-compile all of gcc, you just need to rebuild libgcc (these are mostly compiler intrinsics, e.g. the calls to memset and such that gcc can emit).

To a first order, should just be updating this line: https://github.com/tock/libtock-c/blob/master/libc%2B%2B/build.sh#L45

@JOE1994
Copy link
Author

JOE1994 commented Jul 29, 2020

You shouldn't need to cross-compile all of gcc, you just need to rebuild libgcc (these are mostly compiler intrinsics, e.g. the calls to memset and such that gcc can emit).

To a first order, should just be updating this line: https://github.com/tock/libtock-c/blob/master/libc%2B%2B/build.sh#L45

Thank you for your help!! I was able to rebuild libgcc and successfully build & flash the n-body program to my board.
The app currently panics on my board (when libm/libc is compiled with -float-abi=hard),
so I'll share the execution time comparison after I figure out the cause of the panic 🐈

@ppannuto
Copy link
Member

Unfortunately, I think there are several more steps that are necessary to get hard floating point working in Tock. There was a start once here ( tock/tock#1010 ), but getting this working is actually a fairly substantial change because of the way that ARM implements things.

Specifically:

  1. hard floating point must be explicitly enabled before it can be used (likely why you're getting a fault trying to use it directly)
  2. turning on floating point changes interrupt entry/exit in the hardware; this requires a new syscall interface implementation in the Tock kernel

The best path forward for this is likely what @bradjc suggested in the prior Tock issue: implementing a new cortex-m4f arch for the Tock kernel.

Sorry for not thinking this through so much before and not giving you a heads-up about the additional missing pieces earlier :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants