Merge branch 'master' into mueller/master
This commit is contained in:
commit
399807f230
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
||||
[submodule "etl"]
|
||||
path = etl
|
||||
url = https://github.com/ETLCPP/etl.git
|
||||
[submodule "tmtc"]
|
||||
path = tmtc
|
||||
url = https://git.ksat-stuttgart.de/Robin.Mueller/tmtc.git
|
||||
|
431
Makefile-Hosted
Normal file
431
Makefile-Hosted
Normal file
@ -0,0 +1,431 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# Makefile for SOURCE OBSW
|
||||
#-------------------------------------------------------------------------------
|
||||
# User-modifiable options
|
||||
#-------------------------------------------------------------------------------
|
||||
# Fundamentals on the build process of C/C++ Software:
|
||||
# https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
|
||||
|
||||
# Make documentation: https://www.gnu.org/software/make/manual/make.pdf
|
||||
# Online: https://www.gnu.org/software/make/manual/make.html
|
||||
# General rules: http://make.mad-scientist.net/papers/rules-of-makefiles/#rule3
|
||||
SHELL = /bin/sh
|
||||
|
||||
CUSTOM_DEFINES :=
|
||||
|
||||
# Chip & board used for compilation
|
||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||
BOARD_FILE_ROOT = hosted
|
||||
BOARD = host
|
||||
OS_FSFW = host
|
||||
CUSTOM_DEFINES += -D$(OS_FSFW)
|
||||
|
||||
# Copied from stackoverflow, can be used to differentiate between Windows
|
||||
# and Linux
|
||||
ifeq ($(OS),Windows_NT)
|
||||
CUSTOM_DEFINES += -DWIN32
|
||||
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
|
||||
CUSTOM_DEFINES += -DAMD64
|
||||
else
|
||||
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
|
||||
CUSTOM_DEFINES += -DAMD64
|
||||
endif
|
||||
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
|
||||
CUSTOM_DEFINES += -DIA32
|
||||
endif
|
||||
endif
|
||||
else
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
DETECTED_OS = LINUX
|
||||
CUSTOM_DEFINES += -DLINUX
|
||||
endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CUSTOM_DEFINES += -DOSX
|
||||
endif
|
||||
UNAME_P := $(shell uname -p)
|
||||
ifeq ($(UNAME_P),x86_64)
|
||||
CUSTOM_DEFINES += -DAMD64
|
||||
endif
|
||||
ifneq ($(filter %86,$(UNAME_P)),)
|
||||
CUSTOM_DEFINES += -DIA32
|
||||
endif
|
||||
ifneq ($(filter arm%,$(UNAME_P)),)
|
||||
CUSTOM_DEFINES += -DARM
|
||||
endif
|
||||
endif
|
||||
|
||||
# General folder paths
|
||||
FRAMEWORK_PATH = fsfw
|
||||
MISSION_PATH = mission
|
||||
CONFIG_PATH = $(BOARD_FILE_ROOT)/config
|
||||
TEST_PATH = test
|
||||
UNITTEST_PATH = unittest
|
||||
|
||||
# Board specific paths
|
||||
BSP_PATH = $(BOARD_FILE_ROOT)
|
||||
BOARDTEST_PATH = $(BOARD_FILE_ROOT)/boardtest
|
||||
|
||||
# Output file basename
|
||||
BASENAME = sourceobsw
|
||||
BINARY_NAME = $(BASENAME)-$(BOARD)
|
||||
# Output files will be put in this directory inside
|
||||
OUTPUT_FOLDER = $(OS_FSFW)
|
||||
|
||||
# Default debug output
|
||||
DEBUG_LEVEL = -g3
|
||||
|
||||
# Optimization level. -O0 default, -Os for size, -O3 for speed and size.
|
||||
OPTIMIZATION = -O0
|
||||
|
||||
ifdef GCOV
|
||||
CUSTOM_DEFINES += -DGCOV
|
||||
endif
|
||||
|
||||
# Output directories
|
||||
BUILDPATH = _bin
|
||||
DEPENDPATH = _dep
|
||||
OBJECTPATH = _obj
|
||||
ifeq ($(MAKECMDGOALS),release)
|
||||
BUILD_FOLDER = mission
|
||||
else
|
||||
BUILD_FOLDER = devel
|
||||
endif
|
||||
|
||||
DEPENDDIR = $(DEPENDPATH)/$(OUTPUT_FOLDER)/$(BUILD_FOLDER)
|
||||
OBJDIR = $(OBJECTPATH)/$(OUTPUT_FOLDER)/$(BUILD_FOLDER)
|
||||
BINDIR = $(BUILDPATH)/$(OUTPUT_FOLDER)/$(BUILD_FOLDER)
|
||||
|
||||
CLEANDEP = $(DEPENDPATH)/$(OUTPUT_FOLDER)
|
||||
CLEANOBJ = $(OBJECTPATH)/$(OUTPUT_FOLDER)
|
||||
CLEANBIN = $(BUILDPATH)/$(OUTPUT_FOLDER)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Tools and Includes
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Tool suffix when cross-compiling
|
||||
CROSS_COMPILE =
|
||||
|
||||
# C Compiler
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
|
||||
# C++ compiler
|
||||
CXX = $(CROSS_COMPILE)g++
|
||||
|
||||
# Additional Tools
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
CP = $(CROSS_COMPILE)objcopy
|
||||
|
||||
HEXCOPY = $(CP) -O ihex
|
||||
BINCOPY = $(CP) -O binary
|
||||
# files to be compiled, will be filled in by include makefiles
|
||||
# := assignment here is neccessary as initialization so that the +=
|
||||
# operator can be used in the submakefiles to achieve immediate evaluation.
|
||||
# See: http://make.mad-scientist.net/evaluation-and-expansion/
|
||||
CSRC :=
|
||||
CXXSRC :=
|
||||
ASRC :=
|
||||
INCLUDES :=
|
||||
|
||||
# Directories where $(directoryname).mk files should be included from
|
||||
SUBDIRS := $(FRAMEWORK_PATH) $(TEST_PATH) $(BSP_PATH) \
|
||||
$(CONFIG_PATH) $(MISSION_PATH)
|
||||
# $(MISSION_PATH) $(CONFIG_PATH)
|
||||
# INCLUDES += framework/test/catch2
|
||||
|
||||
# ETL library include.
|
||||
ETL_PATH = etl/include
|
||||
I_INCLUDES += -I$(ETL_PATH)
|
||||
|
||||
I_INCLUDES += $(addprefix -I, $(INCLUDES))
|
||||
|
||||
# This is a hack from http://make.mad-scientist.net/the-eval-function/
|
||||
#
|
||||
# The problem is, that included makefiles should be aware of their relative path
|
||||
# but not need to guess or hardcode it. So we set $(CURRENTPATH) for them. If
|
||||
# we do this globally and the included makefiles want to include other makefiles as
|
||||
# well, they would overwrite $(CURRENTPATH), screwing the include after them.
|
||||
#
|
||||
# By using a for-loop with an eval'd macro, we can generate the code to include all
|
||||
# sub-makefiles (with the correct $(CURRENTPATH) set) before actually evaluating
|
||||
# (and by this possibly changing $(CURRENTPATH)) them.
|
||||
#
|
||||
# This works recursively, if an included makefile wants to include, it can safely set
|
||||
# $(SUBDIRS) (which has already been evaluated here) and do
|
||||
# "$(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))"
|
||||
# $(SUBDIRS) must be relative to the project root, so to include subdir foo, set
|
||||
# $(SUBDIRS) = $(CURRENTPATH)/foo.
|
||||
define INCLUDE_FILE
|
||||
CURRENTPATH := $S
|
||||
include $(S)/$(notdir $S).mk
|
||||
endef
|
||||
$(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Source Files
|
||||
#-------------------------------------------------------------------------------
|
||||
# Additional source files which were not includes by other .mk
|
||||
# files are added here.
|
||||
# To help Makefile find source files, the source location paths
|
||||
# can be added by using the VPATH variable
|
||||
# See: https://www.gnu.org/software/make/manual/html_node/General-Search.html
|
||||
# It is recommended to only use VPATH to add source locations
|
||||
# See: http://make.mad-scientist.net/papers/how-not-to-use-vpath/
|
||||
|
||||
# Please ensure that no files are included by both .mk file and here !
|
||||
|
||||
# VPATH += mission/pus/
|
||||
|
||||
ifeq ($(DETECTED_OS), LINUX)
|
||||
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
|
||||
CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
|
||||
endif
|
||||
# CXXSRC += Service17Test.cpp
|
||||
|
||||
# All C Sources included by .mk files are assigned here
|
||||
# Add the objects to sources so dependency handling works
|
||||
C_OBJECTS += $(CSRC:.c=.o)
|
||||
|
||||
# Objects built from Assembly source files
|
||||
ASM_OBJECTS = $(ASRC:.S=.o)
|
||||
|
||||
# Objects built from C++ source files
|
||||
CXX_OBJECTS += $(CXXSRC:.cpp=.o)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Build Configuration + Output
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
TARGET = Debug
|
||||
DEBUG_MESSAGE = Off
|
||||
OPTIMIZATION_MESSAGE = Off
|
||||
|
||||
# Define Messages
|
||||
MSG_INFO = Software: Hosted EIVE OBSW.
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_BINARY = Generate binary:
|
||||
MSG_OPTIMIZATION = Optimization: $(OPTIMIZATION), $(OPTIMIZATION_MESSAGE)
|
||||
MSG_TARGET = Target Build: $(TARGET)
|
||||
MSG_DEBUG = FSFW Debugging: $(DEBUG_MESSAGE)
|
||||
MSG_COMIF = TMTC Communication Interface: $(COMIF_MESSAGE)
|
||||
|
||||
# See: https://stackoverflow.com/questions/6687630/how-to-remove-unused-c-c-symbols-with-gcc-and-ld
|
||||
# Used to throw away unused code. Reduces code size significantly !
|
||||
# -Wl,--gc-sections: needs to be passed to the linker to throw aways unused code
|
||||
ifdef KEEP_UNUSED_CODE
|
||||
PROTOTYPE_OPTIMIZATION =
|
||||
DEAD_CODE_REMOVAL =
|
||||
else
|
||||
PROTOTYPE_OPTIMIZATION = -ffunction-sections -fdata-sections
|
||||
DEAD_CODE_REMOVAL = -Wl,--gc-sections
|
||||
# Link time optimization
|
||||
# See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html for reference
|
||||
# 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
|
||||
# Requires -ffunction-section in linker call
|
||||
LINK_TIME_OPTIMIZATION = -flto
|
||||
OPTIMIZATION += $(PROTOTYPE_OPTIMIZATION)
|
||||
endif
|
||||
|
||||
# Dependency Flags
|
||||
# These flags tell the compiler to build dependencies
|
||||
# See: https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html
|
||||
# Using following guide:
|
||||
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPENDDIR)/$*.d
|
||||
|
||||
# Flags for the compiler call
|
||||
# - std: Which C++ version to use. Common versions: c++11, c++14 and c++17
|
||||
# - Wall: enable all warnings
|
||||
# - Wextra: enable extra warnings
|
||||
# - g: defines debug level
|
||||
# - fmessage-length: to control the formatting algorithm for diagnostic messages;
|
||||
# =0 means no line-wrapping, each error message appears on a single line
|
||||
# - fno-exceptions: stops generating extra code needed to propagate exceptions,
|
||||
# which can produce significant data size overhead
|
||||
WARNING_FLAGS = -Wall -Wshadow=local -Wextra -Wimplicit-fallthrough=1 \
|
||||
-Wno-unused-parameter
|
||||
|
||||
CXXDEFINES := $(CUSTOM_DEFINES)
|
||||
CFLAGS +=
|
||||
CXXFLAGS += -I. $(DEBUG_LEVEL) $(WARNIING_FLAGS) $(I_INCLUDES) $(DEPFLAGS) \
|
||||
-fmessage-length=0 $(CXXDEFINES) $(OPTIMIZATION)
|
||||
CPPFLAGS += -std=c++17 -fno-exceptions
|
||||
ASFLAGS = -Wall -g $(OPTIMIZATION) $(I_INCLUDES) -D__ASSEMBLY__
|
||||
|
||||
# Flags for the linker call
|
||||
# LINK_INCLUDES specify the path to used libraries and the linker script
|
||||
# LINK_LIBRARIES link HCC and HAL library and enable float support
|
||||
LDFLAGS := -g3 -pthread $(DEAD_CODE_REMOVAL) $(OPTIMIZATION)
|
||||
|
||||
LINK_INCLUDES :=
|
||||
|
||||
LINK_LIBRARIES :=
|
||||
ifeq ($(OS),Windows_NT)
|
||||
LINK_LIBRARIES += -lwsock32 -lws2_32
|
||||
endif
|
||||
|
||||
# Gnu Coverage Tools Flags
|
||||
ifdef GCOV
|
||||
GCOV_CXXFLAGS = -fprofile-arcs -ftest-coverage
|
||||
CXXFLAGS += $(GCOV_CXXFLAGS)
|
||||
GCOV_LINKER_LIBS = -lgcov -fprofile-arcs -ftest-coverage
|
||||
LINK_LIBRARIES += $(GCOV_LINKER_LIBS)
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Rules
|
||||
#-------------------------------------------------------------------------------
|
||||
# Makefile rules: https://www.gnu.org/software/make/manual/html_node/Rules.html
|
||||
# This is the primary section which defines the ruleset to build
|
||||
# the executable from the sources.
|
||||
|
||||
default: all
|
||||
|
||||
# Cleans all files
|
||||
hardclean:
|
||||
-rm -rf $(BUILDPATH)
|
||||
-rm -rf $(OBJECTPATH)
|
||||
-rm -rf $(DEPENDPATH)
|
||||
|
||||
# Only clean files for current build
|
||||
clean:
|
||||
-rm -rf $(CLEANOBJ)
|
||||
-rm -rf $(CLEANBIN)
|
||||
-rm -rf $(CLEANDEP)
|
||||
|
||||
# Only clean binaries. Useful for changing the binary type when object files are already compiled
|
||||
# so complete rebuild is not necessary
|
||||
cleanbin:
|
||||
-rm -rf $(BUILDPATH)/$(OUTPUT_FOLDER)
|
||||
|
||||
# In this section, the binaries are built for all selected memories
|
||||
|
||||
all: executable
|
||||
|
||||
# Build target configuration
|
||||
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
|
||||
release: LINK_TIME_OPTIMIZATION = -flto
|
||||
release: TARGET = Release
|
||||
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
|
||||
release: DEBUG_LEVEL = -g0
|
||||
|
||||
debug: CXXDEFINES += -DDEBUG
|
||||
debug: DEBUG_MESSAGE = On
|
||||
|
||||
ifndef KEEP_UNUSED_CODE
|
||||
debug release: OPTIMIZATION_MESSAGE = Off with unused code removal
|
||||
else
|
||||
debug release: OPTIMIZATION_MESSAGE = Off
|
||||
endif
|
||||
|
||||
debug release: executable
|
||||
|
||||
# executable: $(BINDIR)/$(BINARY_NAME).bin
|
||||
ifeq ($(OS),Windows_NT)
|
||||
executable: $(BINDIR)/$(BINARY_NAME).exe
|
||||
else
|
||||
executable: $(BINDIR)/$(BINARY_NAME).elf
|
||||
endif
|
||||
@echo
|
||||
@echo $(MSG_INFO)
|
||||
@echo $(MSG_TARGET)
|
||||
@echo $(MSG_OPTIMIZATION)
|
||||
@echo $(MSG_DEBUG)
|
||||
|
||||
C_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(C_OBJECTS))
|
||||
CXX_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(CXX_OBJECTS))
|
||||
ASM_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(ASM_OBJECTS))
|
||||
ALL_OBJECTS_PREFIXED = $(ASM_OBJECTS_PREFIXED) $(C_OBJECTS_PREFIXED) \
|
||||
$(CXX_OBJECTS_PREFIXED)
|
||||
|
||||
# Useful for debugging the Makefile
|
||||
# Also see: https://www.oreilly.com/openbook/make3/book/ch12.pdf
|
||||
# $$(info $${CXXDEFINES} is [${CXXDEFINES}])
|
||||
# $$(info $${CXXSRC} is [${CXXSRC}])
|
||||
|
||||
# Automatic variables are used here extensively. Some of them
|
||||
# are escaped($$) to suppress immediate evaluation. The most important ones are:
|
||||
# $@: Name of Target (left side of rule)
|
||||
# $<: Name of the first prerequisite (right side of rule)
|
||||
# @^: List of all prerequisite, omitting duplicates
|
||||
# @D: Directory and file-within-directory part of $@
|
||||
|
||||
# Generates binary and displays all build properties
|
||||
# -p with mkdir ignores error and creates directory when needed.
|
||||
|
||||
# SHOW_DETAILS = 1
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(BINDIR)/$(BINARY_NAME).exe: $(ALL_OBJECTS_PREFIXED)
|
||||
else
|
||||
$(BINDIR)/$(BINARY_NAME).elf: $(ALL_OBJECTS_PREFIXED)
|
||||
endif
|
||||
@echo
|
||||
@echo $(MSG_LINKING) Target $@
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(LDFLAGS) $(LINK_INCLUDES) -o $@ $^ $(LINK_LIBRARIES)
|
||||
ifeq ($(BUILD_FOLDER), mission)
|
||||
# With Link Time Optimization, section size is not available
|
||||
$(SIZE) $@
|
||||
else
|
||||
$(SIZE) $^ $@
|
||||
endif
|
||||
|
||||
# Build new objects for changed dependencies.
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
$(OBJDIR)/%.o: %.cpp $(DEPENDDIR)/%.d | $(DEPENDDIR)
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
@mkdir -p $(@D)
|
||||
ifdef SHOW_DETAILS
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
else
|
||||
@$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
endif
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
$(OBJDIR)/%.o: %.c $(DEPENDDIR)/%.d | $(DEPENDDIR)
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
@mkdir -p $(@D)
|
||||
ifdef SHOW_DETAILS
|
||||
$(CC) $(CXXFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
else
|
||||
@$(CC) $(CXXFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
endif
|
||||
|
||||
$(OBJDIR)/%.o: %.S Makefile
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
@mkdir -p $(@D)
|
||||
ifdef SHOW_DETAILS
|
||||
$(CC) $(ASFLAGS) -c -o $@ $<
|
||||
else
|
||||
@$(CC) $(ASFLAGS) -c -o $@ $<
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Dependency Handling
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Dependency Handling according to following guide:
|
||||
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
|
||||
$(DEPENDDIR):
|
||||
@mkdir -p $(@D)
|
||||
DEPENDENCY_RELATIVE = $(CSRC:.c=.d) $(CXXSRC:.cpp=.d)
|
||||
# This is the list of all dependencies
|
||||
DEPFILES = $(addprefix $(DEPENDDIR)/, $(DEPENDENCY_RELATIVE))
|
||||
# Create subdirectories for dependencies
|
||||
$(DEPFILES):
|
||||
@mkdir -p $(@D)
|
||||
# Include all dependencies
|
||||
include $(wildcard $(DEPFILES))
|
||||
|
||||
# .PHONY tells make that these targets aren't files
|
||||
.PHONY: clean sdramCfg release debug all hardclean
|
100
README.md
100
README.md
@ -1,4 +1,98 @@
|
||||
EIVE On-Board Software
|
||||
======
|
||||
# <a id="top"></a> <a name="linux"></a> EIVE On-Board Software
|
||||
|
||||
## Linux
|
||||
These steps were tested for Ubuntu 20.04.
|
||||
If not done yet, install the full C++ build chain:
|
||||
```sh
|
||||
sudo apt-get install build-essential
|
||||
```
|
||||
|
||||
Linux has a limit to message queue message. Please see the section
|
||||
to set up UNIX environment for more information.
|
||||
Sometimes, special steps are necessary so the real-time functionalities can be used
|
||||
without root privileges. Instructions are contained in the setup section
|
||||
for UNIX as well.
|
||||
|
||||
### Building the software
|
||||
|
||||
1. Clone the repository with
|
||||
```sh
|
||||
git clone https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example.git
|
||||
```
|
||||
|
||||
2. Update all the submodules
|
||||
```sh
|
||||
git submodule init
|
||||
git submodule sync
|
||||
git submodule update
|
||||
```
|
||||
|
||||
3. After that, the linux binary can be built with:
|
||||
```sh
|
||||
make -j all
|
||||
```
|
||||
to compile for Linux. All will build the debug version,
|
||||
which can also be built with the target `debug`. The optimized
|
||||
release version can be built with the target `release`.
|
||||
|
||||
4. Run the binary located inside the `_bin` folder.
|
||||
|
||||
### Setting up UNIX environment for real-time functionalities
|
||||
Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities
|
||||
used by the UNIX pthread module are restricted, which will lead to permission errors when creating these tasks
|
||||
and configuring real-time properites like scheduling priorities.
|
||||
|
||||
To solve this issues, try following steps:
|
||||
|
||||
1. Edit the /etc/security/limits.conf
|
||||
file and add following lines at the end:
|
||||
```sh
|
||||
<username> hard rtprio 99
|
||||
<username> soft rtprio 99
|
||||
```
|
||||
The soft limit can also be set in the console with `ulimit -Sr` if the hard
|
||||
limit has been increased, but it is recommended to add it to the file as well for convenience.
|
||||
If adding the second line is not desired for security reasons,
|
||||
the soft limit needs to be set for each session. If using an IDE like eclipse
|
||||
in that case, the IDE needs to be started from the console after setting
|
||||
the soft limit higher there. After adding the two lines to the file,
|
||||
the computer needs to be restarted.
|
||||
|
||||
It is also recommended to perform the following change so that the unlockRealtime
|
||||
script does not need to be run anymore each time. The following steps
|
||||
raise the maximum allowed message queue length to a higher number permanently, which is
|
||||
required for some framework components. The recommended values for the new message
|
||||
length is 130.
|
||||
|
||||
2. Edit the /etc/sysctl.conf file
|
||||
```sh
|
||||
sudo nano /etc/sysctl.conf
|
||||
```
|
||||
Append at end:
|
||||
```sh
|
||||
fs/mqueue/msg_max = <newMsgMaxLen>
|
||||
```
|
||||
Apply changes with:
|
||||
```sh
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
A possible solution which only persists for the current session is
|
||||
```sh
|
||||
echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
|
||||
```
|
||||
or running the `unlockRealtime` script.
|
||||
|
||||
3. Run the shell script inside the linux folder
|
||||
```sh
|
||||
./unlockRealtime
|
||||
```
|
||||
This script executes the `sudo setcap 'cap_sys_nice=eip' \<application\>`
|
||||
command on the binaries, increases the soft real time limit of the current
|
||||
session and increases the maximum number of message queues by setting
|
||||
`/proc/sys/fs/mqueue/msg_max`.
|
||||
All changes are only applied for the current session (read 2. and 3. for
|
||||
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,
|
||||
the hard real-time limit of the system might not be high enough (see step 1).
|
||||
|
||||
## General Information
|
||||
|
@ -2,20 +2,14 @@
|
||||
#include <boardconfig/gcov.h>
|
||||
#endif
|
||||
|
||||
#include <mission/core/InitMission.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <version.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// This will be the entry to the mission specific code
|
||||
void initMission();
|
||||
|
||||
#ifndef SW_VERSION
|
||||
#define SW_VERSION 0
|
||||
#endif
|
||||
|
||||
#ifndef SW_SUBVERSION
|
||||
#define SW_SUBVERSION 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This is the main program for the hosted build. It can be run for
|
||||
@ -29,10 +23,12 @@ int main(void)
|
||||
std::cout << "-- Software version v" << SW_VERSION << "." << SW_SUBVERSION
|
||||
<< " -- " << std::endl;
|
||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||
initMission();
|
||||
|
||||
InitMission::initMission();
|
||||
|
||||
for(;;) {
|
||||
// suspend main thread by sleeping it.
|
||||
sleep(5);
|
||||
TaskFactory::delayTask(5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
8
config/FSFWConfig.h
Normal file
8
config/FSFWConfig.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef CONFIG_FSFWCONFIG_H_
|
||||
#define CONFIG_FSFWCONFIG_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
14
config/OBSWConfig.h
Normal file
14
config/OBSWConfig.h
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @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_
|
||||
|
||||
#define ADD_TEST_FOLDER 1
|
||||
|
||||
// Define not used yet, PUS stack and TMTC tasks are always started
|
||||
#define ADD_PUS_STACK 1
|
||||
|
||||
#endif /* CONFIG_OBSWCONFIG_H_ */
|
@ -1,48 +0,0 @@
|
||||
#include "dataPoolInit.h"
|
||||
|
||||
void datapool::dataPoolInit(std::map<uint32_t, PoolEntryIF*>* poolMap) {
|
||||
uint8_t UINT8T_INIT[1] = {0};
|
||||
uint16_t UINT16T_INIT[1] = {0};
|
||||
uint32_t UINT32T_INIT[1] = {0};
|
||||
float FLOAT_INIT[2] = {0.0, 0.0};
|
||||
/* FSFW */
|
||||
poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL,
|
||||
new PoolEntry<uint32_t>(UINT32T_INIT,1));
|
||||
poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM,
|
||||
new PoolEntry<uint32_t>(UINT32T_INIT,1));
|
||||
poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES,
|
||||
new PoolEntry<uint32_t>(UINT32T_INIT,1));
|
||||
|
||||
/* TEST */
|
||||
poolMap->emplace(datapool::TEST_UINT8,
|
||||
new PoolEntry<uint8_t>(UINT8T_INIT,1));
|
||||
poolMap->emplace(datapool::TEST_UINT16,
|
||||
new PoolEntry<uint16_t>(UINT16T_INIT,1));
|
||||
poolMap->emplace(datapool::TEST_UINT32,
|
||||
new PoolEntry<uint32_t>(UINT32T_INIT,1));
|
||||
poolMap->emplace(datapool::TEST_FLOAT_VECTOR,
|
||||
new PoolEntry<float>(FLOAT_INIT,2));
|
||||
|
||||
// With new initializer list feature and boolean entries.
|
||||
|
||||
// /* FSFW */
|
||||
// poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL,
|
||||
// new PoolEntry<uint32_t>({0},1));
|
||||
// poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM,
|
||||
// new PoolEntry<uint32_t>({0},1));
|
||||
// poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES,
|
||||
// new PoolEntry<uint32_t>({0},1));
|
||||
//
|
||||
// /* TEST */
|
||||
// poolMap->emplace(datapool::TEST_BOOLEAN,
|
||||
// new PoolEntry<bool>({0},1));
|
||||
// poolMap->emplace(datapool::TEST_UINT8,
|
||||
// new PoolEntry<uint8_t>({0},1));
|
||||
// poolMap->emplace(datapool::TEST_UINT16,
|
||||
// new PoolEntry<uint16_t>({0},1));
|
||||
// poolMap->emplace(datapool::TEST_UINT32,
|
||||
// new PoolEntry<uint32_t>({0},1));
|
||||
// poolMap->emplace(datapool::TEST_FLOAT_VECTOR,
|
||||
// new PoolEntry<float>({0, 0},2));
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#ifndef HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_
|
||||
#define HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_
|
||||
|
||||
#include <fsfw/datapool/DataPool.h>
|
||||
#include <fsfw/datapool/PoolEntryIF.h>
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace datapool {
|
||||
void dataPoolInit(std::map<uint32_t, PoolEntryIF*>* poolMap);
|
||||
|
||||
enum datapoolvariables {
|
||||
NO_PARAMETER = 0,
|
||||
|
||||
/** [EXPORT] : [GROUP] FSFW */
|
||||
INTERNAL_ERROR_STORE_FULL = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Store Entry [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
|
||||
INTERNAL_ERROR_MISSED_LIVE_TM = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Missed Live Tm [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
|
||||
INTERNAL_ERROR_FULL_MSG_QUEUES = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Full Msg Queue [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
|
||||
|
||||
/** [EXPORT] : [GROUP] TEST */
|
||||
TEST_BOOLEAN = 0x01010102, //!< [EXPORT] : [NAME] Test Boolean [UNIT] (-) [SIZE] 1 [TYPE] bool
|
||||
TEST_UINT8 = 0x02020204, //!< [EXPORT] : [NAME] Test Byte [UNIT] (-) [SIZE] 1 [TYPE] uint8_t
|
||||
TEST_UINT16 = 0x03030306, //!< [EXPORT] : [NAME] Test UINT16 [UNIT] (-) [SIZE] 1 [TYPE] uint16_t
|
||||
TEST_UINT32 = 0x04040408, //!< [EXPORT] : [NAME] Test UINT32 [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
|
||||
TEST_FLOAT_VECTOR = 0x05050510, //!< [EXPORT] : [NAME] Test Float [UNIT] (-) [SIZE] 2 [TYPE] float
|
||||
};
|
||||
}
|
||||
#endif /* CONFIG_CDATAPOOL_DATAPOOLINIT_H_ */
|
@ -1,5 +1,5 @@
|
||||
#ifndef CONFIG_TMTC_SUBSYSTEMIDRANGES_H_
|
||||
#define CONFIG_TMTC_SUBSYSTEMIDRANGES_H_
|
||||
#ifndef CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
|
||||
#include <fsfw/events/fwSubsystemIdRanges.h>
|
||||
#include <cstdint>
|
||||
@ -19,8 +19,6 @@ enum: uint8_t {
|
||||
PUS_SERVICE_5 = 85,
|
||||
PUS_SERVICE_6 = 86,
|
||||
PUS_SERVICE_8 = 88,
|
||||
PUS_SERVICE_9 = 89,
|
||||
PUS_SERVICE_17 = 82,
|
||||
PUS_SERVICE_23 = 91,
|
||||
DUMMY_DEVICE = 90,
|
||||
/**
|
||||
@ -33,4 +31,4 @@ enum: uint8_t {
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TMTC_SUBSYSTEMIDRANGES_H_ */
|
||||
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */
|
@ -1,116 +0,0 @@
|
||||
#include <Factory.h>
|
||||
#include <systemObjectList.h>
|
||||
#include <dataPoolInit.h>
|
||||
#include <apid.h>
|
||||
#include <pusIds.h>
|
||||
|
||||
#include <mission/utility/TimeStamper.h>
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/internalError/InternalErrorReporter.h>
|
||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
#include <fsfw/storagemanager/PoolManager.h>
|
||||
#include <fsfw/tcdistribution/CCSDSDistributor.h>
|
||||
#include <fsfw/tcdistribution/PUSDistributor.h>
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||
#include <fsfw/pus/Service1TelecommandVerification.h>
|
||||
#include <fsfw/pus/Service2DeviceAccess.h>
|
||||
#include <fsfw/pus/Service5EventReporting.h>
|
||||
#include <fsfw/pus/Service8FunctionManagement.h>
|
||||
#include <fsfw/pus/CService200ModeCommanding.h>
|
||||
#include <fsfw/osal/linux/TmTcUnixUdpBridge.h>
|
||||
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
|
||||
#include <fsfw/pus/Service17Test.h>
|
||||
#include <test/testtasks/TestTask.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief Produces system objects.
|
||||
* @details
|
||||
* Build tasks by using SystemObject Interface (Interface).
|
||||
* Header files of all tasks must be included
|
||||
* Please note that an object has to implement the system object interface
|
||||
* if the interface validity is checked or retrieved later by using the
|
||||
* get<TargetInterface>(object_id) function from the ObjectManagerIF.
|
||||
*
|
||||
* Framework objects are created first.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
void Factory::produce(void) {
|
||||
setStaticFrameworkObjectIds();
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new HealthTable(objects::HEALTH_TABLE);
|
||||
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER,
|
||||
datapool::INTERNAL_ERROR_FULL_MSG_QUEUES,
|
||||
datapool::INTERNAL_ERROR_MISSED_LIVE_TM,
|
||||
datapool::INTERNAL_ERROR_STORE_FULL);
|
||||
|
||||
/* Pool manager handles storage und mutexes */
|
||||
/* Data Stores. Currently reserving 9600 bytes of memory */
|
||||
uint16_t numberOfElements[4] = {100, 30, 20, 10};
|
||||
uint16_t sizeOfElements[4] = {32, 64, 128, 256};
|
||||
new PoolManager<4>(objects::IPC_STORE, sizeOfElements, numberOfElements);
|
||||
new PoolManager<4>(objects::TM_STORE, sizeOfElements, numberOfElements);
|
||||
new PoolManager<4>(objects::TC_STORE, sizeOfElements, numberOfElements);
|
||||
|
||||
new TimeStamper(objects::PUS_TIME);
|
||||
|
||||
/* Distributor Tasks */
|
||||
new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
new PUSDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
|
||||
/* TM Destination */
|
||||
new TmFunnel(objects::PUS_FUNNEL);
|
||||
|
||||
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE,
|
||||
objects::TC_STORE);
|
||||
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK,
|
||||
objects::UDP_BRIDGE);
|
||||
|
||||
/* PUS Service Base Services */
|
||||
new Service1TelecommandVerification(objects::PUS_SERVICE_1,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_1, objects::PUS_FUNNEL);
|
||||
new Service5EventReporting(objects::PUS_SERVICE_5, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_5);
|
||||
new Service17Test(objects::PUS_SERVICE_17, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_17);
|
||||
|
||||
/* Commanding Service Base Services */
|
||||
new Service2DeviceAccess(objects::PUS_SERVICE_2, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_2);
|
||||
new Service8FunctionManagement(objects::PUS_SERVICE_8, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_8);
|
||||
new CService200ModeCommanding(objects::PUS_SERVICE_200, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_200);
|
||||
|
||||
/* Test Tasks */
|
||||
// CookieIF* dummyCookie = new DummyCookie(0);
|
||||
// new DummyEchoComIF(objects::DUMMY_INTERFACE);
|
||||
// new TestDevice(objects::DUMMY_HANDLER, objects::DUMMY_INTERFACE,
|
||||
// dummyCookie, true);
|
||||
new TestTask(objects::TEST_TASK);
|
||||
}
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
PusServiceBase::packetDestination = objects::PUS_FUNNEL;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::PUS_FUNNEL;
|
||||
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1;
|
||||
//DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2;
|
||||
//DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
|
||||
TmPacketStored::timeStamperId = objects::PUS_TIME;
|
||||
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
#ifndef FACTORY_H_
|
||||
#define FACTORY_H_
|
||||
|
||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||
|
||||
namespace Factory {
|
||||
/**
|
||||
* @brief Creates all SystemObject elements which are persistent
|
||||
* during execution.
|
||||
*/
|
||||
void produce();
|
||||
void setStaticFrameworkObjectIds();
|
||||
|
||||
}
|
||||
|
||||
#endif /* FACTORY_H_ */
|
@ -12,20 +12,15 @@ namespace objects {
|
||||
UDP_BRIDGE = 0x50000300,
|
||||
UDP_POLLING_TASK = 0x50000400,
|
||||
|
||||
PUS_SERVICE_1 = 0x51000100,
|
||||
PUS_SERVICE_2 = 0x51000200,
|
||||
PUS_SERVICE_3 = 0x51000300,
|
||||
PUS_SERVICE_5 = 0x51000400,
|
||||
PUS_SERVICE_6 = 0x51000500,
|
||||
PUS_SERVICE_8 = 0x51000800,
|
||||
PUS_SERVICE_9 = 0x51000900,
|
||||
PUS_SERVICE_17 = 0x51001700,
|
||||
PUS_SERVICE_23 = 0x51002300,
|
||||
PUS_SERVICE_200 = 0x51020000,
|
||||
PUS_SERVICE_201 = 0x51020100,
|
||||
|
||||
PUS_TIME = 0x52000001,
|
||||
PUS_FUNNEL = 0x52000002,
|
||||
TIME_STAMPER = 0x52000001,
|
||||
TM_FUNNEL = 0x52000002,
|
||||
|
||||
/* Test Task */
|
||||
TEST_TASK = 0x42694269,
|
||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
||||
Subproject commit 62508132c0c248d6851fd88207828c7f12c38e50
|
||||
Subproject commit 8017c3c4f0c273abe7032613645b59b6f5e3f1da
|
38
hosted/boardconfig/etl_profile.h
Normal file
38
hosted/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
hosted/boardconfig/gcov.h
Normal file
14
hosted/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
hosted/boardconfig/print.c
Normal file
14
hosted/boardconfig/print.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "print.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void printChar(const char* character, bool errStream) {
|
||||
if(errStream) {
|
||||
putc(*character, stderr);
|
||||
return;
|
||||
}
|
||||
putc(*character, stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
8
hosted/boardconfig/print.h
Normal file
8
hosted/boardconfig/print.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef HOSTED_BOARDCONFIG_PRINT_H_
|
||||
#define HOSTED_BOARDCONFIG_PRINT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void printChar(const char* character, bool errStream);
|
||||
|
||||
#endif /* HOSTED_BOARDCONFIG_PRINT_H_ */
|
9
hosted/config/FSFWConfig.h
Normal file
9
hosted/config/FSFWConfig.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CONFIG_FSFWCONFIG_H_
|
||||
#define CONFIG_FSFWCONFIG_H_
|
||||
|
||||
//! 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.
|
||||
#define FSFW_NO_C99_IO 0
|
||||
|
||||
|
||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
14
hosted/config/OBSWConfig.h
Normal file
14
hosted/config/OBSWConfig.h
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @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_
|
||||
|
||||
#define ADD_TEST_FOLDER 1
|
||||
|
||||
// Define not used yet, PUS stack and TMTC tasks are always started
|
||||
#define ADD_PUS_STACK 1
|
||||
|
||||
#endif /* CONFIG_OBSWCONFIG_H_ */
|
15
hosted/config/config.mk
Normal file
15
hosted/config/config.mk
Normal file
@ -0,0 +1,15 @@
|
||||
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)
|
||||
INCLUDES += $(CURRENTPATH)/objects
|
||||
INCLUDES += $(CURRENTPATH)/ipc
|
||||
INCLUDES += $(CURRENTPATH)/pollingsequence
|
||||
INCLUDES += $(CURRENTPATH)/returnvalues
|
||||
INCLUDES += $(CURRENTPATH)/tmtc
|
||||
INCLUDES += $(CURRENTPATH)/events
|
||||
INCLUDES += $(CURRENTPATH)/devices
|
||||
INCLUDES += $(CURRENTPATH)/cdatapool
|
34
hosted/config/events/subsystemIdRanges.h
Normal file
34
hosted/config/events/subsystemIdRanges.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
|
||||
#include <fsfw/events/fwSubsystemIdRanges.h>
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* These IDs are part of the ID for an event thrown by a subsystem.
|
||||
* Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/)
|
||||
*/
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum: uint8_t {
|
||||
SUBSYSTE_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
||||
/**
|
||||
* 80-105: PUS Services
|
||||
*/
|
||||
PUS_SERVICE_2 = 82,
|
||||
PUS_SERVICE_3 = 83,
|
||||
PUS_SERVICE_5 = 85,
|
||||
PUS_SERVICE_6 = 86,
|
||||
PUS_SERVICE_8 = 88,
|
||||
PUS_SERVICE_23 = 91,
|
||||
DUMMY_DEVICE = 90,
|
||||
/**
|
||||
* 105-115: AOCS
|
||||
*/
|
||||
GPS_DEVICE = 105,
|
||||
|
||||
SPI_COM_IF = 128,
|
||||
I2C_COM_IF = 138
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */
|
11
hosted/config/ipc/MissionMessageTypes.cpp
Normal file
11
hosted/config/ipc/MissionMessageTypes.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "MissionMessageTypes.h"
|
||||
#include <fsfw/ipc/CommandMessage.h>
|
||||
|
||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||
switch(message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
22
hosted/config/ipc/MissionMessageTypes.h
Normal file
22
hosted/config/ipc/MissionMessageTypes.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef CONFIG_IPC_MISSIONMESSAGETYPES_H_
|
||||
#define CONFIG_IPC_MISSIONMESSAGETYPES_H_
|
||||
|
||||
#include <fsfw/ipc/FwMessageTypes.h>
|
||||
|
||||
class CommandMessage;
|
||||
|
||||
/**
|
||||
* Custom command messages are specified here.
|
||||
* Most messages needed to use FSFW are already located in
|
||||
* <fsfw/ipc/FwMessageTypes.h>
|
||||
* @param message Generic Command Message
|
||||
*/
|
||||
namespace messagetypes{
|
||||
enum MESSAGE_TYPE {
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||
};
|
||||
|
||||
void clearMissionMessage(CommandMessage* message);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
9
hosted/config/version.h
Normal file
9
hosted/config/version.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CONFIG_VERSION_H_
|
||||
#define CONFIG_VERSION_H_
|
||||
|
||||
#define SW_VERSION 0
|
||||
#define SW_SUBVERSION 1
|
||||
|
||||
|
||||
|
||||
#endif /* CONFIG_VERSION_H_ */
|
7
hosted/hosted.mk
Normal file
7
hosted/hosted.mk
Normal file
@ -0,0 +1,7 @@
|
||||
# add main and others
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
||||
|
||||
CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c)
|
||||
|
||||
INCLUDES += $(CURRENTPATH)/boardconfig
|
31
hosted/main.cpp
Normal file
31
hosted/main.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include <mission/core/InitMission.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <version.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This is the main program for the hosted build. It can be run for
|
||||
* Linux and Windows.
|
||||
* @return
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||
std::cout << "-- Compiled for Linux " << " --" << std::endl;
|
||||
std::cout << "-- Software version v" << SW_VERSION << "." << SW_SUBVERSION
|
||||
<< " -- " << std::endl;
|
||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||
|
||||
InitMission::initMission();
|
||||
|
||||
for(;;) {
|
||||
// suspend main thread by sleeping it.
|
||||
TaskFactory::delayTask(5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
155
mission/core/InitMission.cpp
Normal file
155
mission/core/InitMission.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
#include "InitMission.h"
|
||||
|
||||
#include <OBSWConfig.h>
|
||||
#include <config/objects/systemObjectList.h>
|
||||
#include <mission/core/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 <iostream>
|
||||
|
||||
// This is configured for linux without \cr
|
||||
ServiceInterfaceStream sif::debug("DEBUG", false);
|
||||
ServiceInterfaceStream sif::info("INFO", false);
|
||||
ServiceInterfaceStream sif::warning("WARNING", false);
|
||||
ServiceInterfaceStream sif::error("ERROR", false, false, true);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
9
mission/core/InitMission.h
Normal file
9
mission/core/InitMission.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef MISSION_CORE_INITMISSION_H_
|
||||
#define MISSION_CORE_INITMISSION_H_
|
||||
|
||||
namespace InitMission {
|
||||
void initMission();
|
||||
void initTasks();
|
||||
};
|
||||
|
||||
#endif /* MISSION_CORE_INITMISSION_H_ */
|
128
mission/core/ObjectFactory.cpp
Normal file
128
mission/core/ObjectFactory.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "ObjectFactory.h"
|
||||
|
||||
#include <config/OBSWConfig.h>
|
||||
#include <config/objects/systemObjectList.h>
|
||||
#include <config/tmtc/apid.h>
|
||||
#include <config/tmtc/pusIds.h>
|
||||
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/storagemanager/PoolManager.h>
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/timemanager/TimeStamper.h>
|
||||
#include <fsfw/internalError/InternalErrorReporter.h>
|
||||
#include <fsfw/monitoring/MonitoringMessageContent.h>
|
||||
#include <fsfw/tcdistribution/CCSDSDistributor.h>
|
||||
#include <fsfw/tcdistribution/PUSDistributor.h>
|
||||
#include <fsfw/pus/Service1TelecommandVerification.h>
|
||||
#include <fsfw/pus/Service2DeviceAccess.h>
|
||||
#include <fsfw/pus/Service5EventReporting.h>
|
||||
#include <fsfw/pus/Service8FunctionManagement.h>
|
||||
#include <fsfw/pus/Service9TimeManagement.h>
|
||||
#include <fsfw/pus/Service17Test.h>
|
||||
#include <fsfw/pus/CService200ModeCommanding.h>
|
||||
#ifdef LINUX
|
||||
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
|
||||
#include <fsfw/osal/linux/TmTcUnixUdpBridge.h>
|
||||
#endif
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||
|
||||
|
||||
#if ADD_TEST_CODE == 1
|
||||
#include <test/TestCookie.h>
|
||||
#include <test/TestDeviceHandler.h>
|
||||
#include <mission/test/TestTask.h>
|
||||
#include <test/TestEchoComIF.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;
|
||||
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
TmPacketStored::timeStamperId = objects::TIME_STAMPER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ObjectFactory::produce(){
|
||||
Factory::setStaticFrameworkObjectIds();
|
||||
|
||||
/* Framework objects */
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new HealthTable(objects::HEALTH_TABLE);
|
||||
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, 0, 0, 0);
|
||||
new TimeStamper(objects::TIME_STAMPER);
|
||||
|
||||
{
|
||||
static constexpr uint8_t NUMBER_OF_POOLS = 5;
|
||||
const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024};
|
||||
const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5};
|
||||
new PoolManager<NUMBER_OF_POOLS>(objects::TC_STORE, element_sizes,
|
||||
n_elements);
|
||||
}
|
||||
|
||||
{
|
||||
static constexpr uint8_t NUMBER_OF_POOLS = 5;
|
||||
const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024};
|
||||
const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5};
|
||||
new PoolManager<NUMBER_OF_POOLS>(objects::TM_STORE, element_sizes,
|
||||
n_elements);
|
||||
}
|
||||
|
||||
{
|
||||
static constexpr uint8_t NUMBER_OF_POOLS = 6;
|
||||
const uint16_t element_sizes[NUMBER_OF_POOLS] = {32, 64, 512,
|
||||
1024, 2048, 4096};
|
||||
const uint16_t n_elements[NUMBER_OF_POOLS] = {200, 100, 50, 25, 15, 5};
|
||||
new PoolManager<NUMBER_OF_POOLS>(objects::IPC_STORE, element_sizes,
|
||||
n_elements);
|
||||
}
|
||||
|
||||
new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
new PUSDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
|
||||
|
||||
/* TMTC Reception via UDP socket */
|
||||
new TmFunnel(objects::TM_FUNNEL);
|
||||
#ifdef LINUX
|
||||
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR,
|
||||
objects::TM_STORE, objects::TC_STORE);
|
||||
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
||||
#endif
|
||||
|
||||
|
||||
/* PUS stack */
|
||||
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_1, objects::TM_FUNNEL);
|
||||
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_2, 3, 10);
|
||||
new Service5EventReporting(objects::PUS_SERVICE_5_EVENT_REPORTING,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_5, 50);
|
||||
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_8, 3, 10);
|
||||
new Service9TimeManagement(objects::PUS_SERVICE_9_TIME_MGMT,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_9);
|
||||
new Service17Test(objects::PUS_SERVICE_17_TEST, apid::EIVE_OBSW,
|
||||
pus::PUS_SERVICE_17);
|
||||
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT,
|
||||
apid::EIVE_OBSW, pus::PUS_SERVICE_200);
|
||||
|
||||
/* Test Device Handler */
|
||||
#if ADD_TEST_CODE == 1
|
||||
CookieIF* testCookie = new TestCookie(0);
|
||||
new TestEchoComIF(objects::TEST_ECHO_COM_IF);
|
||||
new TestDevice(objects::TEST_DEVICE_HANDLER, objects::TEST_ECHO_COM_IF,
|
||||
testCookie, true);
|
||||
#endif
|
||||
}
|
17
mission/core/ObjectFactory.h
Normal file
17
mission/core/ObjectFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* ObjectFactory.h
|
||||
*
|
||||
* Created on: Sep 22, 2020
|
||||
* Author: steffen
|
||||
*/
|
||||
|
||||
#ifndef MISSION_CORE_OBJECTFACTORY_H_
|
||||
#define MISSION_CORE_OBJECTFACTORY_H_
|
||||
|
||||
|
||||
namespace ObjectFactory {
|
||||
void setStatics();
|
||||
void produce();
|
||||
};
|
||||
|
||||
#endif /* MISSION_CORE_OBJECTFACTORY_H_ */
|
@ -1,2 +1,17 @@
|
||||
# add main and others
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
||||
|
||||
CSRC += $(wildcard $(CURRENTPATH)/core/*.c)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/core/*.cpp)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/devices/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/devices/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/utility/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/utility/*.c)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/utility/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/test/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/test/*.c)
|
||||
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
#include <fsfw/timemanager/Clock.h>
|
||||
#include <mission/utility/TimeStamper.h>
|
||||
#include <cstring>
|
||||
|
||||
TimeStamper::TimeStamper(object_id_t objectId): SystemObject(objectId) {}
|
||||
|
||||
|
||||
ReturnValue_t TimeStamper::addTimeStamp(uint8_t* buffer,
|
||||
const uint8_t maxSize) {
|
||||
if(maxSize < TimeStamperIF::MISSION_TIMESTAMP_SIZE) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::CDS_short cds;
|
||||
ReturnValue_t result = CCSDSTime::convertToCcsds(&cds,&now);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
std::memcpy(buffer,&cds,sizeof(cds));
|
||||
return result;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#ifndef MISSION_UTILITY_TIMESTAMPER_H_
|
||||
#define MISSION_UTILITY_TIMESTAMPER_H_
|
||||
|
||||
#include <fsfw/timemanager/TimeStamperIF.h>
|
||||
#include <fsfw/timemanager/CCSDSTime.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @ingroup utility
|
||||
*/
|
||||
class TimeStamper: public TimeStamperIF, public SystemObject {
|
||||
public:
|
||||
TimeStamper(object_id_t objectId);
|
||||
virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize);
|
||||
};
|
||||
|
||||
#endif /* MISSION_UTILITY_TIMESTAMPER_H_ */
|
@ -1,15 +1,14 @@
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketBase.h>
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
|
||||
object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT;
|
||||
object_id_t TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||
|
||||
TmFunnel::TmFunnel(object_id_t objectId_): SystemObject(objectId_),
|
||||
sourceSequenceCount(0), storageTargetSet(false) {
|
||||
TmFunnel::TmFunnel(object_id_t objectId, uint32_t messageDepth):
|
||||
SystemObject(objectId), messageDepth(messageDepth) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
storageQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
|
||||
@ -66,7 +65,7 @@ ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(storageTargetSet) {
|
||||
if(storageDestination != objects::NO_OBJECT) {
|
||||
result = storageQueue->sendToDefault(message);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
@ -100,10 +99,14 @@ ReturnValue_t TmFunnel::initialize() {
|
||||
}
|
||||
tmQueue->setDefaultDestination(tmTarget->getReportReceptionQueue());
|
||||
|
||||
// Storage destination is optional.
|
||||
if(storageDestination == objects::NO_OBJECT) {
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
AcceptsTelemetryIF* storageTarget =
|
||||
objectManager->get<AcceptsTelemetryIF>(storageDestination);
|
||||
if(storageTarget != nullptr) {
|
||||
storageTargetSet = true;
|
||||
storageQueue->setDefaultDestination(
|
||||
storageTarget->getReportReceptionQueue());
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class TmFunnel: public AcceptsTelemetryIF,
|
||||
public SystemObject {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
TmFunnel(object_id_t objectId);
|
||||
TmFunnel(object_id_t objectId, uint32_t messageDepth = 20);
|
||||
virtual ~TmFunnel();
|
||||
|
||||
virtual MessageQueueId_t getReportReceptionQueue(
|
||||
@ -37,14 +37,12 @@ protected:
|
||||
static object_id_t storageDestination;
|
||||
|
||||
private:
|
||||
|
||||
uint16_t sourceSequenceCount;
|
||||
bool storageTargetSet;
|
||||
uint16_t sourceSequenceCount = 0;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
MessageQueueIF* storageQueue = nullptr;
|
||||
|
||||
StorageManagerIF* tmPool = nullptr;
|
||||
uint32_t messageDepth = 10;
|
||||
uint32_t messageDepth = 0;
|
||||
|
||||
ReturnValue_t handlePacket(TmTcMessage* message);
|
||||
};
|
||||
|
1
tmtc
Submodule
1
tmtc
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ee295fa849ec7af33204f437d60742d173ac5c4b
|
Loading…
Reference in New Issue
Block a user