Updating STM32 C template with CMSIS V3

So far we’ve been using old template with CMSIS version 1.30. Since then it was updated several times by adding support of new Cortex processor families, fixing several bugs and adding new features. They also changed folder structure of CMSIS to be more generic. And there is a CMSIS DSP library integrated. With it you can do complex math tasks using only few lines of code. So why not upgrading our software template for Sourcery Codebench G++ toolchain with new CMSIS. Also we are going to get rid of external makefile with ARM GCC Eclipse plug-in. How to install and use this plugin we discussed in previous posts (part1 and part2). Right now we just do this in quick way. And so first of all download latest CMSIS package from arm.com/cmsis. You will have to register in order to access download files. Package with CMSIS, DSP library and documentation weights about 45MB. Since we are working with ST32 microcontrollers you also need to download STM32F10x Standard Peripheral Library from STMicroelectronics.

Creating project template

First of all create Eclipse project. Lets name it STM32template. Again we are going to do this for STM32F103ZET6 microcontroller board. For this we create empty project for Sourcery G++ Lite toolchain. Then we can create new .c file called main.c. Lets write empty loop in main routine for testing purposes:

int main(void)


while(1) { }

return 0;



And yes, you already can try to build the project. It will compile but you’ll get one specific warning telling that compiler can’t find entry symbol _start. And it will be defaulting to 00008000. In this situation your program won’t work on microcontroller just because main should not start at start of flash but after interrupt table.

So now we have to take care of these things.

Startup and linker files

As you probably already know before any program in ARM is run a special startup program needs to be run first. It takes care of loading interrupt vector table, initializing core, initializing variables if needed, and calling main routine which then can run user functions. Startup code can be written in C or ASM language. Earlier we were using C startup file. Now lets try ASM. You can find startup file named startup_ARMCM3.s in CMSIS archive in CMSIS-SP-00300-r3p1-00rel0\Device\ARM\ARMCM3\Source\G++ directory. Extension .s means that this is ASM file. GCC compiler needs .s to be capitalized so rename file to be startup_ARMCM3.S. Lets create a new folder named Device in Eclipse project explorer and import startup file here. Note that you will have to edit it as it only has Only core interrupts listed correctly. You may need to edit external interrupt list. In this template we are going to use corrected startup file with Cortex-M3 HD line vector table. Rename it to startup_stm32f10x_hd.S which is more obvious.

The linker file gcc_cs.ld is in same location as startup. Import it to Device folder as well. The only thing you will need to edit here is memory size.

Make sure that MEMORY part match the microcontroller memory sizes. For STM32F103ZET6 microcontroller it should be

FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K

Lets continue including necessary files. Wee need to add CMSIS core files that allows accessing Cortex core functions and registers. From CMSIS-SP-00300-r3p1-00rel0\CMSIS\Include we will need three files only: core_cm3.h, core_cmFunc.h and core_cmInstr.h. Import those files to Device folder in project tree. Last thing we will bee needing are header files of device. These we need to import from STM32F10x Standard Peripheral Library that we downloaded. We will need stm32f10x.h, system_stm32f10x.c and system_stm32f10x.h. First one describes all registers of STM32 microcontroller while other two take care of initializing system clock. Import these files in to Deviec folder as well. We should have following project tree structure:

Changing project properties

Now lets adjust project settings in order to compile everything correctly. Click on project folder right mouse button and select Properties. Go to C/C++ Build section – this is where all settings needs to be changed:

If you go to C/C++ Build branch then you can see that ARM GCC Plugin done most of work. Builder already uses sourcery built in cs-make tool. It already is selected to generate Makefile automatically. Now go to Settings branch. Here we will need to select target processor to be cortex-m3. In additional tools we can call sourcery tools that does some actions after compile.

For instance Print size calls arm-none-eab-size.exe tool generates binary size of compiled image.

Now go to ARM Sourcery Windows GCC Linker->General menu. Here we need to direct linker to linker file. Just Enter in Script file (-T) field following:


This means that it is located in workspace->project directory->Device folder. Try to avoid using absolute paths as on project location change you will need to change settings again.

Before giving a try don’t forget to add locations of header files. For this In ARM Sourcery Windows GCC Compiler->Directories we need to add all locations where all project related .h files are located. Again use workspace related paths:

Now we can try building and see if something is missing.

When trying to build a project we get an error:

error: #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"

This means that we need to show that we are using STM32 HD device. We can fix this by uncommenting

/* #define STM32F10X_HD *//*!< STM32F10X_HD: STM32 High density devices */

line in stm32f10x.h file. But better do this using project properties. In C compiler preprocessor settings add defined symbol STM32F10X_HD:

Now lets try to compile. Another error:

c:/codesourcery/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-init.o): In function `__libc_init_array':
init.c:(.text+0x3a): undefined reference to `_init'

This is because we left “Do not use standard start files” checked in Properties->C/C++ Build/ARM Sourcery Windows GCC C Linker->General also check “Remove unused sections”:

Now lets try:

text data bss dec hex filename
1192 24 32 1248 4e0 STM32template.elf
'Finished building: STM32template.siz'
' '
**** Build Finished ****

Now its working. Since template is ready you can start building projects around it. Download template here:  STM32template. Also you can download prepared startup files for other stm32 microcontrollers here: startup_files_for_codebench.

Leave a Reply

Your email address will not be published. Required fields are marked *