###### tags: `F'` `FS` `Flight software`
# F' FreeRTOS Port
[ToC]
## FreeRTOS CMake implementation
The first step is to adapt FreeRTOS compilation with CMake instead of Make in order to include it into F' CMake compilation process.
π‘ See [Freertos-CMake repository](https://github.com/jonathanmichel/FreeRTOS-CMake)
## CMake call tree
```
App/CMakeLists.txt π‘ Entry point, custom app topology
β Fprime.cmake
β β Options.cmake
β β platform/CmakeLists.txt π‘ Set `PLATFORM` if not defined (Linux or arm-linux-gnueabihf)
β β β[PLATFORM].cmake
β β Validation.cmake
β β Executable.cmake
β β β Module.cmake
β β β Utils.cmake π‘ get_nearest_build_root(), get_module_name(), ...
β β β AC_Utils.cmake π‘ acwrap()
β β src/CMakeLists.txt π‘ empty.c
β β parser/CmakeLists.txt π‘ Add parsers as build system dependencies
β β (Module.cmake) (Utils.cmake) π‘ Called again ?
β β Unit_Test.cmake π‘ Unit test functions
β β Target.cmake π‘ Function for F' targets addition
β β API-cmake π‘ API of the F' CMake system
β β register_fprime_target
β β dict.cmake π‘ dictgen(), add_global_target()
β β testimpl.cmake π‘ dictgen(), add_global_target()
β β package_gen.cmake π‘ dictgen(), add_global_target()
β β coverage.cmake π‘dictgen(), add_global_target()
β β include lib π‘ dictgen(), add_global_target()
β FPrime_code.cmake π‘ Include Autocoder, Fw, OS, Svc, Drv, CFDP, Utils
```
## Custom variables and definitions
- `PLATFORM` CMake variable
Used in CMakeFiles for platform specific inclusions. Set in [Options.cmake](https://github.com/CHESS-mission/fprime/blob/chess-freertos/cmake/Options.cmake)
```cpp=105
set(PLATFORM FreeRTOSSim)
```
- `TGT_OS_TYPE_FREERTOS_SIM` compiler definition
Used in code for platform specific implementation. Defined in [FreeRTOSSim.cmake](https://github.com/CHESS-mission/fprime/blob/chess-freertos/cmake/platform/FreeRTOSSim.cmake)
```cpp=4
add_definitions(-DTGT_OS_TYPE_FREERTOS_SIM)
```
* **[unused]** `CMAKE_TOOLCHAIN_FILE` CMake variable
Used in CMakeFiles to link RISC-V toolchain. Set in [Options.cmake](https://github.com/CHESS-mission/fprime/blob/chess-freertos/cmake/Options.cmake)
```cpp=95
# set(CMAKE_TOOLCHAIN_FILE /path/to/risc-v/cmake/toolchain)
```
## Files added
### [platform/FreeRTOSSim.cmake](https://github.com/CHESS-mission/fprime/blob/chess-freertos/cmake/platform/FreeRTOSSim.cmake)
Custom CMake platform file for FreeRTOS inclusions.
Called by [platform/CMakeLists.txt](https://github.com/CHESS-mission/fprime/blob/d3e4c82f5b7bc989fae49e43c77b38f1bc976e52/cmake/platform/CMakeLists.txt#L34) depending on `PLATFORM ` CMake variable
### [Fw/Types/FreeRTOSSim/StandardTypes.hpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Fw/Types/FreeRTOSSim/StandardTypes.hpp)
Custom types definition, in our case include `stdint.h`. Called in [platform/FreeRTOSSim.cmake](https://github.com/CHESS-mission/fprime/blob/chess-freertos/cmake/platform/FreeRTOSSim.cmake)
### [OS/FreeRTOSSim/](https://github.com/CHESS-mission/fprime/tree/chess-freertos/Os/FreeRTOSSim)
OSAL implementation with FreeRTOS
- assert.c
- File.cpp *- Not implemented*
- FileSystem.cpp *- Not implemented*
- InterruptLock.cpp
- IntervalTimer.cpp
- Mutex.cpp
- Queue.cpp
- Task.cpp
- WatchdogTimer.cpp
- FreeRTOSConfig.h - *FreeRTOS project config file, see [here](#FreeRTOSConfigh)*
## Files modified
### [OS/CMakeLists.txt](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Os/CMakeLists.txt)
Import FreeRTOS OSAL sources
```cmake=39
# FreeRTOS OSAL implementation
if(${PLATFORM} STREQUAL "FreeRTOSSim")
list(APPEND SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/assert.c"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/File.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/FileSystem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/InterruptLock.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/IntervalTimer.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/Mutex.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/Queue.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/Task.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/TaskId.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FreeRTOSSim/WatchdogTimer.cpp"
"${CMAKE_CURRENT_LIST_DIR}/LogPrintf.cpp"
)
elseif(FPRIME_USE_POSIX) # Posix systems typically share these
[...]
```
Avoid including Linux IPC and Lockless queue implementation
```cpp=73
# Darwin IPC queue implementation
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
list(APPEND SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/MacOs/IPCQueueStub.cpp"
)
elseif(${PLATFORM} STREQUAL "FreeRTOSSim") # avoid next condition entry
message("FreeRTOSSim Queue implementation")
# FreeRTOS Queue implementation include above
# Linux IPC queues implementation
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "arm-linux-gnueabihf")
list(APPEND SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/Posix/IPCQueue.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Posix/LocklessQueue.cpp"
)
# Shared libraries need an -rt dependency for mq libs
if (BUILD_SHARED_LIBS)
list(APPEND MOD_DEPS "-lrt")
endif()
endif()
```
Link FreeRTOS library
```cmake=101
# After register_fprime_module()
if(${PLATFORM} STREQUAL "FreeRTOSSim")
# Has to be done after register_fprime_module()
find_library(freertos "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
target_link_libraries(Os freertos) # Add [ 16%] Built target freertos
endif()
```
### [OS/Queue.hpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Os/Queue.hpp)
Add class attributes needed in FreeRTOS OSAL [Queue.cpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Os/FreeRTOSSim/Queue.cpp) implementation
```cpp=71
#if TGT_OS_TYPE_FREERTOS_SIM
NATIVE_INT_TYPE depth; //!< queue name
NATIVE_INT_TYPE msgSize; //!< message size
U8 *msg_buffer; //!< message buffer
#endif
```
### [Os/TaskIdRepr.hpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Os/TaskIdRepr.hpp)
Define a type for the storage of task IDs
```cpp=18
#if defined(TGT_OS_TYPE_VXWORKS) || defined(TGT_OS_TYPE_FREERTOS_SIM)
typedef int TaskIdRepr;
```
### [Drv/SocketIpDriver/SocketIpDriverComponentImpl.hpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Drv/SocketIpDriver/SocketIpDriverComponentImpl.hpp)
Use Linux implementation for IP layer
```cpp=27
#elif defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN || TGT_OS_TYPE_FREERTOS_SIM
#include <arpa/inet.h>
```
### [Drv/SocketIpDriver/SocketHelper.cpp](https://github.com/CHESS-mission/fprime/blob/chess-freertos/Drv/SocketIpDriver/SocketHelper.cpp)
Use Linux implementation for IP Socket Communications
```cpp=32
#elif defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN || TGT_OS_TYPE_FREERTOS_SIM
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
```
## Tests
Adapt `Os/test/ut/OSQueueTest.cpp` and `OS/test/ut/TestMain.cpp`
## [FreeRTOSConfig.h](https://github.com/CHESS-mission/fprime/tree/chess-freertos/Os/FreeRTOSSim/FreeRTOSConfig.h)
See [FreeRTOS customisation](https://www.freertos.org/a00110.html)
### Hook functions
See [Hook functions](https://www.freertos.org/a00016.html)
If define is set to 1, hook function will be called by FreeRTOS and must be provided by the application
| define | Hook function | Goal |
| - | - | - |
| configUSE_IDLE_HOOK | vApplicationIdleHook() | Called on each iteration of the idle task |
| configUSE_TICK_HOOK | vApplicationTickHook() | Called by each tick interrupt |
| configUSE_DAEMON_TASK_STARTUP_HOOK | vApplicationDaemonTaskStartupHook() | Called as soon as the Daemon Task starts executing for the first time |
| configUSE_MALLOC_FAILED_HOOK | vApplicationMallocFailedHook() | Called if a call to pvPortMalloc() fails |
| configCHECK_FOR_STACK_OVERFLOW | vApplicationStackOverflowHook | Called on stack overflow |
### Static allocation
If define is set to 1, application must provide specific functions
|Options| Functions to provide| Goal |
| - | - | - |
| configSUPPORT_STATIC_ALLOCATION | vApplicationGetIdleTaskMemory() | Provide the memory that is used by the Idle task |
| configUSE_TIMERS (with configUSE_STATIC_ALLOCATION == 1)| vApplicationGetTimerTaskMemory() | Provide the memory that is used by the Timer service task |