meier/ReactionWheelHandler #51
13
.gitignore
vendored
13
.gitignore
vendored
@ -2,8 +2,21 @@ _obj
|
|||||||
_bin
|
_bin
|
||||||
_dep
|
_dep
|
||||||
|
|
||||||
|
Debug
|
||||||
|
Debug*
|
||||||
|
Release
|
||||||
|
Release*
|
||||||
|
MinSizeRel
|
||||||
|
MinSizeRel*
|
||||||
|
RelWithDebInfo
|
||||||
|
RelWithDebInfo*
|
||||||
|
|
||||||
.settings
|
.settings
|
||||||
.metadata
|
.metadata
|
||||||
.project
|
.project
|
||||||
.cproject
|
.cproject
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
!misc/eclipse/**/.cproject
|
||||||
|
!misc/eclipse/**/.project
|
||||||
|
/eive_obsw cmake debug/
|
||||||
|
17
.gitmodules
vendored
17
.gitmodules
vendored
@ -1,12 +1,21 @@
|
|||||||
[submodule "etl"]
|
[submodule "etl"]
|
||||||
path = etl
|
path = thirdparty/etl
|
||||||
url = https://github.com/ETLCPP/etl.git
|
url = https://github.com/ETLCPP/etl.git
|
||||||
[submodule "tmtc"]
|
|
||||||
path = tmtc
|
|
||||||
url = https://git.ksat-stuttgart.de/Robin.Mueller/tmtc.git
|
|
||||||
[submodule "arduino"]
|
[submodule "arduino"]
|
||||||
path = arduino
|
path = arduino
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/eive_arduino_interface.git
|
url = https://egit.irs.uni-stuttgart.de/eive/eive_arduino_interface.git
|
||||||
[submodule "fsfw"]
|
[submodule "fsfw"]
|
||||||
path = fsfw
|
path = fsfw
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/fsfw.git
|
url = https://egit.irs.uni-stuttgart.de/eive/fsfw.git
|
||||||
|
[submodule "tmtc"]
|
||||||
|
path = tmtc
|
||||||
|
url = https://egit.irs.uni-stuttgart.de/eive/eive_tmtc.git
|
||||||
|
[submodule "thirdparty/lwgps"]
|
||||||
|
path = thirdparty/lwgps
|
||||||
|
url = https://github.com/rmspacefish/lwgps.git
|
||||||
|
[submodule "fsfw_hal"]
|
||||||
|
path = fsfw_hal
|
||||||
|
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw_hal.git
|
||||||
|
[submodule "generators/modgen"]
|
||||||
|
path = generators/modgen
|
||||||
|
url = https://git.ksat-stuttgart.de/source/modgen.git
|
||||||
|
228
CMakeLists.txt
Normal file
228
CMakeLists.txt
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
################################################################################
|
||||||
|
# CMake support for the EIVE OBSW
|
||||||
|
#
|
||||||
|
# Developed in an effort to replace Make with a modern build system.
|
||||||
|
#
|
||||||
|
# Author: R. Mueller
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Pre-Project preparation
|
||||||
|
################################################################################
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
|
|
||||||
|
set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
option(ADD_ETL_LIB "Add ETL library" ON)
|
||||||
|
if(NOT OS_FSFW)
|
||||||
|
set(OS_FSFW host CACHE STRING "OS for the FSFW.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Perform steps like loading toolchain files where applicable.
|
||||||
|
include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake)
|
||||||
|
pre_project_config()
|
||||||
|
|
||||||
|
# Project Name
|
||||||
|
project(eive_obsw ASM C CXX)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Pre-Sources preparation
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Specify the C++ standard
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
# Set names and variables
|
||||||
|
set(TARGET_NAME ${CMAKE_PROJECT_NAME})
|
||||||
|
set(LIB_FSFW_NAME fsfw)
|
||||||
|
set(LIB_ETL_NAME etl)
|
||||||
|
set(LIB_CSP_NAME libcsp)
|
||||||
|
set(LIB_FSFW_HAL_NAME fsfw_hal)
|
||||||
|
set(LIB_LWGPS_NAME lwgps)
|
||||||
|
set(THIRD_PARTY_FOLDER thirdparty)
|
||||||
|
|
||||||
|
# Set path names
|
||||||
|
set(FSFW_PATH fsfw)
|
||||||
|
set(MISSION_PATH mission)
|
||||||
|
set(TEST_PATH test/testtasks)
|
||||||
|
set(LINUX_PATH linux)
|
||||||
|
set(COMMON_PATH common)
|
||||||
|
|
||||||
|
set(FSFW_HAL_LIB_PATH fsfw_hal)
|
||||||
|
set(CSP_LIB_PATH ${THIRD_PARTY_FOLDER}/libcsp)
|
||||||
|
set(ETL_LIB_PATH ${THIRD_PARTY_FOLDER}/etl)
|
||||||
|
set(LWGPS_LIB_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
||||||
|
|
||||||
|
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
||||||
|
set(ADD_LINUX_FILES TRUE)
|
||||||
|
|
||||||
|
# Analyse different OS and architecture/target options, determine BSP_PATH,
|
||||||
|
# display information about compiler etc.
|
||||||
|
include (${CMAKE_SCRIPT_PATH}/HardwareOsPreConfig.cmake)
|
||||||
|
pre_source_hw_os_config()
|
||||||
|
|
||||||
|
if(TGT_BSP)
|
||||||
|
if(${TGT_BSP} MATCHES "arm/q7s" OR ${TGT_BSP} MATCHES "arm/raspberrypi")
|
||||||
|
set(ROOT_CONFIG_FOLDER TRUE)
|
||||||
|
set(FSFW_CONFIG_PATH "fsfwconfig")
|
||||||
|
set(ADD_LINUX_FILES TRUE)
|
||||||
|
set(ADD_CSP_LIB TRUE)
|
||||||
|
set(FSFW_HAL_ADD_LINUX ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${TGT_BSP} MATCHES "arm/raspberrypi")
|
||||||
|
add_definitions(-DRASPBERRY_PI)
|
||||||
|
set(FSFW_HAL_ADD_RASPBERRY_PI ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${TGT_BSP} MATCHES "arm/q7s")
|
||||||
|
add_definitions(-DXIPHOS_Q7S)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# Required by FSFW library
|
||||||
|
set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig")
|
||||||
|
endif()
|
||||||
|
# Set for lwgps library
|
||||||
|
set(LWGPS_CONFIG_PATH "${COMMON_PATH}/config")
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Executable and Sources
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Add executable
|
||||||
|
add_executable(${TARGET_NAME})
|
||||||
|
|
||||||
|
# Add subdirectories
|
||||||
|
if(ROOT_CONFIG_FOLDER)
|
||||||
|
add_subdirectory(${FSFW_CONFIG_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ADD_CSP_LIB)
|
||||||
|
add_subdirectory(${CSP_LIB_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ADD_ETL_LIB)
|
||||||
|
add_subdirectory(${ETL_LIB_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ADD_LINUX_FILES)
|
||||||
|
add_subdirectory(${LINUX_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(${LWGPS_LIB_PATH})
|
||||||
|
add_subdirectory(${BSP_PATH})
|
||||||
|
add_subdirectory(${FSFW_PATH})
|
||||||
|
add_subdirectory(${MISSION_PATH})
|
||||||
|
add_subdirectory(${TEST_PATH})
|
||||||
|
add_subdirectory(${FSFW_HAL_LIB_PATH})
|
||||||
|
add_subdirectory(${COMMON_PATH})
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Post-Sources preparation
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
set_property(CACHE OS_FSFW PROPERTY STRINGS host linux)
|
||||||
|
|
||||||
|
# Add libraries for all sources.
|
||||||
|
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||||
|
${LIB_FSFW_NAME}
|
||||||
|
${LIB_OS_NAME}
|
||||||
|
${LIB_LWGPS_NAME}
|
||||||
|
${LIB_FSFW_HAL_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ADD_ETL_LIB)
|
||||||
|
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||||
|
${LIB_ETL_NAME}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ADD_CSP_LIB)
|
||||||
|
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||||
|
${LIB_CSP_NAME}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add include paths for all sources.
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${FSFW_CONFIG_PATH}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(WARNING_FLAGS
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wimplicit-fallthrough=1
|
||||||
|
-Wno-unused-parameter
|
||||||
|
-Wno-psabi
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove unused sections.
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE
|
||||||
|
"-ffunction-sections"
|
||||||
|
"-fdata-sections"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Removed unused sections.
|
||||||
|
target_link_options(${TARGET_NAME} PRIVATE
|
||||||
|
"-Wl,--gc-sections"
|
||||||
|
)
|
||||||
|
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
set(COMPILER_FLAGS "/permissive-")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_VERBOSE)
|
||||||
|
message(STATUS "Warning flags: ${WARNING_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# Compile options for all sources.
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE
|
||||||
|
${WARNING_FLAGS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(${CMAKE_CROSSCOMPILING})
|
||||||
|
include (${CMAKE_SCRIPT_PATH}/HardwareOsPostConfig.cmake)
|
||||||
|
post_source_hw_os_config()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_SIZE)
|
||||||
|
set(CMAKE_SIZE size)
|
||||||
|
if(WIN32)
|
||||||
|
set(FILE_SUFFIX ".exe")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TGT_BSP)
|
||||||
|
set(TARGET_STRING "Target BSP: ${TGT_BSP}")
|
||||||
|
else()
|
||||||
|
set(TARGET_STRING "Target BSP: Hosted")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(CONCAT POST_BUILD_COMMENT
|
||||||
|
"Build directory: ${CMAKE_BINARY_DIR}\n"
|
||||||
|
"Target OSAL: ${OS_FSFW}\n"
|
||||||
|
"Target Build Type: ${CMAKE_BUILD_TYPE}\n"
|
||||||
|
"${TARGET_STRING}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX}
|
||||||
|
COMMENT ${POST_BUILD_COMMENT}
|
||||||
|
)
|
||||||
|
|
||||||
|
include (${CMAKE_SCRIPT_PATH}/BuildType.cmake)
|
||||||
|
set_build_type()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
7
Makefile
7
Makefile
@ -13,7 +13,7 @@ SHELL = /bin/sh
|
|||||||
|
|
||||||
# Chip & board used for compilation
|
# Chip & board used for compilation
|
||||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||||
BOARD_FILE_ROOT = bsp_linux
|
BOARD_FILE_ROOT = bsp_q7s
|
||||||
BOARD = linux
|
BOARD = linux
|
||||||
OS_FSFW = linux
|
OS_FSFW = linux
|
||||||
CUSTOM_DEFINES += -D$(OS_FSFW)
|
CUSTOM_DEFINES += -D$(OS_FSFW)
|
||||||
@ -25,6 +25,7 @@ MISSION_PATH = mission
|
|||||||
CONFIG_PATH = fsfwconfig
|
CONFIG_PATH = fsfwconfig
|
||||||
TEST_PATH = test
|
TEST_PATH = test
|
||||||
UNITTEST_PATH = unittest
|
UNITTEST_PATH = unittest
|
||||||
|
LIBCSP_PATH = libcsp
|
||||||
|
|
||||||
# Board specific paths
|
# Board specific paths
|
||||||
BSP_PATH = $(BOARD_FILE_ROOT)
|
BSP_PATH = $(BOARD_FILE_ROOT)
|
||||||
@ -113,7 +114,7 @@ INCLUDES :=
|
|||||||
|
|
||||||
# Directories where $(directoryname).mk files should be included from
|
# Directories where $(directoryname).mk files should be included from
|
||||||
SUBDIRS := $(FRAMEWORK_PATH) $(TEST_PATH) $(BSP_PATH) $(UNITTEST_PATH)\
|
SUBDIRS := $(FRAMEWORK_PATH) $(TEST_PATH) $(BSP_PATH) $(UNITTEST_PATH)\
|
||||||
$(CONFIG_PATH) $(MISSION_PATH)
|
$(CONFIG_PATH) $(MISSION_PATH) $(LIBCSP_PATH)
|
||||||
# INCLUDES += framework/test/catch2
|
# INCLUDES += framework/test/catch2
|
||||||
|
|
||||||
# ETL library include.
|
# ETL library include.
|
||||||
@ -278,7 +279,7 @@ cleanbin:
|
|||||||
-rm -rf $(BUILDPATH)/$(OUTPUT_FOLDER)
|
-rm -rf $(BUILDPATH)/$(OUTPUT_FOLDER)
|
||||||
|
|
||||||
# Build target configuration
|
# Build target configuration
|
||||||
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
|
release: OPTIMIZATION = -O2 $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
|
||||||
release: LINK_TIME_OPTIMIZATION = -flto
|
release: LINK_TIME_OPTIMIZATION = -flto
|
||||||
release: TARGET = Release
|
release: TARGET = Release
|
||||||
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
|
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
|
||||||
|
@ -15,14 +15,14 @@ CUSTOM_DEFINES :=
|
|||||||
|
|
||||||
# Chip & board used for compilation
|
# Chip & board used for compilation
|
||||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||||
BOARD_FILE_ROOT = hosted
|
BOARD_FILE_ROOT = bsp_hosted
|
||||||
BOARD = host
|
BOARD = host
|
||||||
OS_FSFW = host
|
|
||||||
CUSTOM_DEFINES += -D$(OS_FSFW)
|
|
||||||
|
|
||||||
|
DETECTED_OS :=
|
||||||
# Copied from stackoverflow, can be used to differentiate between Windows
|
# Copied from stackoverflow, can be used to differentiate between Windows
|
||||||
# and Linux
|
# and Linux
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
|
DETECTED_OS = WINDOWS
|
||||||
CUSTOM_DEFINES += -DWIN32
|
CUSTOM_DEFINES += -DWIN32
|
||||||
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
|
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
|
||||||
CUSTOM_DEFINES += -DAMD64
|
CUSTOM_DEFINES += -DAMD64
|
||||||
@ -55,6 +55,14 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq (${DETECTED_OS}, WINDOWS)
|
||||||
|
OS_FSFW = host
|
||||||
|
else
|
||||||
|
OS_FSFW = linux
|
||||||
|
endif
|
||||||
|
|
||||||
|
CUSTOM_DEFINES += -D$(OS_FSFW)
|
||||||
|
|
||||||
# General folder paths
|
# General folder paths
|
||||||
FRAMEWORK_PATH = fsfw
|
FRAMEWORK_PATH = fsfw
|
||||||
MISSION_PATH = mission
|
MISSION_PATH = mission
|
||||||
@ -179,10 +187,10 @@ $(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))
|
|||||||
|
|
||||||
# VPATH += mission/pus/
|
# VPATH += mission/pus/
|
||||||
|
|
||||||
ifeq ($(DETECTED_OS), LINUX)
|
#ifeq ($(DETECTED_OS), LINUX)
|
||||||
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
|
#CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
|
||||||
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
|
#CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
|
||||||
endif
|
#endif
|
||||||
|
|
||||||
# All C Sources included by .mk files are assigned here
|
# All C Sources included by .mk files are assigned here
|
||||||
# Add the objects to sources so dependency handling works
|
# Add the objects to sources so dependency handling works
|
||||||
@ -227,7 +235,6 @@ DEAD_CODE_REMOVAL = -Wl,--gc-sections
|
|||||||
# Link time is larger and size of object files can not be retrieved
|
# Link time is larger and size of object files can not be retrieved
|
||||||
# but resulting binary is smaller. Could be used in mission/deployment build
|
# but resulting binary is smaller. Could be used in mission/deployment build
|
||||||
# Requires -ffunction-section in linker call
|
# Requires -ffunction-section in linker call
|
||||||
LINK_TIME_OPTIMIZATION = -flto
|
|
||||||
OPTIMIZATION += $(PROTOTYPE_OPTIMIZATION)
|
OPTIMIZATION += $(PROTOTYPE_OPTIMIZATION)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -261,12 +268,12 @@ ASFLAGS = -Wall -g $(OPTIMIZATION) $(I_INCLUDES) -D__ASSEMBLY__
|
|||||||
# LINK_INCLUDES specify the path to used libraries and the linker script
|
# LINK_INCLUDES specify the path to used libraries and the linker script
|
||||||
# LINK_LIBRARIES link HCC and HAL library and enable float support
|
# LINK_LIBRARIES link HCC and HAL library and enable float support
|
||||||
LDFLAGS := -g3 -pthread $(DEAD_CODE_REMOVAL) $(OPTIMIZATION)
|
LDFLAGS := -g3 -pthread $(DEAD_CODE_REMOVAL) $(OPTIMIZATION)
|
||||||
|
|
||||||
LINK_INCLUDES :=
|
|
||||||
|
|
||||||
LINK_LIBRARIES :=
|
LINK_LIBRARIES :=
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
LINK_LIBRARIES += -lwsock32 -lws2_32
|
LINK_LIBRARIES += -lwsock32 -lws2_32
|
||||||
|
else
|
||||||
|
LINK_LIBRARIES += -lrt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Gnu Coverage Tools Flags
|
# Gnu Coverage Tools Flags
|
||||||
@ -309,7 +316,10 @@ all: executable
|
|||||||
|
|
||||||
# Build target configuration
|
# Build target configuration
|
||||||
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
|
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
|
||||||
|
# Problematic on MinGW
|
||||||
|
ifneq ($(OS),Windows_NT)
|
||||||
release: LINK_TIME_OPTIMIZATION = -flto
|
release: LINK_TIME_OPTIMIZATION = -flto
|
||||||
|
endif
|
||||||
release: TARGET = Release
|
release: TARGET = Release
|
||||||
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
|
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
|
||||||
release: DEBUG_LEVEL = -g0
|
release: DEBUG_LEVEL = -g0
|
||||||
|
553
README.md
553
README.md
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Target systems:
|
Target systems:
|
||||||
|
|
||||||
* OBC
|
* OBC with Linux OS
|
||||||
* Xiphos Q7S
|
* Xiphos Q7S
|
||||||
* Based on Zynq-7020 SoC (xc7z020clg484-2)
|
* Based on Zynq-7020 SoC (xc7z020clg484-2)
|
||||||
* Dual-core ARM Cortex-A9
|
* Dual-core ARM Cortex-A9
|
||||||
@ -12,56 +12,157 @@ Target systems:
|
|||||||
* Artix-7 FPGA (85K pogrammable logic cells)
|
* Artix-7 FPGA (85K pogrammable logic cells)
|
||||||
* Datasheet at https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S&fileid=340648
|
* Datasheet at https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S&fileid=340648
|
||||||
* Also a lot of informatin about the Q7S can be found on the xiphos trac platform: https://trac.xiphos.com/trac/eive-q7/wiki/Q7RevB
|
* Also a lot of informatin about the Q7S can be found on the xiphos trac platform: https://trac.xiphos.com/trac/eive-q7/wiki/Q7RevB
|
||||||
* Linux OS
|
* Linux OS built with Yocto 2.5
|
||||||
* Built with Yocto 2.5
|
|
||||||
* Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git
|
* Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git
|
||||||
* Host System
|
* Host System
|
||||||
* Generic software components which are not dependant on hardware can also
|
* Generic software components which are not dependant on hardware can also
|
||||||
be run. All host code is contained in the hosted folder
|
be run on a host system. All host code is contained in the `bsp_hosted` folder
|
||||||
* Tested for Linux (Ubuntu 20.04) and Windows 10
|
* Tested for Linux (Ubuntu 20.04) and Windows 10
|
||||||
|
* Raspberry Pi
|
||||||
|
* EIVE OBC can be built for Raspberry Pi as well (either directly on Raspberry Pi or by installing a cross compiler)
|
||||||
|
|
||||||
|
The steps in the primary README are related to the main OBC target Q7S.
|
||||||
|
The CMake build system can be used to generate build systems as well (see helper scripts in `cmake/scripts`:
|
||||||
|
|
||||||
|
- Linux (Raspberry Pi): See special section below.
|
||||||
|
- Linux Host: Uses the `bsp_hosted` BSP folder and the CMake Unix Makefiles generator.
|
||||||
|
- Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2.
|
||||||
|
|
||||||
## Setting up development environment
|
## Setting up development environment
|
||||||
|
|
||||||
|
### Installing Vivado the the Xilinx development tools
|
||||||
|
|
||||||
|
It's also possible to perform debugging with a normal Eclipse installation by installing
|
||||||
|
the TCF plugin. Still, it is necessary to install Vivado to get the toolchain for generating
|
||||||
|
C++ applications. Alternatively you can download the toolchain
|
||||||
|
[from the cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S/Toolchain&fileid=422486).
|
||||||
|
|
||||||
* Install Vivado 2018.2 and Xilinx SDK from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html.
|
* Install Vivado 2018.2 and Xilinx SDK from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html.
|
||||||
Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer
|
Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer.
|
||||||
|
|
||||||
* Install settings. In the Devices selection, it is sufficient to pick SoC → Zynq-7000: <br>
|
* Install settings. In the Devices selection, it is sufficient to pick SoC → Zynq-7000: <br>
|
||||||
<img src="./doc/img/xilinx-install.PNG" width="50%"> <br>
|
|
||||||
|
<img src="./doc/img/vivado-edition.png" width="50%"> <br>
|
||||||
|
|
||||||
|
<img src="./doc/img/vivado-hl-design.png" width="50%"> <br>
|
||||||
|
|
||||||
|
<img src="./doc/img/xilinx-install.PNG" width="50%"> <br>
|
||||||
|
|
||||||
* For supported OS refer to https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug973-vivado-release-notes-install-license.pdf
|
* For supported OS refer to https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug973-vivado-release-notes-install-license.pdf
|
||||||
* Add path of linux cross-compiler to environment variables SDK\2018.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin
|
* Add path of linux cross-compiler to permanent environment variables (`.profile` file in Linux):
|
||||||
* Install make (only on windows, SDK on Linux can use the make installed with the SDK)
|
`<XilinxInstallation>\SDK\2018.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin`
|
||||||
|
or set up path each time before debugging.
|
||||||
|
|
||||||
### Installing make on Windows
|
### Installing CMake and MSYS2 on Windows
|
||||||
1. Install NodeJS LTS
|
|
||||||
2. Install xpm
|
|
||||||
|
|
||||||
```sh
|
1. Install [MSYS2](https://www.msys2.org/) and [CMake](https://cmake.org/download/) first.
|
||||||
npm install --global xpm
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Install Windows build tools (after installation also linux commands like mkdir can be used from windows)
|
2. Open the MinGW64 console. It is recommended to set up aliases in `.bashrc` to navigate to the
|
||||||
|
software repository quickly
|
||||||
|
|
||||||
```sh
|
3. Run the following commands in MinGW64
|
||||||
xpm install --global @xpack-dev-tools/windows-build-tools@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building the software
|
```sh
|
||||||
|
pacman -Syuuu
|
||||||
|
```
|
||||||
|
|
||||||
|
It is recommended to install the full base development toolchain
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -S base-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
It is also possible to only install required packages
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-make mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb python3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installing CMake on Linux
|
||||||
|
|
||||||
|
1. Run the following command
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt-get install cmake
|
||||||
|
````
|
||||||
|
|
||||||
|
## Getting the Q7S system root
|
||||||
|
|
||||||
|
It is necessary to copy the Q7S system root to your local development machine for libraries
|
||||||
|
like `libgpio`. You can find the system root [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S/Toolchain&fileid=422486). Download it and unzip it somewhere in the Xilinx installation folder.
|
||||||
|
|
||||||
|
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
|
||||||
|
|
||||||
|
## Building the software with CMake
|
||||||
|
|
||||||
|
When using Windows, run theses steps in MSYS2.
|
||||||
|
|
||||||
1. Clone the repository with
|
1. Clone the repository with
|
||||||
```sh
|
|
||||||
git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git
|
```sh
|
||||||
```
|
git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git
|
||||||
|
```
|
||||||
|
|
||||||
2. Update all the submodules
|
2. Update all the submodules
|
||||||
```sh
|
|
||||||
git submodule init
|
|
||||||
git submodule sync
|
|
||||||
git submodule update
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Open Xilinx SDK 2018.2
|
```sh
|
||||||
4. Import project
|
git submodule init
|
||||||
|
git submodule sync
|
||||||
|
git submodule update
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`.
|
||||||
|
It is recommended to run the shell script `win_path_helper_xilinx_tools.sh` in `cmake/scripts/Q7S`
|
||||||
|
or to set up the [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path)
|
||||||
|
in the `.profile` file.
|
||||||
|
|
||||||
|
4. Run the CMake configuration to create the build system in a `Debug` folder.
|
||||||
|
Navigate into the `eive_obsw` folder first.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd cmake/scripts/Q7S
|
||||||
|
./create_cmake_debug.sh
|
||||||
|
cd ../../..
|
||||||
|
```
|
||||||
|
|
||||||
|
This will invoke a Python script which in turn invokes CMake with the correct
|
||||||
|
arguments to configure CMake for Q7S cross-compilation.
|
||||||
|
|
||||||
|
5. Build the software with
|
||||||
|
```sh
|
||||||
|
cd Debug
|
||||||
|
cmake --build . -j
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setting up default Eclipse for Q7S projects - TCF agent
|
||||||
|
|
||||||
|
The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S.
|
||||||
|
|
||||||
|
1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it.
|
||||||
|
|
||||||
|
2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**.
|
||||||
|
Here, the Q7S should show up if the local port forwarding was set up as explained previously. Please note that you have to connect to `localhost` and port `1534` with port forwaring set up.
|
||||||
|
|
||||||
|
3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. Alternatively:
|
||||||
|
|
||||||
|
- Create a new **TCF Remote Application** by pressing the cogs button at the top or going to Run → Debug Configurations → Remote Application and creating a new one there.
|
||||||
|
|
||||||
|
- Set up the correct image in the main tab (it might be necessary to send the image to the Q7S manually once) and file transfer properties
|
||||||
|
|
||||||
|
- It is also recommended to link the correct Eclipse project.
|
||||||
|
|
||||||
|
After that, comfortable remote debugging should be possible with the Debug button.
|
||||||
|
|
||||||
|
A build configuration and a shell helper script has been provided to set up the path variables and
|
||||||
|
build the Q7S binary on Windows, but a launch configuration needs to be newly created because the
|
||||||
|
IP address and path settings differ from machine to machine.
|
||||||
|
|
||||||
|
## Building in Xilinx SDK 2018.2
|
||||||
|
|
||||||
|
1. Open Xilinx SDK 2018.2
|
||||||
|
2. Import project
|
||||||
* File → Import → C/C++ → Existing Code as Makefile Project
|
* File → Import → C/C++ → Existing Code as Makefile Project
|
||||||
5. Set build command. Replace \<target\> with either debug or release.
|
3. Set build command. Replace \<target\> with either debug or release.
|
||||||
* When on Linux right click project → Properties → C/C++ Build → Set build command to `make <target> -j`
|
* When on Linux right click project → Properties → C/C++ Build → Set build command to `make <target> -j`
|
||||||
* -j causes the compiler to use all available cores
|
* -j causes the compiler to use all available cores
|
||||||
* The target is used to either compile the debug or the optimized release build.
|
* The target is used to either compile the debug or the optimized release build.
|
||||||
@ -70,153 +171,189 @@ git submodule update
|
|||||||
* Target name: all
|
* Target name: all
|
||||||
* Uncheck "Same as the target name"
|
* Uncheck "Same as the target name"
|
||||||
* Uncheck "Use builder settings"
|
* Uncheck "Use builder settings"
|
||||||
* As build command type: `make -j <target> WINDOWS=1`
|
* As build command type: `cmake --build .`
|
||||||
6. Run build command by double clicking the created target or by right clicking
|
* In the Behaviour tab, you can enable build acceleration
|
||||||
|
4. Run build command by double clicking the created target or by right clicking
|
||||||
the project folder and selecting Build Project.
|
the project folder and selecting Build Project.
|
||||||
|
|
||||||
## Debugging the software (when workstation is directly conncected to Q7S)
|
## TCF-Agent
|
||||||
1. Assign static IP address to Q7S
|
|
||||||
* Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user maunal chapter 10.3)
|
|
||||||
* Baudrate 115200
|
|
||||||
* Login to Q7S:
|
|
||||||
* user: root
|
|
||||||
* pw: root
|
|
||||||
* Set IP address and netmask with
|
|
||||||
|
|
||||||
```sh
|
1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask
|
||||||
|
|
||||||
|
```sh
|
||||||
ifconfig eth0 192.168.133.10
|
ifconfig eth0 192.168.133.10
|
||||||
ifconfig eth0 netmask 255.255.255.0
|
ifconfig eth0 netmask 255.255.255.0
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Connect Q7S to workstation via ethernet
|
2. `tcfagent` application should run automatically but this can be checked with
|
||||||
3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S
|
|
||||||
* When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation
|
|
||||||
is 192.168.133.2
|
|
||||||
4. Run tcf-agent on Q7S
|
|
||||||
* Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
|
systemctl status tcfagent
|
||||||
cd org.eclipse.tcf.agent/agent
|
```
|
||||||
make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1
|
|
||||||
```
|
|
||||||
|
|
||||||
* Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S
|
3. If the agent is not running, check whether `agent` is located inside `usr/bin`.
|
||||||
|
You can run it manually there. To perform auto-start on boot, have a look at the start-up
|
||||||
```sh
|
application section.
|
||||||
cd obj/GNU/Linux/arm/Debug
|
|
||||||
scp agent root@192.168.133.10:/tmp
|
|
||||||
```
|
|
||||||
|
|
||||||
* On Q7S
|
|
||||||
```sh
|
|
||||||
cd /tmp
|
|
||||||
chmod +x agent
|
|
||||||
```
|
|
||||||
|
|
||||||
* Run agent
|
|
||||||
```sh
|
|
||||||
./agent
|
|
||||||
```
|
|
||||||
|
|
||||||
5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations
|
|
||||||
6. Right click Xilinx C/C++ applicaton (System Debugger) → New →
|
|
||||||
7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent
|
|
||||||
8. Click New
|
|
||||||
9. Give connection a name
|
|
||||||
10. Set Host to static IP address of Q7S. e.g. 192.168.133.10
|
|
||||||
11. Test connection (This ensures the TCF Agent is running on the Q7S)
|
|
||||||
12. Select Application tab
|
|
||||||
* Project Name: eive_obsw
|
|
||||||
* Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel)
|
|
||||||
* Remote File Path: /tmp/eive_obsw.elf
|
|
||||||
|
|
||||||
## Debugging the software via Flatsat PC
|
## Debugging the software via Flatsat PC
|
||||||
|
|
||||||
Open SSH connection to flatsat PC:
|
Open SSH connection to flatsat PC:
|
||||||
````
|
|
||||||
|
```sh
|
||||||
|
ssh eive@flatsat.eive.absatvirt.lw
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```sh
|
||||||
ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
|
ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
|
||||||
````
|
```
|
||||||
To access the console of the Q7S run the following:
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ssh eive@192.168.199.227
|
||||||
|
```
|
||||||
|
|
||||||
|
If the static IP address of the Q7S has already been set,
|
||||||
|
you can access it with ssh
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ssh root@192.168.133.10
|
||||||
|
```
|
||||||
|
|
||||||
|
If this has not been done yet, you can access the serial
|
||||||
|
console of the Q7S like this to set it
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
picocom -b 115200 /dev/ttyUSB0
|
picocom -b 115200 /dev/ttyUSB0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If the serial port is blocked for some reason, you can kill
|
||||||
|
the process using it with `q7s_kill`.
|
||||||
|
|
||||||
|
You can use `AltGr` + `X` to exit the picocom session.
|
||||||
|
|
||||||
To debug an application, first make sure a static IP address is assigned to the Q7S. Run ifconfig on the Q7S serial console.
|
To debug an application, first make sure a static IP address is assigned to the Q7S. Run ifconfig on the Q7S serial console.
|
||||||
````
|
|
||||||
|
```sh
|
||||||
ifconfig
|
ifconfig
|
||||||
````
|
```
|
||||||
|
|
||||||
Set IP address and netmask with
|
Set IP address and netmask with
|
||||||
````
|
|
||||||
|
```sh
|
||||||
ifconfig eth0 192.168.133.10
|
ifconfig eth0 192.168.133.10
|
||||||
ifconfig eth0 netmask 255.255.255.0
|
ifconfig eth0 netmask 255.255.255.0
|
||||||
````
|
```
|
||||||
To launch application from Xilinx SDK setup port fowarding on the localhost.
|
|
||||||
````
|
To launch application from Xilinx SDK setup port fowarding on the development machine
|
||||||
ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
|
(not on the flatsat!)
|
||||||
````
|
|
||||||
|
```sh
|
||||||
|
ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t bash
|
||||||
|
```
|
||||||
|
|
||||||
This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address 192.168.133.10.
|
This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address 192.168.133.10.
|
||||||
|
This needs to be done every time, so it is recommended to create an alias to do this quickly.
|
||||||
|
|
||||||
Note: When now setting up a debug session in the Xilinx SDK, the host must be set to localhost instead of the IP address
|
Note: When now setting up a debug session in the Xilinx SDK, the host must be set to localhost instead of the IP address of the Q7S.
|
||||||
of the Q7S.
|
|
||||||
|
|
||||||
|
## Transfering files via SCP
|
||||||
|
|
||||||
|
To transfer files from the local machine to the Q7S, use port forwarding
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can copy an `example` file like this
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scp -P 1535 example root@localhost:/tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
Copying a file from Q7S to flatsat PC
|
||||||
|
````
|
||||||
|
scp -P 22 root@192.168.133.10:/tmp/kernel-config /tmp
|
||||||
|
````
|
||||||
|
|
||||||
|
From a windows machine files can be copied with putty tools
|
||||||
|
````
|
||||||
|
pscp -scp -P 22 eive@192.168.199.227:</directory-to-example-file/>/example-file </windows-machine-path/>
|
||||||
|
````
|
||||||
|
|
||||||
|
## Launching an application at start-up
|
||||||
|
|
||||||
## Launching an application after boot
|
|
||||||
Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images).
|
Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images).
|
||||||
Note: It is not possible to modify the current loaded root partition.
|
Note: It is not possible to modify the currently loaded root partition, e.g. creating directories. To do this,
|
||||||
|
the parition needs to be mounted.
|
||||||
|
|
||||||
1. Disable write protection of the desired root partition
|
1. Disable write protection of the desired root partition
|
||||||
````
|
|
||||||
writeprotect 0 0 0 # unlocks nominal image on nor-flash 0
|
```sh
|
||||||
````
|
writeprotect 0 0 0 # unlocks nominal image on nor-flash 0
|
||||||
|
```
|
||||||
|
|
||||||
2. Mount the root partition
|
2. Mount the root partition
|
||||||
````
|
|
||||||
xsc_mount_copy 0 0 # Mounts the nominal image from nor-flash 0
|
```sh
|
||||||
````
|
xsc_mount_copy 0 0 # Mounts the nominal image from nor-flash 0
|
||||||
3. Copy the executable to /bin/usr
|
```
|
||||||
|
The mounted partition will be located inside the `/tmp` folder
|
||||||
|
|
||||||
|
3. Copy the executable to `/usr/bin`
|
||||||
|
|
||||||
4. Make sure the permissions to execute the application are set
|
4. Make sure the permissions to execute the application are set
|
||||||
````
|
```sh
|
||||||
chmod +x application
|
chmod +x application
|
||||||
````
|
```
|
||||||
|
|
||||||
5. Create systemd service in /lib/systemd/system. The following shows an example service.
|
5. Create systemd service in /lib/systemd/system. The following shows an example service.
|
||||||
````
|
```sh
|
||||||
cat > example.service
|
cat > example.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Example Service
|
Description=Example Service
|
||||||
StartLimitIntervalSec=0
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=1
|
RestartSec=1
|
||||||
User=root
|
User=root
|
||||||
ExecStart=/usr/bin/application
|
ExecStart=/usr/bin/application
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
````
|
```
|
||||||
6. Enable the service. This is normally done with systemctl enable. However, this is not possible when the service is
|
6. Enable the service. This is normally done with systemctl enable. However, this is not possible when the service is
|
||||||
created for a mounted root partition. Therefore create a symlink as follows.
|
created for a mounted root partition. Therefore create a symlink as follows.
|
||||||
````
|
```sh
|
||||||
ln -s '/tmp/the-mounted-xdi-image/lib/systemd/system/example.service' '/tmp/the-mounted-xdi-image/etc/systemd/system/multi-user.target.wants/example.service'
|
ln -s '/tmp/the-mounted-xdi-image/lib/systemd/system/example.service' '/tmp/the-mounted-xdi-image/etc/systemd/system/multi-user.target.wants/example.service'
|
||||||
````
|
```
|
||||||
|
|
||||||
7. The modified root partition is written back when the partion is locked again.
|
7. The modified root partition is written back when the partion is locked again.
|
||||||
````
|
```sh
|
||||||
writeprotect 0 0 1
|
writeprotect 0 0 1
|
||||||
````
|
```
|
||||||
8. Now verify the application start by booting from the modified image
|
8. Now verify the application start by booting from the modified image
|
||||||
````
|
```sh
|
||||||
xsc_boot_copy 0 0
|
xsc_boot_copy 0 0
|
||||||
````
|
````
|
||||||
|
|
||||||
9. After booting verify if the service is running
|
9. After booting verify if the service is running
|
||||||
````
|
```sh
|
||||||
systemctl status example
|
systemctl status example
|
||||||
````
|
```
|
||||||
More detailed information about the used q7s commands can be found in the Q7S user manual.
|
More detailed information about the used q7s commands can be found in the Q7S user manual.
|
||||||
|
|
||||||
### Bringing up CAN
|
### Bringing up CAN
|
||||||
````
|
|
||||||
ip link set can0 down
|
```sh
|
||||||
ip link set can0 type can loopback off
|
ip link set can0 down
|
||||||
ip link set can0 up type can bitrate 1000000
|
ip link set can0 type can loopback off
|
||||||
````
|
ip link set can0 up type can bitrate 1000000
|
||||||
|
```
|
||||||
|
|
||||||
Following command sends 8 bytes to device with id 99 (for petalinux)
|
Following command sends 8 bytes to device with id 99 (for petalinux)
|
||||||
````
|
````
|
||||||
cansend can0 -i99 99 88 77 11 33 11 22 99
|
cansend can0 -i99 99 88 77 11 33 11 22 99
|
||||||
@ -293,17 +430,6 @@ a permanent solution). If running the script before executing the binary does
|
|||||||
not help or an warning is issue that the soft real time value is invalid,
|
not help or an warning is issue that the soft real time value is invalid,
|
||||||
the hard real-time limit of the system might not be high enough (see step 1).
|
the hard real-time limit of the system might not be high enough (see step 1).
|
||||||
|
|
||||||
## Building and running the software on a host system
|
|
||||||
|
|
||||||
The host build can be built with following command
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make -f Makefile-Hosted all -j
|
|
||||||
```
|
|
||||||
|
|
||||||
If compiling on Windows, it is recommended to supply `WINDOWS=1` .
|
|
||||||
A release build can be built by using the `mission` target.
|
|
||||||
|
|
||||||
## Flight Software Framework (FSFW)
|
## Flight Software Framework (FSFW)
|
||||||
|
|
||||||
An EIVE fork of the FSFW is submodules into this repository.
|
An EIVE fork of the FSFW is submodules into this repository.
|
||||||
@ -323,3 +449,134 @@ git merge upstream/master
|
|||||||
|
|
||||||
Alternatively, changes from other upstreams (forks) and branches can be merged like that in
|
Alternatively, changes from other upstreams (forks) and branches can be merged like that in
|
||||||
the same way.
|
the same way.
|
||||||
|
|
||||||
|
## PCDU
|
||||||
|
|
||||||
|
Connect to serial console of P60 Dock
|
||||||
|
````
|
||||||
|
picocom -b 500000 /dev/ttyUSBx
|
||||||
|
````
|
||||||
|
General information
|
||||||
|
````
|
||||||
|
cmp ident
|
||||||
|
````
|
||||||
|
List parameter table:
|
||||||
|
x values: 1,2 or 4
|
||||||
|
````
|
||||||
|
param list x
|
||||||
|
````
|
||||||
|
Table 4 lists HK parameters
|
||||||
|
Changing parameters
|
||||||
|
First switch to table where parameter shall be changed (here table id is 1)
|
||||||
|
````
|
||||||
|
p60-dock # param mem 1
|
||||||
|
p60-dock # param set out_en[0] 1
|
||||||
|
p60-dock # param get out_en[0]
|
||||||
|
GET out_en[0] = 1
|
||||||
|
````
|
||||||
|
|
||||||
|
## Debugging the software (when workstation is directly conncected to Q7S)
|
||||||
|
|
||||||
|
1. Assign static IP address to Q7S
|
||||||
|
* Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user maunal chapter 10.3)
|
||||||
|
* Baudrate 115200
|
||||||
|
* Login to Q7S:
|
||||||
|
* user: root
|
||||||
|
* pw: root
|
||||||
|
|
||||||
|
2. Connect Q7S to workstation via ethernet
|
||||||
|
3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S
|
||||||
|
* When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation
|
||||||
|
is 192.168.133.2
|
||||||
|
|
||||||
|
4. Run tcf-agent on Q7S
|
||||||
|
|
||||||
|
* Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
|
||||||
|
cd org.eclipse.tcf.agent/agent
|
||||||
|
make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1
|
||||||
|
```
|
||||||
|
|
||||||
|
* Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd obj/GNU/Linux/arm/Debug
|
||||||
|
scp agent root@192.168.133.10:/tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
* On Q7S
|
||||||
|
```sh
|
||||||
|
cd /tmp
|
||||||
|
chmod +x agent
|
||||||
|
```
|
||||||
|
|
||||||
|
* Run agent
|
||||||
|
```sh
|
||||||
|
./agent
|
||||||
|
```
|
||||||
|
|
||||||
|
5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations
|
||||||
|
6. Right click Xilinx C/C++ applicaton (System Debugger) → New →
|
||||||
|
7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent
|
||||||
|
8. Click New
|
||||||
|
9. Give connection a name
|
||||||
|
10. Set Host to static IP address of Q7S. e.g. 192.168.133.10
|
||||||
|
11. Test connection (This ensures the TCF Agent is running on the Q7S)
|
||||||
|
12. Select Application tab
|
||||||
|
* Project Name: eive_obsw
|
||||||
|
* Local File Path: Path to eiveobsw-linux.elf (in _bin\linux\devel)
|
||||||
|
* Remote File Path: /tmp/eive_obsw.elf
|
||||||
|
|
||||||
|
## Libgpiod
|
||||||
|
|
||||||
|
Detect all gpio device files:
|
||||||
|
````
|
||||||
|
gpiodetect
|
||||||
|
````
|
||||||
|
Get info about a specific gpio group:
|
||||||
|
````
|
||||||
|
gpioinfo <name of gpio group>
|
||||||
|
````
|
||||||
|
The following sets the gpio 18 from gpio group gpiochip7 to high level.
|
||||||
|
````
|
||||||
|
gpioset gpiochip7 18=1
|
||||||
|
````
|
||||||
|
Setting the gpio to low.
|
||||||
|
````
|
||||||
|
gpioset gpiochip7 18=0
|
||||||
|
````
|
||||||
|
Show options for setting gpios.
|
||||||
|
````
|
||||||
|
gpioset -h
|
||||||
|
````
|
||||||
|
To get the state of a gpio:
|
||||||
|
````
|
||||||
|
gpioget <gpiogroup> <offset>
|
||||||
|
````
|
||||||
|
Example to get state:
|
||||||
|
gpioget gpiochip7 14
|
||||||
|
|
||||||
|
## Running the EIVE OBSW on a Raspberry Pi
|
||||||
|
|
||||||
|
Special section for running the EIVE OBSW on the Raspberry Pi.
|
||||||
|
The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler.
|
||||||
|
|
||||||
|
For running the software on a Raspberry Pi, it is recommended to follow the steps specified in
|
||||||
|
[the fsfw example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example/src/branch/mueller/master/doc/README-rpi.md#top)
|
||||||
|
and using the TCF agent to have a similar set-up process also required for the Q7S.
|
||||||
|
You should run the following command first on your Raspberry Pi
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt-get install gpiod libgpiod-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
to install the required GPIO libraries before cloning the system root folder.
|
||||||
|
|
||||||
|
## Special notes on Eclipse
|
||||||
|
|
||||||
|
When using Eclipse, there are two special build variables in the project properties
|
||||||
|
→ C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set
|
||||||
|
the sysroot path in those variables to get any additional includes like `gpiod.h` in the
|
||||||
|
Eclipse indexer.
|
10
bsp_hosted/CMakeLists.txt
Normal file
10
bsp_hosted/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
target_sources(${TARGET_NAME} PUBLIC
|
||||||
|
InitMission.cpp
|
||||||
|
main.cpp
|
||||||
|
ObjectFactory.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(fsfwconfig)
|
||||||
|
add_subdirectory(boardconfig)
|
||||||
|
|
||||||
|
|
159
bsp_hosted/InitMission.cpp
Normal file
159
bsp_hosted/InitMission.cpp
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
#include "InitMission.h"
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
|
#include <OBSWConfig.h>
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
|
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
|
#include <mission/utility/InitMission.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef LINUX
|
||||||
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
|
ServiceInterfaceStream sif::info("INFO");
|
||||||
|
ServiceInterfaceStream sif::warning("WARNING");
|
||||||
|
ServiceInterfaceStream sif::error("ERROR", false, false, true);
|
||||||
|
#else
|
||||||
|
ServiceInterfaceStream sif::debug("DEBUG", true);
|
||||||
|
ServiceInterfaceStream sif::info("INFO", true);
|
||||||
|
ServiceInterfaceStream sif::warning("WARNING", true);
|
||||||
|
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ObjectManagerIF *objectManager = nullptr;
|
||||||
|
|
||||||
|
void initmission::initMission() {
|
||||||
|
sif::info << "Building global objects.." << std::endl;
|
||||||
|
/* Instantiate global object manager and also create all objects */
|
||||||
|
objectManager = new ObjectManager(ObjectFactory::produce);
|
||||||
|
sif::info << "Initializing all objects.." << std::endl;
|
||||||
|
objectManager->initialize();
|
||||||
|
|
||||||
|
/* This function creates and starts all tasks */
|
||||||
|
initTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initmission::initTasks() {
|
||||||
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
|
if(factory == nullptr) {
|
||||||
|
/* Should never happen ! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
|
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
||||||
|
#else
|
||||||
|
void (*missedDeadlineFunc) (void) = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TMTC Distribution */
|
||||||
|
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||||
|
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
ReturnValue_t result = tmTcDistributor->addComponent(
|
||||||
|
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UDP bridge */
|
||||||
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
|
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
|
}
|
||||||
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
|
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
|
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUS Services */
|
||||||
|
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||||
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||||
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
}
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||||
|
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
|
}
|
||||||
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
|
tmTcDistributor->startTask();
|
||||||
|
udpBridgeTask->startTask();
|
||||||
|
udpPollingTask->startTask();
|
||||||
|
|
||||||
|
pusVerification->startTask();
|
||||||
|
pusEvents->startTask();
|
||||||
|
pusHighPrio->startTask();
|
||||||
|
pusMedPrio->startTask();
|
||||||
|
pusLowPrio->startTask();
|
||||||
|
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
testTask->startTask();
|
||||||
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
|
sif::info << "Tasks started.." << std::endl;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef BSP_LINUX_INITMISSION_H_
|
#ifndef BSP_LINUX_INITMISSION_H_
|
||||||
#define BSP_LINUX_INITMISSION_H_
|
#define BSP_LINUX_INITMISSION_H_
|
||||||
|
|
||||||
namespace InitMission {
|
namespace initmission {
|
||||||
void initMission();
|
void initMission();
|
||||||
void initTasks();
|
void initTasks();
|
||||||
};
|
};
|
@ -1,20 +1,27 @@
|
|||||||
#include "ObjectFactory.h"
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
#include <objects/systemObjectList.h>
|
|
||||||
#include <OBSWConfig.h>
|
#include <OBSWConfig.h>
|
||||||
|
#include <objects/systemObjectList.h>
|
||||||
#include <tmtc/apid.h>
|
#include <tmtc/apid.h>
|
||||||
#include <tmtc/pusIds.h>
|
#include <tmtc/pusIds.h>
|
||||||
|
|
||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
#include <fsfw/osal/linux/TmTcUnixUdpBridge.h>
|
|
||||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
|
||||||
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
|
|
||||||
|
|
||||||
#include <mission/core/GenericFactory.h>
|
#include <mission/core/GenericFactory.h>
|
||||||
#include <mission/utility/TmFunnel.h>
|
#include <mission/utility/TmFunnel.h>
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
#include <fsfw/osal/common/UdpTcPollingTask.h>
|
||||||
|
#include <fsfw/osal/common/UdpTmTcBridge.h>
|
||||||
|
|
||||||
|
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
#include <test/testtasks/TestTask.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Factory::setStaticFrameworkObjectIds(){
|
||||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
@ -29,14 +36,13 @@ void Factory::setStaticFrameworkObjectIds() {
|
|||||||
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
|
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ObjectFactory::produce(){
|
void ObjectFactory::produce(){
|
||||||
Factory::setStaticFrameworkObjectIds();
|
Factory::setStaticFrameworkObjectIds();
|
||||||
ObjectFactory::produceGenericObjects();
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
|
new UdpTmTcBridge(objects::UDP_BRIDGE,
|
||||||
objects::CCSDS_PACKET_DISTRIBUTOR,
|
objects::CCSDS_PACKET_DISTRIBUTOR,
|
||||||
objects::TM_STORE, objects::TC_STORE);
|
objects::TM_STORE, objects::TC_STORE);
|
||||||
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
||||||
|
|
||||||
}
|
}
|
10
bsp_hosted/boardconfig/CMakeLists.txt
Normal file
10
bsp_hosted/boardconfig/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
print.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
8
bsp_hosted/boardconfig/print.h
Normal file
8
bsp_hosted/boardconfig/print.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef BSP_HOSTED_BOARDCONFIG_PRINT_H_
|
||||||
|
#define BSP_HOSTED_BOARDCONFIG_PRINT_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void printChar(const char* character, bool errStream);
|
||||||
|
|
||||||
|
#endif /* BSP_HOSTED_BOARDCONFIG_PRINT_H_ */
|
@ -8,3 +8,4 @@ CXXSRC += $(wildcard $(CURRENTPATH)/comIF/*.cpp)
|
|||||||
CSRC += $(wildcard $(CURRENTPATH)/comIF/*.c)
|
CSRC += $(wildcard $(CURRENTPATH)/comIF/*.c)
|
||||||
|
|
||||||
INCLUDES += $(CURRENTPATH)/boardconfig
|
INCLUDES += $(CURRENTPATH)/boardconfig
|
||||||
|
INCLUDES += $(CURRENTPATH)/fsfwconfig
|
@ -8,6 +8,8 @@
|
|||||||
// This only works on Linux
|
// This only works on Linux
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
@ -255,7 +257,7 @@ ReturnValue_t ArduinoComIF::sendMessage(uint8_t command,
|
|||||||
encodedLen = sizeof(sendBuffer) - remainingLen;
|
encodedLen = sizeof(sendBuffer) - remainingLen;
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
ssize_t writtenlen = write(serialPort, sendBuffer, encodedLen);
|
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
|
||||||
if (writtenlen < 0) {
|
if (writtenlen < 0) {
|
||||||
//we could try to find out what happened...
|
//we could try to find out what happened...
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
@ -286,7 +288,7 @@ void ArduinoComIF::handleSerialPortRx() {
|
|||||||
|
|
||||||
rxBuffer.writeData(dataFromSerial, bytesRead);
|
rxBuffer.writeData(dataFromSerial, bytesRead);
|
||||||
|
|
||||||
uint8_t dataReceivedSoFar[rxBuffer.maxSize()];
|
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
|
||||||
|
|
||||||
uint32_t dataLenReceivedSoFar = 0;
|
uint32_t dataLenReceivedSoFar = 0;
|
||||||
|
|
||||||
@ -296,11 +298,11 @@ void ArduinoComIF::handleSerialPortRx() {
|
|||||||
//look for STX
|
//look for STX
|
||||||
size_t firstSTXinRawData = 0;
|
size_t firstSTXinRawData = 0;
|
||||||
while ((firstSTXinRawData < dataLenReceivedSoFar)
|
while ((firstSTXinRawData < dataLenReceivedSoFar)
|
||||||
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX)) {
|
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
|
||||||
firstSTXinRawData++;
|
firstSTXinRawData++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX) {
|
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
|
||||||
//there is no STX in our data, throw it away...
|
//there is no STX in our data, throw it away...
|
||||||
rxBuffer.deleteData(dataLenReceivedSoFar);
|
rxBuffer.deleteData(dataLenReceivedSoFar);
|
||||||
return;
|
return;
|
@ -1,4 +1,4 @@
|
|||||||
#include "ArduinoCookie.h"
|
#include <bsp_hosted/comIF/ArduinoCookie.h>
|
||||||
|
|
||||||
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
|
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
|
||||||
const size_t maxReplySize) :
|
const size_t maxReplySize) :
|
8
bsp_hosted/comIF/CMakeLists.txt
Normal file
8
bsp_hosted/comIF/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
target_sources(${TARGET_NAME} PUBLIC
|
||||||
|
ArduinoComIF.cpp
|
||||||
|
ArduinoCookie.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
10
bsp_hosted/fsfwconfig/CMakeLists.txt
Normal file
10
bsp_hosted/fsfwconfig/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
ipc/MissionMessageTypes.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
|||||||
#ifndef CONFIG_FSFWCONFIG_H_
|
#ifndef CONFIG_FSFWCONFIG_H_
|
||||||
#define CONFIG_FSFWCONFIG_H_
|
#define CONFIG_FSFWCONFIG_H_
|
||||||
|
|
||||||
#include <FSFWVersion.h>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
//! Used to determine whether C++ ostreams are used
|
//! Used to determine whether C++ ostreams are used which can increase
|
||||||
//! Those can lead to code bloat.
|
//! the binary size significantly. If this is disabled,
|
||||||
#define FSFW_CPP_OSTREAM_ENABLED 1
|
//! the C stdio functions can be used alternatively
|
||||||
|
#define FSFW_CPP_OSTREAM_ENABLED 1
|
||||||
|
|
||||||
//! Reduced printout to further decrese code size
|
//! More FSFW related printouts depending on level. Useful for development.
|
||||||
//! Be careful, this also turns off most diagnostic prinouts!
|
#define FSFW_VERBOSE_LEVEL 1
|
||||||
#define FSFW_REDUCED_PRINTOUT 0
|
|
||||||
|
|
||||||
//! Can be used to enable debugging printouts for developing the FSFW
|
//! Can be used to completely disable printouts, even the C stdio ones.
|
||||||
#define FSFW_DEBUGGING 0
|
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
|
||||||
|
#define FSFW_DISABLE_PRINTOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
//! Defines the FIFO depth of each commanding service base which
|
//! Can be used to disable the ANSI color sequences for C stdio.
|
||||||
//! also determines how many commands a CSB service can handle in one cycle
|
#define FSFW_COLORED_OUTPUT 1
|
||||||
//! simulataneously. This will increase the required RAM for
|
|
||||||
//! each CSB service !
|
//! Can be used to disable the ANSI color sequences for C stdio.
|
||||||
#define FSFW_CSB_FIFO_DEPTH 6
|
#define FSFW_COLORED_OUTPUT 1
|
||||||
|
|
||||||
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
||||||
//! additional output which requires the translation files translateObjects
|
//! additional output which requires the translation files translateObjects
|
||||||
@ -27,18 +29,19 @@
|
|||||||
#define FSFW_OBJ_EVENT_TRANSLATION 0
|
#define FSFW_OBJ_EVENT_TRANSLATION 0
|
||||||
|
|
||||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||||
#define FSFW_DEBUG_OUTPUT 1
|
|
||||||
//! Specify whether info events are printed too.
|
//! Specify whether info events are printed too.
|
||||||
#define FSFW_DEBUG_INFO 1
|
#define FSFW_DEBUG_INFO 1
|
||||||
#include <translateObjects.h>
|
#include "objects/translateObjects.h"
|
||||||
#include <translateEvents.h>
|
#include "events/translateEvents.h"
|
||||||
#else
|
#else
|
||||||
#define FSFW_DEBUG_OUTPUT 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! When using the newlib nano library, C99 support for stdio facilities
|
//! When using the newlib nano library, C99 support for stdio facilities
|
||||||
//! will not be provided. This define should be set to 1 if this is the case.
|
//! will not be provided. This define should be set to 1 if this is the case.
|
||||||
#define FSFW_NO_C99_IO 1
|
#define FSFW_NO_C99_IO 1
|
||||||
|
|
||||||
|
//! Specify whether a special mode store is used for Subsystem components.
|
||||||
|
#define FSFW_USE_MODESTORE 0
|
||||||
|
|
||||||
namespace fsfwconfig {
|
namespace fsfwconfig {
|
||||||
//! Default timestamp size. The default timestamp will be an eight byte CDC
|
//! Default timestamp size. The default timestamp will be an eight byte CDC
|
||||||
@ -49,6 +52,14 @@ static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8;
|
|||||||
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
||||||
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
||||||
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
||||||
|
|
||||||
|
//! Defines the FIFO depth of each commanding service base which
|
||||||
|
//! also determines how many commands a CSB service can handle in one cycle
|
||||||
|
//! simulataneously. This will increase the required RAM for
|
||||||
|
//! each CSB service !
|
||||||
|
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
||||||
|
|
||||||
|
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
#endif /* CONFIG_FSFWCONFIG_H_ */
|
32
bsp_hosted/fsfwconfig/OBSWConfig.h
Normal file
32
bsp_hosted/fsfwconfig/OBSWConfig.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @brief This file can be used to add preprocessor define for conditional
|
||||||
|
* code inclusion exclusion or various other project constants and
|
||||||
|
* properties in one place.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_OBSWCONFIG_H_
|
||||||
|
#define CONFIG_OBSWCONFIG_H_
|
||||||
|
|
||||||
|
#include "commonConfig.h"
|
||||||
|
|
||||||
|
#define OBSW_ADD_TEST_CODE 1
|
||||||
|
|
||||||
|
/* These defines should be disabled for mission code but are useful for
|
||||||
|
debugging. */
|
||||||
|
#define OBSW_VEBOSE_LEVEL 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "objects/systemObjectList.h"
|
||||||
|
#include "events/subsystemIdRanges.h"
|
||||||
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
|
namespace config {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Add mission configuration flags here */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CONFIG_OBSWCONFIG_H_ */
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
const char* const SW_NAME = "eive";
|
const char* const SW_NAME = "eive";
|
||||||
|
|
||||||
#define SW_VERSION 0
|
#define SW_VERSION 1
|
||||||
#define SW_SUBVERSION 2
|
#define SW_SUBVERSION 0
|
||||||
#define SW_SUBSUBVERSION 0
|
#define SW_SUBSUBVERSION 0
|
||||||
|
|
||||||
|
|
59
bsp_hosted/fsfwconfig/devices/gpioIds.h
Normal file
59
bsp_hosted/fsfwconfig/devices/gpioIds.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_
|
||||||
|
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
|
||||||
|
|
||||||
|
#include <linux/gpio/GpioIF.h>
|
||||||
|
|
||||||
|
namespace gpioIds {
|
||||||
|
enum gpioId_t {
|
||||||
|
HEATER_0,
|
||||||
|
HEATER_1,
|
||||||
|
HEATER_2,
|
||||||
|
HEATER_3,
|
||||||
|
HEATER_4,
|
||||||
|
HEATER_5,
|
||||||
|
HEATER_6,
|
||||||
|
HEATER_7,
|
||||||
|
DEPLSA1,
|
||||||
|
DEPLSA2,
|
||||||
|
|
||||||
|
MGM_0_LIS3_CS,
|
||||||
|
MGM_1_RM3100_CS,
|
||||||
|
GYRO_0_ADIS_CS,
|
||||||
|
GYRO_1_L3G_CS,
|
||||||
|
GYRO_2_L3G_CS,
|
||||||
|
MGM_2_LIS3_CS,
|
||||||
|
MGM_3_RM3100_CS,
|
||||||
|
|
||||||
|
TEST_ID_0,
|
||||||
|
TEST_ID_1,
|
||||||
|
|
||||||
|
RTD_IC3,
|
||||||
|
RTD_IC4,
|
||||||
|
RTD_IC5,
|
||||||
|
RTD_IC6,
|
||||||
|
RTD_IC7,
|
||||||
|
RTD_IC8,
|
||||||
|
RTD_IC9,
|
||||||
|
RTD_IC10,
|
||||||
|
RTD_IC11,
|
||||||
|
RTD_IC12,
|
||||||
|
RTD_IC13,
|
||||||
|
RTD_IC14,
|
||||||
|
RTD_IC15,
|
||||||
|
RTD_IC16,
|
||||||
|
RTD_IC17,
|
||||||
|
RTD_IC18,
|
||||||
|
|
||||||
|
SPI_MUX_BIT_1,
|
||||||
|
SPI_MUX_BIT_2,
|
||||||
|
SPI_MUX_BIT_3,
|
||||||
|
SPI_MUX_BIT_4,
|
||||||
|
SPI_MUX_BIT_5,
|
||||||
|
SPI_MUX_BIT_6
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */
|
58
bsp_hosted/fsfwconfig/devices/powerSwitcherList.h
Normal file
58
bsp_hosted/fsfwconfig/devices/powerSwitcherList.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
|
||||||
|
#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
|
||||||
|
|
||||||
|
#include <OBSWConfig.h>
|
||||||
|
|
||||||
|
namespace pcduSwitches {
|
||||||
|
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||||
|
enum switcherList {
|
||||||
|
Q7S,
|
||||||
|
PAYLOAD_PCDU_CH1,
|
||||||
|
RW,
|
||||||
|
TCS_BOARD_8V_HEATER_IN,
|
||||||
|
SUS_REDUNDANT,
|
||||||
|
DEPLOYMENT_MECHANISM,
|
||||||
|
PAYLOAD_PCDU_CH6,
|
||||||
|
ACS_BOARD_SIDE_B,
|
||||||
|
PAYLOAD_CAMERA,
|
||||||
|
TCS_BOARD_3V3,
|
||||||
|
SYRLINKS,
|
||||||
|
STAR_TRACKER,
|
||||||
|
MGT,
|
||||||
|
SUS_NOMINAL,
|
||||||
|
SOLAR_CELL_EXP,
|
||||||
|
PLOC,
|
||||||
|
ACS_BORAD_SIDE_A,
|
||||||
|
NUMBER_OF_SWITCHES
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t ON = 1;
|
||||||
|
static const uint8_t OFF = 0;
|
||||||
|
|
||||||
|
/* Output states after reboot of the PDUs */
|
||||||
|
static const uint8_t INIT_STATE_Q7S = ON;
|
||||||
|
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||||
|
static const uint8_t INIT_STATE_RW = OFF;
|
||||||
|
#if TE0720 == 1
|
||||||
|
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||||
|
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||||
|
#else
|
||||||
|
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||||
|
#endif
|
||||||
|
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||||
|
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||||
|
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||||
|
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||||
|
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||||
|
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||||
|
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
||||||
|
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
||||||
|
static const uint8_t INIT_STATE_MGT = OFF;
|
||||||
|
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
||||||
|
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
||||||
|
static const uint8_t INIT_STATE_PLOC = OFF;
|
||||||
|
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
namespace SUBSYSTEM_ID {
|
namespace SUBSYSTEM_ID {
|
||||||
enum: uint8_t {
|
enum: uint8_t {
|
||||||
SUBSYSTE_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
||||||
PUS_SERVICE_2,
|
PUS_SERVICE_2,
|
||||||
PUS_SERVICE_3,
|
PUS_SERVICE_3,
|
||||||
PUS_SERVICE_5,
|
PUS_SERVICE_5,
|
||||||
@ -18,6 +18,7 @@ enum: uint8_t {
|
|||||||
PUS_SERVICE_8,
|
PUS_SERVICE_8,
|
||||||
PUS_SERVICE_23,
|
PUS_SERVICE_23,
|
||||||
MGM_LIS3MDL,
|
MGM_LIS3MDL,
|
||||||
|
MGM_RM3100,
|
||||||
|
|
||||||
DUMMY_DEVICE,
|
DUMMY_DEVICE,
|
||||||
};
|
};
|
7
bsp_hosted/fsfwconfig/fsfwconfig.mk
Normal file
7
bsp_hosted/fsfwconfig/fsfwconfig.mk
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/cdatapool/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
|
||||||
|
|
||||||
|
INCLUDES += $(CURRENTPATH)
|
@ -1,5 +1,5 @@
|
|||||||
|
#include "MissionMessageTypes.h"
|
||||||
#include <fsfw/ipc/CommandMessage.h>
|
#include <fsfw/ipc/CommandMessage.h>
|
||||||
#include <hosted/fsfwconfig/ipc/MissionMessageTypes.h>
|
|
||||||
|
|
||||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||||
switch(message->getMessageType()) {
|
switch(message->getMessageType()) {
|
@ -11,7 +11,7 @@ class CommandMessage;
|
|||||||
* <fsfw/ipc/FwMessageTypes.h>
|
* <fsfw/ipc/FwMessageTypes.h>
|
||||||
* @param message Generic Command Message
|
* @param message Generic Command Message
|
||||||
*/
|
*/
|
||||||
namespace messagetypes{
|
namespace messagetypes {
|
||||||
enum MESSAGE_TYPE {
|
enum MESSAGE_TYPE {
|
||||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||||
};
|
};
|
50
bsp_hosted/fsfwconfig/objects/systemObjectList.h
Normal file
50
bsp_hosted/fsfwconfig/objects/systemObjectList.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||||
|
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// The objects will be instantiated in the ID order
|
||||||
|
namespace objects {
|
||||||
|
enum sourceObjects: uint32_t {
|
||||||
|
/* First Byte 0x50-0x52 reserved for PUS Services **/
|
||||||
|
CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
|
||||||
|
PUS_PACKET_DISTRIBUTOR = 0x50000200,
|
||||||
|
UDP_BRIDGE = 0x50000300,
|
||||||
|
UDP_POLLING_TASK = 0x50000400,
|
||||||
|
|
||||||
|
PUS_SERVICE_3 = 0x51000300,
|
||||||
|
PUS_SERVICE_5 = 0x51000400,
|
||||||
|
PUS_SERVICE_6 = 0x51000500,
|
||||||
|
PUS_SERVICE_8 = 0x51000800,
|
||||||
|
PUS_SERVICE_23 = 0x51002300,
|
||||||
|
PUS_SERVICE_201 = 0x51020100,
|
||||||
|
|
||||||
|
TM_FUNNEL = 0x52000002,
|
||||||
|
|
||||||
|
/* Test Task */
|
||||||
|
|
||||||
|
TEST_TASK = 0x42694269,
|
||||||
|
DUMMY_INTERFACE = 0xCAFECAFE,
|
||||||
|
DUMMY_HANDLER = 0x4400AFFE,
|
||||||
|
|
||||||
|
/* 0x44 ('D') for device handlers */
|
||||||
|
P60DOCK_HANDLER = 0x44000001,
|
||||||
|
PDU1_HANDLER = 0x44000002,
|
||||||
|
PDU2_HANDLER = 0x44000003,
|
||||||
|
ACU_HANDLER = 0x44000004,
|
||||||
|
TMP1075_HANDLER_1 = 0x44000005,
|
||||||
|
TMP1075_HANDLER_2 = 0x44000006,
|
||||||
|
MGM_0_LIS3_HANDLER = 0x4400007,
|
||||||
|
MGM_1_RM3100_HANDLER = 0x44000008,
|
||||||
|
MGM_2_LIS3_HANDLER = 0x44000009,
|
||||||
|
MGM_3_RM3100_HANDLER = 0x44000010,
|
||||||
|
GYRO_0_ADIS_HANDLER = 0x44000011,
|
||||||
|
GYRO_1_L3G_HANDLER = 0x44000012,
|
||||||
|
GYRO_2_L3G_HANDLER = 0x44000013,
|
||||||
|
|
||||||
|
/* 0x49 ('I') for Communication Interfaces **/
|
||||||
|
ARDUINO_COM_IF = 0x49000001
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
@ -11,7 +11,8 @@
|
|||||||
namespace CLASS_ID {
|
namespace CLASS_ID {
|
||||||
enum {
|
enum {
|
||||||
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
|
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
|
||||||
MGM_LIS3MDL
|
MGM_LIS3MDL,
|
||||||
|
MGM_RM3100
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
19
bsp_hosted/fsfwconfig/tmtc/apid.h
Normal file
19
bsp_hosted/fsfwconfig/tmtc/apid.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef FSFWCONFIG_TMTC_APID_H_
|
||||||
|
#define FSFWCONFIG_TMTC_APID_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application Process Definition: entity, uniquely identified by an
|
||||||
|
* application process ID (APID), capable of generating telemetry source
|
||||||
|
* packets and receiving telecommand packets
|
||||||
|
*
|
||||||
|
* SOURCE APID: 0x73 / 115 / s
|
||||||
|
* APID is a 11 bit number
|
||||||
|
*/
|
||||||
|
namespace apid {
|
||||||
|
static const uint16_t EIVE_OBSW = 0x65;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFWCONFIG_TMTC_APID_H_ */
|
23
bsp_hosted/fsfwconfig/tmtc/pusIds.h
Normal file
23
bsp_hosted/fsfwconfig/tmtc/pusIds.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef CONFIG_TMTC_PUSIDS_HPP_
|
||||||
|
#define CONFIG_TMTC_PUSIDS_HPP_
|
||||||
|
|
||||||
|
namespace pus {
|
||||||
|
enum Ids{
|
||||||
|
PUS_SERVICE_1 = 1,
|
||||||
|
PUS_SERVICE_2 = 2,
|
||||||
|
PUS_SERVICE_3 = 3,
|
||||||
|
PUS_SERVICE_3_PSB = 3,
|
||||||
|
PUS_SERVICE_5 = 5,
|
||||||
|
PUS_SERVICE_6 = 6,
|
||||||
|
PUS_SERVICE_8 = 8,
|
||||||
|
PUS_SERVICE_9 = 9,
|
||||||
|
PUS_SERVICE_17 = 17,
|
||||||
|
PUS_SERVICE_19 = 19,
|
||||||
|
PUS_SERVICE_20 = 20,
|
||||||
|
PUS_SERVICE_23 = 23,
|
||||||
|
PUS_SERVICE_200 = 200,
|
||||||
|
PUS_SERVICE_201 = 201,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CONFIG_TMTC_PUSIDS_HPP_ */
|
@ -1,7 +1,7 @@
|
|||||||
#include <bsp_linux/InitMission.h>
|
#include "InitMission.h"
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
|
||||||
#include <hosted/fsfwconfig/OBSWVersion.h>
|
|
||||||
|
|
||||||
|
#include <OBSWVersion.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -24,7 +24,7 @@ int main(void)
|
|||||||
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
|
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
|
||||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
|
|
||||||
InitMission::initMission();
|
initmission::initMission();
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// suspend main thread by sleeping it.
|
// suspend main thread by sleeping it.
|
@ -1,159 +0,0 @@
|
|||||||
#include <bsp_linux/InitMission.h>
|
|
||||||
#include <bsp_linux/ObjectFactory.h>
|
|
||||||
|
|
||||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
|
||||||
#include <fsfw/datapool/DataPool.h>
|
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
|
||||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
|
||||||
#include <fsfw/tasks/PeriodicTaskIF.h>
|
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
|
||||||
#include <fsfwconfig/objects/systemObjectList.h>
|
|
||||||
#include <fsfwconfig/OBSWConfig.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// This is configured for linux without \cr
|
|
||||||
#ifdef LINUX
|
|
||||||
ServiceInterfaceStream sif::debug("DEBUG");
|
|
||||||
ServiceInterfaceStream sif::info("INFO");
|
|
||||||
ServiceInterfaceStream sif::warning("WARNING");
|
|
||||||
ServiceInterfaceStream sif::error("ERROR", false, false, true);
|
|
||||||
#else
|
|
||||||
ServiceInterfaceStream sif::debug("DEBUG", true);
|
|
||||||
ServiceInterfaceStream sif::info("INFO", true);
|
|
||||||
ServiceInterfaceStream sif::warning("WARNING", true);
|
|
||||||
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ObjectManagerIF *objectManager = nullptr;
|
|
||||||
|
|
||||||
//Initialize Data Pool
|
|
||||||
DataPool dataPool(nullptr);
|
|
||||||
|
|
||||||
void InitMission::initMission() {
|
|
||||||
sif::info << "Building global objects.." << std::endl;
|
|
||||||
/* Instantiate global object manager and also create all objects */
|
|
||||||
objectManager = new ObjectManager(ObjectFactory::produce);
|
|
||||||
sif::info << "Initializing all objects.." << std::endl;
|
|
||||||
objectManager->initialize();
|
|
||||||
|
|
||||||
/* This function creates and starts all tasks */
|
|
||||||
initTasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitMission::initTasks(){
|
|
||||||
/* TMTC Distribution */
|
|
||||||
PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE,
|
|
||||||
0.100, nullptr);
|
|
||||||
ReturnValue_t result = TmTcDistributor->addComponent(
|
|
||||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
result = TmTcDistributor->addComponent(objects::TM_FUNNEL);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UDP bridge */
|
|
||||||
PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask(
|
|
||||||
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE,
|
|
||||||
0.2, nullptr);
|
|
||||||
result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
|
||||||
}
|
|
||||||
PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("UDP_POLLING", 80,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr);
|
|
||||||
result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PUS Services */
|
|
||||||
PeriodicTaskIF* PusVerification = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("PUS_VERIF_1", 40,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
|
|
||||||
result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicTaskIF* PusEvents = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("PUS_VERIF_1", 60,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
|
|
||||||
result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicTaskIF* PusHighPrio = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("PUS_HIGH_PRIO", 50,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE,
|
|
||||||
0.200, nullptr);
|
|
||||||
result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicTaskIF* PusMedPrio = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("PUS_HIGH_PRIO", 40,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE,
|
|
||||||
0.8, nullptr);
|
|
||||||
result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicTaskIF* PusLowPrio = TaskFactory::instance()->
|
|
||||||
createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE,
|
|
||||||
1.6, nullptr);
|
|
||||||
result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if ADD_TEST_CODE == 1
|
|
||||||
FixedTimeslotTaskIF* TestTimeslotTask = TaskFactory::instance()->
|
|
||||||
createFixedTimeslotTask("PST_TEST_TASK", 10,
|
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
|
|
||||||
result = pst::pollingSequenceTestFunction(TestTimeslotTask);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "InitMission::createTasks: Test PST initialization "
|
|
||||||
<< "failed!" << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Main thread sleep
|
|
||||||
sif::info << "Starting tasks.." << std::endl;
|
|
||||||
TmTcDistributor->startTask();
|
|
||||||
UdpBridgeTask->startTask();
|
|
||||||
UdpPollingTask->startTask();
|
|
||||||
|
|
||||||
PusVerification->startTask();
|
|
||||||
PusEvents->startTask();
|
|
||||||
PusHighPrio->startTask();
|
|
||||||
PusMedPrio->startTask();
|
|
||||||
PusLowPrio->startTask();
|
|
||||||
#if ADD_TEST_CODE == 1
|
|
||||||
TestTimeslotTask->startTask();
|
|
||||||
#endif
|
|
||||||
sif::info << "Tasks started.." << std::endl;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
|
|
||||||
CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
|
||||||
|
|
||||||
CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)
|
|
@ -1,324 +0,0 @@
|
|||||||
#include "ArduinoCookie.h"
|
|
||||||
#include "ArduinoComIF.h"
|
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fsfw/globalfunctions/CRC.h>
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
ArduinoCommInterface::ArduinoCommInterface(object_id_t setObjectId,
|
|
||||||
const char *serialDevice) :
|
|
||||||
spiMap(MAX_NUMBER_OF_SPI_DEVICES), rxBuffer(
|
|
||||||
MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES*10, true), SystemObject(setObjectId) {
|
|
||||||
initialized = false;
|
|
||||||
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
|
|
||||||
|
|
||||||
if (serialPort < 0) {
|
|
||||||
//configuration error
|
|
||||||
printf("Error %i from open: %s\n", errno, strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct termios tty;
|
|
||||||
memset(&tty, 0, sizeof tty);
|
|
||||||
|
|
||||||
// Read in existing settings, and handle any error
|
|
||||||
if (tcgetattr(serialPort, &tty) != 0) {
|
|
||||||
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
|
|
||||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
|
||||||
tty.c_cflag |= CS8; // 8 bits per byte
|
|
||||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
|
||||||
tty.c_lflag &= ~ICANON; //Disable Canonical Mode
|
|
||||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
|
||||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
|
||||||
tty.c_cc[VTIME] = 0; // Non Blocking
|
|
||||||
tty.c_cc[VMIN] = 0;
|
|
||||||
|
|
||||||
cfsetispeed(&tty, B9600); //Baudrate
|
|
||||||
|
|
||||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
|
||||||
//printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ArduinoCommInterface::~ArduinoCommInterface() {
|
|
||||||
::close(serialPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::open(Cookie **cookie, uint32_t address,
|
|
||||||
uint32_t maxReplyLen) {
|
|
||||||
//This is a hack, will be gone with https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/19
|
|
||||||
switch ((address >> 8) & 0xff) {
|
|
||||||
case 0:
|
|
||||||
*cookie = new ArduinoCookie(ArduinoCookie::SPI, address, maxReplyLen);
|
|
||||||
spiMap.insert(address, (ArduinoCookie*) *cookie); //Yes, I *do* know that it is an ArduinoSpiCookie, I just new'd it
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::reOpen(Cookie *cookie, uint32_t address,
|
|
||||||
uint32_t maxReplyLen) {
|
|
||||||
//too lazy right now will be irrelevant with https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/19
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArduinoCommInterface::close(Cookie *cookie) {
|
|
||||||
//too lazy as well, find the correct Map, delete it there, then the cookie...
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::sendMessage(Cookie *cookie, uint8_t *data,
|
|
||||||
uint32_t len) {
|
|
||||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
|
||||||
if (arduinoCookie == NULL) {
|
|
||||||
return INVALID_COOKIE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendMessage(arduinoCookie->command, arduinoCookie->address, data,
|
|
||||||
len);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::getSendSuccess(Cookie *cookie) {
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::requestReceiveMessage(Cookie *cookie) {
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::readReceivedMessage(Cookie *cookie,
|
|
||||||
uint8_t **buffer, uint32_t *size) {
|
|
||||||
|
|
||||||
handleSerialPortRx();
|
|
||||||
|
|
||||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
|
||||||
if (arduinoCookie == NULL) {
|
|
||||||
return INVALID_COOKIE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = arduinoCookie->replyBuffer;
|
|
||||||
*size = arduinoCookie->receivedDataLen;
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::setAddress(Cookie *cookie,
|
|
||||||
uint32_t address) {
|
|
||||||
//not implemented
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ArduinoCommInterface::getAddress(Cookie *cookie) {
|
|
||||||
//not implemented
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::setParameter(Cookie *cookie,
|
|
||||||
uint32_t parameter) {
|
|
||||||
//not implemented
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ArduinoCommInterface::getParameter(Cookie *cookie) {
|
|
||||||
//not implemented
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoCommInterface::sendMessage(uint8_t command,
|
|
||||||
uint8_t address, const uint8_t *data, size_t dataLen) {
|
|
||||||
if (dataLen > UINT16_MAX) {
|
|
||||||
return TOO_MUCH_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
//being conservative here
|
|
||||||
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
|
|
||||||
|
|
||||||
sendBuffer[0] = DleEncoder::STX;
|
|
||||||
|
|
||||||
uint8_t *currentPosition = sendBuffer + 1;
|
|
||||||
size_t remainingLen = sizeof(sendBuffer) - 1;
|
|
||||||
uint32_t encodedLen;
|
|
||||||
|
|
||||||
ReturnValue_t result = DleEncoder::encode(&command, 1, currentPosition,
|
|
||||||
remainingLen, &encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen,
|
|
||||||
&encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
uint8_t temporaryBuffer[2];
|
|
||||||
|
|
||||||
//note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
|
|
||||||
temporaryBuffer[0] = dataLen >> 8; //we checked dataLen above
|
|
||||||
temporaryBuffer[1] = dataLen;
|
|
||||||
|
|
||||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
|
||||||
remainingLen, &encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
//encoding the actual data
|
|
||||||
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen,
|
|
||||||
&encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
uint16_t crc = CRC::crc16ccitt(&command, 1);
|
|
||||||
crc = CRC::crc16ccitt(&address, 1, crc);
|
|
||||||
//fortunately the length is still there
|
|
||||||
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
|
|
||||||
crc = CRC::crc16ccitt(data, dataLen, crc);
|
|
||||||
|
|
||||||
temporaryBuffer[0] = crc >> 8;
|
|
||||||
temporaryBuffer[1] = crc;
|
|
||||||
|
|
||||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
|
||||||
remainingLen, &encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
if (remainingLen > 0) {
|
|
||||||
*currentPosition = DleEncoder::ETX;
|
|
||||||
}
|
|
||||||
remainingLen -= 1;
|
|
||||||
|
|
||||||
encodedLen = sizeof(sendBuffer) - remainingLen;
|
|
||||||
|
|
||||||
ssize_t writtenlen = write(serialPort, sendBuffer, encodedLen);
|
|
||||||
if (writtenlen < 0) {
|
|
||||||
//we could try to find out what happened...
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
if (writtenlen != encodedLen) {
|
|
||||||
//the OS failed us, we do not try to block until everything is written, as
|
|
||||||
//we can not block the whole system here
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArduinoCommInterface::handleSerialPortRx() {
|
|
||||||
uint32_t availableSpace = rxBuffer.availableWriteSpace();
|
|
||||||
|
|
||||||
uint8_t dataFromSerial[availableSpace];
|
|
||||||
|
|
||||||
ssize_t bytesRead = read(serialPort, dataFromSerial,
|
|
||||||
sizeof(dataFromSerial));
|
|
||||||
|
|
||||||
if (bytesRead < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rxBuffer.writeData(dataFromSerial, bytesRead);
|
|
||||||
|
|
||||||
uint8_t dataReceivedSoFar[rxBuffer.maxSize()];
|
|
||||||
|
|
||||||
uint32_t dataLenReceivedSoFar = 0;
|
|
||||||
|
|
||||||
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true,
|
|
||||||
&dataLenReceivedSoFar);
|
|
||||||
|
|
||||||
//look for STX
|
|
||||||
size_t firstSTXinRawData = 0;
|
|
||||||
while ((firstSTXinRawData < dataLenReceivedSoFar)
|
|
||||||
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX)) {
|
|
||||||
firstSTXinRawData++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX) {
|
|
||||||
//there is no STX in our data, throw it away...
|
|
||||||
rxBuffer.deleteData(dataLenReceivedSoFar);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t packet[MAX_PACKET_SIZE];
|
|
||||||
uint32_t packetLen;
|
|
||||||
|
|
||||||
uint32_t readSize;
|
|
||||||
|
|
||||||
ReturnValue_t result = DleEncoder::decode(
|
|
||||||
dataReceivedSoFar + firstSTXinRawData,
|
|
||||||
dataLenReceivedSoFar - firstSTXinRawData, &readSize, packet,
|
|
||||||
sizeof(packet), &packetLen);
|
|
||||||
|
|
||||||
size_t toDelete = firstSTXinRawData;
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
handlePacket(packet, packetLen);
|
|
||||||
|
|
||||||
//after handling the packet, we can delete it from the raw stream, it has been copied to packet
|
|
||||||
toDelete += readSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove Data which was processed
|
|
||||||
rxBuffer.deleteData(toDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArduinoCommInterface::handlePacket(uint8_t *packet, size_t packetLen) {
|
|
||||||
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
|
|
||||||
if (crc != 0) {
|
|
||||||
//CRC error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t command = packet[0];
|
|
||||||
uint8_t address = packet[1];
|
|
||||||
|
|
||||||
uint16_t size = (packet[2] << 8) + packet[3];
|
|
||||||
|
|
||||||
if (size != packetLen - 6) {
|
|
||||||
//Invalid Length
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (command) {
|
|
||||||
case ArduinoCookie::SPI: {
|
|
||||||
ArduinoCookie **itsComplicated;
|
|
||||||
ReturnValue_t result = spiMap.find(address, &itsComplicated);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
//we do no know this address
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ArduinoCookie *theActualCookie = *itsComplicated;
|
|
||||||
if (packetLen > theActualCookie->maxReplySize + 6) {
|
|
||||||
packetLen = theActualCookie->maxReplySize + 6;
|
|
||||||
}
|
|
||||||
memcpy(theActualCookie->replyBuffer, packet + 4, packetLen - 6);
|
|
||||||
theActualCookie->receivedDataLen = packetLen - 6;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
//#ifndef MISSION_ARDUINOCOMMINTERFACE_H_
|
|
||||||
//#define MISSION_ARDUINOCOMMINTERFACE_H_
|
|
||||||
//
|
|
||||||
//#include <bits/stdint-uintn.h>
|
|
||||||
//#include <framework/container/FixedMap.h>
|
|
||||||
//#include <framework/container/SimpleRingBuffer.h>
|
|
||||||
//#include <framework/devicehandlers/DeviceCommunicationIF.h>
|
|
||||||
//#include <framework/returnvalues/HasReturnvaluesIF.h>
|
|
||||||
//#include <stddef.h>
|
|
||||||
//
|
|
||||||
//#include "../../framework/objectmanager/SystemObject.h"
|
|
||||||
//#include "ArduinoCookie.h"
|
|
||||||
//
|
|
||||||
////Forward declaration, so users don't peek
|
|
||||||
//class ArduinoCookie;
|
|
||||||
//
|
|
||||||
//class ArduinoComIF: public SystemObject,
|
|
||||||
// public DeviceCommunicationIF {
|
|
||||||
//public:
|
|
||||||
// static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
|
|
||||||
// static const uint8_t MAX_PACKET_SIZE = 64;
|
|
||||||
//
|
|
||||||
// static const uint8_t COMMAND_INVALID = -1;
|
|
||||||
// static const uint8_t COMMAND_SPI = 1;
|
|
||||||
//
|
|
||||||
// ArduinoComIF(object_id_t setObjectId, const char *serialDevice);
|
|
||||||
// virtual ~ArduinoComIF();
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
|
|
||||||
// uint32_t maxReplyLen);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
|
|
||||||
// uint32_t maxReplyLen);
|
|
||||||
//
|
|
||||||
// virtual void close(Cookie *cookie);
|
|
||||||
//
|
|
||||||
// //SHOULDDO can data be const?
|
|
||||||
// virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
|
|
||||||
// uint32_t len);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t getSendSuccess(Cookie *cookie);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t requestReceiveMessage(Cookie *cookie);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
|
|
||||||
// uint32_t *size);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address);
|
|
||||||
//
|
|
||||||
// virtual uint32_t getAddress(Cookie *cookie);
|
|
||||||
//
|
|
||||||
// virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter);
|
|
||||||
//
|
|
||||||
// virtual uint32_t getParameter(Cookie *cookie);
|
|
||||||
//private:
|
|
||||||
// //remembering if the initialization in the ctor worked
|
|
||||||
// //if not, all calls are disabled
|
|
||||||
// bool initialized;
|
|
||||||
// int serialPort;
|
|
||||||
// //used to know where to put the data if a reply is received
|
|
||||||
// FixedMap<uint8_t, ArduinoCookie*> spiMap;
|
|
||||||
//
|
|
||||||
// SimpleRingBuffer rxBuffer;
|
|
||||||
//
|
|
||||||
// ReturnValue_t sendMessage(uint8_t command, uint8_t address,
|
|
||||||
// const uint8_t *data, size_t dataLen);
|
|
||||||
//
|
|
||||||
// void handleSerialPortRx();
|
|
||||||
//
|
|
||||||
// void handlePacket(uint8_t *packet, size_t packetLen);
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */
|
|
@ -1,12 +0,0 @@
|
|||||||
//#include <mission/Arduino/ArduinoCookie.h>
|
|
||||||
//
|
|
||||||
//ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
|
|
||||||
// size_t maxReplySize) :
|
|
||||||
// command(protocol), address(address), receivedDataLen(0), maxReplySize(
|
|
||||||
// maxReplySize) {
|
|
||||||
// replyBuffer = new uint8_t[maxReplySize];
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//ArduinoCookie::~ArduinoCookie() {
|
|
||||||
// delete[] replyBuffer;
|
|
||||||
//}
|
|
@ -1,25 +0,0 @@
|
|||||||
//#ifndef MISSION_ARDUINO_ARDUINOCOOKIE_H_
|
|
||||||
//#define MISSION_ARDUINO_ARDUINOCOOKIE_H_
|
|
||||||
//
|
|
||||||
//#include <framework/devicehandlers/Cookie.h>
|
|
||||||
//
|
|
||||||
//#include <stdint.h>
|
|
||||||
//#include <stdlib.h>
|
|
||||||
//
|
|
||||||
//class ArduinoCookie: public Cookie {
|
|
||||||
//public:
|
|
||||||
// enum Protocol_t {
|
|
||||||
// INVALID = 0, SPI = 1
|
|
||||||
// };
|
|
||||||
// ArduinoCookie(Protocol_t protocol, uint8_t address, size_t maxReplySize);
|
|
||||||
// virtual ~ArduinoCookie();
|
|
||||||
//
|
|
||||||
// uint8_t command;
|
|
||||||
// uint8_t address;
|
|
||||||
// uint8_t *replyBuffer;
|
|
||||||
// size_t receivedDataLen;
|
|
||||||
// size_t maxReplySize;
|
|
||||||
//
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//#endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */
|
|
14
bsp_q7s/CMakeLists.txt
Normal file
14
bsp_q7s/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
target_sources(${TARGET_NAME} PUBLIC
|
||||||
|
InitMission.cpp
|
||||||
|
main.cpp
|
||||||
|
ObjectFactory.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(boardconfig)
|
||||||
|
add_subdirectory(comIF)
|
||||||
|
add_subdirectory(devices)
|
||||||
|
add_subdirectory(boardtest)
|
||||||
|
add_subdirectory(gpio)
|
||||||
|
|
||||||
|
|
||||||
|
|
205
bsp_q7s/InitMission.cpp
Normal file
205
bsp_q7s/InitMission.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
#include "InitMission.h"
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
#include <OBSWConfig.h>
|
||||||
|
|
||||||
|
#include <mission/utility/InitMission.h>
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
|
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <fsfwconfig/pollingsequence/pollingSequenceFactory.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/* This is configured for linux without CR */
|
||||||
|
#ifdef LINUX
|
||||||
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
|
ServiceInterfaceStream sif::info("INFO");
|
||||||
|
ServiceInterfaceStream sif::warning("WARNING");
|
||||||
|
ServiceInterfaceStream sif::error("ERROR", false, false, true);
|
||||||
|
#else
|
||||||
|
ServiceInterfaceStream sif::debug("DEBUG", true);
|
||||||
|
ServiceInterfaceStream sif::info("INFO", true);
|
||||||
|
ServiceInterfaceStream sif::warning("WARNING", true);
|
||||||
|
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ObjectManagerIF *objectManager = nullptr;
|
||||||
|
|
||||||
|
void initmission::initMission() {
|
||||||
|
sif::info << "Building global objects.." << std::endl;
|
||||||
|
/* Instantiate global object manager and also create all objects */
|
||||||
|
objectManager = new ObjectManager(ObjectFactory::produce);
|
||||||
|
sif::info << "Initializing all objects.." << std::endl;
|
||||||
|
objectManager->initialize();
|
||||||
|
|
||||||
|
/* This function creates and starts all tasks */
|
||||||
|
initTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initmission::initTasks() {
|
||||||
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
|
if(factory == nullptr) {
|
||||||
|
/* Should never happen ! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
|
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
||||||
|
#else
|
||||||
|
void (*missedDeadlineFunc) (void) = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TMTC Distribution */
|
||||||
|
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||||
|
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
ReturnValue_t result = tmTcDistributor->addComponent(
|
||||||
|
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UDP bridge */
|
||||||
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
|
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE);
|
||||||
|
}
|
||||||
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
|
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
|
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUS Services */
|
||||||
|
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||||
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||||
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
}
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
||||||
|
if(result!=HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Add handling of missed deadlines
|
||||||
|
/* Polling Sequence Table Default */
|
||||||
|
#if Q7S_ADD_SPI_TEST == 0
|
||||||
|
FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask(
|
||||||
|
"PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
|
||||||
|
missedDeadlineFunc);
|
||||||
|
result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TE0720 == 0
|
||||||
|
FixedTimeslotTaskIF* gomSpacePstTask = factory->
|
||||||
|
createFixedTimeslotTask("GS_PST_TASK", 50,
|
||||||
|
PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc);
|
||||||
|
result = pst::gomspacePstInit(gomSpacePstTask);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||||
|
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
|
||||||
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if Q7S_ADD_SPI_TEST == 1
|
||||||
|
result = testTask->addComponent(objects::SPI_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
#if TE0720 == 1 && TEST_LIBGPIOD == 1
|
||||||
|
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
||||||
|
}
|
||||||
|
#endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */
|
||||||
|
|
||||||
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
|
tmTcDistributor->startTask();
|
||||||
|
udpBridgeTask->startTask();
|
||||||
|
udpPollingTask->startTask();
|
||||||
|
|
||||||
|
#if TE0720 == 0
|
||||||
|
gomSpacePstTask->startTask();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if Q7S_ADD_SPI_TEST == 0
|
||||||
|
pollingSequenceTableTaskDefault->startTask();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pusVerification->startTask();
|
||||||
|
pusEvents->startTask();
|
||||||
|
pusHighPrio->startTask();
|
||||||
|
pusMedPrio->startTask();
|
||||||
|
pusLowPrio->startTask();
|
||||||
|
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
testTask->startTask();
|
||||||
|
#endif
|
||||||
|
sif::info << "Tasks started.." << std::endl;
|
||||||
|
}
|
9
bsp_q7s/InitMission.h
Normal file
9
bsp_q7s/InitMission.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef BSP_Q7S_INITMISSION_H_
|
||||||
|
#define BSP_Q7S_INITMISSION_H_
|
||||||
|
|
||||||
|
namespace initmission {
|
||||||
|
void initMission();
|
||||||
|
void initTasks();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* BSP_Q7S_INITMISSION_H_ */
|
439
bsp_q7s/ObjectFactory.cpp
Normal file
439
bsp_q7s/ObjectFactory.cpp
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
#include "ObjectFactory.h"
|
||||||
|
#include <OBSWConfig.h>
|
||||||
|
#include <tmtc/apid.h>
|
||||||
|
#include <devices/addresses.h>
|
||||||
|
#include <devices/gpioIds.h>
|
||||||
|
#include <tmtc/pusIds.h>
|
||||||
|
#include <devices/powerSwitcherList.h>
|
||||||
|
#include <devices/spi.h>
|
||||||
|
|
||||||
|
#include <bsp_q7s/devices/HeaterHandler.h>
|
||||||
|
#include <bsp_q7s/devices/SolarArrayDeploymentHandler.h>
|
||||||
|
#include <bsp_q7s/gpio/gpioCallbacks.h>
|
||||||
|
|
||||||
|
#include <mission/core/GenericFactory.h>
|
||||||
|
#include <mission/devices/PDU1Handler.h>
|
||||||
|
#include <mission/devices/PDU2Handler.h>
|
||||||
|
#include <mission/devices/ACUHandler.h>
|
||||||
|
#include <mission/devices/PCDUHandler.h>
|
||||||
|
#include <mission/devices/P60DockHandler.h>
|
||||||
|
#include <mission/devices/Tmp1075Handler.h>
|
||||||
|
#include <mission/devices/Max31865PT1000Handler.h>
|
||||||
|
#include <mission/devices/IMTQHandler.h>
|
||||||
|
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
|
||||||
|
#include <mission/devices/SyrlinksHkHandler.h>
|
||||||
|
#include <mission/devices/MGMHandlerLIS3MDL.h>
|
||||||
|
#include <mission/devices/MGMHandlerRM3100.h>
|
||||||
|
#include <mission/devices/GyroL3GD20Handler.h>
|
||||||
|
|
||||||
|
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||||
|
#include <mission/devices/devicedefinitions/SyrlinksDefinitions.h>
|
||||||
|
#include <mission/utility/TmFunnel.h>
|
||||||
|
|
||||||
|
#include <linux/csp/CspCookie.h>
|
||||||
|
#include <linux/csp/CspComIF.h>
|
||||||
|
|
||||||
|
#include <linux/uart/UartComIF.h>
|
||||||
|
#include <linux/uart/UartCookie.h>
|
||||||
|
|
||||||
|
#include <fsfw_hal/linux/i2c/I2cCookie.h>
|
||||||
|
#include <fsfw_hal/linux/i2c/I2cComIF.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
|
||||||
|
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
|
||||||
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
|
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||||
|
|
||||||
|
/* UDP server includes */
|
||||||
|
#include <fsfw/osal/common/UdpTmTcBridge.h>
|
||||||
|
#include <fsfw/osal/common/UdpTcPollingTask.h>
|
||||||
|
#include <linux/boardtest/SpiTestClass.h>
|
||||||
|
|
||||||
|
#if TEST_LIBGPIOD == 1
|
||||||
|
#include <linux/boardtest/LibgpiodTest.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
|
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
|
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
|
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
||||||
|
// No storage object for now.
|
||||||
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
||||||
|
|
||||||
|
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||||
|
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ObjectFactory::produce(){
|
||||||
|
Factory::setStaticFrameworkObjectIds();
|
||||||
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
|
#if TE0720 == 1
|
||||||
|
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
|
||||||
|
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
|
||||||
|
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
|
||||||
|
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
|
||||||
|
#else
|
||||||
|
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
|
||||||
|
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
|
||||||
|
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
|
||||||
|
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
|
||||||
|
#endif
|
||||||
|
LinuxLibgpioIF* gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
||||||
|
|
||||||
|
/* Communication interfaces */
|
||||||
|
new CspComIF(objects::CSP_COM_IF);
|
||||||
|
new I2cComIF(objects::I2C_COM_IF);
|
||||||
|
new UartComIF(objects::UART_COM_IF);
|
||||||
|
#if Q7S_ADD_SPI_TEST == 0
|
||||||
|
new SpiComIF(objects::SPI_COM_IF, gpioComIF);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Temperature sensors */
|
||||||
|
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
|
||||||
|
objects::TMP1075_HANDLER_1, objects::I2C_COM_IF,
|
||||||
|
i2cCookieTmp1075tcs1);
|
||||||
|
tmp1075Handler_1->setStartUpImmediately();
|
||||||
|
Tmp1075Handler* tmp1075Handler_2 = new Tmp1075Handler(
|
||||||
|
objects::TMP1075_HANDLER_2, objects::I2C_COM_IF,
|
||||||
|
i2cCookieTmp1075tcs2);
|
||||||
|
tmp1075Handler_2->setStartUpImmediately();
|
||||||
|
|
||||||
|
GpioCookie* heaterGpiosCookie = new GpioCookie;
|
||||||
|
|
||||||
|
#if TE0720 == 0
|
||||||
|
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH,
|
||||||
|
addresses::P60DOCK);
|
||||||
|
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
|
||||||
|
addresses::PDU1);
|
||||||
|
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH,
|
||||||
|
addresses::PDU2);
|
||||||
|
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH,
|
||||||
|
addresses::ACU);
|
||||||
|
/* Device Handler */
|
||||||
|
P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER,
|
||||||
|
objects::CSP_COM_IF, p60DockCspCookie);
|
||||||
|
PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER,
|
||||||
|
objects::CSP_COM_IF, pdu1CspCookie);
|
||||||
|
PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER,
|
||||||
|
objects::CSP_COM_IF, pdu2CspCookie);
|
||||||
|
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER,
|
||||||
|
objects::CSP_COM_IF, acuCspCookie);
|
||||||
|
new PCDUHandler(objects::PCDU_HANDLER, 50);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting PCDU devices to mode normal immediately after start up because PCDU is always
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
/** For now this needs to be commented out because there is no PCDU connected to the OBC */
|
||||||
|
// p60dockhandler->setModeNormal();
|
||||||
|
// pdu1handler->setModeNormal();
|
||||||
|
// pdu2handler->setModeNormal();
|
||||||
|
// acuhandler->setModeNormal();
|
||||||
|
(void) p60dockhandler;
|
||||||
|
(void) pdu1handler;
|
||||||
|
(void) pdu2handler;
|
||||||
|
(void) acuhandler;
|
||||||
|
|
||||||
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
|
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||||
|
GpiodRegular* gpio = nullptr;
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 1, std::string("CS_GYRO_1_ADIS"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 7, std::string("CS_GYRO_2_L3G"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 3, std::string("CS_GYRO_3_L3G"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_L3G_CS, gpio);
|
||||||
|
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 5, std::string("CS_MGM_0_LIS3_A"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
|
||||||
|
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 17, std::string("CS_MGM_1_RM3100_A"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||||
|
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip6"), 0, std::string("CS_MGM_2_LIS3_B"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
|
||||||
|
|
||||||
|
gpio = new GpiodRegular(std::string("gpiochip5"), 10, std::string("CS_MGM_3_RM3100_B"),
|
||||||
|
gpio::OUT, gpio::HIGH);
|
||||||
|
gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
|
||||||
|
|
||||||
|
gpioComIF->addGpios(gpioCookieAcsBoard);
|
||||||
|
|
||||||
|
std::string spiDev = "/dev/spidev2.0";
|
||||||
|
SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
|
||||||
|
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
||||||
|
auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER,
|
||||||
|
objects::SPI_COM_IF, spiCookie);
|
||||||
|
mgmLis3Handler->setStartUpImmediately();
|
||||||
|
|
||||||
|
spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev,
|
||||||
|
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
||||||
|
auto mgmLis3Handler2 = new MGMHandlerLIS3MDL(objects::MGM_2_LIS3_HANDLER,
|
||||||
|
objects::SPI_COM_IF, spiCookie);
|
||||||
|
mgmLis3Handler2->setStartUpImmediately();
|
||||||
|
|
||||||
|
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
|
||||||
|
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
||||||
|
auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER,
|
||||||
|
objects::SPI_COM_IF, spiCookie);
|
||||||
|
mgmRm3100Handler->setStartUpImmediately();
|
||||||
|
|
||||||
|
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
|
||||||
|
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
|
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
|
||||||
|
spiCookie);
|
||||||
|
gyroL3gHandler->setStartUpImmediately();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pin H2-11 on stack connector */
|
||||||
|
GpiodRegular* gpioConfigHeater0 = new GpiodRegular(std::string("gpiochip7"), 6,
|
||||||
|
std::string("Heater0"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0);
|
||||||
|
|
||||||
|
/* Pin H2-12 on stack connector */
|
||||||
|
GpiodRegular* gpioConfigHeater1 = new GpiodRegular(std::string("gpiochip7"), 12,
|
||||||
|
std::string("Heater1"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1);
|
||||||
|
|
||||||
|
/* Pin H2-13 on stack connector */
|
||||||
|
GpiodRegular* gpioConfigHeater2 = new GpiodRegular(std::string("gpiochip7"), 7,
|
||||||
|
std::string("Heater2"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2);
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigHeater3 = new GpiodRegular(std::string("gpiochip7"), 5,
|
||||||
|
std::string("Heater3"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3);
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigHeater4 = new GpiodRegular(std::string("gpiochip7"), 3,
|
||||||
|
std::string("Heater4"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4);
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigHeater5 = new GpiodRegular(std::string("gpiochip7"), 0,
|
||||||
|
std::string("Heater5"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5);
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigHeater6 = new GpiodRegular(std::string("gpiochip7"), 1,
|
||||||
|
std::string("Heater6"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6);
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigHeater7 = new GpiodRegular(std::string("gpiochip7"), 11,
|
||||||
|
std::string("Heater7"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7);
|
||||||
|
|
||||||
|
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie,
|
||||||
|
objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN);
|
||||||
|
|
||||||
|
GpioCookie* solarArrayDeplCookie = new GpioCookie;
|
||||||
|
|
||||||
|
GpiodRegular* gpioConfigDeplSA0 = new GpiodRegular(std::string("gpiochip7"), 4,
|
||||||
|
std::string("DeplSA1"), gpio::OUT, 0);
|
||||||
|
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA0);
|
||||||
|
GpiodRegular* gpioConfigDeplSA1 = new GpiodRegular(std::string("gpiochip7"), 2,
|
||||||
|
std::string("DeplSA2"), gpio::OUT, 0);
|
||||||
|
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA1);
|
||||||
|
|
||||||
|
//TODO: Find out burn time. For now set to 1000 ms.
|
||||||
|
new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF,
|
||||||
|
solarArrayDeplCookie, objects::PCDU_HANDLER, pcduSwitches::DEPLOYMENT_MECHANISM,
|
||||||
|
gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000);
|
||||||
|
|
||||||
|
UartCookie* syrlinksUartCookie = new UartCookie(
|
||||||
|
std::string("/dev/ttyUL0"), 38400, SYRLINKS::MAX_REPLY_SIZE);
|
||||||
|
syrlinksUartCookie->setParityEven();
|
||||||
|
|
||||||
|
SyrlinksHkHandler* syrlinksHkHandler = new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER,
|
||||||
|
objects::UART_COM_IF, syrlinksUartCookie);
|
||||||
|
syrlinksHkHandler->setModeNormal();
|
||||||
|
|
||||||
|
#if Q7S_ADD_RTD_DEVICES == 1
|
||||||
|
GpioCookie* rtdGpioCookie = new GpioCookie;
|
||||||
|
|
||||||
|
gpioCallbacks::initTcsBoardDecoder(gpioComIF);
|
||||||
|
GpioCallback* gpioRtdIc3 = new GpioCallback(std::string("Chip select RTD IC3"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC3, gpioRtdIc3);
|
||||||
|
GpioCallback* gpioRtdIc4 = new GpioCallback(std::string("Chip select RTD IC4"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC4, gpioRtdIc4);
|
||||||
|
GpioCallback* gpioRtdIc5 = new GpioCallback(std::string("Chip select RTD IC5"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC5, gpioRtdIc5);
|
||||||
|
GpioCallback* gpioRtdIc6 = new GpioCallback(std::string("Chip select RTD IC6"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC6, gpioRtdIc6);
|
||||||
|
GpioCallback* gpioRtdIc7 = new GpioCallback(std::string("Chip select RTD IC7"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC7, gpioRtdIc7);
|
||||||
|
GpioCallback* gpioRtdIc8 = new GpioCallback(std::string("Chip select RTD IC8"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC8, gpioRtdIc8);
|
||||||
|
GpioCallback* gpioRtdIc9 = new GpioCallback(std::string("Chip select RTD IC9"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC9, gpioRtdIc9);
|
||||||
|
GpioCallback* gpioRtdIc10 = new GpioCallback(std::string("Chip select RTD IC10"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC10, gpioRtdIc10);
|
||||||
|
GpioCallback* gpioRtdIc11 = new GpioCallback(std::string("Chip select RTD IC11"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC11, gpioRtdIc11);
|
||||||
|
GpioCallback* gpioRtdIc12 = new GpioCallback(std::string("Chip select RTD IC12"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC12, gpioRtdIc12);
|
||||||
|
GpioCallback* gpioRtdIc13 = new GpioCallback(std::string("Chip select RTD IC13"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC13, gpioRtdIc13);
|
||||||
|
GpioCallback* gpioRtdIc14 = new GpioCallback(std::string("Chip select RTD IC14"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC14, gpioRtdIc14);
|
||||||
|
GpioCallback* gpioRtdIc15 = new GpioCallback(std::string("Chip select RTD IC15"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC15, gpioRtdIc15);
|
||||||
|
GpioCallback* gpioRtdIc16 = new GpioCallback(std::string("Chip select RTD IC16"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC16, gpioRtdIc16);
|
||||||
|
GpioCallback* gpioRtdIc17 = new GpioCallback(std::string("Chip select RTD IC17"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC17, gpioRtdIc17);
|
||||||
|
GpioCallback* gpioRtdIc18 = new GpioCallback(std::string("Chip select RTD IC18"), gpio::OUT, 1,
|
||||||
|
&gpioCallbacks::tcsBoardDecoderCallback, gpioComIF);
|
||||||
|
rtdGpioCookie->addGpio(gpioIds::RTD_IC18, gpioRtdIc18);
|
||||||
|
|
||||||
|
gpioComIF->addGpios(rtdGpioCookie);
|
||||||
|
|
||||||
|
SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC3, gpioIds::RTD_IC3,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC4, gpioIds::RTD_IC4,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc5 = new SpiCookie(addresses::RTD_IC5, gpioIds::RTD_IC5,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc6 = new SpiCookie(addresses::RTD_IC6, gpioIds::RTD_IC6,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc7 = new SpiCookie(addresses::RTD_IC7, gpioIds::RTD_IC7,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc8 = new SpiCookie(addresses::RTD_IC8, gpioIds::RTD_IC8,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc9 = new SpiCookie(addresses::RTD_IC9, gpioIds::RTD_IC9,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc10 = new SpiCookie(addresses::RTD_IC10, gpioIds::RTD_IC10,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc11 = new SpiCookie(addresses::RTD_IC11, gpioIds::RTD_IC11,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc12 = new SpiCookie(addresses::RTD_IC12, gpioIds::RTD_IC12,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc13 = new SpiCookie(addresses::RTD_IC13, gpioIds::RTD_IC13,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc14 = new SpiCookie(addresses::RTD_IC14, gpioIds::RTD_IC14,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc15 = new SpiCookie(addresses::RTD_IC15, gpioIds::RTD_IC15,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc16 = new SpiCookie(addresses::RTD_IC16, gpioIds::RTD_IC16,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc17 = new SpiCookie(addresses::RTD_IC17, gpioIds::RTD_IC17,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
SpiCookie* spiRtdIc18 = new SpiCookie(addresses::RTD_IC18, gpioIds::RTD_IC18,
|
||||||
|
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
|
||||||
|
spi::SpiModes::MODE_1, 2000000);
|
||||||
|
|
||||||
|
Max31865PT1000Handler* rtdIc3 = new Max31865PT1000Handler(objects::RTD_IC3, objects::SPI_COM_IF, spiRtdIc3, 0); // 0 is switchId
|
||||||
|
Max31865PT1000Handler* rtdIc4 = new Max31865PT1000Handler(objects::RTD_IC4, objects::SPI_COM_IF, spiRtdIc4, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc5 = new Max31865PT1000Handler(objects::RTD_IC5, objects::SPI_COM_IF, spiRtdIc5, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc6 = new Max31865PT1000Handler(objects::RTD_IC6, objects::SPI_COM_IF, spiRtdIc6, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc7 = new Max31865PT1000Handler(objects::RTD_IC7, objects::SPI_COM_IF, spiRtdIc7, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc8 = new Max31865PT1000Handler(objects::RTD_IC8, objects::SPI_COM_IF, spiRtdIc8, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc9 = new Max31865PT1000Handler(objects::RTD_IC9, objects::SPI_COM_IF, spiRtdIc9, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc10 = new Max31865PT1000Handler(objects::RTD_IC10, objects::SPI_COM_IF, spiRtdIc10, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc11 = new Max31865PT1000Handler(objects::RTD_IC11, objects::SPI_COM_IF, spiRtdIc11, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc12 = new Max31865PT1000Handler(objects::RTD_IC12, objects::SPI_COM_IF, spiRtdIc12, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc13 = new Max31865PT1000Handler(objects::RTD_IC13, objects::SPI_COM_IF, spiRtdIc13, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc14 = new Max31865PT1000Handler(objects::RTD_IC14, objects::SPI_COM_IF, spiRtdIc14, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc15 = new Max31865PT1000Handler(objects::RTD_IC15, objects::SPI_COM_IF, spiRtdIc15, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc16 = new Max31865PT1000Handler(objects::RTD_IC16, objects::SPI_COM_IF, spiRtdIc16, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc17 = new Max31865PT1000Handler(objects::RTD_IC17, objects::SPI_COM_IF, spiRtdIc17, 0);
|
||||||
|
Max31865PT1000Handler* rtdIc18 = new Max31865PT1000Handler(objects::RTD_IC18, objects::SPI_COM_IF, spiRtdIc18, 0);
|
||||||
|
// rtdIc10->setStartUpImmediately();
|
||||||
|
// rtdIc4->setStartUpImmediately();
|
||||||
|
|
||||||
|
(void) rtdIc3;
|
||||||
|
(void) rtdIc4;
|
||||||
|
(void) rtdIc5;
|
||||||
|
(void) rtdIc6;
|
||||||
|
(void) rtdIc7;
|
||||||
|
(void) rtdIc8;
|
||||||
|
(void) rtdIc9;
|
||||||
|
(void) rtdIc10;
|
||||||
|
(void) rtdIc11;
|
||||||
|
(void) rtdIc12;
|
||||||
|
(void) rtdIc13;
|
||||||
|
(void) rtdIc14;
|
||||||
|
(void) rtdIc15;
|
||||||
|
(void) rtdIc16;
|
||||||
|
(void) rtdIc17;
|
||||||
|
(void) rtdIc18;
|
||||||
|
|
||||||
|
#endif /* Q7S_ADD_RTD_DEVICES == 1 */
|
||||||
|
|
||||||
|
#endif /* TE0720 == 0 */
|
||||||
|
|
||||||
|
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE,
|
||||||
|
objects::TC_STORE);
|
||||||
|
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
||||||
|
|
||||||
|
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE,
|
||||||
|
std::string("/dev/i2c-0"));
|
||||||
|
IMTQHandler* imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie);
|
||||||
|
imtqHandler->setStartUpImmediately();
|
||||||
|
|
||||||
|
#if TE0720 == 1 && TEST_LIBGPIOD == 1
|
||||||
|
/* Configure MIO0 as input */
|
||||||
|
GpiodRegular gpioConfigMio0(std::string("gpiochip0"), 0,
|
||||||
|
std::string("MIO0"), gpio::IN, 0);
|
||||||
|
GpioCookie* gpioCookie = new GpioCookie;
|
||||||
|
gpioCookie->addGpio(gpioIds::TEST_ID_0, gpioConfigMio0);
|
||||||
|
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie);
|
||||||
|
#elif TE0720 == 1
|
||||||
|
/* Configuration for MIO0 on TE0720-03-1CFA */
|
||||||
|
GpiodRegular gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
|
||||||
|
std::string("Heater0"), gpio::OUT, 0);
|
||||||
|
heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater);
|
||||||
|
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie,
|
||||||
|
objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if Q7S_ADD_SPI_TEST == 1
|
||||||
|
new SpiTestClass(objects::SPI_TEST, gpioComIF);
|
||||||
|
#endif
|
||||||
|
}
|
9
bsp_q7s/ObjectFactory.h
Normal file
9
bsp_q7s/ObjectFactory.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef BSP_Q7S_OBJECTFACTORY_H_
|
||||||
|
#define BSP_Q7S_OBJECTFACTORY_H_
|
||||||
|
|
||||||
|
namespace ObjectFactory {
|
||||||
|
void setStatics();
|
||||||
|
void produce();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */
|
10
bsp_q7s/boardconfig/CMakeLists.txt
Normal file
10
bsp_q7s/boardconfig/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
print.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
#include "print.h"
|
#include <bsp_q7s/boardconfig/print.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
13
bsp_q7s/boardconfig/q7s_config.h
Normal file
13
bsp_q7s/boardconfig/q7s_config.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
|
||||||
|
#define BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
|
||||||
|
|
||||||
|
#define Q7S_ADD_RTD_DEVICES 0
|
||||||
|
|
||||||
|
/* Only one of those 2 should be enabled! */
|
||||||
|
/* Add code for ACS board */
|
||||||
|
#define OBSW_ADD_ACS_BOARD 0
|
||||||
|
#define Q7S_ADD_SPI_TEST 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_ */
|
6
bsp_q7s/boardtest/CMakeLists.txt
Normal file
6
bsp_q7s/boardtest/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
6
bsp_q7s/bsp_q7s.mk
Normal file
6
bsp_q7s/bsp_q7s.mk
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/comIF/cookies/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(CURRENTPATH)/comIF/*.cpp)
|
||||||
|
CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
||||||
|
|
||||||
|
CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)
|
6
bsp_q7s/comIF/CMakeLists.txt
Normal file
6
bsp_q7s/comIF/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
4
bsp_q7s/devices/CMakeLists.txt
Normal file
4
bsp_q7s/devices/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
HeaterHandler.cpp
|
||||||
|
SolarArrayDeploymentHandler.cpp
|
||||||
|
)
|
370
bsp_q7s/devices/HeaterHandler.cpp
Normal file
370
bsp_q7s/devices/HeaterHandler.cpp
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
#include "HeaterHandler.h"
|
||||||
|
#include <fsfwconfig/devices/powerSwitcherList.h>
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
#include <devices/gpioIds.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
|
||||||
|
HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_,
|
||||||
|
CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) :
|
||||||
|
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
|
||||||
|
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
|
||||||
|
actionHelper(this, nullptr) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
||||||
|
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
HeaterHandler::~HeaterHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
|
||||||
|
|
||||||
|
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
|
||||||
|
readCommandQueue();
|
||||||
|
handleActiveCommands();
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = initializeHeaterMap();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
|
||||||
|
if (gpioInterface == nullptr) {
|
||||||
|
sif::error << "HeaterHandler::initialize: Invalid Gpio interface." << std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if (IPCStore == nullptr) {
|
||||||
|
sif::error << "HeaterHandler::initialize: IPC store not set up in factory." << std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mainLineSwitcherObjectId != objects::NO_OBJECT) {
|
||||||
|
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
|
||||||
|
if (mainLineSwitcher == nullptr) {
|
||||||
|
sif::error << "HeaterHandler::initialize: Main line switcher failed to fetch object"
|
||||||
|
<< "from object ID." << std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::initializeHeaterMap(){
|
||||||
|
HeaterCommandInfo_t heaterCommandInfo;
|
||||||
|
for(switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
|
||||||
|
std::pair status = heaterMap.emplace(switchNr, heaterCommandInfo);
|
||||||
|
if (status.second == false) {
|
||||||
|
sif::error << "HeaterHandler::initializeHeaterMap: Failed to initialize heater map"
|
||||||
|
<< std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::setInitialSwitchStates() {
|
||||||
|
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
|
||||||
|
switchStates[switchNr] = OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::readCommandQueue() {
|
||||||
|
CommandMessage command;
|
||||||
|
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = actionHelper.handleActionMessage(&command);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||||
|
ReturnValue_t result;
|
||||||
|
if (actionId != SWITCH_HEATER) {
|
||||||
|
result = COMMAND_NOT_SUPPORTED;
|
||||||
|
} else {
|
||||||
|
switchNr_t switchNr = *data;
|
||||||
|
HeaterMapIter heaterMapIter = heaterMap.find(switchNr);
|
||||||
|
if (heaterMapIter != heaterMap.end()) {
|
||||||
|
if (heaterMapIter->second.active) {
|
||||||
|
return COMMAND_ALREADY_WAITING;
|
||||||
|
}
|
||||||
|
heaterMapIter->second.action = *(data + 1);
|
||||||
|
heaterMapIter->second.active = true;
|
||||||
|
heaterMapIter->second.replyQueue = commandedBy;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl;
|
||||||
|
return INVALID_SWITCH_NR;
|
||||||
|
}
|
||||||
|
result = RETURN_OK;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
|
||||||
|
ReturnValue_t onOff) const {
|
||||||
|
|
||||||
|
ReturnValue_t result;
|
||||||
|
store_address_t storeAddress;
|
||||||
|
uint8_t commandData[2];
|
||||||
|
|
||||||
|
switch(onOff) {
|
||||||
|
case PowerSwitchIF::SWITCH_ON:
|
||||||
|
commandData[0] = switchNr;
|
||||||
|
commandData[1] = SET_SWITCH_ON;
|
||||||
|
break;
|
||||||
|
case PowerSwitchIF::SWITCH_OFF:
|
||||||
|
commandData[0] = switchNr;
|
||||||
|
commandData[1] = SET_SWITCH_OFF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData));
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
CommandMessage message;
|
||||||
|
ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress);
|
||||||
|
/* Send heater command to own command queue */
|
||||||
|
result = commandQueue->sendMessage(commandQueue->getId(), &message, 0);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
|
||||||
|
<< "message" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::handleActiveCommands(){
|
||||||
|
|
||||||
|
HeaterMapIter heaterMapIter = heaterMap.begin();
|
||||||
|
for (; heaterMapIter != heaterMap.end(); heaterMapIter++) {
|
||||||
|
if (heaterMapIter->second.active) {
|
||||||
|
switch(heaterMapIter->second.action) {
|
||||||
|
case SET_SWITCH_ON:
|
||||||
|
handleSwitchOnCommand(heaterMapIter);
|
||||||
|
break;
|
||||||
|
case SET_SWITCH_OFF:
|
||||||
|
handleSwitchOffCommand(heaterMapIter);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) {
|
||||||
|
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
switchNr_t switchNr;
|
||||||
|
|
||||||
|
/* Check if command waits for main switch being set on and whether the timeout has expired */
|
||||||
|
if (heaterMapIter->second.waitMainSwitchOn
|
||||||
|
&& heaterMapIter->second.mainSwitchCountdown.hasTimedOut()) {
|
||||||
|
//TODO - This requires the initiation of an FDIR procedure
|
||||||
|
triggerEvent(MAIN_SWITCH_TIMEOUT);
|
||||||
|
sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout"
|
||||||
|
<< std::endl;
|
||||||
|
heaterMapIter->second.active = false;
|
||||||
|
heaterMapIter->second.waitMainSwitchOn = false;
|
||||||
|
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
|
||||||
|
actionHelper.finish(false, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, MAIN_SWITCH_SET_TIMEOUT );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switchNr = heaterMapIter->first;
|
||||||
|
/* Check state of main line switch */
|
||||||
|
ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch);
|
||||||
|
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
|
||||||
|
if (!checkSwitchState(switchNr)) {
|
||||||
|
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
|
||||||
|
result = gpioInterface->pullHigh(gpioId);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id "
|
||||||
|
<< gpioId << " high" << std::endl;
|
||||||
|
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switchStates[switchNr] = ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
triggerEvent(SWITCH_ALREADY_ON, switchNr);
|
||||||
|
}
|
||||||
|
/* There is no need to send action finish replies if the sender was the
|
||||||
|
* HeaterHandler itself. */
|
||||||
|
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
|
||||||
|
if(result == RETURN_OK) {
|
||||||
|
actionHelper.finish(true, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actionHelper.finish(false, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
heaterMapIter->second.active = false;
|
||||||
|
heaterMapIter->second.waitMainSwitchOn = false;
|
||||||
|
}
|
||||||
|
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF
|
||||||
|
&& heaterMapIter->second.waitMainSwitchOn) {
|
||||||
|
/* Just waiting for the main switch being set on */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF) {
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch,
|
||||||
|
PowerSwitchIF::SWITCH_ON);
|
||||||
|
heaterMapIter->second.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||||
|
heaterMapIter->second.waitMainSwitchOn = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of"
|
||||||
|
<< " main line switch" << std::endl;
|
||||||
|
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
|
||||||
|
actionHelper.finish(false, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, mainSwitchState);
|
||||||
|
}
|
||||||
|
heaterMapIter->second.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
switchNr_t switchNr = heaterMapIter->first;
|
||||||
|
/* Check whether switch is already off */
|
||||||
|
if (checkSwitchState(switchNr)) {
|
||||||
|
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
|
||||||
|
result = gpioInterface->pullLow(gpioId);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
|
||||||
|
<< gpioId << " low" << std::endl;
|
||||||
|
triggerEvent(GPIO_PULL_LOW_FAILED, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switchStates[switchNr] = OFF;
|
||||||
|
/* When all switches are off, also main line switch will be turned off */
|
||||||
|
if (allSwitchesOff()) {
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::info << "HeaterHandler::handleSwitchOffCommand: Switch already off" << std::endl;
|
||||||
|
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
|
||||||
|
}
|
||||||
|
if (heaterMapIter->second.replyQueue != NO_COMMANDER) {
|
||||||
|
/* Report back switch command reply if necessary */
|
||||||
|
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
actionHelper.finish(true, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actionHelper.finish(false, heaterMapIter->second.replyQueue,
|
||||||
|
heaterMapIter->second.action, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
heaterMapIter->second.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HeaterHandler::checkSwitchState(int switchNr) {
|
||||||
|
return switchStates[switchNr];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HeaterHandler::allSwitchesOff() {
|
||||||
|
bool allSwitchesOrd = false;
|
||||||
|
/* Or all switches. As soon one switch is on, allSwitchesOrd will be true */
|
||||||
|
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
|
||||||
|
allSwitchesOrd = allSwitchesOrd || switchStates[switchNr];
|
||||||
|
}
|
||||||
|
return !allSwitchesOrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) {
|
||||||
|
gpioId_t gpioId = 0xFFFF;
|
||||||
|
switch(switchNr) {
|
||||||
|
case heaterSwitches::HEATER_0:
|
||||||
|
gpioId = gpioIds::HEATER_0;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_1:
|
||||||
|
gpioId = gpioIds::HEATER_1;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_2:
|
||||||
|
gpioId = gpioIds::HEATER_2;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_3:
|
||||||
|
gpioId = gpioIds::HEATER_3;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_4:
|
||||||
|
gpioId = gpioIds::HEATER_4;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_5:
|
||||||
|
gpioId = gpioIds::HEATER_5;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_6:
|
||||||
|
gpioId = gpioIds::HEATER_6;
|
||||||
|
break;
|
||||||
|
case heaterSwitches::HEATER_7:
|
||||||
|
gpioId = gpioIds::HEATER_7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return gpioId;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t HeaterHandler::getCommandQueue() const {
|
||||||
|
return commandQueue->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) const {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::getSwitchState( uint8_t switchNr ) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HeaterHandler::getFuseState( uint8_t fuseNr ) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HeaterHandler::getSwitchDelayMs(void) const {
|
||||||
|
return 0;
|
||||||
|
}
|
177
bsp_q7s/devices/HeaterHandler.h
Normal file
177
bsp_q7s/devices/HeaterHandler.h
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#ifndef MISSION_DEVICES_HEATERHANDLER_H_
|
||||||
|
#define MISSION_DEVICES_HEATERHANDLER_H_
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <fsfw/action/HasActionsIF.h>
|
||||||
|
#include <fsfw/power/PowerSwitchIF.h>
|
||||||
|
#include <fsfwconfig/devices/heaterSwitcherList.h>
|
||||||
|
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||||
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class intends the control of heaters.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class HeaterHandler: public ExecutableObjectIF,
|
||||||
|
public PowerSwitchIF,
|
||||||
|
public SystemObject,
|
||||||
|
public HasActionsIF {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Device command IDs */
|
||||||
|
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
|
||||||
|
|
||||||
|
HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF * gpioCookie,
|
||||||
|
object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch);
|
||||||
|
|
||||||
|
virtual ~HeaterHandler();
|
||||||
|
|
||||||
|
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
|
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
|
||||||
|
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
|
||||||
|
/**
|
||||||
|
* @brief This function will be called from the Heater object to check
|
||||||
|
* the current switch state.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) const override;
|
||||||
|
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) const override;
|
||||||
|
virtual uint32_t getSwitchDelayMs(void) const override;
|
||||||
|
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size) override;
|
||||||
|
virtual ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER;
|
||||||
|
|
||||||
|
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
|
||||||
|
static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4);
|
||||||
|
static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5);
|
||||||
|
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER_HANDLER;
|
||||||
|
static const Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
|
static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||||
|
static const Event SWITCH_ALREADY_ON = MAKE_EVENT(2, severity::LOW);
|
||||||
|
static const Event SWITCH_ALREADY_OFF = MAKE_EVENT(3, severity::LOW);
|
||||||
|
static const Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(4, severity::LOW);
|
||||||
|
|
||||||
|
static const MessageQueueId_t NO_COMMANDER = 0;
|
||||||
|
|
||||||
|
enum SwitchState : bool {
|
||||||
|
ON = true,
|
||||||
|
OFF = false
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Struct holding information about a heater command to execute.
|
||||||
|
*
|
||||||
|
* @param action The action to perform.
|
||||||
|
* @param replyQueue The queue of the commander to which status replies
|
||||||
|
* will be sent.
|
||||||
|
* @param active True if command is waiting for execution, otherwise false.
|
||||||
|
* @param waitSwitchOn True if the command is waiting for the main switch being set on.
|
||||||
|
* @param mainSwitchCountdown Sets timeout to wait for main switch being set on.
|
||||||
|
*/
|
||||||
|
typedef struct HeaterCommandInfo {
|
||||||
|
uint8_t action;
|
||||||
|
MessageQueueId_t replyQueue;
|
||||||
|
bool active = false;
|
||||||
|
bool waitMainSwitchOn = false;
|
||||||
|
Countdown mainSwitchCountdown;
|
||||||
|
} HeaterCommandInfo_t;
|
||||||
|
|
||||||
|
enum SwitchAction {
|
||||||
|
SET_SWITCH_OFF,
|
||||||
|
SET_SWITCH_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
using switchNr_t = uint8_t;
|
||||||
|
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
|
||||||
|
using HeaterMapIter = HeaterMap::iterator;
|
||||||
|
|
||||||
|
HeaterMap heaterMap;
|
||||||
|
|
||||||
|
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
|
||||||
|
|
||||||
|
/** Size of command queue */
|
||||||
|
size_t cmdQueueSize = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object ID of the GPIO driver which enables and disables the
|
||||||
|
* heaters.
|
||||||
|
*/
|
||||||
|
object_id_t gpioDriverId;
|
||||||
|
|
||||||
|
CookieIF * gpioCookie;
|
||||||
|
|
||||||
|
GpioIF* gpioInterface = nullptr;
|
||||||
|
|
||||||
|
/** Queue to receive messages from other objects. */
|
||||||
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
|
|
||||||
|
object_id_t mainLineSwitcherObjectId;
|
||||||
|
|
||||||
|
/** Switch number of the heater power supply switch */
|
||||||
|
uint8_t mainLineSwitch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Power switcher object which controls the 8V main line of the heater
|
||||||
|
* logic on the TCS board.
|
||||||
|
*/
|
||||||
|
PowerSwitchIF *mainLineSwitcher = nullptr;
|
||||||
|
|
||||||
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
|
StorageManagerIF *IPCStore = nullptr;
|
||||||
|
|
||||||
|
void readCommandQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the state of a switch (ON - true, or OFF - false).
|
||||||
|
* @param switchNr The number of the switch to check.
|
||||||
|
*/
|
||||||
|
bool checkSwitchState(int switchNr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the ID of the GPIO related to a heater identified by the switch number
|
||||||
|
* which is defined in the heaterSwitches list.
|
||||||
|
*/
|
||||||
|
gpioId_t getGpioIdFromSwitchNr(int switchNr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function runs commands waiting for execution.
|
||||||
|
*/
|
||||||
|
void handleActiveCommands();
|
||||||
|
|
||||||
|
ReturnValue_t initializeHeaterMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets all switches to OFF.
|
||||||
|
*/
|
||||||
|
void setInitialSwitchStates();
|
||||||
|
|
||||||
|
void handleSwitchOnCommand(HeaterMapIter heaterMapIter);
|
||||||
|
|
||||||
|
void handleSwitchOffCommand(HeaterMapIter heaterMapIter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if all switches are off.
|
||||||
|
* @return True if all switches are off, otherwise false.
|
||||||
|
*/
|
||||||
|
bool allSwitchesOff();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */
|
201
bsp_q7s/devices/SolarArrayDeploymentHandler.cpp
Normal file
201
bsp_q7s/devices/SolarArrayDeploymentHandler.cpp
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
#include "SolarArrayDeploymentHandler.h"
|
||||||
|
|
||||||
|
#include <devices/powerSwitcherList.h>
|
||||||
|
#include <devices/gpioIds.h>
|
||||||
|
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
|
||||||
|
|
||||||
|
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
|
||||||
|
object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_,
|
||||||
|
uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) :
|
||||||
|
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
|
||||||
|
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
|
||||||
|
deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
||||||
|
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) {
|
||||||
|
|
||||||
|
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
|
||||||
|
handleStateMachine();
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SolarArrayDeploymentHandler::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
|
||||||
|
if (gpioInterface == nullptr) {
|
||||||
|
sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface."
|
||||||
|
<< std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface"
|
||||||
|
<< std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainLineSwitcherObjectId != objects::NO_OBJECT) {
|
||||||
|
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
|
||||||
|
if (mainLineSwitcher == nullptr) {
|
||||||
|
sif::error
|
||||||
|
<< "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object"
|
||||||
|
<< "from object ID." << std::endl;
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolarArrayDeploymentHandler::handleStateMachine() {
|
||||||
|
switch (stateMachine) {
|
||||||
|
case WAIT_ON_DELOYMENT_COMMAND:
|
||||||
|
readCommandQueue();
|
||||||
|
break;
|
||||||
|
case SWITCH_8V_ON:
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON);
|
||||||
|
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||||
|
stateMachine = WAIT_ON_8V_SWITCH;
|
||||||
|
break;
|
||||||
|
case WAIT_ON_8V_SWITCH:
|
||||||
|
performWaitOn8VActions();
|
||||||
|
break;
|
||||||
|
case SWITCH_DEPL_GPIOS:
|
||||||
|
switchDeploymentTransistors();
|
||||||
|
break;
|
||||||
|
case WAIT_ON_DEPLOYMENT_FINISH:
|
||||||
|
handleDeploymentFinish();
|
||||||
|
break;
|
||||||
|
case WAIT_FOR_MAIN_SWITCH_OFF:
|
||||||
|
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) {
|
||||||
|
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
} else if (mainSwitchCountdown.hasTimedOut()) {
|
||||||
|
triggerEvent(MAIN_SWITCH_OFF_TIMEOUT);
|
||||||
|
sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main"
|
||||||
|
<< " switch off" << std::endl;
|
||||||
|
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolarArrayDeploymentHandler::performWaitOn8VActions() {
|
||||||
|
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) {
|
||||||
|
stateMachine = SWITCH_DEPL_GPIOS;
|
||||||
|
} else {
|
||||||
|
if (mainSwitchCountdown.hasTimedOut()) {
|
||||||
|
triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
|
||||||
|
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||||
|
MAIN_SWITCH_TIMEOUT_FAILURE);
|
||||||
|
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
result = gpioInterface->pullHigh(deplSA1);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||||
|
" array deployment switch 1 high " << std::endl;
|
||||||
|
/* If gpio switch high failed, state machine is reset to wait for a command reinitiating
|
||||||
|
* the deployment sequence. */
|
||||||
|
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
|
||||||
|
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||||
|
SWITCHING_DEPL_SA2_FAILED);
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||||
|
}
|
||||||
|
result = gpioInterface->pullHigh(deplSA2);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||||
|
" array deployment switch 2 high " << std::endl;
|
||||||
|
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
|
||||||
|
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||||
|
SWITCHING_DEPL_SA2_FAILED);
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||||
|
}
|
||||||
|
deploymentCountdown.setTimeout(burnTimeMs);
|
||||||
|
stateMachine = WAIT_ON_DEPLOYMENT_FINISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolarArrayDeploymentHandler::handleDeploymentFinish() {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
if (deploymentCountdown.hasTimedOut()) {
|
||||||
|
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK);
|
||||||
|
result = gpioInterface->pullLow(deplSA1);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||||
|
" array deployment switch 1 low " << std::endl;
|
||||||
|
}
|
||||||
|
result = gpioInterface->pullLow(deplSA2);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||||
|
" array deployment switch 2 low " << std::endl;
|
||||||
|
}
|
||||||
|
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||||
|
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||||
|
stateMachine = WAIT_FOR_MAIN_SWITCH_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolarArrayDeploymentHandler::readCommandQueue() {
|
||||||
|
CommandMessage command;
|
||||||
|
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = actionHelper.handleActionMessage(&command);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||||
|
ReturnValue_t result;
|
||||||
|
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
|
||||||
|
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
|
||||||
|
<< "waiting-on-command-state" << std::endl;
|
||||||
|
return DEPLOYMENT_ALREADY_EXECUTING;
|
||||||
|
}
|
||||||
|
if (actionId != DEPLOY_SOLAR_ARRAYS) {
|
||||||
|
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command"
|
||||||
|
<< std::endl;
|
||||||
|
result = COMMAND_NOT_SUPPORTED;
|
||||||
|
} else {
|
||||||
|
stateMachine = SWITCH_8V_ON;
|
||||||
|
rememberCommanderId = commandedBy;
|
||||||
|
result = RETURN_OK;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const {
|
||||||
|
return commandQueue->getId();
|
||||||
|
}
|
158
bsp_q7s/devices/SolarArrayDeploymentHandler.h
Normal file
158
bsp_q7s/devices/SolarArrayDeploymentHandler.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
||||||
|
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <fsfw/action/HasActionsIF.h>
|
||||||
|
#include <fsfw/power/PowerSwitchIF.h>
|
||||||
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||||
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class is used to control the solar array deployment.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class SolarArrayDeploymentHandler: public ExecutableObjectIF,
|
||||||
|
public SystemObject,
|
||||||
|
public HasReturnvaluesIF,
|
||||||
|
public HasActionsIF {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief constructor
|
||||||
|
*
|
||||||
|
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
|
||||||
|
* @param gpioDriverId The id of the gpio com if.
|
||||||
|
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
|
||||||
|
* transistors.
|
||||||
|
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
|
||||||
|
* the 8V power source. This is normally the PCDU.
|
||||||
|
* @param mainLineSwitch The id of the main line switch. This is defined in
|
||||||
|
* powerSwitcherList.h.
|
||||||
|
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
|
||||||
|
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
|
||||||
|
* @param burnTimeMs Time duration the power will be applied to the burn wires.
|
||||||
|
*/
|
||||||
|
SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId,
|
||||||
|
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch,
|
||||||
|
gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs);
|
||||||
|
|
||||||
|
virtual ~SolarArrayDeploymentHandler();
|
||||||
|
|
||||||
|
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size) override;
|
||||||
|
virtual ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
|
||||||
|
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
|
||||||
|
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
|
||||||
|
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
|
||||||
|
static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW);
|
||||||
|
static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW);
|
||||||
|
static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||||
|
static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH);
|
||||||
|
static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH);
|
||||||
|
|
||||||
|
|
||||||
|
enum StateMachine {
|
||||||
|
WAIT_ON_DELOYMENT_COMMAND,
|
||||||
|
SWITCH_8V_ON,
|
||||||
|
WAIT_ON_8V_SWITCH,
|
||||||
|
SWITCH_DEPL_GPIOS,
|
||||||
|
WAIT_ON_DEPLOYMENT_FINISH,
|
||||||
|
WAIT_FOR_MAIN_SWITCH_OFF
|
||||||
|
};
|
||||||
|
|
||||||
|
StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
|
||||||
|
*/
|
||||||
|
Countdown mainSwitchCountdown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This countdown is used to wait for the burn wire being successful cut.
|
||||||
|
*/
|
||||||
|
Countdown deploymentCountdown;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message queue id of the component commanding an action will be stored in this variable.
|
||||||
|
* This is necessary to send later the action finish replies.
|
||||||
|
*/
|
||||||
|
MessageQueueId_t rememberCommanderId = 0;
|
||||||
|
|
||||||
|
/** Size of command queue */
|
||||||
|
size_t cmdQueueSize = 20;
|
||||||
|
|
||||||
|
/** The object ID of the GPIO driver which switches the deployment transistors */
|
||||||
|
object_id_t gpioDriverId;
|
||||||
|
|
||||||
|
CookieIF * gpioCookie;
|
||||||
|
|
||||||
|
/** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */
|
||||||
|
object_id_t mainLineSwitcherObjectId;
|
||||||
|
|
||||||
|
/** Switch number of the 8V power switch */
|
||||||
|
uint8_t mainLineSwitch;
|
||||||
|
|
||||||
|
gpioId_t deplSA1;
|
||||||
|
gpioId_t deplSA2;
|
||||||
|
|
||||||
|
GpioIF* gpioInterface = nullptr;
|
||||||
|
|
||||||
|
/** Time duration switches are active to cut the burn wire */
|
||||||
|
uint32_t burnTimeMs;
|
||||||
|
|
||||||
|
/** Queue to receive messages from other objects. */
|
||||||
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After initialization this pointer will hold the reference to the main line switcher object.
|
||||||
|
*/
|
||||||
|
PowerSwitchIF *mainLineSwitcher = nullptr;
|
||||||
|
|
||||||
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
|
void readCommandQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function performs actions dependent on the current state.
|
||||||
|
*/
|
||||||
|
void handleStateMachine();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function polls the 8V switch state and changes the state machine when the
|
||||||
|
* switch has been enabled.
|
||||||
|
*/
|
||||||
|
void performWaitOn8VActions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This functions handles the switching of the solar array deployment transistors.
|
||||||
|
*/
|
||||||
|
void switchDeploymentTransistors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function performs actions to finish the deployment. Essentially switches
|
||||||
|
* are turned of after the burn time has expired.
|
||||||
|
*/
|
||||||
|
void handleDeploymentFinish();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */
|
3
bsp_q7s/gpio/CMakeLists.txt
Normal file
3
bsp_q7s/gpio/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
gpioCallbacks.cpp
|
||||||
|
)
|
221
bsp_q7s/gpio/gpioCallbacks.cpp
Normal file
221
bsp_q7s/gpio/gpioCallbacks.cpp
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
#include "gpioCallbacks.h"
|
||||||
|
#include <devices/gpioIds.h>
|
||||||
|
|
||||||
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace gpioCallbacks {
|
||||||
|
|
||||||
|
GpioIF* gpioComInterface;
|
||||||
|
|
||||||
|
void initTcsBoardDecoder(GpioIF* gpioComIF) {
|
||||||
|
|
||||||
|
ReturnValue_t result;
|
||||||
|
|
||||||
|
if (gpioComIF == nullptr) {
|
||||||
|
sif::debug << "initTcsBoardDecoder: Invalid gpioComIF" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioComInterface = gpioComIF;
|
||||||
|
|
||||||
|
GpioCookie* spiMuxGpios = new GpioCookie;
|
||||||
|
/**
|
||||||
|
* Initial values of the spi mux gpios can all be set to an arbitrary value expect for spi mux
|
||||||
|
* bit 1. Setting spi mux bit 1 to high will pull all decoder outputs to high voltage level.
|
||||||
|
*/
|
||||||
|
GpiodRegular* spiMuxBit1 = new GpiodRegular(std::string("gpiochip7"), 13,
|
||||||
|
std::string("SPI Mux Bit 1"), gpio::OUT, 1);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit1);
|
||||||
|
GpiodRegular* spiMuxBit2 = new GpiodRegular(std::string("gpiochip7"), 14,
|
||||||
|
std::string("SPI Mux Bit 2"), gpio::OUT, 0);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit2);
|
||||||
|
GpiodRegular* spiMuxBit3 = new GpiodRegular(std::string("gpiochip7"), 15,
|
||||||
|
std::string("SPI Mux Bit 3"), gpio::OUT, 0);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit3);
|
||||||
|
GpiodRegular* spiMuxBit4 = new GpiodRegular(std::string("gpiochip7"), 16,
|
||||||
|
std::string("SPI Mux Bit 4"), gpio::OUT, 0);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit4);
|
||||||
|
GpiodRegular* spiMuxBit5 = new GpiodRegular(std::string("gpiochip7"), 17,
|
||||||
|
std::string("SPI Mux Bit 5"), gpio::OUT, 0);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit5);
|
||||||
|
GpiodRegular* spiMuxBit6 = new GpiodRegular(std::string("gpiochip7"), 18,
|
||||||
|
std::string("SPI Mux Bit 6"), gpio::OUT, 0);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit6);
|
||||||
|
|
||||||
|
result = gpioComInterface->addGpios(spiMuxGpios);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "initTcsBoardDecoder: Failed to add mux bit gpios to gpioComIF"
|
||||||
|
<< std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcsBoardDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value,
|
||||||
|
void* args) {
|
||||||
|
|
||||||
|
if (gpioComInterface == nullptr) {
|
||||||
|
sif::debug << "tcsBoardDecoderCallback: No gpioComIF specified. Call initTcsBoardDecoder "
|
||||||
|
<< "to specify gpioComIF" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read is not supported by the callback function */
|
||||||
|
if (gpioOp == gpio::GpioOperation::READ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == 1) {
|
||||||
|
/* This will pull all 16 decoder outputs to high */
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
}
|
||||||
|
else if (value == 0) {
|
||||||
|
switch (gpioId) {
|
||||||
|
case(gpioIds::RTD_IC3): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC4): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC5): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC6): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC7): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC8): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC9): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC10): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC11): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC12): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC13): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC14): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC15): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC16): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC17): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpioIds::RTD_IC18): {
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "tcsBoardDecoderCallback: Invalid gpioid " << gpioId << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::debug << "tcsBoardDecoderCallback: Invalid value. Must be 0 or 1" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
bsp_q7s/gpio/gpioCallbacks.h
Normal file
23
bsp_q7s/gpio/gpioCallbacks.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef LINUX_GPIO_GPIOCALLBACKS_H_
|
||||||
|
#define LINUX_GPIO_GPIOCALLBACKS_H_
|
||||||
|
|
||||||
|
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace gpioCallbacks {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on
|
||||||
|
* the TCS Board.
|
||||||
|
*/
|
||||||
|
void initTcsBoardDecoder(GpioIF* gpioComIF);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function implements the decoding to multiply gpios by using the two decoder
|
||||||
|
* chips SN74LVC138APWR on the TCS board.
|
||||||
|
*/
|
||||||
|
void tcsBoardDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */
|
@ -1,5 +1,4 @@
|
|||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
|
|
||||||
#include <OBSWVersion.h>
|
#include <OBSWVersion.h>
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
@ -14,15 +13,15 @@
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||||
std::cout << "-- Compiled for Linux " << " --" << std::endl;
|
std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
|
||||||
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
|
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
|
||||||
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
|
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
|
||||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
|
|
||||||
InitMission::initMission();
|
initmission::initMission();
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// suspend main thread by sleeping it.
|
/* Suspend main thread by sleeping it. */
|
||||||
TaskFactory::delayTask(5000);
|
TaskFactory::delayTask(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
14
bsp_rpi/CMakeLists.txt
Normal file
14
bsp_rpi/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
target_sources(${TARGET_NAME} PUBLIC
|
||||||
|
InitMission.cpp
|
||||||
|
main.cpp
|
||||||
|
ObjectFactory.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(boardconfig)
|
||||||
|
add_subdirectory(boardtest)
|
||||||
|
add_subdirectory(gpio)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
177
bsp_rpi/InitMission.cpp
Normal file
177
bsp_rpi/InitMission.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#include "InitMission.h"
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
|
#include <fsfwconfig/objects/systemObjectList.h>
|
||||||
|
#include <fsfwconfig/OBSWConfig.h>
|
||||||
|
#include <fsfwconfig/pollingsequence/pollingSequenceFactory.h>
|
||||||
|
|
||||||
|
#include <mission/utility/InitMission.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
|
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
|
ServiceInterfaceStream sif::info("INFO");
|
||||||
|
ServiceInterfaceStream sif::warning("WARNING");
|
||||||
|
ServiceInterfaceStream sif::error("ERROR");
|
||||||
|
|
||||||
|
ObjectManagerIF *objectManager = nullptr;
|
||||||
|
|
||||||
|
void initmission::initMission() {
|
||||||
|
sif::info << "Building global objects.." << std::endl;
|
||||||
|
/* Instantiate global object manager and also create all objects */
|
||||||
|
objectManager = new ObjectManager(ObjectFactory::produce);
|
||||||
|
sif::info << "Initializing all objects.." << std::endl;
|
||||||
|
objectManager->initialize();
|
||||||
|
|
||||||
|
/* This function creates and starts all tasks */
|
||||||
|
initTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initmission::initTasks() {
|
||||||
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
|
if(factory == nullptr) {
|
||||||
|
/* Should never happen ! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
|
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
||||||
|
#else
|
||||||
|
void (*missedDeadlineFunc) (void) = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TMTC Distribution */
|
||||||
|
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||||
|
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
ReturnValue_t result = tmTcDistributor->addComponent(
|
||||||
|
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UDP bridge */
|
||||||
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
|
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
|
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
|
}
|
||||||
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
|
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
|
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUS Services */
|
||||||
|
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||||
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
sif::error << "Object add component failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||||
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
|
}
|
||||||
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
|
}
|
||||||
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||||
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RPI_TEST_ACS_BOARD == 1
|
||||||
|
FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask(
|
||||||
|
"ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
|
||||||
|
result = pst::pollingSequenceAcsTest(acsTask);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl;
|
||||||
|
}
|
||||||
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
|
|
||||||
|
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||||
|
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
|
}
|
||||||
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
#if RPI_ADD_SPI_TEST == 1
|
||||||
|
result = testTask->addComponent(objects::SPI_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
||||||
|
}
|
||||||
|
#endif /* RPI_ADD_SPI_TEST == 1 */
|
||||||
|
#if RPI_ADD_GPIO_TEST == 1
|
||||||
|
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
||||||
|
}
|
||||||
|
#endif /* RPI_ADD_GPIO_TEST == 1 */
|
||||||
|
|
||||||
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
|
tmTcDistributor->startTask();
|
||||||
|
udpBridgeTask->startTask();
|
||||||
|
udpPollingTask->startTask();
|
||||||
|
|
||||||
|
pusVerification->startTask();
|
||||||
|
pusEvents->startTask();
|
||||||
|
pusHighPrio->startTask();
|
||||||
|
pusMedPrio->startTask();
|
||||||
|
pusLowPrio->startTask();
|
||||||
|
|
||||||
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
testTask->startTask();
|
||||||
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
|
#if RPI_TEST_ACS_BOARD == 1
|
||||||
|
acsTask->startTask();
|
||||||
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
|
sif::info << "Tasks started.." << std::endl;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef BSP_LINUX_INITMISSION_H_
|
#ifndef BSP_LINUX_INITMISSION_H_
|
||||||
#define BSP_LINUX_INITMISSION_H_
|
#define BSP_LINUX_INITMISSION_H_
|
||||||
|
|
||||||
namespace InitMission {
|
namespace initmission {
|
||||||
void initMission();
|
void initMission();
|
||||||
void initTasks();
|
void initTasks();
|
||||||
};
|
};
|
125
bsp_rpi/ObjectFactory.cpp
Normal file
125
bsp_rpi/ObjectFactory.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
|
#include <fsfwconfig/objects/systemObjectList.h>
|
||||||
|
#include <fsfwconfig/devices/addresses.h>
|
||||||
|
#include <fsfwconfig/devices/gpioIds.h>
|
||||||
|
#include <fsfwconfig/OBSWConfig.h>
|
||||||
|
#include <fsfwconfig/tmtc/apid.h>
|
||||||
|
#include <fsfwconfig/tmtc/pusIds.h>
|
||||||
|
#include <fsfwconfig/devices/spi.h>
|
||||||
|
|
||||||
|
#include <linux/boardtest/LibgpiodTest.h>
|
||||||
|
#include <linux/boardtest/SpiTestClass.h>
|
||||||
|
|
||||||
|
#include <mission/devices/GyroL3GD20Handler.h>
|
||||||
|
#include <mission/core/GenericFactory.h>
|
||||||
|
#include <mission/utility/TmFunnel.h>
|
||||||
|
#include <mission/devices/MGMHandlerLIS3MDL.h>
|
||||||
|
#include <mission/devices/MGMHandlerRM3100.h>
|
||||||
|
|
||||||
|
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
|
||||||
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
|
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
|
/* UDP server includes */
|
||||||
|
#include <fsfw/osal/common/UdpTmTcBridge.h>
|
||||||
|
#include <fsfw/osal/common/UdpTcPollingTask.h>
|
||||||
|
|
||||||
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
|
#include <fsfw_hal/linux/rpi/GpioRPi.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
|
||||||
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
|
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
|
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
|
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
||||||
|
// No storage object for now.
|
||||||
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||||
|
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ObjectFactory::produce(){
|
||||||
|
Factory::setStaticFrameworkObjectIds();
|
||||||
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
|
new UdpTmTcBridge(objects::UDP_BRIDGE,
|
||||||
|
objects::CCSDS_PACKET_DISTRIBUTOR,
|
||||||
|
objects::TM_STORE, objects::TC_STORE);
|
||||||
|
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
||||||
|
|
||||||
|
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
||||||
|
|
||||||
|
#if RPI_ADD_SPI_TEST == 1
|
||||||
|
new SpiTestClass(objects::SPI_TEST, gpioIF);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RPI_LOOPBACK_TEST_GPIO == 1
|
||||||
|
GpioCookie* gpioCookieLoopback = new GpioCookie();
|
||||||
|
/* Loopback pins. Adapt according to setup */
|
||||||
|
gpioId_t gpioIdSender = gpioIds::TEST_ID_0;
|
||||||
|
int bcmPinSender = 26;
|
||||||
|
gpioId_t gpioIdReader = gpioIds::TEST_ID_1;
|
||||||
|
int bcmPinReader = 16;
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER",
|
||||||
|
gpio::Direction::OUT, 0);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER",
|
||||||
|
gpio::Direction::IN, 0);
|
||||||
|
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback);
|
||||||
|
#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */
|
||||||
|
|
||||||
|
new SpiComIF(objects::SPI_COM_IF, gpioIF);
|
||||||
|
|
||||||
|
#if RPI_TEST_ACS_BOARD == 1
|
||||||
|
|
||||||
|
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN,
|
||||||
|
"MGM_0_LIS3", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
|
||||||
|
"MGM_1_RM3100", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN,
|
||||||
|
"MGM_2_LIS3", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
|
||||||
|
"MGM_3_RM3100", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
|
||||||
|
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN,
|
||||||
|
"GYRO_1_L3G", gpio::Direction::OUT, 1);
|
||||||
|
gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_2_L3G_CS, gpio::GYRO_2_BCM_PIN,
|
||||||
|
"GYRO_2_L3G", gpio::Direction::OUT, 1);
|
||||||
|
gpioIF->addGpios(gpioCookieAcsBoard);
|
||||||
|
|
||||||
|
std::string spiDev = "/dev/spidev0.0";
|
||||||
|
SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
|
||||||
|
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
||||||
|
auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER,
|
||||||
|
objects::SPI_COM_IF, spiCookie);
|
||||||
|
mgmLis3Handler->setStartUpImmediately();
|
||||||
|
|
||||||
|
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
|
||||||
|
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
||||||
|
auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER,
|
||||||
|
objects::SPI_COM_IF, spiCookie);
|
||||||
|
mgmRm3100Handler->setStartUpImmediately();
|
||||||
|
|
||||||
|
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
|
||||||
|
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
|
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
|
||||||
|
spiCookie);
|
||||||
|
gyroL3gHandler->setStartUpImmediately();
|
||||||
|
|
||||||
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
|
}
|
10
bsp_rpi/boardconfig/CMakeLists.txt
Normal file
10
bsp_rpi/boardconfig/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
print.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
38
bsp_rpi/boardconfig/etl_profile.h
Normal file
38
bsp_rpi/boardconfig/etl_profile.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2019 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __ETL_PROFILE_H__
|
||||||
|
#define __ETL_PROFILE_H__
|
||||||
|
|
||||||
|
#define ETL_CHECK_PUSH_POP
|
||||||
|
|
||||||
|
#define ETL_CPP11_SUPPORTED 1
|
||||||
|
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||||
|
|
||||||
|
#endif
|
14
bsp_rpi/boardconfig/gcov.h
Normal file
14
bsp_rpi/boardconfig/gcov.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef LINUX_GCOV_H_
|
||||||
|
#define LINUX_GCOV_H_
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
|
||||||
|
#ifdef GCOV
|
||||||
|
extern "C" void __gcov_flush();
|
||||||
|
#else
|
||||||
|
void __gcov_flush() {
|
||||||
|
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||||
|
"coverage information is desired.\n" << std::flush;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LINUX_GCOV_H_ */
|
14
bsp_rpi/boardconfig/print.c
Normal file
14
bsp_rpi/boardconfig/print.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <bsp_q7s/boardconfig/print.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void printChar(const char* character, bool errStream) {
|
||||||
|
if(errStream) {
|
||||||
|
putc(*character, stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
putc(*character, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
24
bsp_rpi/boardconfig/rpi_config.h
Normal file
24
bsp_rpi/boardconfig/rpi_config.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
|
||||||
|
#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define RPI_ADD_GPIO_TEST 0
|
||||||
|
#define RPI_LOOPBACK_TEST_GPIO 0
|
||||||
|
|
||||||
|
/* Only one of those 2 should be enabled! */
|
||||||
|
#define RPI_ADD_SPI_TEST 0
|
||||||
|
#define RPI_TEST_ACS_BOARD 0
|
||||||
|
|
||||||
|
/* Adapt these values accordingly */
|
||||||
|
namespace gpio {
|
||||||
|
static constexpr uint8_t MGM_0_BCM_PIN = 0;
|
||||||
|
static constexpr uint8_t MGM_1_BCM_PIN = 1;
|
||||||
|
static constexpr uint8_t MGM_2_BCM_PIN = 17;
|
||||||
|
static constexpr uint8_t MGM_3_BCM_PIN = 27;
|
||||||
|
static constexpr uint8_t GYRO_0_BCM_PIN = 5;
|
||||||
|
static constexpr uint8_t GYRO_1_BCM_PIN = 6;
|
||||||
|
static constexpr uint8_t GYRO_2_BCM_PIN = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */
|
6
bsp_rpi/boardtest/CMakeLists.txt
Normal file
6
bsp_rpi/boardtest/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
8
bsp_rpi/gpio/CMakeLists.txt
Normal file
8
bsp_rpi/gpio/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
target_sources(${TARGET_NAME} PUBLIC
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
28
bsp_rpi/main.cpp
Normal file
28
bsp_rpi/main.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "InitMission.h"
|
||||||
|
#include <OBSWVersion.h>
|
||||||
|
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is the main program and entry point for the Raspberry Pi.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||||
|
std::cout << "-- Compiled for Linux (Raspberry Pi) --" << std::endl;
|
||||||
|
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
|
||||||
|
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl;
|
||||||
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
|
|
||||||
|
initmission::initMission();
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
/* Suspend main thread by sleeping it. */
|
||||||
|
TaskFactory::delayTask(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
45
cmake/BuildType.cmake
Normal file
45
cmake/BuildType.cmake
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
function(set_build_type)
|
||||||
|
|
||||||
|
message(STATUS "Used build generator: ${CMAKE_GENERATOR}")
|
||||||
|
|
||||||
|
# Set a default build type if none was specified
|
||||||
|
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||||
|
set(DEFAULT_BUILD_TYPE "Debug")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS
|
||||||
|
"Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified."
|
||||||
|
)
|
||||||
|
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
|
||||||
|
STRING "Choose the type of build." FORCE
|
||||||
|
)
|
||||||
|
# Set the possible values of build type for cmake-gui
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||||
|
"Debug" "Release" "MinSizeRel" "RelWithDebInfo"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||||
|
message(STATUS
|
||||||
|
"Building Debug application with flags: ${CMAKE_C_FLAGS_DEBUG}"
|
||||||
|
)
|
||||||
|
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
|
||||||
|
message(STATUS
|
||||||
|
"Building Release (Debug) application with "
|
||||||
|
"flags: ${CMAKE_C_FLAGS_RELWITHDEBINFO}"
|
||||||
|
)
|
||||||
|
elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
|
||||||
|
message(STATUS
|
||||||
|
"Building Release (Size) application with "
|
||||||
|
"flags: ${CMAKE_C_FLAGS_MINSIZEREL}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS
|
||||||
|
"Building Release (Speed) application with "
|
||||||
|
"flags: ${CMAKE_C_FLAGS_RELEASE}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
62
cmake/HardwareOsPostConfig.cmake
Normal file
62
cmake/HardwareOsPostConfig.cmake
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
function(post_source_hw_os_config)
|
||||||
|
|
||||||
|
if(LINK_LWIP)
|
||||||
|
message(STATUS "Linking against ${LIB_LWIP_NAME} lwIP library")
|
||||||
|
if(LIB_LWIP_NAME)
|
||||||
|
target_link_libraries(${TARGET_NAME} PUBLIC
|
||||||
|
${LIB_LWIP_NAME}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING "lwIP library name not set!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LINK_HAL)
|
||||||
|
message(STATUS "Linking against ${LIB_HAL_NAME} HAL library")
|
||||||
|
if(LIB_HAL_NAME)
|
||||||
|
target_link_libraries(${TARGET_NAME} PUBLIC
|
||||||
|
${LIB_HAL_NAME}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING "HAL library name not set!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LINKER_SCRIPT)
|
||||||
|
target_link_options(${TARGET_NAME} PRIVATE
|
||||||
|
-T${LINKER_SCRIPT}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(C_FLAGS "" CACHE INTERNAL "C flags")
|
||||||
|
|
||||||
|
set(C_DEFS ""
|
||||||
|
CACHE INTERNAL
|
||||||
|
"C Defines"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CXX_FLAGS ${C_FLAGS})
|
||||||
|
set(CXX_DEFS ${C_DEFS})
|
||||||
|
|
||||||
|
if(CMAKE_VERBOSE)
|
||||||
|
message(STATUS "C Flags: ${C_FLAGS}")
|
||||||
|
message(STATUS "CXX Flags: ${CXX_FLAGS}")
|
||||||
|
message(STATUS "C Defs: ${C_DEFS}")
|
||||||
|
message(STATUS "CXX Defs: ${CXX_DEFS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Generator expression. Can be used to set different C, CXX and ASM flags.
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:${C_DEFS} ${C_FLAGS}>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:${CXX_DEFS} ${CXX_FLAGS}>
|
||||||
|
$<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_NAME} ${TARGET_NAME}.bin
|
||||||
|
COMMENT "Generating binary file ${CMAKE_PROJECT_NAME}.bin.."
|
||||||
|
)
|
||||||
|
|
||||||
|
endfunction()
|
70
cmake/HardwareOsPreConfig.cmake
Normal file
70
cmake/HardwareOsPreConfig.cmake
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
function(pre_source_hw_os_config)
|
||||||
|
|
||||||
|
# FreeRTOS
|
||||||
|
if(${OS_FSFW} MATCHES freertos)
|
||||||
|
message(FATAL_ERROR "No FreeRTOS support implemented yet.")
|
||||||
|
# RTEMS
|
||||||
|
elseif(${OS_FSFW} STREQUAL rtems)
|
||||||
|
add_definitions(-DRTEMS)
|
||||||
|
message(FATAL_ERROR "No RTEMS support implemented yet.")
|
||||||
|
elseif(${OS_FSFW} STREQUAL linux)
|
||||||
|
add_definitions(-DUNIX -DLINUX)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
# Hosted
|
||||||
|
else()
|
||||||
|
set(BSP_PATH "bsp_hosted")
|
||||||
|
if(WIN32)
|
||||||
|
add_definitions(-DWIN32)
|
||||||
|
elseif(UNIX)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
add_definitions(-DUNIX -DLINUX)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Cross-compile information
|
||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
|
|
||||||
|
message(STATUS "Cross-compiling for ${TGT_BSP} target")
|
||||||
|
message(STATUS "Cross-compile gcc: ${CMAKE_C_COMPILER}")
|
||||||
|
message(STATUS "Cross-compile g++: ${CMAKE_CXX_COMPILER}")
|
||||||
|
|
||||||
|
if(CMAKE_VERBOSE)
|
||||||
|
message(STATUS "Cross-compile linker: ${CMAKE_LINKER}")
|
||||||
|
message(STATUS "Cross-compile size utility: ${CMAKE_SIZE}")
|
||||||
|
message(STATUS "Cross-compile objcopy utility: ${CMAKE_OBJCOPY}")
|
||||||
|
message(STATUS "Cross-compile ranlib utility: ${CMAKE_RANLIB}")
|
||||||
|
message(STATUS "Cross-compile ar utility: ${CMAKE_AR}")
|
||||||
|
message(STATUS "Cross-compile nm utility: ${CMAKE_NM}")
|
||||||
|
message(STATUS "Cross-compile strip utility: ${CMAKE_STRIP}")
|
||||||
|
message(STATUS
|
||||||
|
"Cross-compile assembler: ${CMAKE_ASM_COMPILER} "
|
||||||
|
"-x assembler-with-cpp"
|
||||||
|
)
|
||||||
|
message(STATUS "ABI flags: ${ABI_FLAGS}")
|
||||||
|
message(STATUS "Custom linker script: ${LINKER_SCRIPT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_property(CACHE TGT_BSP
|
||||||
|
PROPERTY STRINGS
|
||||||
|
"arm/q7s" "arm/raspberrypi"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(TGT_BSP)
|
||||||
|
if (${TGT_BSP} MATCHES "arm/raspberrypi")
|
||||||
|
set(BSP_PATH "bsp_rpi")
|
||||||
|
elseif(${TGT_BSP} MATCHES "arm/q7s")
|
||||||
|
set(BSP_PATH "bsp_q7s")
|
||||||
|
else()
|
||||||
|
message(WARNING "CMake not configured for this target!")
|
||||||
|
message(FATAL_ERROR "Target: ${TGT_BSP}!")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(BSP_PATH "bsp_hosted")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(BSP_PATH ${BSP_PATH} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
59
cmake/PreProjectConfig.cmake
Normal file
59
cmake/PreProjectConfig.cmake
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
function(pre_project_config)
|
||||||
|
|
||||||
|
# Basic input sanitization
|
||||||
|
if(DEFINED TGT_BSP)
|
||||||
|
if(${TGT_BSP} MATCHES "arm/raspberrypi" AND NOT ${OS_FSFW} MATCHES linux)
|
||||||
|
message(STATUS "FSFW OSAL invalid for specified target BSP ${TGT_BSP}!")
|
||||||
|
message(STATUS "Setting valid OS_FSFW: linux")
|
||||||
|
set(OS_FSFW "linux")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Disable compiler checks for cross-compiling.
|
||||||
|
if(${OS_FSFW} STREQUAL linux AND TGT_BSP)
|
||||||
|
|
||||||
|
if(${TGT_BSP} MATCHES "arm/q7s")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
|
"${CMAKE_SCRIPT_PATH}/Q7SCrossCompileConfig.cmake"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
elseif (${TGT_BSP} MATCHES "arm/raspberrypi")
|
||||||
|
if(NOT DEFINED ENV{RASPBIAN_ROOTFS})
|
||||||
|
if(NOT DEFINED RASPBIAN_ROOTFS)
|
||||||
|
message(WARNING "No RASPBIAN_ROOTFS environmental or CMake variable set!")
|
||||||
|
set(ENV{RASPBIAN_ROOTFS} "$ENV{HOME}/raspberrypi/rootfs")
|
||||||
|
else()
|
||||||
|
set(ENV{RASPBIAN_ROOTFS} "${RASPBIAN_ROOTFS}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS
|
||||||
|
"RASPBIAN_ROOTFS from environmental variables used: $ENV{RASPBIAN_ROOTFS}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{RASPBERRY_VERSION})
|
||||||
|
if(NOT RASPBERRY_VERSION)
|
||||||
|
message(STATUS "No RASPBERRY_VERSION specified, setting to 4")
|
||||||
|
set(RASPBERRY_VERSION "4" CACHE STRING "Raspberry Pi version")
|
||||||
|
else()
|
||||||
|
message(STATUS "Setting RASPBERRY_VERSION to ${RASPBERRY_VERSION}")
|
||||||
|
set(RASPBERRY_VERSION ${RASPBERRY_VERSION} CACHE STRING "Raspberry Pi version")
|
||||||
|
set(ENV{RASPBERRY_VERSION} ${RASPBERRY_VERSION})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS
|
||||||
|
"RASPBERRY_VERSION from environmental variables used: "
|
||||||
|
"$ENV{RASPBERRY_VERSION}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
|
"${CMAKE_SCRIPT_PATH}/RPiCrossCompileConfig.cmake"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING "Target BSP (TGT_BSP) ${TGT_BSP} unknown!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
88
cmake/Q7SCrossCompileConfig.cmake
Normal file
88
cmake/Q7SCrossCompileConfig.cmake
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{Q7S_SYSROOT})
|
||||||
|
# message(FATAL_ERROR
|
||||||
|
# "Define the Q7S_ROOTFS variable to "
|
||||||
|
# "point to the raspbian rootfs."
|
||||||
|
# )
|
||||||
|
else()
|
||||||
|
set(SYSROOT_PATH "$ENV{Q7S_SYSROOT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{CROSS_COMPILE})
|
||||||
|
set(CROSS_COMPILE "arm-linux-gnueabihf")
|
||||||
|
message(STATUS
|
||||||
|
"No CROSS_COMPILE environmental variable set, using default ARM linux "
|
||||||
|
"cross compiler name ${CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(CROSS_COMPILE "$ENV{CROSS_COMPILE}")
|
||||||
|
message(STATUS
|
||||||
|
"Using environmental variable CROSS_COMPILE as cross-compiler: "
|
||||||
|
"$ENV{CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
|
||||||
|
|
||||||
|
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
|
||||||
|
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
|
||||||
|
set(CROSS_COMPILE_LD "${CROSS_COMPILE}-ld")
|
||||||
|
set(CROSS_COMPILE_AR "${CROSS_COMPILE}-ar")
|
||||||
|
set(CROSS_COMPILE_RANLIB "${CROSS_COMPILE}-ranlib")
|
||||||
|
set(CROSS_COMPILE_STRIP "${CROSS_COMPILE}-strip")
|
||||||
|
set(CROSS_COMPILE_NM "${CROSS_COMPILE}-nm")
|
||||||
|
set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
|
||||||
|
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
|
||||||
|
|
||||||
|
# At the very least, cross compile gcc and g++ have to be set!
|
||||||
|
find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
|
||||||
|
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
|
||||||
|
|
||||||
|
set(CMAKE_CROSSCOMPILING TRUE)
|
||||||
|
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
|
||||||
|
|
||||||
|
# Define name of the target system
|
||||||
|
set(CMAKE_SYSTEM_NAME "Linux")
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "armv7")
|
||||||
|
|
||||||
|
# Define the compiler
|
||||||
|
set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC})
|
||||||
|
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
|
||||||
|
|
||||||
|
# List of library dirs where LD has to look. Pass them directly through gcc.
|
||||||
|
set(LIB_DIRS
|
||||||
|
"${SYSROOT_PATH}/usr/include"
|
||||||
|
"${SYSROOT_PATH}/usr/include/linux"
|
||||||
|
"${SYSROOT_PATH}/usr/lib"
|
||||||
|
"${SYSROOT_PATH}/lib"
|
||||||
|
"${SYSROOT_PATH}"
|
||||||
|
"${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi"
|
||||||
|
)
|
||||||
|
# You can additionally check the linker paths if you add the
|
||||||
|
# flags ' -Xlinker --verbose'
|
||||||
|
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib")
|
||||||
|
foreach(LIB ${LIB_DIRS})
|
||||||
|
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(CMAKE_PREFIX_PATH
|
||||||
|
"${CMAKE_PREFIX_PATH}"
|
||||||
|
# "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod"
|
||||||
|
CACHE STRING "C flags for Q7S"
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_C_FLAGS}"
|
||||||
|
CACHE STRING "CPP flags for Q7S"
|
||||||
|
)
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
146
cmake/RPiCrossCompileConfig.cmake
Normal file
146
cmake/RPiCrossCompileConfig.cmake
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# Based on https://github.com/Pro/raspi-toolchain but rewritten completely.
|
||||||
|
|
||||||
|
# Adapted for the FSFW Example
|
||||||
|
if(NOT $ENV{RASPBERRY_VERSION})
|
||||||
|
message(STATUS "Raspberry Pi version not specified, setting version 4!")
|
||||||
|
set(RASPBERRY_VERSION 4)
|
||||||
|
else()
|
||||||
|
set(RASPBERRY_VERSION $ENV{RASPBERRY_VERSION})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# RASPBIAN_ROOTFS should point to the local directory which contains all the
|
||||||
|
# libraries and includes from the target raspi.
|
||||||
|
# The following command can be used to do this, replace <ip-address> and the
|
||||||
|
# local <rootfs-path> accordingly:
|
||||||
|
# rsync -vR --progress -rl --delete-after --safe-links pi@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
|
||||||
|
# RASPBIAN_ROOTFS needs to be passed to the CMake command or defined in the
|
||||||
|
# application CMakeLists.txt before loading the toolchain file.
|
||||||
|
|
||||||
|
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{RASPBIAN_ROOTFS})
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Define the RASPBIAN_ROOTFS variable to "
|
||||||
|
"point to the raspbian rootfs."
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(SYSROOT_PATH "$ENV{RASPBIAN_ROOTFS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{CROSS_COMPILE})
|
||||||
|
set(CROSS_COMPILE "arm-linux-gnueabihf")
|
||||||
|
message(STATUS
|
||||||
|
"No CROSS_COMPILE environmental variable set, using default ARM linux "
|
||||||
|
"cross compiler name ${CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(CROSS_COMPILE "$ENV{CROSS_COMPILE}")
|
||||||
|
message(STATUS
|
||||||
|
"Using environmental variable CROSS_COMPILE as cross-compiler: "
|
||||||
|
"$ENV{CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
|
||||||
|
|
||||||
|
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
|
||||||
|
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
|
||||||
|
set(CROSS_COMPILE_LD "${CROSS_COMPILE}-ld")
|
||||||
|
set(CROSS_COMPILE_AR "${CROSS_COMPILE}-ar")
|
||||||
|
set(CROSS_COMPILE_RANLIB "${CROSS_COMPILE}-ranlib")
|
||||||
|
set(CROSS_COMPILE_STRIP "${CROSS_COMPILE}-strip")
|
||||||
|
set(CROSS_COMPILE_NM "${CROSS_COMPILE}-nm")
|
||||||
|
set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
|
||||||
|
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
|
||||||
|
|
||||||
|
# At the very least, cross compile gcc and g++ have to be set!
|
||||||
|
find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
|
||||||
|
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
|
||||||
|
|
||||||
|
set(CMAKE_CROSSCOMPILING TRUE)
|
||||||
|
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
|
||||||
|
|
||||||
|
# Define name of the target system
|
||||||
|
set(CMAKE_SYSTEM_NAME "Linux")
|
||||||
|
if(RASPBERRY_VERSION VERSION_GREATER 1)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "armv7")
|
||||||
|
else()
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Define the compiler
|
||||||
|
set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC})
|
||||||
|
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
|
||||||
|
|
||||||
|
# List of library dirs where LD has to look. Pass them directly through gcc.
|
||||||
|
# LD_LIBRARY_PATH is not evaluated by arm-*-ld
|
||||||
|
set(LIB_DIRS
|
||||||
|
"/opt/cross-pi-gcc/arm-linux-gnueabihf/lib"
|
||||||
|
"/opt/cross-pi-gcc/lib"
|
||||||
|
"${SYSROOT_PATH}/opt/vc/lib"
|
||||||
|
"${SYSROOT_PATH}/lib/${CROSS_COMPILE}"
|
||||||
|
"${SYSROOT_PATH}/usr/local/lib"
|
||||||
|
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
|
||||||
|
"${SYSROOT_PATH}/usr/lib"
|
||||||
|
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}/blas"
|
||||||
|
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}/lapack"
|
||||||
|
)
|
||||||
|
# You can additionally check the linker paths if you add the
|
||||||
|
# flags ' -Xlinker --verbose'
|
||||||
|
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/include")
|
||||||
|
foreach(LIB ${LIB_DIRS})
|
||||||
|
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(CMAKE_PREFIX_PATH
|
||||||
|
"${CMAKE_PREFIX_PATH}"
|
||||||
|
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(RASPBERRY_VERSION VERSION_GREATER 3)
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
|
||||||
|
CACHE STRING "CPP flags for Raspberry PI 4"
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_C_FLAGS}"
|
||||||
|
CACHE STRING "C flags for Raspberry PI 4"
|
||||||
|
)
|
||||||
|
elseif(RASPBERRY_VERSION VERSION_GREATER 2)
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
|
||||||
|
CACHE STRING "C flags for Raspberry PI 3"
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
|
||||||
|
CACHE STRING "CPP flags for Raspberry PI 3"
|
||||||
|
)
|
||||||
|
elseif(RASPBERRY_VERSION VERSION_GREATER 1)
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard ${COMMON_FLAGS}"
|
||||||
|
CACHE STRING "C flags for Raspberry PI 2"
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
|
||||||
|
CACHE STRING "CPP flags for Raspberry PI 2"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard ${COMMON_FLAGS}"
|
||||||
|
CACHE STRING "C flags for Raspberry PI 1 B+ Zero"
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
|
||||||
|
CACHE STRING "CPP flags for Raspberry PI 1 B+ Zero"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH
|
||||||
|
"${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH};${CMAKE_SYSROOT}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
6
cmake/scripts/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
cmake/scripts/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
4
cmake/scripts/.idea/misc.xml
generated
Normal file
4
cmake/scripts/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
cmake/scripts/.idea/modules.xml
generated
Normal file
8
cmake/scripts/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/scripts.iml" filepath="$PROJECT_DIR$/.idea/scripts.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
cmake/scripts/.idea/scripts.iml
generated
Normal file
8
cmake/scripts/.idea/scripts.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
cmake/scripts/.idea/vcs.xml
generated
Normal file
6
cmake/scripts/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
89
cmake/scripts/.idea/workspace.xml
generated
Normal file
89
cmake/scripts/.idea/workspace.xml
generated
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="b7804b00-6384-4363-ae17-406610449420" name="Default Changelist" comment="" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../../.." />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectId" id="1mFLMh77EFiQ6e8GGJM4DSy44LC" />
|
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||||
|
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="node.js.detected.package.eslint" value="true" />
|
||||||
|
<property name="node.js.detected.package.tslint" value="true" />
|
||||||
|
<property name="node.js.path.for.package.eslint" value="project" />
|
||||||
|
<property name="node.js.path.for.package.tslint" value="project" />
|
||||||
|
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||||
|
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="cmake_build_config" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="scripts" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/cmake_build_config.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.cmake_build_config" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="b7804b00-6384-4363-ae17-406610449420" name="Default Changelist" comment="" />
|
||||||
|
<created>1609084345199</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1609084345199</updated>
|
||||||
|
<workItem from="1609084346343" duration="6791000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
|
<component name="Vcs.Log.Tabs.Properties">
|
||||||
|
<option name="TAB_STATES">
|
||||||
|
<map>
|
||||||
|
<entry key="MAIN">
|
||||||
|
<value>
|
||||||
|
<State />
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||||
|
<SUITE FILE_PATH="coverage/scripts$cmake_build_config.coverage" NAME="cmake_build_config Coverage Results" MODIFIED="1609089450693" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
</project>
|
27
cmake/scripts/Host/create_cmake_debug_cfg.sh
Normal file
27
cmake/scripts/Host/create_cmake_debug_cfg.sh
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator=""
|
||||||
|
build_dir="Debug-Host"
|
||||||
|
os_fsfw="host"
|
||||||
|
if [ "${OS}" = "Windows_NT" ]; then
|
||||||
|
build_generator="MinGW Makefiles"
|
||||||
|
# Could be other OS but this works for now.
|
||||||
|
else
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l"${build_dir}"
|
27
cmake/scripts/Host/create_cmake_release_cfg.sh
Normal file
27
cmake/scripts/Host/create_cmake_release_cfg.sh
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator=""
|
||||||
|
os_fsfw="host"
|
||||||
|
build_dir="Release-Host"
|
||||||
|
if [ "${OS}" = "Windows_NT" ]; then
|
||||||
|
build_generator="MinGW Makefiles"
|
||||||
|
# Could be other OS but this works for now.
|
||||||
|
else
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -l"${build_dir}"
|
26
cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh
Normal file
26
cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator=""
|
||||||
|
os_fsfw="host"
|
||||||
|
if [ "${OS}" = "Windows_NT" ]; then
|
||||||
|
build_generator="MinGW Makefiles"
|
||||||
|
# Could be other OS but this works for now.
|
||||||
|
else
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb"
|
26
cmake/scripts/Host/create_cmake_size_cfg.sh
Normal file
26
cmake/scripts/Host/create_cmake_size_cfg.sh
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator=""
|
||||||
|
os_fsfw="host"
|
||||||
|
if [ "${OS}" = "Windows_NT" ]; then
|
||||||
|
build_generator="MinGW Makefiles"
|
||||||
|
# Could be other OS but this works for now.
|
||||||
|
else
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "size"
|
25
cmake/scripts/Linux/create_cmake_debug_cfg.sh
Executable file
25
cmake/scripts/Linux/create_cmake_debug_cfg.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
os_fsfw="linux"
|
||||||
|
builddir="Debug-Linux"
|
||||||
|
|
||||||
|
echo "Running command (without the leading +):"
|
||||||
|
set -x # Print command
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
|
||||||
|
# Use this if commands are added which should not be printed
|
||||||
|
# set +x
|
25
cmake/scripts/Linux/create_cmake_release_cfg.sh
Executable file
25
cmake/scripts/Linux/create_cmake_release_cfg.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
os_fsfw="linux"
|
||||||
|
builddir="Release-Linux"
|
||||||
|
|
||||||
|
echo "Running command (without the leading +):"
|
||||||
|
set -x # Print command
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
|
||||||
|
# Use this if commands are added which should not be printed
|
||||||
|
# set +x
|
25
cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh
Executable file
25
cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
os_fsfw="linux"
|
||||||
|
builddir="RelWithDeb-Linux"
|
||||||
|
|
||||||
|
echo "Running command (without the leading +):"
|
||||||
|
set -x # Print command
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}"
|
||||||
|
# Use this if commands are added which should not be printed
|
||||||
|
# set +x
|
20
cmake/scripts/Linux/create_cmake_size_cfg.sh
Executable file
20
cmake/scripts/Linux/create_cmake_size_cfg.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
counter=0
|
||||||
|
while [ ${counter} -lt 5 ]
|
||||||
|
do
|
||||||
|
cd ..
|
||||||
|
if [ -f "cmake_build_config.py" ];then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
counter=$((counter=counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${counter}" -ge 5 ];then
|
||||||
|
echo "create_cmake_cfg.sh not found in upper directories!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_generator="Unix Makefiles"
|
||||||
|
os_fsfw="linux"
|
||||||
|
|
||||||
|
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "size"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user