|
@@ -37,7 +37,9 @@ It will compile a project for the `F4` family by default, but you can also compi
|
|
|
# Usage
|
|
# Usage
|
|
|
|
|
|
|
|
First of all you need to configure toolchain and library paths using CMake variables.
|
|
First of all you need to configure toolchain and library paths using CMake variables.
|
|
|
-You can do this by passing values through command line during cmake run or by setting variables inside your `CMakeLists.txt`
|
|
|
|
|
|
|
+You can do this by passing values through command line during cmake run or by setting variables
|
|
|
|
|
+inside your `CMakeLists.txt`. You can also set pass these variables to CMake by setting them
|
|
|
|
|
+as environmental variables.
|
|
|
|
|
|
|
|
## Configuration
|
|
## Configuration
|
|
|
|
|
|
|
@@ -45,17 +47,22 @@ You can do this by passing values through command line during cmake run or by se
|
|
|
* `TARGET_TRIPLET` - toolchain target triplet, **default**: `arm-none-eabi`
|
|
* `TARGET_TRIPLET` - toolchain target triplet, **default**: `arm-none-eabi`
|
|
|
* `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>`
|
|
* `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
|
|
|
|
|
|
|
+## <a id="cmsis"></a> Common usage
|
|
|
|
|
|
|
|
First thing that you need to do after toolchain configuration in your `CMakeLists.txt` script is to find CMSIS package:
|
|
First thing that you need to do after toolchain configuration in your `CMakeLists.txt` script is to find CMSIS package:
|
|
|
```cmake
|
|
```cmake
|
|
|
find_package(CMSIS [CMSIS_version] COMPONENTS STM32F4 REQUIRED)
|
|
find_package(CMSIS [CMSIS_version] 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).
|
|
|
|
|
|
|
+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).
|
|
|
|
|
|
|
|
-[CMSIS_version] is an optional version requirement. See [find_package documentation](https://cmake.org/cmake/help/v3.13/command/find_package.html?highlight=find%20package#id4). This parameter does not make sense if multiple STM32 families are requested.
|
|
|
|
|
|
|
+[CMSIS_version] is an optional version requirement. See
|
|
|
|
|
+[find_package documentation](https://cmake.org/cmake/help/v3.13/command/find_package.html?highlight=find%20package#id4).
|
|
|
|
|
+This parameter does not make sense if multiple STM32 families are requested.
|
|
|
|
|
|
|
|
-Each STM32 device can be categorized into family and device type groups, for example STM32F407VG is device from `F4` family, with type `F407xx`.
|
|
|
|
|
|
|
+Each STM32 device can be categorized into family and device type groups, for example STM32F407VG
|
|
|
|
|
+is device from `F4` family, with type `F407xx`.
|
|
|
|
|
|
|
|
***Note**: Some devices in STM32H7 family have two different cores (Cortex-M7 and Cortex-M4).
|
|
***Note**: Some devices in STM32H7 family have two different cores (Cortex-M7 and Cortex-M4).
|
|
|
For those devices the name used must include the core name e.g STM32H7_M7 and STM32H7_M4.
|
|
For those devices the name used must include the core name e.g STM32H7_M7 and STM32H7_M4.
|
|
@@ -67,7 +74,10 @@ CMSIS consists of three main components:
|
|
|
* Device-specific linker scripts which requires information about memory sizes
|
|
* Device-specific linker scripts which requires information about memory sizes
|
|
|
|
|
|
|
|
stm32-cmake uses modern CMake features notably imported targets and target properties.
|
|
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 propagate them as dependencies. So in a simple use-case all you need is to link your executable with library `CMSIS::STM32::<device>`:
|
|
|
|
|
|
|
+Every CMSIS component is CMake's target (aka library), which defines compiler definitions,
|
|
|
|
|
+compiler flags, include dirs, sources, etc. to build and propagate them as dependencies.
|
|
|
|
|
+So in a simple use-case all you need is to link your executable with library `CMSIS::STM32::<device>`:
|
|
|
|
|
+
|
|
|
```cmake
|
|
```cmake
|
|
|
add_executable(stm32-template main.c)
|
|
add_executable(stm32-template main.c)
|
|
|
target_link_libraries(stm32-template CMSIS::STM32::F407VG)
|
|
target_link_libraries(stm32-template CMSIS::STM32::F407VG)
|
|
@@ -80,22 +90,35 @@ CMSIS creates the following targets:
|
|
|
* `CMSIS::STM32::<TYPE>` (e.g. `CMSIS::STM32::F407xx`) - common startup source for device type, depends on `CMSIS::STM32::<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>`
|
|
* `CMSIS::STM32::<DEVICE>` (e.g. `CMSIS::STM32::F407VG`) - linker script for device, depends on `CMSIS::STM32::<TYPE>`
|
|
|
|
|
|
|
|
-So, if you don't need linker script, you can link only `CMSIS::STM32::<TYPE>` library and provide your own script using `stm32_add_linker_script` function
|
|
|
|
|
|
|
+So, if you don't need the linker script or want to adapt it for your own needs, you can link
|
|
|
|
|
+only `CMSIS::STM32::<TYPE>` library and provide your own script using `stm32_add_linker_script`
|
|
|
|
|
+function
|
|
|
|
|
|
|
|
-***Note**: For H7 family, because of it's multi-core architecture, all H7 targets also have a suffix (::M7 or ::M4).
|
|
|
|
|
-For example, targets created for STM32H747BI will look like `CMSIS::STM32::H7::M7`, `CMSIS::STM32::H7::M4`, `CMSIS::STM32::H747BI::M7`, `CMSIS::STM32::H747BI::M4`, etc.*
|
|
|
|
|
|
|
+***Note**: For H7 family, because of its multi-core architecture, all H7 targets also have a suffix (::M7 or ::M4).
|
|
|
|
|
+For example, targets created for STM32H747BI will look like `CMSIS::STM32::H7::M7`,
|
|
|
|
|
+`CMSIS::STM32::H7::M4`, `CMSIS::STM32::H747BI::M7`, `CMSIS::STM32::H747BI::M4`, etc.*
|
|
|
|
|
|
|
|
-The GCC C/C++ standard libraries are added by linking the library `STM32::NoSys`. This will add the `--specs=nosys.specs` to compiler and linker flags.
|
|
|
|
|
-If you want to use C++ on MCUs with little flash, you might instead want to link the newlib-nano to reduce the code size. You can do so by linking `STM32::Nano`, which will add the `--specs=nano.specs` flags to both compiler and linker.
|
|
|
|
|
-Keep in mind that when using `STM32::Nano`, by default you cannot use floats in printf/scanf calls, and you have to provide implementations for several OS interfacing functions (_sbrk, _close, _fstat, and others).
|
|
|
|
|
|
|
+The GCC C/C++ standard libraries are added by linking the library `STM32::NoSys`. This will add
|
|
|
|
|
+the `--specs=nosys.specs` to compiler and linker flags.
|
|
|
|
|
+If you want to use C++ on MCUs with little flash, you might instead want to link the newlib-nano to
|
|
|
|
|
+reduce the code size. You can do so by linking `STM32::Nano`, which will add the
|
|
|
|
|
+`--specs=nano.specs` flags to both compiler and linker.
|
|
|
|
|
+Keep in mind that when using `STM32::Nano`, by default you cannot use floats in printf/scanf calls,
|
|
|
|
|
+and you have to provide implementations for several OS interfacing
|
|
|
|
|
+functions (`_sbrk`, `_close`, `_fstat`, and others). You can enable printf/scanf floating point
|
|
|
|
|
+support with newlib-nano by linking against `STM32::Nano::FloatPrint` and/or
|
|
|
|
|
+`STM32::Nano::FloatScan`. It is also possible to combine `STM32::Nano` and `STM32::NoSys`
|
|
|
|
|
+to have the benefits of reduced code size while not being forced to implement system calls.
|
|
|
|
|
|
|
|
-## HAL
|
|
|
|
|
|
|
+## <a id="hal"></a> HAL
|
|
|
|
|
|
|
|
STM32 HAL can be used similar to CMSIS.
|
|
STM32 HAL can be used similar to CMSIS.
|
|
|
|
|
+
|
|
|
```cmake
|
|
```cmake
|
|
|
find_package(HAL [HAL_version] COMPONENTS STM32F4 REQUIRED)
|
|
find_package(HAL [HAL_version] COMPONENTS STM32F4 REQUIRED)
|
|
|
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
|
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.*
|
|
*`CMAKE_INCLUDE_CURRENT_DIR` here because HAL requires `stm32<family>xx_hal_conf.h` file being in include headers path.*
|
|
|
|
|
|
|
|
[HAL_version] is an optional version requirement. See [find_package documentation](https://cmake.org/cmake/help/v3.13/command/find_package.html?highlight=find%20package#id4). This parameter does not make sense if multiple STM32 families are requested.
|
|
[HAL_version] is an optional version requirement. See [find_package documentation](https://cmake.org/cmake/help/v3.13/command/find_package.html?highlight=find%20package#id4). This parameter does not make sense if multiple STM32 families are requested.
|
|
@@ -109,11 +132,11 @@ HAL module will search all drivers supported by family and create the following
|
|
|
|
|
|
|
|
***Note**: Targets for STM32H7 will look like `HAL::STM32::<FAMILY>::[M7|M4]`, `HAL::STM32::<FAMILY>::[M7|M4]::<DRIVER>`, etc.*
|
|
***Note**: Targets for STM32H7 will look like `HAL::STM32::<FAMILY>::[M7|M4]`, `HAL::STM32::<FAMILY>::[M7|M4]::<DRIVER>`, etc.*
|
|
|
|
|
|
|
|
-Here is typical usage:
|
|
|
|
|
|
|
+Here is typical usage for a F4 device:
|
|
|
|
|
|
|
|
```cmake
|
|
```cmake
|
|
|
-add_executable(stm32-blinky-f4 blinky.c stm32f4xx_hal_conf.h)
|
|
|
|
|
-target_link_libraries(stm32-blinky-f4
|
|
|
|
|
|
|
+add_executable(${TARGET_NAME} blinky.c stm32f4xx_hal_conf.h)
|
|
|
|
|
+target_link_libraries(${TARGET_NAME}
|
|
|
HAL::STM32::F4::RCC
|
|
HAL::STM32::F4::RCC
|
|
|
HAL::STM32::F4::GPIO
|
|
HAL::STM32::F4::GPIO
|
|
|
HAL::STM32::F4::CORTEX
|
|
HAL::STM32::F4::CORTEX
|
|
@@ -122,16 +145,33 @@ target_link_libraries(stm32-blinky-f4
|
|
|
)
|
|
)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### Building
|
|
|
|
|
|
|
+Here is another usage for a H7 device with the M7 core:
|
|
|
|
|
|
|
|
|
|
+```cmake
|
|
|
|
|
+target_link_libraries(${TARGET_NAME} PRIVATE
|
|
|
|
|
+ HAL::STM32::H7::M7::RCC
|
|
|
|
|
+ HAL::STM32::H7::M7::GPIO
|
|
|
|
|
+ HAL::STM32::H7::M7::CORTEX
|
|
|
|
|
+ CMSIS::STM32::H743ZI::M7
|
|
|
|
|
+ STM32::NoSys
|
|
|
|
|
+)
|
|
|
```
|
|
```
|
|
|
- $ cmake -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug <path_to_sources>
|
|
|
|
|
- $ make
|
|
|
|
|
|
|
+
|
|
|
|
|
+### Building
|
|
|
|
|
+
|
|
|
|
|
+```sh
|
|
|
|
|
+cmake -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug <path_to_sources>
|
|
|
|
|
+cmake --build .
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+You can also ommit the `-DCMAKE_TOOLCHAIN_FILE` argument and use `set (CMAKE_TOOLCHAIN_FILE ...)`
|
|
|
|
|
+in your `CMakeLists.txt` file
|
|
|
|
|
+
|
|
|
## Linker script & variables
|
|
## Linker script & variables
|
|
|
|
|
|
|
|
-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.
|
|
|
|
|
|
|
+CMSIS package will generate linker script for your device automatically (target
|
|
|
|
|
+`CMSIS::STM32::<DEVICE>`). To specify a custom linker script, use the
|
|
|
|
|
+`stm32_add_linker_script` function.
|
|
|
|
|
|
|
|
## Useful CMake functions
|
|
## Useful CMake functions
|
|
|
|
|
|
|
@@ -146,9 +186,14 @@ CMSIS package will generate linker script for your device automatically (target
|
|
|
|
|
|
|
|
stm32-cmake contains additional CMake modules for finding and configuring various libraries and RTOSes used in the embedded world.
|
|
stm32-cmake contains additional CMake modules for finding and configuring various libraries and RTOSes used in the embedded world.
|
|
|
|
|
|
|
|
-## FreeRTOS
|
|
|
|
|
|
|
+## <a id="freertos"></a> FreeRTOS
|
|
|
|
|
|
|
|
-[cmake/FindFreeRTOS](cmake/FindFreeRTOS) - finds FreeRTOS sources in location specified by `FREERTOS_PATH` (*default*: `/opt/FreeRTOS`) variable and format them as `IMPORTED` targets. `FREERTOS_PATH` can be either the path to the whole [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) github repo, or the path to FreeRTOS-Kernel (usually located in the subfolder `FreeRTOS` on a downloaded release)
|
|
|
|
|
|
|
+[cmake/FindFreeRTOS](cmake/FindFreeRTOS.cmake) - finds FreeRTOS sources in location specified by
|
|
|
|
|
+`FREERTOS_PATH` (*default*: `/opt/FreeRTOS`) variable and format them as `IMPORTED` targets.
|
|
|
|
|
+`FREERTOS_PATH` can be either the path to the whole
|
|
|
|
|
+[FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) github repo, or the path to
|
|
|
|
|
+FreeRTOS-Kernel (usually located in the subfolder `FreeRTOS` on a downloaded release).
|
|
|
|
|
+You can supply `FREERTOS_PATH` as an environmental variable as well.
|
|
|
|
|
|
|
|
Typical usage:
|
|
Typical usage:
|
|
|
|
|
|
|
@@ -166,4 +211,3 @@ Other FreeRTOS libraries:
|
|
|
* `FreeRTOS::StreamBuffer` - stream buffer (`stream_buffer.c`)
|
|
* `FreeRTOS::StreamBuffer` - stream buffer (`stream_buffer.c`)
|
|
|
* `FreeRTOS::Timers` - timers (`timers.c`)
|
|
* `FreeRTOS::Timers` - timers (`timers.c`)
|
|
|
* `FreeRTOS::Heap::<N>` - heap implementation (`heap_<N>.c`), `<N>`: [1-5]
|
|
* `FreeRTOS::Heap::<N>` - heap implementation (`heap_<N>.c`), `<N>`: [1-5]
|
|
|
-
|
|
|