Hi!
[Edit: This HOWTO is mostly outdated now because of the script summon-arm-toolchain I have created together with Uwe. You can find it here at GitHub. A short description on the usage of the script can be found in the Open-BLDC wiki.]
As I decided to use the STM32 for open-bldc and ordered an Olimex H103 evaluation board. I had to build the toolchain for it. This controller is an ARM Cortex-M3 and needs a GCC version beyond 4.3 because there the support was added.
There is a pretty good HowTo on eLua. But as I decided to use the newest versions of the tools some things changed and I decided to write my own HowTo. And here it goes!
I am using macports on my mac, so the howto is based on that. You need to install additionally gmp and mpfr. It is needed so that gcc can be compiled. I also use for most of the stuff I use stow. The toolchain cannot be installed using stow because of the softlinks it creates. You cane install it using macports too.
Sources:
Now you will need the following:
- binutils: http://ftp.gnu.org/gnu/binutils/binutils-2.19.1.tar.bz2
- gcc: http://gcc.cybermirror.org/releases/gcc-4.3.3/gcc-4.3.3.tar.bz2
- newlib: ftp://sources.redhat.com/pub/newlib/newlib-1.17.0.tar.gz
- libusb: http://sourceforge.net/project/showfiles.php?group_id=1674&package_id=1632&release_id=398442
- libftdi: http://www.intra2net.com/en/developer/libftdi/download/libftdi-0.15.tar.gz
-
openocd: I am using svn version of openocd. The revision I tested was 1382. So to get it you need to run
> svn co -R 1382 svn://svn.berlios.de/openocd/trunk openocd-svn
- insight: The versions that I tested for now all had infinite loop bug. Will update that later when I found the right solution.
Compiling binutils:
I store everything that I build by myself in /opt/mine directory. I added it to my path and other relevant environment variables just as I did with /opt/local (the macports install directory). The toolchain needs its own directory. I call it /opt/mine/arm-none-eabi to distinguish it from other arm toolchains that I have on my machine.
I need to add another note here. I chose to use the arm-none-eabi target. This way the toolchain builds Version 4 EABI binaries instead of GNU EABI. I am not 100% sure what the difference is. (Please enlighten me here) But if I understand it correctly the Version 4 EABI is the ARM standarized EABI and not the GNU version of the EABI. But as stated before I am not really sure about that.
> tar xfvj binutils-2.19.1.tar.bz2
> cd binutils-2.19.1
> mkdir build
> cd build
> ../configure --target=arm-none-eabi --prefix=/opt/mine/arm-none-eabi --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls
> make
> sudo make install
> cd ../..
Now you should also add the toolchain bin directory to your PATH so that the further steps can find the binutils binaries.
> export PATH=/opt/mine/arm-none-eabi/bin:$PATH
Building GCC bootstrap:
GCC needs the newlib to build all of it’s libraries but newlib needs gcc to build. This chicken and egg problem can be solved by building GCC without libraries first, then building newlib and finally building GCC it it’s full form.
> tar xfvj gcc-4.3.3.tar.bz2
> cd gcc-4.3.3
> mkdir build
> cd build
> ../configure --with-libiconv-prefix=/opt/local --target=arm-none-eabi --prefix=/opt/mine/arm-none-eabi --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --without-headers --disable-shared --with-gnu-as --with-gnu-ld --with-gmp=/opt/local --with-mpfr=/opt/local
> make all-gcc
> sudo make install-gcc
> cd ../..
I have to comment here on some options used. Somehow the configure of gcc is not able to find gmp and mpfr by itself. Because they are installed in nonstandard directories when you look at a linux system. That is why you have to help it by providing –with-gmp and –with-mpfr. In the case of libiconv you have to add –with-libiconv. Not adding this option does not break the configure but introduces problems in the build process.
Building newlib:
Now that we have binutils and a basic gcc install we can build newlib. This one is pretty streightforward.
[EDIT This section should be obsolete! The patch does not even apply to the newlib-1.17.0 sorry] Still you will probably need a patch that deals with makeinfo being not found by configure. I found it in a post on comp.gcc.cross-compiling.arm. But I offer the patch here for download and your conveniance.
> tar xfvz newlib-1.17.0.tar.gz
> cd newlib-1.17.0
> patch -p1 -i ../newlib-1.14.0-missing-makeinfo.patch # the patch will yield a warning because it is for an older version of newlib but should apply
> mkdir build
> cd build
> ../configure --target=arm-none-eabi --prefix=/opt/mine/arm-none-eabi --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls
> make
> sudo make install
> cd ../..
Building GCC:
This should be simple now. We build the full GCC version.
> cd gcc-4.3.3/build
> rm -rf * # clean up everything it makes stuff safer ^^
> ../configure --with-libiconv-prefix=/opt/local --target=arm-none-eabi --prefix=/opt/mine/arm-none-eabi --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --disable-shared --with-gnu-as --with-gnu-ld --with-gmp=/opt/local --with-mpfr=/opt/local
> make
> sudo make install
> cd ../..
Building libusb:
This library and the following libftdi is needed for jtagkey-tiny support in openocd.
> tar xfvz libusb-0.1.12.tar.gz
> cd libusb-0.1.12
> mkdir build
> cd build
> ../configure --prefix=/opt/mine/DIR/libusb-0.1.12
> make
> sudo make install
> sudo -s
> cd /opt/mine/DIR
> stow libusb-0.1.12
> exit
> cd ../..
Building libftdi:
> tar xfvz libftdi-0.15.tar.gz
> cd libftdi-0.15
> mkdir build
> cd build
> ../configure --prefix=/opt/mine/DIR/libftdi-0.15
> make
> sudo make install
> sudo -s
> cd /opt/mine/DIR
> stow libftdi-0.15
> exit
> cd ../..
Building openocd:
I am using the jtagkey-tiny from Amontec, and usbprog. If you are using something else the options to configure will need enabling the other device.
> cd openocd-svn
> mkdir build
> cd build
> ../configure --prefix=/opt/mine/DIR/openocd-svn --enable-ft2232_libftdi --enable-usbprog
> make
> sudo make install
> sudo -s
> cd /opt/mine/DIR
> stow openocd-svn
> exit
> cd ../..
Building insight/gdb:
Well I still have some problems here. I will update the post as soon as I find a solution here.
Compiling and flashing an example program:
Openocd supplied config file for jtagkey-tiny has an error in my case. On my machine the jtagkey-tiny appears as “Amontec JTAGkey” and not “Amontec JTAGkey A”. You have to edit /opt/mine/lib/openocd/interface/jtagkey-tiny.cfg
and change the line ft2232_device_desc "Amontec JTAGkey A"
to ft2232_device_desc "Amontec JTAGkey"
.
Now you can download stm32-blink.tar.bz2 that I cleaned up a bit. It is based on the example blink project from Olimex.
The example project from Olimex uses parts of the Firmware Library from ST. The documentation and the library itself can be found and downloaded here. You have to be careful though, the library has a very wierd license that is probably problematic when used in open source projects. I assume that the strange license may pose also problems when used in closed source projects too. But I am not a lawyer so do not kill me if I am wrong. 🙂
> tar xfvj stm32-blink.tar.bz2
> cd stm32-blink
> make
Next step is to start openocd. You should start opencd in the stm32-blink directory so that later openocd can find the binary you will be uploading.
> openocd -f /opt/mine/lib/openocd/interface/jtagkey-tiny.cfg -f /opt/mine/lib/openocd/target/stm32.cfg
Now open a new terminal and run the following commands to flash the stm32-blink binary.
> telnet localhost 4444
> halt
> flash write_image erase stm_h103_blink_rom.bin 0x08000000
> resume 0x08000000
Now the diode on the stm32-h103 board should start to blink happily! 🙂
Notes and links:
Here I gathered some additional links that may be usefull:
Disclamers:
I hope this tutorial is useful. If I made any mistakes feel free to write a comment to this post. I will try to update it if something changes and/or needs to be corrected.
Cheers Esden
Updates:
- Fixed link to stm32-blink.tar.bz2
- Changed links to source packages to real links.
- Added newlib patch for missing makeinfo
- Added some additional links. For example to the ST Firmware Library and it’s documentation.
- Added link to the Reference manual of STM32.
- Removed the newlib patch section.
Hi,
I’ve been trying to build the macports arm toolchain on MacOSX 10.5 (and now 10.6) without success. I’d just like to know how different is your approach from the one sin the portfiles. I’m not familiar with portfiles so I don’t know what to look for.
I’m getting problems such as the following when trying to port install arm-elf-gcc 4.3.2:
“checking for suffix of object files… configure: error: cannot compute suffix of object files: cannot compile
See `config.log’ for more details.”
On 10.6, I can’t even get arm-elf-binutils built.
My plan is to build the arm crosscompiler toolchain for use with LEGO NXT bare metal development, for teaching ARM Assembly Language.
I don’t know the error you get there. Have you tried to use summon-arm-toolchain shellscript? You can get it here: http://github.com/esden/summon-arm-toolchain I have not tried to build the toolchain using portfiles though I have no idea what they are doing there.
Hi, yes, I managed to build the toolchain using the summon-arm-toolchain script. I was just wondering why you decided to do it independently of macports, instead of using ports (though the versions of the arm toolchain in macports is older), since you already obtained the other dependencies via macports itself.
I prefer to be in full control of the toolchain and know what I am working with. I now took a look into the arm-elf-gcc portfile. They are doing some more stuff applying patches for example what I don’t do. I also have gcc-4.4.0 version in summon-arm-toolchain and macports still are providing gcc-4.3.2. That are the major differences. I have not tried to compile the macports toolchain yet. I will try to do it soon and see how it works.
Why I did not really care about the libraries that I use from macports that is why I depend on them instead of compiling them by hand. It is that simple. 😉
And one more thing the script also works on linux and if I made it a port file it would not work on linux, without installing port. ^^
i’m trying to compile on Mac os X 10.6 and I’ve some problem…
compiling binutils may require –disable-werror;
I had to compile libgmp-4.3.1 and libmpfr-2.4.1
Still having problems installing gcc:
make[3]: Nothing to be done for `install’.
/bin/sh: line 0: cd: arm-none-eabi/libssp: No such file or directory
make[1]: *** [install-target-libssp] Error 1
make: *** [install] Error 2
@Lorenzo, if libssp is failing try to reconfigure and disable the smash stacking protection library with –disable-libssp If GCC isn’t building because of warnings use -w
hth
Thanks to the script I have managed to build a arm-none-eabi toolchain on OS X 10.6. However when I try and compile a simple hello world program in c it fails with undefined references to _exit and other methods typically found in the runtime (crt).
I didn’t patch the binutils – could that be it?
Pingback: Building an ARM cross-toolchain with binutils, gcc, newlib, and gdb from source
Really good joke the ‘rm -rf *’
I fell right in.
No applications left in my /Applications, except for System Preferences.
Message to everyone… JUST DON’T DO THE RM -RF * !!
I wonder why you are using –enable-interwork if you are building for STM32 with cortex-m3 which only supports thumb/thumb2 instructions?
@pacman: that is only partly a joke, I actually meant it there. It is only the build directory that you are doing it in.
@Tormod: Yes it does not really make sense I agree, it was something I carried over from other documentations how to build the toolchain.