diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..1cdf56de --- /dev/null +++ b/Makefile @@ -0,0 +1,369 @@ +#------------------------------------------------------------------------------- +# Makefile for EIVE 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 + +# Chip & board used for compilation +# (can be overriden by adding CHIP=chip and BOARD=board to the command-line) +BOARD_FILE_ROOT = bsp_linux +BOARD = linux +OS_FSFW = linux +CUSTOM_DEFINES += -D$(OS_FSFW) +CUSTOM_DEFINES += -DLINUX + +SW_VERSION = 1 +SW_SUBVERSION = 6 +CUSTOM_DEFINES += -DSW_VERSION=$(SW_VERSION) +CUSTOM_DEFINES += -DSW_SUBVERSION=$(SW_SUBVERSION) + +# 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) +CLEANBIN1 = $(BUILDPATH)/$(OUTPUT_FOLDER)/mission +CLEANBIN2 = $(BUILDPATH)/$(OUTPUT_FOLDER)/devel + +#------------------------------------------------------------------------------- +# 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) $(UNITTEST_PATH)\ + $(CONFIG_PATH) $(MISSION_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 ! + +# 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: SOURCE OBSW Linux. +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 is done; 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) $(OPTIMIZATION) $(DEPFLAGS) $(WARNING_FLAGS) \ + $(I_INCLUDES) -fmessage-length=0 $(CXXDEFINES) +CPPFLAGS += -std=c++17 -fno-exceptions +ASFLAGS = -Wall $(DEBUG_LEVEL) $(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 +LINK_FLAGS = $(DEBUG_LEVEL) $(DEAD_CODE_REMOVAL) $(OPTIMIZATION) -pthread +LINK_INCLUDES = +LINK_LIBRARIES = -lrt + +# 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 + +# In this section, the binaries are built for all selected memories + +all: executable + +# 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) + +# 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 + +debug release: executable + +executable: $(BINDIR)/$(BINARY_NAME).elf + @echo + @echo $(MSG_INFO) + @echo $(MSG_TARGET) + @echo $(MSG_OPTIMIZATION) + @echo $(MSG_DEBUG) + +# For debugging. +# $(info $${C_OBJECTS} is [${C_OBJECTS}]) +# $(info $${CXX_OBJECTS} is [${CXX_OBJECTS}]) + +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 $${ALL_OBJECTS_PREFIXED} is [${ALL_OBJECTS_PREFIXED}]) + +# 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 + +$(BINDIR)/$(BINARY_NAME).elf: $(ALL_OBJECTS_PREFIXED) + @echo $(MSG_LINKING) Target $@ + @mkdir -p $(@D) +ifdef SHOW_DETAILS + $(CXX) $(LINK_FLAGS) $(LINK_INCLUDES) -o $@ $^ $(LINK_LIBRARIES) +else + @$(CXX) $(LINK_FLAGS) $(LINK_INCLUDES) -o $@ $^ $(LINK_LIBRARIES) +endif +ifeq ($(BUILD_FOLDER), release) +# With Link Time Optimization, section size is not available + $(SIZE) $@ +else + @$(SIZE) $^ $@ +endif + + +$(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 + +#------------------------------------------------------------------------------- +# 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 diff --git a/config/config.mk b/config/config.mk new file mode 100644 index 00000000..e69de29b