1.4. Creating a new project

1. Create a new project

Open File → New → C Project

Give a project name ‘nucleo64_F072RB_template’. Use Empty Project profile.


Click Next and leave the configurations as proposed:


Click Finish.

You should get the following project structure. All you have is an empty file structure with only few include definitions. These includes are for the GCC compiler libraries, and are part of any GCC related project:


2. Prepare project structure and files

Using Right-Click → New → Folder from the Project Explorer, prepare the following folder structure in order to organize the project files:

  • /app folder will be used to put application level source files:
    • /app/inc for headers (.h)
    • /app/src for functions implementation (.c)
  • /bsp (board support package) folder will used to put source files used for peripherals initialization and board-related low-level functions:
    • /bsp/inc for headers (.h)
    • /bsp/src for functions implementation (.c)
  • /cmsis folder will be used to put STM32 device drivers:
    • /cmsis/core for CMSIS headers
    • /cmsis/device/inc for device headers
    • /cmsis/device/src for device startup source code

Note that this folder structure is only a suggestion. If you know what you are doing, you can organize files the way you want and even put everything below root folder, although not recommended…

As your project grows, the number of source files can become really big. You need a clean file structure that you know and understand well to navigate comfortably between sources. The sooner you get familiar with your choice of folder structure, the better. Even for small projects.


3. Get CMSIS, device headers, startup code and linker script

In order to get up-to-date CMSIS driver and startup files, a good option is to download the latest release of STM32 Cube libraries for the targeted device. It comes as a pretty big package including HAL libraries, but do not worry, we will only pick-up few files from this archive.

You can get the STM32F0 Cube library from ST website :

Unzip the archive somewhere on your file system. The content should be as below:


In another window, open your project folder located in your workspace folder:


Then copy/paste the following files, from the Cube library, into your project folders:

File(s)  Source folder Destination folder
*.h  \Drivers\CMSIS\Include\ \cmsis\core\
stm32f0xx.h, stm32f072xb.h system_stm32f0xx.h \Drivers\CMSIS\Device\ST\STM32F0xx\Include \cmsis\device\inc
startup_stm32f072xb.s  \Drivers\CMSIS\Device\ST\STM32F0xx\
system_stm32f0xx.c \Projects\STM32F072RB-Nucleo\Templates\Src \cmsis\device\src
stm32f0xx_it.h \Projects\STM32F072RB-Nucleo\Templates\Inc \app\inc
stm32f0xx_it.c \Projects\STM32F072RB-Nucleo\Templates\Src \app\src


If you are working with a device other than STM32F0RB, just adapt the previous table to your needs… All ST Cube libraries share the same file structure.

Back into Eclipse, right-click on the project name in the Project Explorer and select Refresh (or press F5). Your project structure now should be:


Some explainations about files we've just added to the project:

  • CMSIS stands for “Cortex Micro-controller System Interface Standard”. The core headers are required to access dedicated CPU (ARM Cortex-M) functionalities, which are not part of ST hardware. For instance, we use core CPU functions to configure the system timer (Systick) or the Nested Vector Interrupt Controller (NVIC), or Low-Power modes.
  • STM32F0 headers (stm32f0xx.h, stm32f072xb.h) contain definitions (names) for all STM32 peripheral registers and their content. It is not a library, it is more like a long list of #define. It allows to call a register and associated bit by names instead of addresses. For example, the code below we used to toggle the LED state (pin PA5) in previous labs:
*(int *)0x48000014 ^= 0x00000020U;

now becomes:


which is exactly same code, as there are just a #define behind GPIOA, ODR, GPIO_ODR_5 labels. Still, it makes code writing and reading way more comfortable. When hovering the mouse over a #defined symbol, you get a bubble info that provides the definition:

These headers also include data types based on <stdint.h> that we will use instead of standard C types for integer numbers:

C types Embedded types
char int8_t
unsigned char uint8_t
short int16_t
unsigned short  uint16_t
int int32_t
unsigned int uint32_t


  • system_stm32.c and system_stm32.h provide few functions and macros you may want to use. In particular, the default clock settings are defined here and called from the startup function.
  • Startup code startup_stm32f072xb.s and associated linker script.


4. Add main.c and main.h files

Right-click on the /app/src folder in the Project Explorer and choose New → Source File and add main.c to that folder

Right-click on the /app/inc folder in the Project Explorer and choose New → Header File and add main.h to that folder



Open main.c in the editor. Let us write something simple, just to have something to watch in the debugger:

 * main.c
 *  Created on: 5 août 2017
 *      Author: Laurent

#include "stm32f0xx.h"

int main()
	uint8_t i = 0;


Save main.c. We can leave main.h empty for the moment.

Double-click stm32f0xx_it.c to open editor. Then scroll down until you find the SysTick_Handler() function. Comment (or delete) the call to HAL_IncTick() function as we are not going to use the HAL library.

  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
void SysTick_Handler(void)
  // HAL_IncTick();

Save all image019.png


5. Setting project build properties


5.1. Target setting and Linker Script

Open project Properties (right-click→Properties) and select the C/C++ Build→Settings category or simply click the build configuration button.

Atollic will first prompt you for target (device) setting:


Click OK. Then select the MCU you want as project target:


Click Apply.

Let TrueSTUDIO generate a new linker script based on the MCU you've just set:


Clicking OK in the popup window

Leave default folder and file name. Just click Finish.
Click OK.
Now open the Tool Settings tab ( Tool Settings) and select the category C Linker → General
Make sure that the Linker Script is there:
For some reason, Atollic loose the path to this Linker Script after you close/re-open Eclipse. To prevent this little inconvenience, you may want to change the path from relative to absolute. Just click the Browse button, navigate to your project directory and select the Linker Script to get a full path as follows:

Even better, if you plan to share your project using Git, you may use workspace and project name global variables to avoid using your own paths, making the import into another workspace directly working:


5.2. Include paths

You must provide the compiler with all the paths you've used to store header (.h) files. Having them into the project file structure is not enough.

Go into C Compiler → Directories


Use the Add button image022.png of the Include paths frame to add the following folders by browsing into the workspace:

  • /app/inc
  • /bsp/inc
  • /cmsis/core
  • /cmsis/device/inc

5.3. Symbols definition

Most library source files (.h, .c) include conditional-build sections (using the #ifdef compiler directive). These sections are included in or excluded from the build depending on the definition (or not) of specific symbols. In particular, you need to tell the generic header stm32f0xx.h wich particular device you are using in order to include the right code sections.

Go into C Compiler → Symbols

Use the Add button image022.png and enter STM32F072xB as a new symbol to add to the project:

5.4. Done!

Click the bottom Apply button in order to apply all the changes you've made to the build settings.
Click Yes.
Click OK to exit the Build Configuration window.

6. First build

Hit the rebuild button or right-click the project name and select Build Project. The project should build successfully without any warning or error! If you have error, then carefully review the above settings...


Note that two new items have appeared in the Project Explorer:

  • Binaries
  • Debug


7. Setting-up the debugger

Open the Debug Configuration window .


Select Embedded C/C++ Application and then click the New button image036.png

Review the Main tab to make sure that the right .elf file is set:



In the Debugger tab, set the probe to whatever you have (ST-Link or J-Link). Most likely, if you're working with a fresh Nucleo board, you need to set the probe to ST-Link, with SWD interface.



When you are done reviewing these settings, just Apply.


You can then click the Debug button, or close the window and click . If it doesn’t work, make sure you have a connected Nucleo at the end of the USB cable !

Once in the debugger environment, you can control program execution via usual toolbar commands (, , , , , ...), add variables or expressions to watch, etc.


Set a breakpoint on the i++ line, and then press resume several times watching the i variable:


Then terminate image041.png the debug session and switch back to C/C++ perspective.


8. Summary

In this tutorial, you have created a new project to work with the STM32F072 target under Atollic TrueSTUDIO®. You now have a clear view of files you need to include in order to have a clean startup code, register definitions, and access to Cortex-M specific functions.