This article is for an old version of msp430-gcc and does not work with the latest version!
Find the updated lesson here.
In this lesson we will be setting up the msp430-gcc toolchain on our virtual machine. The timing for this couldn’t be better because just last month TI officially released msp430-gcc after taking it over from the open source community. This [hopefully] means there will be support for the latest chips as well as improvements and bug fixes. TI has actually provided a Linux installer, but I will show you how to compile it from source instead. I want to go through this exercise because the compiler for your target may not always be available in a pre-packaged binary or the version available may be older than required.
Step 1: Get the compiler sources and support files
If you remember from the last lesson, we already installed gcc in our virtual machine. However the version of gcc that is available in the repositories is built for your host architecture, in our case x86. Compiling code for a target that is a different architecture than your host machine is called cross-compiling. We will build a gcc (using gcc) which runs on an x86 machine, but compiles machine code for the msp430. So to start, fire up your virtual machine, open Firefox and go to TI’s download site.
At the bottom in the “Products Downloads” table, you should download these two files:
Open up a terminal, navigate to your downloads folder and extract the first package.
cd ~/Downloads tar xvf msp430-gcc-source.tar.bz2
This might take a while… If you are not familiar with the tar command, it is a very widely used archiving utility which supports multiple compression algorithms. The command line parameters we passed are as follows:
- x – extract
- v – verbose
- f – for file, always followed by the filename of the file you want to compress/extract
If you want to learn more about the tar command you should read the man page (i.e. “man tar” in the command line).
Navigate to the newly created “sources/tools” directory. What you see in here may be a bit overwhelming, but really what TI has done is packaged all the components required to build the compiler and created a build system around it. Technically, gcc itself is only the compiler. The toolchain consists of many other packages which perform various tasks such as assembling, linking, built-in functions etc… Most of these are contained in binutils, but there are separate math libraries like mpc, mpfr and gmp. A standard C library (libc) is also typically included unless you are developing an operating system. In the case of TI’s package, newlib is the C library they have chosen to include but there are plenty others such as glibc and uClibc. We will go into more detail on some of these components in a later lesson. For now what you need to know is that typically you would compile binutils, gcc, and some version of libc separately using the following method:
- configure, compile and install binutils
- configure, partially compile and install gcc
- partially compile means using make all-gcc and make install-gcc
- configure, compile and install your standard c library
- finish the installation by doing the full gcc compile
- make all && make install
The reason you have do this sort of recursive dance with gcc is because the cross-compiler is required to build libc for your target architecture but gcc also references the standard C library when compiling application code, so it needs to be installed as part of the toolchain.
Step 2: Compile the toolchain
Compiling gcc takes long, so I let’s get it started and while it is compiling you can read the explanation for everything below.
cd ~/Downloads sudo apt-get install texinfo expect libx11-dev g++ flex bison libncurses5-dev mkdir build cd build export PREFIX=/opt/msp430-toolchain export TARGET=msp430-none-elf export PATH=$PREFIX/bin:$PATH ../sources/tools/configure --target=$TARGET --prefix=$PREFIX --program-prefix=msp430- --enable-languages=c --disable-nls make all
Now that its running, here is the breakdown of what you just did.
sudo apt-get install texinfo expect libx11-dev g++ flex bison libncurses5-dev
Here we are installing packages that are required to compile gcc
- texinfo: utility to help create documentation in various formats
- expect: program which talks to other programs interactively, used in scripts
- libx11-dev: X11 windowing system development package
- g++: gnu C++ compiler (we only installed the C compiler last lesson)
- flex: fast lexical analyser generator
- bison: parser generator
- libncurses5-dev: screen handling and optimization package, basically a terminal upgrade
mkdir build cd build
Next we create a build directory. One very important note about compiling gcc is you cannot build it in the source directory. If you try, you are very likely to get build errors.
export PREFIX=/opt/msp430-toolchain export TARGET=msp430-none-elf export PATH=$PREFIX/bin:$PATH
Before building gcc, some environment variables should be set. We don’t want them to be system wide or persistent so we will set them only in the context of our shell. To do so we use the export command. The environment variables defined are:
- PREFIX – the directory where your cross-compiler will be installed – I like to install my toolchains under the “/opt” directory
- TARGET – the target architecture in the format <arch>-<target-os>-<abi/output> or something of that nature (its not really well defined). In our case the arch is msp430, target-os is none because it will be bare metal development, and output is elf format
- PATH – the system path, already defined but we must add location of the binaries we will build to it
../sources/tools/configure --target=$TARGET --prefix=$PREFIX --program-prefix=msp430- --enable-languages=c --disable-nls
As with most gnu programs, the build environment is based on automake/autoconf. These tools can be fairly complicated to understand and the parameters that you have pass into them are sometimes obscure and poorly documented. Basically this is what need to be done:
- Run the configure script passing in the required arguments which are defined by the configuration file for a specific program
- The script analyses your system for various dependencies and from the information it collects, it is able to generate makefiles, configuration files and sometimes header files that will be compatible with your system. If you are not familiar with makefiles, don’t worry about it for now, I will have a lesson dedicated to them. Sometimes dependencies cannot be resolved in which case the configuration (or build) will fail
- Compile the code
- Install the program
In the case of gcc, the configure script accepts many arguments but only a few are required in most cases. The target and prefix argument are as described above in the environment variables section. The program-prefix simply adds a prefix to all the binary files, so for example gcc will become msp430-gcc. This is useful when you want to have one makefile that can build the same code for many architectures. For example, if I wanted compile main.c for both msp430 and arm, I could define my compiler as $(target)-gcc and then configure with target=msp430 to use msp430-gcc or configure with target=arm to use arm-gcc.
The disable-nls flag tells the build to disable Native Language Support (NLS) which basically means GCC only outputs diagnostics in English.
Finally, enable-languages tells the build system to compile only the specified languages. Only C is enabled since that is the language we will be using. If you are interested in the many other options for gcc compilation you can read all about them here.
One last thing, if you need to completely clean your build directory or rebuild from scratch, the “make distclean” command is supposed to do this for you but in my experience it is often not effective. Its easier and safer to just delete the whole build directory and start again.
Did the compilation finish? If not take a coffee break…
Now that its done, you have to install it. Since /opt is owned by root, the install command has to be run with sudo.
sudo make install
This copies all the required files from the build directory to the directory specified by the environment variable PREFIX.
Step 3: Adding the support files
The final step before we are done is installing the device support header and linker files. These files are provided separately from TI in the second file downloaded in step 1.
cd ~/Downloads unzip msp430-support-files.zip
The files will be extracted to an “include” directory. Inside you will see a lot of header files and linker scripts. The header files include all the device specific definitions and memory locations for registers and peripherals. The linker scripts tell the linker how to map various sections of code to physical memory locations on the device. Although they are all packaged together, the header and linker files belong in different locations in your installation. Use the following commands to copy the files to the appropriate location.
cd include chmod -R 644 * sudo cp *.ld $PREFIX/msp430-none-elf/lib/430/ sudo cp *.h $PREFIX/msp430-none-elf/include
The second command is used to change the permissions of the files so they can be read by any user. This way the user compiling does not have to have root privileges. The location where the files are copied to is defined by the toolchain. If you put them somewhere else, it won’t find them.
And there you have it. Next lesson I will give you your first piece of code to compile, introduce you to the various utilities that come with the compiler and show you how to program and run the application on the MSP430 Launchpad.