Skip to content

Carl2/cmake_bare_metal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cmake bare metal (cbm)

Overview

This Repo is project using cmake to develop stm32fxx projects under the same repo. And thereby sharing commmon functionality. It is based on the STM32Cube which is downloaded during configure state when running cmake.

The idea was to use the output from StmCubeIde to easy incoperate the project into cmake. This means that the easy configuration i.e system clocks and peripherals can be made inside StmCubeIde and then copy the Core functionality into this project.

Quick start build

Lets start to get going. There are several ways of building but lets go for the terminal first.

Terminal

Some configuration needs to be done in order for the system to figure out what to use.

FLAVOR
These are the projects. For this build we will use the BLACK_PILL, there are 3 others that can be used STEPPER,PH_DISCO,sml_test They all depend on setting the other variables right (MCU_CONFIG,CONF_DIR).
MCU_CONFIG
This points to a file which sets some different variables/flags during compile time which are related to the specific MCU. They are located in:
ls cmake/mcu_conf/*
cmake/mcu_conf/stm32f103xb.cmake
cmake/mcu_conf/stm32f401xc.cmake
cmake/mcu_conf/stm32f411xe.cmake

The project listed are not MCU compatible, which means if you decide to build i.e BLACK_PILL you need to use the stm32f411xe.cmake as MCU_CONFIG

So lets try a build example, the configure step may take some time (depending on you internet connection) since it will download the Stm32Cube library.

mkdir black_pill_build cd black_pill_build

cmake -DFLAVOR=BLACK_PILL \
      -DMCU_CONFIG=stm32f411xe.cmake \
      -DCMAKE_BUILD_TYPE=Release \
      ..

make -j8
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc - skipped
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ - skipped
-- Now m4 conf src/black_pill/Inc
-- Configure files to use: /home/calle/git/PH_WIP/cmake/mcu_conf/stm32f103xb.cmake;/home/calle/git/PH_WIP/cmake/mcu_conf/stm32f401xc.cmake;/home/calle/git/PH_WIP/cmake/mcu_conf/stm32f411xe.cmake
-- Using /usr/bin/arm-none-eabi-g++ /usr/bin/arm-none-eabi-gcc
-- FPU supported
-- Setting build type to 'RelWithDebInfo' as none was specified.
-- No colored compiler diagnostic set for '' compiler.
-- Using Conf One
-- Black Pill is used
-- Creating target stm32F4_mcu_support_lib
-- Configuring done
-- Generating done
-- Build files have been written to: /home/calle/git/PH_WIP/black_pill_build
Scanning dependencies of target hal
Scanning dependencies of target startup
[  1%] Building CXX object libs/hal/CMakeFiles/hal.dir/src/stm32/hal.cpp.obj
[  2%] Building ASM object src/black_pill/CMakeFiles/startup.dir/Startup/startup_stm32f411retx.s.obj
[  2%] Built target startup
[  3%] Linking CXX static library libhal.a
[  3%] Built target hal
Scanning dependencies of target stm32F4_HAL_support_lib
[  4%] Building C object src/black_pill/CMakeFiles/stm32F4_HAL_support_lib.dir/__/__/external/STM32F4xx_HAL_DRIVER/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c.obj
[  5%] Building C object src/black_pill/CMakeFiles/stm32F4_HAL_support_lib.dir/__/__/external/STM32F4xx_HAL_DRIVER/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c.obj
.
.
.

[ 93%] Building C object src/black_pill/CMakeFiles/stm32F4_HAL_support_lib.dir/__/__/external/STM32F4xx_HAL_DRIVER/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c.obj
[ 93%] Built target stm32F4_HAL_support_lib
Scanning dependencies of target BlackPill
[ 95%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/main.c.obj
[ 95%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/stm32f4xx_it.c.obj
[ 97%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/system_stm32f4xx.c.obj
[ 97%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/sysmem.c.obj
[ 98%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/syscalls.c.obj
[ 99%] Building C object src/black_pill/CMakeFiles/BlackPill.dir/Src/stm32f4xx_hal_msp.c.obj
[100%] Linking C executable BlackPill
[100%] Built target BlackPill

doc/black_pill_configure.gif doc/black_pill_build.gif When the build is finished you should be able to find a working solution in

ls black_pill_build/src/black_pill/BlackPill*
black_pill_build/src/black_pill/BlackPill
black_pill_build/src/black_pill/BlackPill.hex

The same idea is used with the different project (stepper,ph_disco,sml_test).

The sml_test is somewhat different since it depends on sml c++ header file. This can be cloned or downloaded to ${CMAKE_SOURCE_DIR}/external/

Build type

When using cmake its possible to use different build types.

RelWithDebInfo
Release with debug info (-O2 -g -DNDEBUG, to be fixed)
Debug
using debug flags
Release
Using optimization (-O2 for now)
MinSizeRel
Optimize for size (-Os) (Not yet fixed!)

So that leaves us with a command line looking like (building Release):

cmake -DFLAVOR=BLACK_PILL \
      -DMCU_CONFIG=stm32f411xe.cmake \
      -DCMAKE_BUILD_TYPE=Release \
      ..

Here are some tests with different sizes.

ProjectRelWithdebinfoDebugReleaseMinSizeRel
Ph_disco92401369692408328
Black_pill5668809656685332

Using ccmake

ccmake is a tui (terminal user interface) that can be a bit easier to work with, since you can see the actual configurations. Though bare in mind that setting .i.e the MCU_CONFIG and configure, leaves the FLAVOR which means you need to first update the MCU_CONFIG then configure , then update the FLAVOR the configure again. and finally generate, and build. This is hard to explain without some pictures. So here is a configuration/build of the STEPPER (stm32f401).

doc/ccmake_stepper_conf.gif doc/ccmake_stepper_build.gif

Target selection

In this repository there are 3 working stm32 targets.

  • Black_Pill
  • Stepper
  • PH_disco
  • sml_test

each of the target resides under src

tree src -d -L 1
src
├── black_pill
├── include
├── ph_disco
├── sml_test
└── Stepper

5 directories

Config selection

The config is based on different board platforms, for example using different configuration for a certain target. By selecting CONF_ONE the conf_one/config.hpp will be selected and selecting CONF_TWO conf_two/config.hpp will be selected. the tree structure used is:

tree src/include
src/include
├── common
│   └── common.hpp
├── conf_one
│   └── config.hpp
└── conf_two
    └── config.hpp

3 directories, 3 files

there is also a common, which are used by all the targets and has common functionality.

Flashing

using ccmake one can set what kind of adapter to use (e.g cmsis-dap) and the location of the openocd. This can be used to create a flash target for the project.

make_openocd_target(NAME ${TARGET_BIN}
  OPENOCD_PATH ${OPENOCD_PATH}
  OPENOCD_INTERFACE ${OPENOCD_INTERFACE}
  OPENOCD_TARGET stm32f4x
)

Here is an example when using stm32f4 device. See black_pill target

to flash the device there exists a target flash or ocd_flash The first one is using stlink and the other is using openocd

make ocd_flash

debug

Debugging is done through openocd and appopriate adapter (e.g cmsis-dap using picopropbe) after successful build there is a target called debug which will execute openocd, with the appropriate flags.

make debug

or even simpler.

make run_debug

The above command will open a tmux session in the terminal and split it in two, one side is the openocd output, the other starts and initializes a gdb session using the adapter and the device.

This of cource needs to be configured, which is done through cmake. For example the black_pill target is configured as follows

include(${CMAKE_SOURCE_DIR}/cmake/mcu_command_targets.cmake)
make_openocd_target(NAME ${TARGET_BIN}
  OPENOCD_PATH ${OPENOCD_PATH}
  OPENOCD_INTERFACE ${OPENOCD_INTERFACE}
  OPENOCD_TARGET stm32f4x
)

The OPENOCD_TARGET needs to be configured to be the appropriate device which can be found in openocd source directory openocd/tcl/target/

The OPENOCD_PATH where to find the openocd, it is also a cached variable so if you run ccmake this variable can be set. That also includes the OPENOCD_INTERFACE which is the adapter to use (cmsis-dap for example).

Freertos

Freertos is included into the black_pill flavor. More on that later

Add a new Project (from StmCubeIde)

The idea here is to use the good features of StmCubeIde for configuration i.e clock setup and peripherals configuration. So when all is done and you made sure that the project is working. Its time to add it to the project. Lets now consider that the MCU cmake file (see MCU_CONFIG) is existing so we are using a already known MCU. The first thing to do is to copy everything from the STMCubeIDE project core directory to PH_WIP/src/<prj>

Here is an example

#Create a new project directory
mkdir ${HOME}/PH_WIP/src/MyPrj
# Copy all existing StmCubeIde file under Core
cp -r ${HOME}/STM32CubeIDE/WorkSpace/MyProject/Core \
   ${HOME}/PH_WIP/src/MyPrj

# Copy an existing cmake file from a project with the same MCU
cp -r ${HOME}/PH_WIP/src/Stepper/CMakeLists.txt ${HOME}/PH_WIP/src/MyPrj

#Edit the file by setting a new target name..
sed -i 's/Stepper/MyPrj/g' ${HOME}/PH_WIP/src/MyPrj/CMakeLists.txt

# Now we need to edit the MCU_CONF file to add our project, that should tie the MyPrj
# to stm32f401 as a Flavor (see ccmake)
sed -i -e '/set_property/s/STEPPER/STEPPER MyPrj/' cmake/mcu_conf/stm32f401xc.cmake

You also need to add the project to the src/CMakeLists.txt as an elseif statement.

elseif( FLAVOR STREQUAL "MyProj")
add_subdirectory(MyPrj)

There are however some things that probably needs to be changed . for example the Src directory in your new project might consists of other files that needs to be compiled, and since you copied the CMakeLists.txt you need to do some minor adjustment for example the source files and project name. These files needs to be added to the SRC in the CMakeLists.txt in you new project, and don’t forget to change the executable name.

set(TARGET_BIN "sml_test")

add_executable(${TARGET_BIN} ${SRC})

set(SRC
  Src/main.c
  .
  .
  .
  Src/syscalls.c
  Src/sysmem.c
  Src/<new files.(c|cpp)
  )

The new project also needs a memory map script ( if you not already using an existing). these are located in libs/conf/mem. When using StmCubeIde these files are located in the root direcotry of your project.

ls libs/conf/mem
STM32F103T8UX_FLASH.ld
STM32F401CCUX_FLASH.ld
STM32F411RETX_FLASH.ld

If you are adding a new one, the mcu config file needs to be changed. In other words the one of the files located in cmake/mcu_conf/.cmake There you will find a line consisting of: set(MCU_MEMORY_LAYOUT_FILES "STM32F401CCUX_FLASH.ld") for example:

sed -i 's|STM32F401CCUX_FLASH.ld|my_linker_script_name.ld|g' cmake/mcu_conf/stm32f401xc.cmake

Adding a new MCU

Tests

Unit test are compiled using ExternalProject_add and is built nativly. To make it even simpler conan is used (both conan1 and conan2 is supported).

About

Use cmake with your stm32 project.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published