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:
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.