###### 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 |