i'm new in this type of coding and i'm trying to do some test executing bare-metal software for Cortex-A processors. I have experience with Cortex-M MCU and i compiled code with an IDE like ARM-Keil and with SDK by Nordic for some BLE jobs. Now i want to try to understand better the world of Cortex-A and i would learn coding in a bare-metal way, starting from some examples that i found online. I had some experiences with freeRTOS with Cortex-M, so i found online some git repository from some good guy that makes a porting of freeRTOS for RaspberryPI and BeableBoneBlack. From now on i will just explain my problem for the BeableBoneBlack, beacouse for the RaspberryPI it's similar.
I'm on linux, i installed gcc-arm-none-eabi compiler, so i cloned the BeagleBone Black with freeRTOS repository from this link.
I usually use VS Code to write code, so in the integrated terminal when i run the command make everything it's working and the of my BBB flashes correctly.
So now i would like to improve my code, and in order to do some tests i would like to use the rand()
function, from stdlib.h. Unhappily I find that there are some errors: undefined reference to rand
.
The last months, before doing tests with the BBB, i found other repos for RPi2 and i learn something about the linker of the arm-none-eabi compiler, that needs the addition of some parameters in order link library files during the process.
From this repo now i have two files: makedefs_ti and makefile. Opening the make file i found in line 26-27 the part of the generation of the file app, so where the linker is called. In this lines there are references to LIB_GCC
and LIB_C
, which are defined in the makedefs_ti. In lines 49-50 there are the references to the directory where the compiler is installed (I changed 4.7.3 with the correct one installed on my linux pc that is 9.2.1).
In the makefile, after -L$(LIB_C)
, if i add the linker parameters like -lc
or -lg
and try to recompile, i had error like arm-none-eabi-ld: cannot find -lc
.
With some understanding from online resources i modified the the makedefs_ti as following:
# Toolchain/library path. LIB_PATH is an exported environmental variable which
# shall point to the installation of toolchain
#
#LIB_GCC=${LIB_PATH}/lib/gcc/arm-none-eabi/4.7.3/
#LIB_C=${LIB_PATH}/arm-none-eabi/lib/
LIB_GCC= /usr/lib/gcc/arm-none-eabi/9.2.1
LIB_C= /usr/lib/arm-none-eabi/lib
and the makefile :
$(LD) -o [email protected] $< -T bbb.ld -Map bbb.map $(APP_LIB) $(LDFLAGS) $(RUNTIMELIB) -L $(LPATH) \
-L $(LIB_GCC) -lgcc -L $(LIB_C) -lc -lg
In this way my main.c file that calls a rand()
function compile correctly.
During another test i tried to compile another code. Now i wrote a pair of .c and .h file (i placed them in the rtos directory in order to exploit the same makefile that is present there) that have inside a function that calls sqrt()
. So, calling the function in the main()
and compiling, even if i include everywhere <math.h>
i have the error:
undefined reference to `sqrt'
and obviously the compilation stops. Starting from this i tried to add another parameter to the linker, so i modified the makefile as following:
$(LD) -o [email protected] $< -T bbb.ld -Map bbb.map $(APP_LIB) $(LDFLAGS) $(RUNTIMELIB) -L $(LPATH) \
-L $(LIB_GCC) -lgcc -L $(LIB_C) -lc -lg -lm
and i get other errors which i am unable to resolve in any way:
arm-none-eabi-ld: /usr/lib/arm-none-eabi/lib/libm.a(lib_a-w_sqrt.o): in function `sqrt':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:62: undefined reference to `__aeabi_dcmpun'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:63: undefined reference to `__aeabi_dcmplt'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:64: undefined reference to `__errno'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:65: undefined reference to `__aeabi_ddiv'
arm-none-eabi-ld: /usr/lib/arm-none-eabi/lib/libm.a(lib_a-e_sqrt.o): in function `__ieee754_sqrt':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:110: undefined reference to `__aeabi_dmul'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:110: undefined reference to `__aeabi_dadd'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:117: undefined reference to `__aeabi_dsub'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:117: undefined reference to `__aeabi_ddiv'
make: *** [makefile:26: app] Errore 1
I would remark that, calling the sqrt()
in the main works correctly, the problem happens when i call the sqrt()
in other .c file. Instead the rand()
function in the .c additional file works correctly.
I don't know how to resolve those errors, someone could help me?
What i tried another day is to write the same code in a Code Composer Studio project and it worked (with same functions that call sqrt and rand in additional .c file. What is the difference?
I'm very sorry if this is a long explanation, but i didn't find another way to explain my situation.
Thanks a lot in advance.
Salvo
start.s
notmain.c
(not a real baremetal app, derived from one)
build for hard float
hardware float used
build for soft float
It needs gcclib.
Using gcc as a linker (I know how horrible a thought that is).
...
gcc is passing these to ld.
So to use ld then
Why does it use addf3 now? do not know.
That is how you deal with the aeabi stuff, you need to either use hard float or include the path to gcclib or just add it to the line
Now sqrt() is a C library thing not a gcc library thing so you need a C library (looks like you are trying to use newlib) and you need to build the C library to match gcc so you need to build it for hard or soft float and need to include the right library. Which I do not have...well....
so
looks familiar
find
armv5te should work for armv6
errno is a global variable. that the C library probably wants to use for the soft float.
and now the tool is happy
but this is hard float not soft.
You get the idea though as to what the path to take to solve this is. You need a properly matched/built library then you need to link it. Keil and others simply do that for you in the toolchain, matching things based on the project. And/or a C library that is integrated with the toolchain.
Building for hard float
tool is happy.
Would have to make this a real application main calls another function that has a call to sqrt in it. And then run it on hardware and/or examine these instructions. Or even better get a C library implementation of sqrt and build it in the project so that it matches the target and instruction sets. (same story with the libgcc calls as needed, test them or build them).