tags: F' FS Flight software

F' FreeRTOS Port

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

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
set(PLATFORM FreeRTOSSim)
  • TGT_OS_TYPE_FREERTOS_SIM compiler definition
    Used in code for platform specific implementation. Defined in FreeRTOSSim.cmake
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
# set(CMAKE_TOOLCHAIN_FILE /path/to/risc-v/cmake/toolchain)

Files added

platform/FreeRTOSSim.cmake

Custom CMake platform file for FreeRTOS inclusions.

Called by platform/CMakeLists.txt depending on PLATFORM CMake variable

Fw/Types/FreeRTOSSim/StandardTypes.hpp

Custom types definition, in our case include stdint.h. Called in platform/FreeRTOSSim.cmake

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

Files modified

OS/CMakeLists.txt

Import FreeRTOS OSAL sources

# 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

# 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

# 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

Add class attributes needed in FreeRTOS OSAL Queue.cpp implementation

#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

Define a type for the storage of task IDs

#if defined(TGT_OS_TYPE_VXWORKS) || defined(TGT_OS_TYPE_FREERTOS_SIM) typedef int TaskIdRepr;

Drv/SocketIpDriver/SocketIpDriverComponentImpl.hpp

Use Linux implementation for IP layer

#elif defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN || TGT_OS_TYPE_FREERTOS_SIM #include <arpa/inet.h>

Drv/SocketIpDriver/SocketHelper.cpp

Use Linux implementation for IP Socket Communications

#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

See FreeRTOS customisation

Hook functions

See Hook functions

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