Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMSIS RTOS Feature #227

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d74300a
Add support for CMSIS RTOS
g-arjones Apr 16, 2021
28e4de0
Allow choosing FreeRTOS from STM32Cube
g-arjones Apr 16, 2021
a035f82
added doc for CMSIS
robamu Jun 28, 2021
9089819
Merge remote-tracking branch 'upstream/master' into garjones/add_cmsi…
robamu Jun 28, 2021
995eca8
fixed inconsistent indentation
robamu Jun 28, 2021
664bd3f
added line to remove duplicates
robamu Jul 2, 2021
1e6353e
removed line which is not needed after all
robamu Jul 2, 2021
f7f0df7
Merge branch 'garjones/add_cmsis_rtos_support' into feature/rtos
robamu Jul 4, 2021
e16eab7
Merge branch 'garjones/add_support_for_freertos_from_stm32cube' into …
robamu Jul 4, 2021
283261b
completing feature branch
robamu Jul 4, 2021
5b0bd76
README update
robamu Jul 4, 2021
7c47793
added updated example
robamu Jul 4, 2021
9cb4d5a
this is better
robamu Jul 4, 2021
cbc35f5
tiny tweak
robamu Jul 4, 2021
e1ec091
removed section which is not part of PR
robamu Jul 4, 2021
3c5484e
better FreeRTOS section
robamu Jul 4, 2021
07798ed
some fixes in order/structure
robamu Jul 4, 2021
ac679f4
newline removed
robamu Jul 4, 2021
edf1234
updated example explanation
robamu Jul 4, 2021
e78f20e
blinky fix
robamu Jul 4, 2021
9d76f52
Merge remote-tracking branch 'upstream/master' into feature/rtos
robamu Jul 11, 2021
c616752
added ports, added comments
robamu Jul 11, 2021
90c73d7
clarification
robamu Jul 11, 2021
69c26da
more doc
robamu Jul 11, 2021
fcbdfc3
Added CMSIS architectures which are supported
robamu Jul 12, 2021
15ae0bf
Added ARM_CM7_MPU
robamu Jul 12, 2021
aca3a3e
another option to select FreeRTOS
robamu Jul 15, 2021
e8ae4e4
more info printout
robamu Jul 15, 2021
465bed9
updated CMakelists
robamu Jul 15, 2021
faa4337
better output, more checks
robamu Jul 15, 2021
e61e358
minor fix
robamu Jul 15, 2021
ae4ba41
Merge remote-tracking branch 'upstream/master' into feature/rtos
robamu Aug 1, 2021
3f462ec
Update for new stm32_get_devices_by_family call
robamu Aug 1, 2021
b3f97e2
updated .cmake file
robamu Aug 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 71 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,24 @@ It uses cmake and GCC, along with newlib (libc), STM32Cube. Supports F0 F1 F2 F3
* `fetch-cube` ([examples/fetch-cube](examples/fetch-cube)) - example of using FetchContent for fetching STM32Cube from ST's git.
* `fetch-cmsis-hal` ([examples/fetch-cmsis-hal](examples/fetch-cmsis-hal)) - example of using FetchContent for fetching STM32 CMSIS and HAL from ST's git.
* `blinky` ([examples/blinky](examples/blinky)) - blink led using STM32 HAL library and SysTick.
It will compile a project for the `F4` family by default, but you can also compile for the
`L0` and `F1` family by passing `L0_EXAMPLE=ON` or `F1_EXAMPLE=ON` to the CMake generation call.
It will compile a project for the `F4` family by default, but you can also compile for the
`L0` and `F1` family by passing `BLINKY_L0_EXAMPLE=ON` or `BLINKY_F1_EXAMPLE=ON` to the CMake
generation call.
* `freertos` ([examples/freertos](examples/freertos)) - blink led using STM32 HAL library and FreeRTOS.
You need to specify at least one board by passing `FREERTOS_<BOARD>_EXAMPLE=ON` to CMake.
Currently, the example can be built for the `H743ZI` and `F407VG` board targets.
You can opt to use the FreeRTOS CMSIS implementation provided by the Cube repository by supplying
`USE_CMSIS_RTOS=ON` or `USE_CMSIS_RTOS_V2` to CMake.

# Usage

First of all you need to configure toolchain and library paths using CMake variables. There are
generally three ways to do this:

1. Pass the variables through command line during cmake run with passed to CMake with
1. Pass the variables through command line during cmake run with passed to CMake with
`-D<VAR_NAME>=...`
2. Set the variables inside your `CMakeLists.txt`
3. Pass these variables to CMake by setting them as environmental variables.
3. Pass these variables to CMake by setting them as environmental variables.

The most important set of variables which needs to be set can be found in the following section.

Expand Down Expand Up @@ -208,19 +213,72 @@ stm32-cmake contains additional CMake modules for finding and configuring variou
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:
You can either use the FreeRTOS kernel provided in the Cube repositories, or a separate
FreeRTOS kernel. The Cube repository also provides the CMSIS RTOS and CMSIS RTOS V2 implementations.
If you like to use the CMSIS implementations, it is recommended to also use the FreeRTOS sources
provided in the Cube repository because the CMSIS port might be incompatible to newer kernel
versions.

You can specify to use CMSIS with a `CMSIS` target and by finding the CMSIS `RTOS` package.
To select which FreeRTOS to use, you can find the package for a specific FreeRTOS port and then
link against that port target within a specific namespace.

Typical usage for a H7 device when using the M7 core, using an external kernel without CMSIS
support. The FreeRTOS namespace is set to `FreeRTOS` and the `ARM_CM7` port is used:

```cmake
find_package(CMSIS COMPONENTS STM32H743ZI STM32H7_M7 REQUIRED)
find_package(FreeRTOS ARM_CM7 REQUIRED)
target_link_libraries(${TARGET_NAME} PRIVATE
...
FreeRTOS::ARM_CM7
)
```

Typical usage for a F4 device, using an external kernel without CMSIS support.
The FreeRTOS namespace is set to `FreeRTOS` and the `ARM_CM4F` port is used:

```cmake
find_package(FreeRTOS COMPONENTS ARM_CM4F REQUIRED)
target_link_libraries(... FreeRTOS::ARM_CM4F)
target_link_libraries(${TARGET_NAME} PRIVATE
...
FreeRTOS::ARM_CM4F
)
```

Another typical usage using the FreeRTOS provided in the Cube repository and the CMSIS support.
The FreeRTOS namespace is set to `FreeRTOS::STM32::<FAMILY>` and the `ARM_CM7` port is used:

```cmake
find_package(CMSIS COMPONENTS STM32H743ZI STM32H7_M7 RTOS REQUIRED)
find_package(FreeRTOS COMPONENTS ARM_CM7 STM32H7 REQUIRED)
target_link_libraries(${TARGET_NAME} PRIVATE
...
FreeRTOS::STM32::H7::M7::ARM_CM7
CMSIS::STM32::H7::M7::RTOS
)
```

The following FreeRTOS ports are supported: `ARM_CM0`, `ARM_CM3`, `ARM_CM4F`, `ARM_CM7`.
The following CMSIS targets are available in general:

* `CMSIS::STM32::<Family>::RTOS`
* `CMSIS::STM32::<Family>::RTOS_V2`

The following additional FreeRTOS targets are available in general to use the FreeRTOS provided
in the Cube repository

* `FreeRTOS::STM32::<Family>`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a cube path is provided this should be populated and usable but it is not the case from my tests.
Maybe FREERTOS_PATH should not be mandatory when a STM32_CUBE_<FAMILY>_PATH is provided?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you added the STM32<Family> to the FreeRTOS components? This is necessary to use the target inside the namespace I think

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I have not. And it was not enough to solve the issue.
But this did:

#if(USE_CMSIS_RTOS OR USE_CMSIS_RTOS_V2)
        list(APPEND FREERTOS_COMP_LIST STM32H7)
        set(FREERTOS_H7_NAMESPACE ${FREERTOS_NAMESPACE}::STM32::H7::M7)
#else()
#    set(FREERTOS_H7_NAMESPACE ${FREERTOS_NAMESPACE})
#endif()

You are more expert that I am. Does the example need update ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah was that the example? That is weird, FREERTOS_PATH should not be necessary.. What was the build generation command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tested it. I loaded the STM32_CUBE_H7_PATH by setting it as an environment with
export STM32_CUBE_H7_PATH=<pathToCube> and the toolchain with export STM32_TOOLCHAIN_PATH=<pathToToolchain>

I the ran the following command inside example/freertos/build:

cmake -DUSE_CMSIS_RTOS=ON -DFREERTOS_H743ZI_EXAMPLE=ON -DSTM32_TOOLCHAIN_PATH=$STM32_TOOLCHAIN_PATH ..

For CMSIS V2 I ran

cmake -DUSE_CMSIS_RTOS_V2=ON -DFREERTOS_H743ZI_EXAMPLE=ON -DSTM32_TOOLCHAIN_PATH=$STM32_TOOLCHAIN_PATH ..

Copy link
Contributor Author

@robamu robamu Jul 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, if neither USE_CMSIS_RTOS nor USE_CMSIS_RTOS_V2 is specified the example could theoretically use both external kernel or STM32H7 kernel. But then what is taken as the default choice? Maybe introduce another option for that? For CMSIS, it is recommended to take the Cube kernel, so I just hardcoded it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I updated it. It should work for your case now as well. There is an option to specify whether the Cube FreeRTOS or an external kernel is picked.


For the multi-core architectures, you have to specify both family and core like specified in the
example above.

The following FreeRTOS ports are supported in general: `ARM_CM0`, `ARM_CM3`, `ARM_CM4F`, `ARM_CM7`,
`ARM_CM3_MPU`, `ARM_CM4_MPU`, `ARM_CM7_MPU`.

Other FreeRTOS libraries:
Other FreeRTOS libraries, with `FREERTOS_NAMESPACE` being set as specified in the examples above:

* `FreeRTOS::Coroutine` - co-routines (`croutines.c`)
* `FreeRTOS::EventGroups` - event groups (`event_groups.c`)
* `FreeRTOS::StreamBuffer` - stream buffer (`stream_buffer.c`)
* `FreeRTOS::Timers` - timers (`timers.c`)
* `FreeRTOS::Heap::<N>` - heap implementation (`heap_<N>.c`), `<N>`: [1-5]
* `${FREERTOS_NAMESPACE}::Coroutine` - co-routines (`croutines.c`)
* `${FREERTOS_NAMESPACE}::EventGroups` - event groups (`event_groups.c`)
* `${FREERTOS_NAMESPACE}::StreamBuffer` - stream buffer (`stream_buffer.c`)
* `${FREERTOS_NAMESPACE}::Timers` - timers (`timers.c`)
* `${FREERTOS_NAMESPACE}::Heap::<N>` - heap implementation (`heap_<N>.c`), `<N>`: [1-5]
71 changes: 70 additions & 1 deletion cmake/FindCMSIS.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set(CMSIS_RTOS RTOS RTOS_V2)

if(NOT CMSIS_FIND_COMPONENTS)
set(CMSIS_FIND_COMPONENTS ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
endif()
Expand All @@ -7,6 +9,35 @@ if(STM32H7 IN_LIST CMSIS_FIND_COMPONENTS)
endif()
list(REMOVE_DUPLICATES CMSIS_FIND_COMPONENTS)

# This section fills the RTOS or family components list
foreach(COMP ${CMSIS_FIND_COMPONENTS})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not expert so I'm sorry if it's supposed to be trivial for me. But if you find it relevant to beginners and maintainers: please add (relevant) comments into the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added more documentation for all component list filler loops

string(TOLOWER ${COMP} COMP_L)
string(TOUPPER ${COMP} COMP)

# Component is RTOS component
if(${COMP} IN_LIST CMSIS_RTOS)
list(APPEND CMSIS_FIND_COMPONENTS_RTOS ${COMP})
continue()
endif()

# Component is not RTOS component, so check whether it is a family component
string(REGEX MATCH "^STM32([A-Z][0-9])([0-9A-Z][0-9][A-Z][0-9A-Z])?_?(M[47])?.*$" COMP ${COMP})
if(CMAKE_MATCH_1)
list(APPEND CMSIS_FIND_COMPONENTS_FAMILIES ${COMP})
endif()
endforeach()

if(NOT CMSIS_FIND_COMPONENTS_FAMILIES)
set(CMSIS_FIND_COMPONENTS_FAMILIES ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
endif()

if(NOT CMSIS_FIND_COMPONENTS_RTOS)
set(CMSIS_FIND_COMPONENTS_RTOS ${CMSIS_RTOS})
endif()

message(STATUS "Search for CMSIS families: ${CMSIS_FIND_COMPONENTS_FAMILIES}")
message(STATUS "Search for CMSIS RTOS: ${CMSIS_FIND_COMPONENTS_RTOS}")

include(stm32/devices)

function(cmsis_generate_default_linker_script FAMILY DEVICE CORE)
Expand Down Expand Up @@ -41,7 +72,7 @@ function(cmsis_generate_default_linker_script FAMILY DEVICE CORE)
stm32_add_linker_script(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE "${OUTPUT_LD_FILE}")
endfunction()

foreach(COMP ${CMSIS_FIND_COMPONENTS})
foreach(COMP ${CMSIS_FIND_COMPONENTS_FAMILIES})
string(TOLOWER ${COMP} COMP_L)
string(TOUPPER ${COMP} COMP)

Expand Down Expand Up @@ -176,6 +207,44 @@ foreach(COMP ${CMSIS_FIND_COMPONENTS})
else()
set(CMSIS_${COMP}_FOUND FALSE)
endif()

foreach(RTOS_COMP ${CMSIS_FIND_COMPONENTS_RTOS})
if (${RTOS_COMP} STREQUAL "RTOS_V2")
set(RTOS_COMP_VERSION "2")
else()
unset(RTOS_COMP_VERSION)
endif()

find_path(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH
NAMES "cmsis_os${RTOS_COMP_VERSION}.h"
PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
NO_DEFAULT_PATH
)
if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH)
continue()
endif()

find_file(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE
NAMES "cmsis_os${RTOS_COMP_VERSION}.c"
PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
NO_DEFAULT_PATH
)
if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE)
continue()
endif()

if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP}))
add_library(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE IMPORTED)
target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C})
target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
target_sources(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
endif()

list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
set(CMSIS_${RTOS_COMP}_FOUND TRUE)
endforeach()

list(REMOVE_DUPLICATES CMSIS_INCLUDE_DIRS)
list(REMOVE_DUPLICATES CMSIS_SOURCES)
endforeach()
Expand Down
Loading