Some months ago I bought a STM32F4 Discovery Board. It’s a good start to ARM programming. The good thing about this starter kit is that it can be programmed with open source tools. Also ST Electronics provides a neat peripheral library, which will save me a lot of time.
I followed a great description how to get running the compilation and programming environment from mikrocontroller.net. This description is written in German. I will describe steps, which I performed to get it running.
Toolchain installtion – Sourcery CodeBench
Free toolchain can be obtained from Mentor Graphics website. It’s called Sourcery CodeBench.
To download the package with the toolchain, goto Sourcery CodeBench website. In the ‘ARM Processors’ section click on the link ‘Download the EABI Release’, fill the form. An e-mail will be sent with a download link. After entering the link from the e-mail, choose a release. I chose ‘Sourcery CodeBench Lite 2012.09-63′ and the ‘IA32 GNU/Linux TAR’ package.
Now after downloading the package with toolchain software, we can install it in a place which would be accessible for all users.
sudo mkdir -v /opt/CodeSourcery cd /opt/CodeSourcery sudo tar xjvf arm-2012.09-63-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
Programming tool installation
Checkout from texane’s github the stlink tool. This will be needed to flash the program to the chip’s memory.
git clone git://github.com/texane/stlink.git cd stlink
Some additional packages were needed to compile this software:
sudo apt-get install autoconf libusb-1.0-0-dev
Now we can compile:
./autogen.sh ./configure make
Create installation dir and copy executables:
sudo mkdir -v /opt/stlink sudo cp -v st-flash /opt/stlink sudo cp -v st-util /opt/stlink
Udev rules to recognize the Discovery board when connected to the USB port.
sudo cp -v 49-stlinkv*.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules
Now add path information to /etc/environment file. It needs to be edited with root privileges. Add to the end of file:
/opt/CodeSourcery/arm-2012.09/bin /opt/stlink PATH="$PATH:/opt/CodeSourcery/arm-2012.09/bin:/opt/stlink"
In order to update all environment paths, a logout and login is needed. My Eclipse did not recognize new PATH variable and there were no include paths added when a new project was created.
Now, let’s test our programmer. Only a read is sufficient to check if everything works. Connect the board to PC (via the miniUSB, not the micro) and try to download the demo binary from the board:
st-flash read ~/STM32F4-Discovery.bin 0x8000000 0x100000
If this works, then everything is setup for programming from the command line. To make it easier to develop programs, there is a possibility to integrate these tools with Eclipse IDE.
Eclipse IDE configuration
The only thing right now to do is to install ARM development plugin. Once it is installed, there will be new entries in the ‘New project’ wizard. Of course, CDT (C/C++) plugin should be also installed.
Link to Eclipse installation site: http://gnuarmeclipse.sourceforge.net/updates
Let’s test out new development environment
1. Open Eclipse IDE
2. File > New > C Project
3. ARM Cross Target Application > Empty Project
4. Toolchains = ARM Linux GCC (Sourcery G++ Lite)
5. Type in “Project name”
6. Finish
If the PATH variable is properly recognized by Eclipse, after creating a new project, there will be automatically added include paths:
/opt/CodeSourcery/arm-2012.09/arm-none-eabi/include /opt/CodeSourcery/arm-2012.09/lib/gcc/arm-none-eabi/4.7.2/include /opt/CodeSourcery/arm-2012.09/lib/gcc/arm-none-eabi/4.7.2/include-fixed
Now we have to download a libraries package from ST Electronics: STM32F4 Standard Peripheral Library. Download it and extract it. Now we will add include paths to this library.
1. Project -> Properties
2. C/C++ General > Paths and Symbols
3. Configuration = [All configurations]
4. Includes tab, Languages = GNU C
5. Add -> File system…
<path_to_extracted_lib_files>/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/Libraries/CMSIS/Include <path_to_extracted_lib_files>/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/Libraries/CMSIS/Device/ST/STM32F4xx/Include <path_to_extracted_lib_files>/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/Libraries/STM32F4xx_StdPeriph_Driver/inc ${ProjDirPath}
The last one type in manually.
Now we will add a link source path.
1. Source location tab.
2. Link folder…
3. Name: StdPeriph
4. Check: Link to folder in the filesystem
5. Browse…
<path_to_extracted_lib_files>/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/Libraries/STM32F4xx_StdPeriph_Driver/src
Next we have to add some symbols.
1. Symbols tab.
2. Add… -> USE_STDPERIPH_DRIVER
3. Add… -> USE_STM32_DISCOVERY
4. Add… -> HSE_VALUE = 8000000
Also the linker script has to be setup.
1. C/C++ Build > Settings
2. Configuration = [All configurations]
3. ARM Sourcery Linux GCC Linker > General
4. Script File (-T) = ${ProjDirPath}/stm32_flash.ld
5. ARM Sourcery Linux GNU Create Flash Image -> Output
6. Output file format (-O) -> binary
In order to have all the symbols indexed, we have to setup some last things.
1. C/C++ General > Indexer
2. Check the following:
- Enable project specific settings
- Store settings with project
- Enable indexer
- Index source files not included in the build
- Index unused headers
- Index source and header files opened in editor
- Allow heuristic resolution of includes
Now we can close the project properties and proceed. To start develop, we have to copy from the standard peripheral library directory four files.
<path_to_extracted_lib_files>/home/user/eclipse/STM32/STM32F4xx StdPeriphLib V1.0.0/Project/STM32F4xx_StdPeriph_Templates/TrueSTUDIO/STM324xG_EVAL/stm32_flash.ld <path_to_extracted_lib_files>/home/user/eclipse/STM32/STM32F4xx StdPeriphLib V1.0.0/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c <path_to_extracted_lib_files>/home/user/eclipse/STM32/STM32F4xx StdPeriphLib V1.0.0/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/TrueSTUDIO/startup_stm32f4xx.s <path_to_extracted_lib_files>/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_conf.h
Change the extension of ‘startup_stm32f4xx.s’ to capital ‘S’ and comment out:
/* Call static constructors */ // bl __libc_init_array
In the stm32f4xx_conf.h comment out all the includes except for:
#include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h"
main.c source file content:
#include "stm32f4xx_conf.h" #include "stm32f4xx.h" GPIO_InitTypeDef GPIO_InitStructure; void Delay(__IO uint32_t nCount) { while(nCount--) { } } int main(void) { /* GPIOD Periph clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Configure PD12, 13, 14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); while (1) { /* Set PD12 Green */ GPIOD->BSRRL = GPIO_Pin_12; /* Reset PD13 Orange, PD14 Red, PD15 Blue */ GPIOD->BSRRH = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; Delay(10000000L); /* Set PD13 Orange */ GPIOD->BSRRL = GPIO_Pin_13; /* Reset PD12 Green, PD14 Red, PD15 Blue */ GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15; Delay(10000000L); /* Set PD14 Red */ GPIOD->BSRRL = GPIO_Pin_14; /* Reset PD12 Green, PD13 Orange, PD15 Blue */ GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15; Delay(10000000L); /* Set PD15 Blue */ GPIOD->BSRRL = GPIO_Pin_15; /* Reset PD12 Green, PD13 Orange, PD14 Red */ GPIOD->BSRRH = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; Delay(10000000L); } }
The above code will turn on and off four LEDs on the board. They are placed in the middle of the board. One diode will be turned at a time.
So if everything was setup properly, we can build the project and flash it into the board’s chips memory:
st-flash write Debug/STM32F4Test.hex 0x8000000 2012-11-25T21:24:20 INFO src/stlink-usb.c: -- exit_dfu_mode 2012-11-25T21:24:20 INFO src/stlink-common.c: Loading device parameters.... 2012-11-25T21:24:20 INFO src/stlink-common.c: Device connected is: F4 device, id 0x20006411 2012-11-25T21:24:20 INFO src/stlink-common.c: SRAM size: 0x30000 bytes (192 KiB), Flash: 0x100000 bytes (1024 KiB) in pages of 16384 bytes 2012-11-25T21:24:20 INFO src/stlink-common.c: Attempting to write 56836 (0xde04) bytes to stm32 address: 134217728 (0x8000000) EraseFlash - Sector:0x0 Size:0x4000 Flash page at addr: 0x08000000 erasedEraseFlash - Sector:0x1 Size:0x4000 Flash page at addr: 0x08004000 erasedEraseFlash - Sector:0x2 Size:0x4000 Flash page at addr: 0x08008000 erasedEraseFlash - Sector:0x3 Size:0x4000 Flash page at addr: 0x0800c000 erased 2012-11-25T21:24:22 INFO src/stlink-common.c: Finished erasing 4 pages of 16384 (0x4000) bytes 2012-11-25T21:24:22 INFO src/stlink-common.c: Starting Flash write for F2/F4 2012-11-25T21:24:22 INFO src/stlink-common.c: Successfully loaded flash loader in sram size: 32768 size: 24068 2012-11-25T21:24:23 INFO src/stlink-common.c: Starting verification of write complete 2012-11-25T21:24:24 INFO src/stlink-common.c: Flash written and verified! jolly good!
