Wednesday, June 17, 2015

Programming an STM32F4DISCOVERY with Ada and GPS in Linux

Niels Huisman & Peter Chapin
VTC CubeSatLab

This tutorial was created using Linux Mint 17.1 Rebecca, and has been tested using Ubuntu 14.04. This information should also work with other Ubuntu-based distros, but that has not been tested.

Shorthand used:

<user> - Your username.
<filename> - Generic file name placeholder. Use whatever file name you wish.

 To make sure we have the required dependencies, get the following packages:

    $ sudo apt-get install autoconf
    $ sudo apt-get install automake
    $ sudo apt-get install pkg-config
    $ sudo apt-get install libusb-1.0
    $ sudo apt-get install git

This can also be done on one line:

    $ sudo apt-get install autoconf automake pkg-config libusb-1.0 git

Go to, click on the banner to download GNAT GPL select "Free Software for Academic Development", click on the button that says "Build Your Download Package", select "ARM ELF format (hosted on Linux)" from the drop-down menu, and download the GNAT GPL tarball for Linux.

Once downloaded, open a terminal (Ctrl+Alt+T), and navigate to the folder where it was downloaded (usually /home/<user>/Downloads). Once there, extract the file as follows:

    $ tar -xvf gnat-gpl-2015-arm-elf-linux-bin

This will create a folder of the same name.  Navigate to that folder using a command such as:

    $ cd gnat-gpl-2015-arm-elf-linux-bin

If you list all the files,  you will see a file called doinstall.  Execute that file using a command such as:

    $ sudo ./doinstall

You will need to enter your root password here. At some point during the install, you will be asked to specify the installation directory. If you already have GNAT installed for native development, you will need to somehow differentiate between the two. Here we use /opt/ARMgnat as the installation directory. If you have two separate GNAT installations, you will need to write a shell script to set the correct path when using GNAT for ARM. Open a text editor of your choice, write:

    export PATH=/opt/ARMgnat/bin:$PATH
    export ARMRUNTIME=/opt/ARMgnat/lib/gnat/arm-eabi/ravenscar-sfp-stm32f4

The first line makes the tools available at the shell prompt. The second line sets an environment variable used to locate the runtime system to be used in the programs. The idea is that Windows users could set ARMRUNTIME appropriately for their system and thus it is possible to share project files between Linux and Windows. For example in the GNAT project file for a project you might include:

    package Builder is
       for Default_Switches ("ada")
          use ("-g", "--RTS=" & external("ARMRUNTIME", ""));
    end Builder;

Save the shell script as <filename>.sh in /home/<user>/bin. Before using GNAT for ARM, you will need to run:

    $ source <filename>.sh

This will set the correct path for the ARM tool chain.

Now that we have GNAT and GPS installed, we need a way to communicate with the STM board, such as ST-Link. Fortunately, we can retrieve Texane STLink using Git using a command such as:

    $ git clone stlink

This will make a directory in /home/<user> called stlink. You can use any target directory name you like. Enter that director using a command such as:

    $ cd stlink

and run the following:

    $ ./
    $ ./configure
    $ make install

This will install st-flash, st-info, st-term, and st-util (the one we care about the most) in /usr/local/bin. To ensure that when st-util is run it behaves as though it was run as root, we need to modify it slightly. Change the owner (should be root already, but just to be sure), and the permissions as follows:

    $ sudo chown root /usr/local/bin/st-util
    $ sudo chmod 4755 /usr/local/bin/st-util

To check that everything took the way it's supposed to, run:

    $ ls -l /usr/local/bin

You should see an output similar to the following (the file size and, of course, date/time may be somewhat different):

    $ -rwsr-xr-x 1 root root 299527 May 14 12:11 st-util

Now that we have everything installed, connect your STM board using the USB mini B port, open a terminal, and run:

    $ /usr/local/bin/st-util

You should see a number of messages giving some information about your board and ending with "Listening at *:4242..." Open a separate terminal, navigate to the directory containing your project, run the script created earlier if necessary, and open GPS.

    $ source /home/<user>/bin/
    $ gps

This will open up the GPS startup window where you can begin working.

VirtualBox Notes

If you are running Linux inside a VirtualBox virtual machine, you may wish to set up a USB filter so VirtualBox automatically recognizes the STM board. To do this, open up the virtual machine settings dialog box and select "USB." Click on the '+' symbol on the right to add a new USB filter. If you have the board plugged into your host, you should see it listed among the USB devices in the menu that appears. Selecting the board will set up a filter automatically.

Alternatively the filter can be set up manually using parameters such as the ones below. These values are appropriate for the STMF4DISCOVERY board. We suggest leaving the Serial Number field blank so the settings will work for any instance of the board (useful for sharing boards).

    Name: STMicroelectronics STM32 STLink [0100]
    Vendor ID: 0483
    Product ID: 3748
    Revision: 0100
    Manufacturer: STMicroelectronics
    Product: STM32 STLink
    Remote: No

After configuring a USB filter, boot the virtual machine with the board plugged into the host and VirtualBox should automatically make the board available to the VM.


  1. An update... GNAT GPL 2015 for ARM does not require using the ARMRUNTIME environment variable as a way of providing host platform independence. Instead you can add: for Runtime("Ada") use "ravenscar-sfp-stm32f4" to the project file, and gprbuild will locate the runtime system from the proper location in the GNAT installation folder.

  2. Hello,

    Thanks for this tutorial. I'm very new to Ada and Linux. I installed GNAT GPS 2016 arm-elf-linux in Ubuntu 16.04 using the procedure you describe, which is in essence the same that it's described in one of the README files that comes with the package.

    This may sound naive, but how do you start the GPS IDE? I tried executing the 'gps' shell script that is located inside '/usr/gnat/bin' (I installed in the suggested default directory)using this command:


    But then I get this error:

    ./gps: 108: exec: /usr/gnat/bin/gps_exe: not found

    What I understand is that the script is trying to execute the file 'gps_exe' and it doesn't find it, even though that file is really present in the bin directory.

    Any hint will be much appreciated, thanks in advance.

    Raul Alvarez

    1. Hi Raul,

      It sounds like you may not have /usr/gnat/bin mentioned in your PATH environment variable. Try doing:

      $ export PATH=/usr/gnat/bin:$PATH

      This should allow you to run 'gps' without specifying a path on the command itself. More importantly, it should allow gps_exe to be found when it is needed. Just because gps_exe is in the same directory as gps that, by itself, does not mean it will be found automatically.