I've been trying, for a couple of days, to build the project which was associated with the Embedded.com articles "Building Bare-Metal ARM Systems with GNU". I've been hoping that this will clarify alot of the confusion that I've experienced in trying to convert an existing project from IAR to gnuarm. As it turns out, after three weeks of research, I have at least four different versions of GNUARM on my system: 1. gnuarm (arm-elf) 2. winarm (arm-elf) (slightly earlier version than gnuarm) 3. Ride (arm-none-eabi) 4. Sarm (arm-eabi) Ultimately, only ONE of these four packages could actually build the project - Ride's arm-none-eabi. All others would fail in different ways. What's interesting, though, is that the output of the project, using arm-none-eabi, is a .elf file!!! So... what is the difference between arm-elf, arm-none-eabi, and arm-eabi ??? Obviously, the "none" in arm-none-eabi does not mean no-elf ...
Dan Miller wrote: > I've been trying, for a couple of days, to build the project which was > associated with the Embedded.com articles "Building Bare-Metal ARM > Systems with GNU". I've been hoping that this will clarify alot of the > confusion that I've experienced in trying to convert an existing project > from IAR to gnuarm. As far as I know the code from the embedded.com tutorial has been tested with a Codesourcery G++ package (the lite version is free, Codesourcery gets paid by ARM to improve the GNU tools AFAIK). So maybe this is the package that should be used to avoid further confusion. Once you have some basic knowledge of the tools you will see that it is not that difficult to adapt the code for other GNU-precompiled-packages or to/from other compilers. > As it turns out, after three weeks of research, Three weeks? - Uff. > I have at least four > different versions of GNUARM on my system: > 1. gnuarm (arm-elf) > 2. winarm (arm-elf) (slightly earlier version than gnuarm) > 3. Ride (arm-none-eabi) > 4. Sarm (arm-eabi) gnuarm (I expect this is a package from gnuarm.org) and "older" versions of WinARM are very similar. Main differences: WinARM has been created for "non-cygwin" hosts and uses a slightly different newlib configuration. EABI and "old" ABI are different "targets" for which the GNU toolchain can be build. EABI has been created as a common binary interface so object code and libraries created with one toolchain/compiler can linked to a project created with another one. Search on www.arm.com for further details. > Ultimately, only ONE of these four packages could actually build the > project - Ride's arm-none-eabi. It is well possible that the "Ride binaries" are very similar or even a copy of the Codesourcery package. So this might be the reason why the Quantum example-code can be build with this tools without problems. Until gcc 4.3.0 the Codesourcery package has been the only one which offered Cortex-M3 support and AFAIK Ride supports STM32 too. Just speculation, I have never used the Ride tools. I don't know "Sarm" so I can not comment on it at all. > All others would fail in different > ways. You did not write the error-messages created during the attempts with the other packages so it's difficult to analyze the reason why they failed. If would be interesting to see the error-messages when you try to build with DevkitARM R23 or WinARM test-version 20080831. > What's interesting, though, is that the output of the project, > using arm-none-eabi, is a .elf file!!! The file-extension is not important. elf and axf are just the usual extensions. Just look into the makefile. Why "!!!"? What did you expect? > So... what is the difference between arm-elf, arm-none-eabi, and > arm-eabi ??? arm-elf is usually the prefix for GNU toolchains created for the arm-elf target, arm-none-eabi for the target arm-eabi. But this does not mean much since one can set the prefix when building the toolchain. At least eabi should be an indicator that the toolchain has been created for target arm-eabi. >Obviously, the "none" in arm-none-eabi does not mean > no-elf ... This might be wrong. As far as I know it means "no operating-system" on the target (for "bare metal") compared to for example arm-linux-elf. I do understand your confusion, so stay with the GNU package that works for you to get started. Once you know a little bit about the usage of the GNU tools you will see that the differences are small and porting code between them is rather easy. Porting code from IAR to GNU is a more difficult esp. if the EWARM compiler-extension have been used.
> >> Ultimately, only ONE of these four packages could actually build the >> project - Ride's arm-none-eabi. > It is well possible that the "Ride binaries" are very similar or even a > copy of the Codesourcery package. So this might be the reason why the > Quantum example-code can be build with this tools without problems. > Until gcc 4.3.0 the Codesourcery package has been the only one which > offered Cortex-M3 support and AFAIK Ride supports STM32 too. Just > speculation, I have never used the Ride tools. I don't know "Sarm" so I > can not comment on it at all. > I can tell you ride use the codesoucery toolchain as delivered. sarm is the toolchain delivered with Anglia IDEaliST, it is based on codesoucery but has a few tweaks with newlib. Cheers Spen
Wow, alot of feedback, thanks!! 1. Regarding failures with other compilers: With gnuarm/winarm (Gcc V4.1.1) compiles and assemblys go fine, my compiler/assembler flags are: CCFLAGS = -nostartfiles -mlittle-endian -gdwarf-2 -c -mcpu=$(ARM_CPU) -mthumb-interwork -O -mlong-calls -ffunction-sections -Wall -o $@ ASMFLAGS = -gdwarf2 -mcpu=$(ARM_CPU) -mthumb-interwork -o $@ but link fails with: c:/gnuarm/bin/arm-elf-gcc dbg/startup.o dbg/arm_exc.o dbg/low_level_init.o \ dbg/bsp.o dbg/isr.o dbg/blinky.o \ -mlittle-endian -T ./blinky.ld -o dbg/blinky.elf -Wl,-Map,dbg/blinky.map,--cref -lm dbg/startup.o: In function `_start': /cygdrive/c/download/bare_arm9/startup.s:47: multiple definition of `_start' /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ crt0.o:../../../../../../newlib-1.14.0/newlib/libc/sys/arm/crt0.S:46: first defined here /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: ERROR: dbg/startup.o uses VFP instructions, whereas dbg/blinky.elf does not /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: Warning: dbg/startup.o supports interworking, whereas dbg/blinky.elf does not /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: failed to merge target specific data of file dbg/startup.o If I put -nostartfiles in the linker flags (I'm not actually sure where it goes), I then fail differently: /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: ERROR: /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o) uses FPA instructions, whereas dbg/blinky.elf does not /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: ERROR: /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o) uses software FP, whereas dbg/blinky.elf uses hardware FP /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: Warning: /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o) does not support interworking, whereas dbg/blinky.elf does /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: failed to merge target specific data of file /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o) dbg/startup.o: In function `_cstartup': /cygdrive/c/download/bare_arm9/startup.s:163: undefined reference to `__data_load' /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o): In function `__libc_fini_array': ../../../../../newlib-1.14.0/newlib/libc/misc/init.c:58: undefined reference to `_fini' /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/lib/ libc.a(init.o): In function `__libc_init_array': ../../../../../newlib-1.14.0/newlib/libc/misc/init.c:40: undefined reference to `_init' /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: BFD 2.17 internal error, aborting at ../../binutils-2.17/bfd/elflink.c line 6509 in elf_link_output_extsym /cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ ld: Please report this bug. collect2: ld returned 1 exit status make: *** [dbg/blinky.elf] Error 1 //************************************************************* When I use Idealist's sarm version of gnuarm (gcc V4.2.3), assembly is fine but gcc fails strangely: C:/sarm/bin/as -gdwarf2 -mcpu=arm966e-s -mthumb-interwork -o dbg/startup.o startup.s C:/sarm/bin/as -gdwarf2 -mcpu=arm966e-s -mthumb-interwork -o dbg/arm_exc.o arm_exc.s C:/sarm/bin/gcc -marm -nostartfiles -mlittle-endian -gdwarf-2 -c -mcpu=arm966e-s -mthumb-interwork -O -mlong-calls -ffunction-sections -Wall -o dbg/low_level_init.o -I. low_level_init.c gcc.exe: CreateProcess: No such file or directory make: *** [dbg/low_level_init.o] Error 1 //************************************************************* In fact, I was about to give up, but then discovered Ride's version (CodeSourcery gcc V4.2.1)and tried with that... and it worked fine. In fact, I had to go back and remove a number of changes that I'd make in makefiles, trying to get the other versions to work. I gotta admit, I find it a little disconcerting to find that three different packages, all based on GnuArm, all gcc V4+, are completely different in functionality... Is this a good thing?? LATER NOTE: ########## I just went back and tried building our package, which builds fine with gnuarm, and it does not build successfully using Ride's package. This cannot be good. Clearly it won't be sufficient for me to tell the other engineers "we are using GnuArm", I'll have to have a specific package which works, and make sure we keep track of it... sheesh... results of Ride build on our GnuArm package: c:/Ride/arm-gcc/bin/arm-none-eabi-gcc -Wall -I. -Iinclude -MD -DGNUARM -D_STR912FW44_ -D_STR91x_ -D_STR9x_ -mcpu=arm966e-s -std=c99 -nostartfiles -mlittle-endian -TSTR91xFx44_FLASH.ld -Os -g -Wl,-Map=odu.map,--cref,--no-warn-mismatch startup/91x_init.o main.o 91x_it.o feprom.o atmel_flash_memory.o Internal_flash_memory.o source/91x_adc.o source/91x_caps.o source/91x_gpio.o source/91x_lib.o source/91x_rtc.o source/91x_uart.o source/91x_vic.o source/91x_wdg.o source/91x_fmi.o source/91x_scu.o source/91x_emi.o source/91x_dma.o -o odu.elf c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/bin/ld.exe: section .ARM.extab [0002d75c -> 0002d767] overlaps section .data [0002d75c -> 0002e26b] c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-abort.o): In function `abort': abort.c:(.text+0xc): undefined reference to `_exit' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-signalr.o): In function `_getpid_r': signalr.c:(.text+0x4): undefined reference to `_getpid' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-signalr.o): In function `_kill_r': signalr.c:(.text+0x2c): undefined reference to `_kill' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-makebuf.o): In function `__smakebuf': makebuf.c:(.text+0xf8): undefined reference to `isatty' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c:(.text+0x18): undefined reference to `_sbrk' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-writer.o): In function `_write_r': writer.c:(.text+0x20): undefined reference to `_write' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-closer.o): In function `_close_r': closer.c:(.text+0x18): undefined reference to `_close' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r': fstatr.c:(.text+0x1c): undefined reference to `_fstat' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r': lseekr.c:(.text+0x20): undefined reference to `_lseek' c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-readr.o): In function `_read_r': readr.c:(.text+0x20): undefined reference to `_read' collect2: ld returned 1 exit status make: *** [odu.elf] Error 1 ### I get the same errors whether or not I use -nostartfiles in LDFLAGS //************************************************************* The reason I was surprised to see .elf output from the eabi packages was because I assumed that when two general packages existed (arm-elf and arm-eabi), that the second was an alternative to the first, rather than the two package names having nothing to do with each other, as appears to be the case... Dan
> I gotta admit, I find it a little disconcerting to find that three > different packages, all based on GnuArm, all gcc V4+, are completely > different in functionality... Is this a good thing?? This is because there are slight differences in the configuration of the multilib-support of gcc and the newlib (libc used in most packages). The reason why I created the first WinARM-package was that all other packages which have been available at this time did not offer the setup I needed (for a library called newlib-lpc) beside of Cygwin dependencies. > LATER NOTE: ########## > I just went back and tried building our package, which builds fine > with gnuarm, and it does not build successfully using Ride's package. > This cannot be good. Clearly it won't be sufficient for me to tell the > other engineers "we are using GnuArm", I'll have to have a specific > package which works, and make sure we keep track of it... sheesh... Well, first it should be defined what is meant with "GnuArm". I use GNUARM or gnuarm for packages available from gnuarm.com. There are several other packages based on GNU sources compiled for Win32 hosts and ARM targets. - gnuarm from gnuarm.org (arm-elf, extened multilib settings, newlib for non-reentrant syscalls. - Codesourcery G++ ARM "bare metal" (also the tools behind Ride and Rowley's ARM-projects AFAIK). (arm-eabi, don't know the multilib and newlib configuration) Some extensions for the "startup" which I have not investigated but they are described in a pdf-file that comes with the package. - Anglia ARM tool (or Sarm as recently learned) similar to Codesourcery but with newlib "tweaks". Spen is the once who creates it so he can give further details of needed - Michael Fischer's Yagarto, should be very similar to gnuarm.org, but without Cygwin dependency - DevkitARM from devkitpro (r23b: arm-eabi, newlib for reentrant-syscalls, small modifications in newlib headers) - my WinARM, the last "official" release 20060606 has a similar setup for multilibs as gnuarm.org and Yagarto but the newlib has been configured to expect "reentrant" syscalls for newlib-lpc compatiblity, arm-elf There are more packages but I don't remember or know them. I suggest you go with the Codesourcery-package. The lite-package is free but you can buy another package with support which may be important for you and the "other engineers" and they should help you to port your code if you bought the commercial version. > results of Ride build on our GnuArm package: > c:/Ride/arm-gcc/bin/arm-none-eabi-gcc -Wall -I. -Iinclude -MD -DGNUARM > -D_STR912FW44_ -D_STR91x_ -D_STR9x_ -mcpu=arm966e-s -std=c99 > -nostartfiles -mlittle-endian -TSTR91xFx44_FLASH.ld -Os -g > -Wl,-Map=odu.map,--cref,--no-warn-mismatch startup/91x_init.o main.o > 91x_it.o feprom.o atmel_flash_memory.o Internal_flash_memory.o > source/91x_adc.o source/91x_caps.o source/91x_gpio.o source/91x_lib.o > source/91x_rtc.o source/91x_uart.o source/91x_vic.o source/91x_wdg.o > source/91x_fmi.o source/91x_scu.o source/91x_emi.o source/91x_dma.o -o > odu.elf > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/bin/ld.exe: > section .ARM.extab [0002d75c -> 0002d767] overlaps section .data > [0002d75c -> 0002e26b] > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-abort.o): > In function `abort': > abort.c:(.text+0xc): undefined reference to `_exit' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-signalr.o): > In function `_getpid_r': > signalr.c:(.text+0x4): undefined reference to `_getpid' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-signalr.o): > In function `_kill_r': > signalr.c:(.text+0x2c): undefined reference to `_kill' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-makebuf.o): > In function `__smakebuf': > makebuf.c:(.text+0xf8): undefined reference to `isatty' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-sbrkr.o): > In function `_sbrk_r': > sbrkr.c:(.text+0x18): undefined reference to `_sbrk' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-writer.o): > In function `_write_r': > writer.c:(.text+0x20): undefined reference to `_write' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-closer.o): > In function `_close_r': > closer.c:(.text+0x18): undefined reference to `_close' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-fstatr.o): > In function `_fstat_r': > fstatr.c:(.text+0x1c): undefined reference to `_fstat' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-lseekr.o): > In function `_lseek_r': > lseekr.c:(.text+0x20): undefined reference to `_lseek' > c:/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.2.1/../../../../arm-none- eabi/lib\libc.a(lib_a-readr.o): > In function `_read_r': > readr.c:(.text+0x20): undefined reference to `_read' > collect2: ld returned 1 exit status > make: *** [odu.elf] Error 1 The newlib syscalls are missing. > > ### I get the same errors whether or not I use -nostartfiles in LDFLAGS This is libc-related. The libc needs some basic-interface-functions to the hardware (i.e. to allocate memory or to write-characters from the stdio-functions. These functions have to be provided either by a "board-support-package", an extra library or self-written code. > > //************************************************************* > The reason I was surprised to see .elf output from the eabi packages was > because I assumed that when two general packages existed (arm-elf and > arm-eabi), that the second was an alternative to the first, rather than > the two package names having nothing to do with each other, as appears > to be the case... The targets arm-elf and arm-eabi have very much in common. The main difference is the binary-interface but not "nothing to do with each other".
Okay, thank you for all that information!! It clarifies alot for me. I'm still going to stick with GnuArm (actually, I'm using Yagarto, which is a more recent compiler version) for now, since it's compiling (even though the compiled code still has some anomalies). I won't be able to build our project under the free CodeSourcery because it's limited to 16K, and our code is much larger than that at this point. But I'll know it's there if I need it!
Dan Miller wrote: > Okay, thank you for all that information!! It clarifies alot for me. > I'm still going to stick with GnuArm (actually, I'm using Yagarto, which > is a more recent compiler version) for now, since it's compiling (even > though the compiled code still has some anomalies). I won't be able to > build our project under the free CodeSourcery because it's limited to > 16K, and our code is much larger than that at this point. But I'll > know it's there if I need it! codesoucery is not limited to 16k - where is this info from? some vendors, eg. Raisonance limit the amount of code you can debug, but they cannot limit the amount of code produced by the tools. Unless i am mistaken. Regards Spen
Spencer Oliver wrote: > Dan Miller wrote: >> ...stick with GnuArm (actually, I'm using Yagarto... You "stick" with an arm-elf cross-compiler based on GNU sources, you are "using" a package named Yagarto with binaries of the GNU toolchain for Win32-host. >> I won't be able to >> build our project under the free CodeSourcery because it's limited to >> 16K, and our code is much larger than that at this point. But I'll >> know it's there if I need it! > > codesoucery is not limited to 16k - where is this info from? I have also never noticed a limitation in CS G++ ARM lite packages too > some vendors, eg. Raisonance limit the amount of code you can debug, but > they cannot limit the amount of code produced by the tools. > > Unless i am mistaken.
Martin Thomas wrote: > Spencer Oliver wrote: >> Dan Miller wrote: >>> ...stick with GnuArm (actually, I'm using Yagarto... > > You "stick" with an arm-elf cross-compiler based on GNU sources, you are > "using" a package named Yagarto with binaries of the GNU toolchain for > Win32-host. > >>> I won't be able to >>> build our project under the free CodeSourcery because it's limited to >>> 16K, and our code is much larger than that at this point. But I'll >>> know it's there if I need it! >> >> codesoucery is not limited to 16k - where is this info from? > > I have also never noticed a limitation in CS G++ ARM lite packages too > >> some vendors, eg. Raisonance limit the amount of code you can debug, but >> they cannot limit the amount of code produced by the tools. >> >> Unless i am mistaken. Whoops... no, I was confused. Indeed, it's the Raisonance package which has the 16KB limit... nevermind. I'll go back and look at Code Sourcery again...
> > Whoops... no, I was confused. Indeed, it's the Raisonance package which > has the 16KB limit... nevermind. I'll go back and look at Code Sourcery > again... Only for debugging, you can build and program and size code. Cheers Spen
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.