UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


guides:stm32toolchain

STM32 Toolchain Setup

There are two peripheral libraries which can be used. Firstly is the official ST libraries, or alternately libopencm3. There are more examples available for the ST libraries, however libopencm3 is nicer to use, but still in development.

STM32 Intro (Jon) slides here: stm32_intro_ukhas14.pdf

Linux, libopencm3

Step 1 - Install toolchain

Ideally you should be able to apt-get install the tools, however the version in the repo is broken slightly and doesnt have the 'nano' version of newlib (printf etc)

  • For use of newlib-nano, best to grab the binary tarball from https://launchpad.net/gcc-arm-embedded. Latest at time of writing is gcc-arm-none-eabi-4_8-2014q2 (-linux or -mac one as appropriate).
  • Extract to somewhere like /usr/local and add /usr/local/gcc-arm-none-eabi-4_8-2014q2/bin to PATH, by adding:

export PATH=/usr/local/gcc-arm-none-eabi-4_8-2014q2/bin:$PATH to your ~/.bashrc (assuming using bash).

  • Then to use the amended PATH:

$ source ~/.bashrc

  • Alternatively (and for when they fix newlib nano in the repos), install from ppa:

$ sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded

$ sudo apt-get update

$ sudo apt-get install gcc-arm-none-eabi

  • Check install is working by running

$ arm-none-eabi-gcc –version

Step 2 - Clone a blank project

Step 3 - Fetch and build libopencm3

  1. cd into the root of the repo
  2. Run $ git submodule update –init to fetch libopencm3.
  3. cd to the libopencm3 directory and run $ make to build.

Step 4 - Adjust for your device

We've not got things set up for the F1 (or other) series yet, give us a shout if this is what you're after and we can help.

Open up Makefile in firmware/src/. Adjust the last line for either the F0 or F4 as appropriate

  • include ../common/Makefile.f0.include OR
  • include ../common/Makefile.f4.include

Now open up common/stm32f0-discovery.ld or common/stm32f4-discovery. Adjust the RAM and ROM lengths as appropriate for your particular device. If you want to change the name of this file to satisfy your OCD, do so and then make the relevant change in firmware/common/Makefile.fx.include (where x=0 or 4 as appropriate).

Step 5 - Install flashing/debug software

Step 6 - Build

A libopencm3 LED blink example is provided in firmware/src/main.c.

cd to this directory and build the firmware with $ make - this should produce the main.elf file.

If you're having issues then use $ make V=1 for more verbose build output.

Step 7 - Flash the firmware

  • Connect the board to the machine via the USB port
  • Erase the device with $ st-flash erase
  • Make the .bin version of the binary with $ make bin
  • Flash the firmware to the device with $ st-flash write main.bin 0x8000000
    • 0x800000 is the start address of the flash memory in the device memory address space

On Linux, st-flash needs root privileges ( sudo ./st-flash …) to access the USB system until you set up udev rules


Windows, Makefile, libopencm3

In theory you should be able to follow the linux instructions. You will need to have make installed, as well as python.

Windows, IDE

This guide will get a windows IDE based toolchain up and running. There is the option of either using ST or openlibcm3 libraries (see above). This guide uses 'coIDE,' however there are several available. This has the advantage that the ST libraries are 'built in', and so you just need to click on the ones you want and they are copied into the project. libopencm3 can still be used, but it requires a few more tweeks

Step 1 - Install

Step 2 - Install programmer drivers

These are the drivers and downloading program for ST-Link, which is found on the ST development boards

The STM32s also have a UART booloader, the tool to download is here: http://www.st.com/web/en/catalog/tools/PF257525 (you dont need this if you intend to use the SWD interface on the development boards)

Step 3 - Tell coIDE where the tools are (first time only)

  • Open coIDE
  • go Project → Select toolchain path
  • Select toolchain install directory (eg C:\Program Files (x86)\GNU Tools ARM Embedded\4.8 2014q2\bin )

Step 4 - Create a new project

  • Project → New project
  • Type a project name, select a project path (you probably dont what the default one)
  • Click Chip
  • Select ST→…
  • A blank main.c should be created

Step 5 (ST Libraries)

(skip to the next step if you want to use libopencm3)

This example will now get an LED flashing. After project creation the 'repository' window should be showing, which has a selection of libraries that can be copied to the project. (if not, go view→repository)

With the repository showing, click 'GPIO'. A whole load of files should have been copied into the project. Also click 'C library' (for printf/sprintf etc).

Open main.c, and copy in the sample code below

Step 5 (libopencm3 Libraries)

Firstly add the libopencm3 files to the project directory. This can be fetched from the libopencm3 repository and compiled as per above instructions, or run git submodule add https://github.com/libopencm3/libopencm3 .\firmware\libopencm3 if you want to add it to an existing repository. Since it is unlikely for all the tools (make, python and others) to be set up correctly. As a result, a precompiled version is available here. Unzip the contents into a separate libopencm3 folder along side your project

The final file needed is part of the linker script. Copy this file (f4) or this file (f0) along side your project. Note that this file needs editing depending on how much flash/RAM the target has

Now set up the IDE with these files:

  • Right click on the project → Configuration
  • Under compile, add STM32F0 (change as appropriate) to the defined symbols section; then remove USE_STDPERIPH_DRIVER (if it is there)
  • Under compile, add libopencm3/include to the IncludePaths
  • Under Link, add opencm3_stm32f0.a to the linked libraries (located in libopencm3/lib)
  • Under Link, tick 'Discard unused sections' and 'Dont use the standard system startup files'
  • Under Link, untick 'Use memory layout from memory window' and 'Enable LTO'
  • Under Link, select the scatter file as stm32f0-discovery.ld

Step 6 - Download and run

To run the program:

  • Click Project → Build
  • Click Flash → Program Download (downloads and runs), OR
  • Click Debug → Debug (to enter debug mode)

coIDE defaults to STLink to download programs, however if you are having issues, check 'Download' settings in the project configuration


Code Listings

ST Libraries (using API)

#include "stm32f0xx.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
//include further headers as more peripherals are used
 
int main(void)
{
 
    //turn on GPIOC
    //IMPORTANT: every peripheral must be turned on before use
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
 
    //init structure for GPIO
    GPIO_InitTypeDef GPIO_InitS;
    GPIO_InitS.GPIO_Pin = GPIO_Pin_9;          //the pin we are configuring
    GPIO_InitS.GPIO_Mode = GPIO_Mode_OUT;      //set to output mode
    GPIO_InitS.GPIO_OType = GPIO_OType_PP;      //set to push/pull
    GPIO_InitS.GPIO_PuPd = GPIO_PuPd_NOPULL;  //no pullup resistors 
    GPIO_InitS.GPIO_Speed = GPIO_Speed_50MHz; //set to max speed
    GPIO_Init(GPIOC, &GPIO_InitS);            //write this config to GPIOC
 
    while(1) //flash forever
    {
        GPIO_SetBits(GPIOC, GPIO_Pin_9);      //set pin on
        int32_t i = 4800000;
        while(i) i--;                          //delay a bit
        GPIO_ResetBits(GPIOC, GPIO_Pin_9);    //set pin off
        i = 4800000;
        while(i) i--;                         //delay a bit
    }
}

libopencm3 (using API)

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
 
#define LED_PORT GPIOC
#define LED_PIN GPIO9
 
int main(void)
{
    // Set clock to 48MHz (max)
    rcc_clock_setup_in_hsi_out_48mhz();
 
    // IMPORTANT: every peripheral must be clocked before use
    rcc_periph_clock_enable(RCC_GPIOC);
 
    // Configure GPIO C.9 as an output
    gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN);
 
    // Flash the pin forever
    while(1)
    {
        gpio_set(LED_PORT, LED_PIN);                  
        int32_t i = 4800000;
        while(i)
            i--;
        gpio_clear(LED_PORT, LED_PIN);
        i = 4800000;
        while(i)
            i--;
    }
}

ST Libraries (direct register manipulation)

    while(1)   //flash forever
    {
        GPIOC->BSRR |= (1<<9);                  
        int32_t i = 4800000;
        while(i) i--;
        GPIOC->BRR |= (1<<9);
        i = 4800000;
        while(i) i--;
    }

libopencm3 (direct register manipulation)

guides/stm32toolchain.txt · Last modified: 2016/04/07 20:48 by mbrejza