Turn-key PCB assembly services in prototype quantities or low-volume to mid-volume production runs

Updating STM32 C template with CMSIS V3

So far we’ve been using an 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 the 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 a 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). First of all download the latest CMSIS package from arm.com/cmsis. You will have to register 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 a project template

First of all, create an Eclipse project. Let’s name it STM32template. Again we are going to do this for STM32F103ZET6 microcontroller board. For this, we create an empty project for Sourcery G++ Lite toolchain. Then we can create a new .c file called main.c. Let’s write an empty loop in the 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 the 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 the 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 let’s 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 an ASM file. GCC compiler needs .s to be capitalized so rename the 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 the 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 the same location as a 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 matches the microcontroller memory sizes. For STM32F103ZET6 microcontroller it should be

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

Let’s continue including necessary files. We need to add CMSIS core files that allow 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 the project tree. The last thing we will be needing is header files of the device. These we need to import from the 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 the other two take care of initializing system clock. Import these files into Device folder as well. We should have the following project tree structure:

Changing project properties

Now, let’s adjust project settings to compile everything correctly. Click right mouse button on and select Properties. Go to C/C++ Build section – this is where all settings need to be changed:

If you go to C/C++ Build branch, then you can see that the ARM GCC Plugin is done most of the work. Builder already uses a built-in cs-make tool. It already is selected to generate Makefile automatically. Now go to Settings branch. Here we will need to select the target processor to be cortex-m3. In additional tools, we can call Sourcery tools that do 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 the 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 the 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 property. In C compiler preprocessor settings add defined symbol STM32F10X_HD:

Now let us 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 let us try:

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

Now it is working. Since the 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