FreeRTOS as a CMake interface library

I’m wondering if it is worth redesigning the way FreeRTOS is being consumed by CMake projects. Currently, I’m only allowed to have a single configuration for the entire project. I have to specify the config library, port, and memory management strategy before I even call add_subdirectory() in CMake. If I have a multi-target project ( various targets with different cores ) and I want them to use the same RTOS files, my only option is to reconfigure the entire project for each case… Wouldn’t it be a much more “elastic” approach if the kernel, (each)port, and memory management files were simply interface libraries so each of CMake targets will only have to link the libraries they need, and each target will define its own compile options? Are there any constraints to that?

For example, I will be able to do something like this:

add_subdirectory(freertos)
target_link_libraries(MY_CM0_target PRIVATE freertos_kernel freertos_CM0_Port freertos_HEAP4 freertos_config_for_CM0_target )
target_link_libraries(MY_CM4_target PRIVATE freertos_kernel freertos_CM4_Port freertos_HEAP2 freertos_config_for_CM4_target)
etc...

Hi @eMKa94,
IMHO, the idea should work but your proposal may not work as your expectation. To build FreeRTOS files as library, you have to provide several customized files, such as port, config files, etc. Those customized files make it not possible to build single library for different targets. Instead, you still need to have multiple freertos libraries for different targets to include different customized files.

Thank you.

For example:

set( FREERTOS_KERNEL_COMMON_SOURCES
    # common source files )
set( FREERTOS_KERNEL_COMMON_INCLUDE_PATH
    # common include path )

# CM0
add_library( freertos_kernel_CM0 )
target_sources( freertos_kernel_CM0
    ${FREERTOS_KERNEL_COMMON_SOURCES}
    # other files, like memory management, port files, FreeRTOS config file )
target_include_directories( freertos_kernel_CM0
    ${FREERTOS_KERNEL_COMMON_INCLUDE_PATH}
    # other include paths
)

target_link_libraries(MY_CM0_target PRIVATE freertos_kernel_CM0 )

# CM4
add_library( freertos_kernel_CM4 )
target_sources( freertos_kernel_CM4
    ${FREERTOS_KERNEL_COMMON_SOURCES}
    # other files, like memory management, port files, FreeRTOS config file )
target_include_directories( freertos_kernel_CM4
    ${FREERTOS_KERNEL_COMMON_INCLUDE_PATH}
    # other include paths
)

target_link_libraries(MY_CM4_target PRIVATE freertos_kernel_CM4 )

@ActoryOu

I mannaged to do it the way i wanted.

I’m aware that i need multiple instances. The problem i wanted to solve is that with default CMake for FreeRTOS the configuration for particular port / heap is based on CMake variables which needs to be set before call to add_subdirectory(FreeRTOS). And also OBJECT library is being created so it is compiled once per configuration. In such case I cannot compile FreeRTOS sources for multiple targets in single CMake build process. I have to reconfigure whole project and build all code again for each target…

I’ve changed library type to INTERFACE for the kernel, and create a small ones for port, and heap libraries so they are not being compiled as separated libraries but become sources of target that consumes them as libraries.

target_sources(freertos_kernel INTERFACE
    croutine.c
    event_groups.c
    list.c
    queue.c
    stream_buffer.c
    tasks.c
    timers.c
)
add_library(freertos_kernel_mem_heap4 INTERFACE)
target_sources(freertos_kernel_mem_heap4 INTERFACE MemMang/heap_4.c)

add_library(freertos_kernel_port_CM0 INTERFACE)
target_sources(freertos_kernel_port_CM0 INTERFACE GCC/ARM_CM0/port.c GCC/ARM_CM0/portasm.c GCC/ARM_CM0/mpu_wrappers_v2_asm.c)
target_include_directories(freertos_kernel_port_CM0 INTERFACE ${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM0)

And now, when creating actual targets they can consume the set they need, for example:

target_link_libraries(CM0_based_target PRIVATE
freertos_kernel
freertos_kernel_port_CM0
freertos_kernel_mem_heap4
)

target_link_libraries(CM4_based_target PRIVATE
freertos_kernel
freertos_kernel_port_CM4
freertos_kernel_mem_heap2
)

As U can see now each my target is able to pick the correct heap / port sources and provide specific set of compile options. IMO much better usage then the original one.

1 Like

Hi @eMKa94,
Actually I like the idea. I’ll bring it up with team internally and get back to you with our decision.

Thank you for bringing this to us!