|
|
@@ -1,103 +1,119 @@
|
|
|
# About
|
|
|
|
|
|
-This project is used to develop applications for the STM32 - ST's ARM Cortex-Mx MCUs. It uses cmake and GCC, along with newlib (libc), STM32CubeMX or ChibiOS.
|
|
|
+This project is used to develop applications for the STM32 - ST's ARM Cortex-Mx MCUs.
|
|
|
+It uses cmake and GCC, along with newlib (libc), STM32Cube. Supports F0 G0 L0 F1 L1 F2 F3 F4 G4 L4 F7 H7 device families.
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
-* cmake >= 3.0
|
|
|
+* cmake >= 3.8
|
|
|
* GCC toolchain with newlib (optional).
|
|
|
-* STM32CubeMX package for STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7, STM32H7, STM32L0, STM32L1, STM32L4 families.
|
|
|
+* STM32Cube package for appropriate STM32 family.
|
|
|
|
|
|
## Project contains
|
|
|
|
|
|
-* CMake common toolchain file, that configures cmake to use the arm toolchain.
|
|
|
-* CMake toolchain file that can generate a tunable linker script
|
|
|
-* CMake STM32 family-specific toolchain file, that configures family-specific parameters.
|
|
|
-* CMake modules to find and configure CMSIS and STM32HAL components.
|
|
|
-* CMake modules to find and configure ChibiOS components.
|
|
|
-* CMake project template.
|
|
|
+* CMake toolchain file, that configures cmake to use the arm toolchain: [cmake/stm32_gcc.cmake](cmake/stm32_gcc.cmake).
|
|
|
+* CMake module that contains useful functions: [cmake/stm32/common.cmake](cmake/stm32/common.cmake)
|
|
|
+* CMake modules that contains information about each family - RAM/flash sizes, CPU types, device types and device naming (e.g. it can tell that STM32F407VG is F4 family with 1MB flash, 128KB RAM with CMSIS type F407xx)
|
|
|
+* CMake toolchain file that can generate a tunable linker script [cmake/stm32/linker_ld.cmake](cmake/stm32/linker_ld.cmake)
|
|
|
+* CMake module to find and configure CMSIS library [cmake/FindCMSIS.cmake](cmake/FindCMSIS.cmake)
|
|
|
+* CMake module to find and configure STM32 HAL library [cmake/FindHAL.cmake](cmake/FindHAL.cmake)
|
|
|
+* CMake project template and examples [cmake/examples](cmake/examples)
|
|
|
+* Some testing project to check cmake scripts working properly [cmake/tests](cmake/tests)
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
-* `stm32-blinky` - blink LED using timers and PWM.
|
|
|
-* `stm32-newlib` - show date using uart and libc functions from newlib.
|
|
|
-* `stm32-chibios` - blink led using ChibiOS/NIL.
|
|
|
+* `template` ([cmake/examples/template](cmake/examples/template)) - project template, empty source linked compiled with CMSIS.
|
|
|
+* `custom-linker-script` ([cmake/examples/custom-linker-script](cmake/examples/custom-linker-script)) - similiar to `template` but using custom linker script.
|
|
|
+* `blinky` ([cmake/examples/blinky](cmake/examples/blinky)) - blink led using STM32 HAL library and SysTick.
|
|
|
|
|
|
# Usage
|
|
|
|
|
|
-First of all you need to configure toolchain and libraries, you can do this by editing `gcc_stm32.cmake` or, preferably, by passing it through the command line.
|
|
|
+First of all you need to configure toolchain and library pathes using CMake varibles.
|
|
|
+You can do this by passing values through command line during cmake run or by setting variables inside your CMakeLists.txt
|
|
|
|
|
|
## Configuration
|
|
|
|
|
|
* `TOOLCHAIN_PREFIX` - where toolchain is located, **default**: `/usr`
|
|
|
* `TARGET_TRIPLET` - toolchain target triplet, **default**: `arm-none-eabi`
|
|
|
-* `STM32_CHIP` - STM32 device code, e.g. `STM32F407VG` or `STM32F103VG`
|
|
|
-* `STM32_FAMILY` - STM32 family (F0, F1, F4, etc.) currently, F0, F1, F2, F4, F7, H7, L0, L1 and L4 families are supported. **Note:** If `STM32_CHIP` variable is set, `STM32_FAMILY` is optional.
|
|
|
-* `STM32Cube_DIR` - path to STM32CubeMX directory **default**: `/opt/STM32Cube_FW_F0_V1.4.0 /opt/STM32Cube_FW_F1_V1.1.0 /opt/STM32Cube_FW_F2_V1.1.0 /opt/STM32Cube_FW_F4_V1.6.0`
|
|
|
-
|
|
|
-To use the toolchain, you'll need to copy contents of the `cmake` folder into cmake's modules path, or use the `CMAKE_MODULE_PATH` variable.
|
|
|
+* `STM32_CUBE_<FAMILY>_PATH` - path to STM32Cube directory, where `<FAMILY>` is one of `F0 G0 L0 F1 L1 F2 F3 F4 G4 L4 F7 H7` **default**: `/opt/STM32Cube<FAMILY>`
|
|
|
|
|
|
## Common usage
|
|
|
|
|
|
- cmake -DSTM32_CHIP=<chip> -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug <path_to_source_dir>
|
|
|
+First thing that you need to do after toolchain configration in your `CMakeLists.txt` script is to find CMSIS package:
|
|
|
+```
|
|
|
+find_package(CMSIS COMPONENTS STM32F4 REQUIRED)
|
|
|
+```
|
|
|
+You can specify STM32 family or even specific device (`STM32F407VG`) in `COMPONENTS` or omit `COMPONENTS` totally - in that case stm32-cmake will find ALL sources for ALL families and ALL chips (you'll need ALL STM32Cube packages somewhere).
|
|
|
|
|
|
-Where `<chip>` is the STM32 chip name (e.g. `STM32F100C8`, `STM32F407IG`).
|
|
|
+Each STM32 device can be categorized into family and device type groups, for example STM32F407VG is device from `F4` family, with type `F407xx`
|
|
|
|
|
|
-This command will generate Makefile for project. For a `Release` build, change `CMAKE_BUILD_TYPE`.
|
|
|
+CMSIS consists of three main components:
|
|
|
|
|
|
-The script will try to detect chip parameters automatically from the chip name (type, flash/ram size), or, you can set these directly with these variables:
|
|
|
+* Family-specific headers, e.g. `stm32f4xx.h`
|
|
|
+* Device type-specific startup sources (e.g. `startup_stm32f407xx.s`)
|
|
|
+* Device-specific linker scripts which requires information about memory sizes
|
|
|
|
|
|
-* `STM32_CHIP_TYPE` - family-dependent chip type. Global variable `STM32_CHIP_TYPES` contains list of valid types for current family (e.g `207xG`)
|
|
|
-* `STM32_FLASH_SIZE` - chip flash size (e.g. 64K)
|
|
|
-* `STM32_RAM_SIZE` - chip RAM size (e.g. 4K)
|
|
|
+stm32-cmake uses modern CMake features notably imported targets and target properties.
|
|
|
+Every CMSIS component is CMake's target (aka library), which defines compiler definitions, compiler flags, include dirs, sources, etc. to build and propagates them as dependencies. So in simple use-case all you need is to link your executable with library `CMSIS::STM32::<device>`:
|
|
|
+```
|
|
|
+add_executable(stm32-template main.c)
|
|
|
+target_link_libraries(stm32-template CMSIS::STM32::F407VG)
|
|
|
+```
|
|
|
+That will add include directories, startup source, linker script and compiler flags to your executable.
|
|
|
|
|
|
-### Usage with Eclipse CDT:
|
|
|
+CMSIS creates following targets:
|
|
|
|
|
|
- cmake -DSTM32_CHIP=<chip> -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug -G "Eclipse CDT4 - Unix Makefiles" <path_to_source_dir>
|
|
|
+* `CMSIS::STM32::<FAMILY>` (e.g. `CMSIS::STM32::F4`) - common includes, compiler flags and defines for family
|
|
|
+* `CMSIS::STM32::<TYPE>` (e.g. `CMSIS::STM32::F407xx`) - common startup source for device type, depends on `CMSIS::STM32::<FAMILY>`
|
|
|
+* `CMSIS::STM32::<DEVICE>` (e.g. `CMSIS::STM32::F407VG`) - linker script for device, depends on `CMSIS::STM32::<TYPE>`
|
|
|
|
|
|
-## Building
|
|
|
+So, if you don't need linker script, you can link only `CMSIS::STM32::<TYPE>` library and provide own script using `stm32_add_linker_script` function
|
|
|
|
|
|
-* To build elf file: `make`
|
|
|
-* To build .hex: `make <project name>.hex`
|
|
|
-* To build .bin: `make <project name>.bin`
|
|
|
+Also, there is special library `STM32::NoSys` which adds `--specs=nosys.specs` to compiler flags.
|
|
|
|
|
|
-## Linker script & variables
|
|
|
+## HAL
|
|
|
|
|
|
-You can use cmake variables below to tune the generated linker. To specify a custom linker script, set `STM32_LINKER_SCRIPT` (you can still use these variables in your custom script).
|
|
|
+STM32 HAL can be used similiar to CMSIS.
|
|
|
+```
|
|
|
+find_package(HAL COMPONENTS STM32F4 REQUIRED)
|
|
|
+set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
|
|
+```
|
|
|
+*`CMAKE_INCLUDE_CURRENT_DIR` here because HAL requires `stm32<family>xx_hal_conf.h` file being in include headers path.*
|
|
|
|
|
|
-* `STM32_FLASH_ORIGIN` - Start address of flash (**default**: 0x08000000)
|
|
|
-* `STM32_RAM_ORIGIN` - Start address of RAM (**default**: 0x20000000)
|
|
|
-* `STM32_FLASH_SIZE` - Flash size (**default**: from chip name)
|
|
|
-* `STM32_RAM_SIZE` - RAM size (**default**: from chip name)
|
|
|
-* `STM32_MIN_STACK_SIZE` - Minimum stack size for error detection at link-time (**default**: 512 bytes)
|
|
|
-* `STM32_MIN_HEAP_SIZE` - Minimum heap size for error detection at link-time (**default**: 0 bytes)
|
|
|
-* `STM32_CCRAM_ORIGIN` - Start address of Core-Coupled RAM (**default**: 0x10000000)
|
|
|
-* `STM32_CCRAM_SIZE` - Core-Coupled RAM size (**default**: 64 KiB)
|
|
|
+HAL module will search all drivers supported by family and create following targets:
|
|
|
|
|
|
-## Useful cmake macros
|
|
|
+* `HAL::STM32::<FAMILY>` (e.g. `HAL::STM32::F4`) - common HAL source, depends on `CMSIS::STM32::<FAMILY>`
|
|
|
+* `HAL::STM32::<FAMILY>::<DRIVER>` (e.g. `HAL::STM32::F4::GPIO`) - HAL driver <DRIVER>, depends on `HAL::STM32::<FAMILY>`
|
|
|
+* `HAL::STM32::<FAMILY>::<DRIVER>Ex` (e.g. `HAL::STM32::F4::ADCEx`) - HAL Extension driver , depends on `HAL::STM32::<FAMILY>::<DRIVER>`
|
|
|
+* `HAL::STM32::<FAMILY>::LL_<DRIVER>` (e.g. `HAL::STM32::F4::LL_ADC`) - HAL LL (Low-Level) driver , depends on `HAL::STM32::<FAMILY>`
|
|
|
|
|
|
-* `STM32_GET_CHIP_TYPE(CHIP CHIP_TYPE)` - gets chip type from chip name.
|
|
|
-* `STM32_GET_CHIP_PARAMETERS(CHIP FLASH_SIZE RAM_SIZE CCRAM_SIZE)` - gets chip ram/flash size from chip name.
|
|
|
-* `STM32_SET_FLASH_PARAMS(TARGET ...)` - sets chip flash/ram parameters for target.
|
|
|
-* `STM32_SET_CHIP_DEFINITIONS(TARGET CHIP_TYPE)` - sets chip family and type-specific compiler flags for target.
|
|
|
-* `STM32_SET_TARGET_PROPERTIES(TARGET)` - sets all needed parameters and compiler flags for target.
|
|
|
-* `STM32_GENERATE_LIBRARIES(NAME SOURCES LIBRARIES)` - generates libraries for all chip types in family. Resulting libraries stored in LIBRARIES and have names in ${NAME}_${FAMILY}_${CHIP_TYPE} format.
|
|
|
+Here is typical usage:
|
|
|
|
|
|
-# ChibiOS Support
|
|
|
+```
|
|
|
+add_executable(stm32-blinky-f4 blinky.c stm32f4xx_hal_conf.h)
|
|
|
+target_link_libraries(stm32-blinky-f4
|
|
|
+ HAL::STM32::F4::RCC
|
|
|
+ HAL::STM32::F4::GPIO
|
|
|
+ HAL::STM32::F4::CORTEX
|
|
|
+ CMSIS::STM32::F407VG
|
|
|
+ STM32::NoSys
|
|
|
+)
|
|
|
+```
|
|
|
|
|
|
-This project also supports ChibiOS v3.x.x and ChibiOS v16.x.x (both nil and rt kernels).
|
|
|
+### Building
|
|
|
|
|
|
-CMake modules for ChibiOS can find specified ChibiOS components using the COMPONENTS directive.
|
|
|
+```
|
|
|
+ $ cmake -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug <path_to_sources>
|
|
|
+ $ make
|
|
|
+```
|
|
|
|
|
|
-See project `stm32-chibios` for example usage.
|
|
|
+## Linker script & variables
|
|
|
|
|
|
-# FreeRTOS Support
|
|
|
+CMSIS package will generate linker script for your device automatically (target `CMSIS::STM32::<DEVICE>`). To specify a custom linker script, use `stm32_add_linker_script` function.
|
|
|
|
|
|
-FreeRTOS is also supported. To include it in your project you should set a variable named `FREERTOS_HEAP_IMPL` with
|
|
|
-a proper number of FreeRTOS heap implementation. You can do this by invoking:
|
|
|
+## Useful cmake function
|
|
|
|
|
|
-```
|
|
|
-SET(FREERTOS_HEAP_IMPL 4)
|
|
|
-```
|
|
|
+* `stm32_get_chip_info(CHIP FAMILY TYPE DEVICE)` - classify device using name, will return device family, type and canonical name (uppercase without any package codes)
|
|
|
+* `stm32_get_memory_info(FAMILY DEVICE FLASH_SIZE RAM_SIZE CCRAM_SIZE STACK_SIZE HEAP_SIZE FLASH_ORIGIN RAM_ORIGIN CCRAM_ORIGIN)` - get information about device memories. Linker script generator uses values from this function
|
|
|
+* `stm32_get_devices_by_family(FAMILY DEVICES)` - return into `DEVICES` all supported devices by family
|
|
|
|
|
|
-before `FIND_PACKAGE` command.
|