diff --git a/CMakeLists.txt b/CMakeLists.txt index f313fb20c..7a147eeb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,21 @@ project(CFE C) # Allow unit tests to be added by any recipe enable_testing() +# This switch determines whether to use EDS framework +# By default it is set OFF/false as this is a new/experimental feature. +option(CFE_EDS_ENABLED_BUILD "Use EDS framework" OFF) + +# Always create directories to hold generated files/wrappers +# EDS makes signficant use of generated files. In non-EDS builds +# some headers and wrapper files are also generated. Directories +# may simply remain empty if not used/needed in the current config. +file(MAKE_DIRECTORY + "${CMAKE_BINARY_DIR}/eds" + "${CMAKE_BINARY_DIR}/obj" + "${CMAKE_BINARY_DIR}/inc" + "${CMAKE_BINARY_DIR}/src" +) + # Include the global routines include("cmake/global_functions.cmake") @@ -123,4 +138,3 @@ prepare() foreach(SYSVAR ${TGTSYS_LIST}) process_arch(${SYSVAR}) endforeach(SYSVAR ${TGTSYS_LIST}) - diff --git a/cmake/arch_build.cmake b/cmake/arch_build.cmake index e0bae5dde..e152d7182 100644 --- a/cmake/arch_build.cmake +++ b/cmake/arch_build.cmake @@ -101,6 +101,17 @@ function(add_cfe_app APP_NAME APP_SRC_FILES) add_library(${APP_NAME} ${APPTYPE} ${APP_SRC_FILES} ${ARGN}) target_link_libraries(${APP_NAME} core_api) + # If using "local" EDS linkage, then link the app with the EDS library here. + # Note that the linker will only pull in the compilation unit that actually + # resolves an undefined symbol, which in this case would be the app-specific + # DATATYPE_DB object if one is referenced at all. + # + # By linking with the respective application like this, the net result is that + # only the _referenced_ EDS DBs (i.e. those for loaded apps) are held in memory. + if (CFE_EDS_ENABLED_BUILD AND CFE_EDS_LINK_MODE STREQUAL LOCAL) + target_link_libraries($(APP_NAME) cfe_edsdb_static) + endif() + # An "install" step is only needed for dynamic/runtime loaded apps if (APP_DYNAMIC_TARGET_LIST) cfs_app_do_install(${APP_NAME} ${APP_DYNAMIC_TARGET_LIST}) diff --git a/cmake/mission_build.cmake b/cmake/mission_build.cmake index 76adfe97c..299307fc2 100644 --- a/cmake/mission_build.cmake +++ b/cmake/mission_build.cmake @@ -260,6 +260,7 @@ function(export_variable_cache USER_VARLIST) "MISSION_EDS_FILELIST" "MISSION_EDS_SCRIPTLIST" "ENABLE_UNIT_TESTS" + "CFE_EDS_ENABLED_BUILD" ) set(MISSION_VARCACHE) @@ -293,12 +294,6 @@ function(prepare) add_definitions(-DSIMULATION=${SIMULATION}) endif (SIMULATION) - # Create directories to hold generated files/wrappers - file(MAKE_DIRECTORY "${MISSION_BINARY_DIR}/eds") - file(MAKE_DIRECTORY "${MISSION_BINARY_DIR}/obj") - file(MAKE_DIRECTORY "${MISSION_BINARY_DIR}/inc") - file(MAKE_DIRECTORY "${MISSION_BINARY_DIR}/src") - # Certain runtime variables need to be "exported" to the subordinate build, such as # the specific arch settings and the location of all the apps. This list is collected # during this function execution and exported at the end. @@ -548,7 +543,7 @@ function(process_arch TARGETSYSTEM) # convert to a string which is safe for a directory name string(REGEX REPLACE "[^A-Za-z0-9]" "_" ARCH_CONFIG_NAME "${BUILD_CONFIG}") set(ARCH_BINARY_DIR "${CMAKE_BINARY_DIR}/${ARCH_TOOLCHAIN_NAME}/${ARCH_CONFIG_NAME}") - file(MAKE_DIRECTORY "${ARCH_BINARY_DIR}" "${ARCH_BINARY_DIR}/inc") + file(MAKE_DIRECTORY "${ARCH_BINARY_DIR}") message(STATUS "Configuring for system arch: ${ARCH_TOOLCHAIN_NAME}/${ARCH_CONFIG_NAME}") diff --git a/cmake/mission_defaults.cmake b/cmake/mission_defaults.cmake index c7871c5ce..fb2885711 100644 --- a/cmake/mission_defaults.cmake +++ b/cmake/mission_defaults.cmake @@ -67,6 +67,46 @@ set(MISSION_MODULE_SEARCH_PATH set(osal_SEARCH_PATH ".") set(psp_SEARCH_PATH ".") +# Account for differences when EDS is enabled +if(CFE_EDS_ENABLED_BUILD) + + # Propagate the setting to a C preprocessor define of the same name + # The CFE_EDS_ENABLED_BUILD switch indicates that any + # compile-time preprocessor blocks should be enabled in this build + add_definitions(-DCFE_EDS_ENABLED_BUILD) + + # The EDS database is an object (or set of objects) generated by the tools from the EDS files. + # This can be linked into CFE either as a whole (GLOBAL) or as part of each app (LOCAL). + # + # LOCAL mode may use less memory by only only including DB objects for the apps that are + # originating or terminating CFS message traffic, but GLOBAL mode is simpler as it ensures + # that the entire DB is accessible by any app, even for data definitions that are not its own. + # + # NOTE: If running CI/TO, SBN, or other "generic" apps that relay SB traffic (or otherwise + # handle data that may not have originated on the same CFE instance) then it is recommended + # to stay with GLOBAL mode. + if (NOT DEFINED CFE_EDS_LINK_MODE) + set(CFE_EDS_LINK_MODE GLOBAL) + endif() + + # The standard msg module is not used in EDS build, edslib provides an alternate + list(REMOVE_ITEM MISSION_CORE_MODULES msg) + + list(APPEND MISSION_CORE_MODULES + "edslib" + "missionlib" + "edsmsg" + ) + + list(APPEND MISSION_MODULE_SEARCH_PATH + "tools/eds/cfecfs" # CFE/CFS modules and extensions from EdsLib + ) + + # edslib exists directly under tools/eds (EDS runtime libraries) + set(edslib_SEARCH_PATH "tools/eds") + +endif(CFE_EDS_ENABLED_BUILD) + # Include "cfe_assert" library in all builds, because it is included # in the default startup script. It should not have any effect if not # used. diff --git a/cmake/target/CMakeLists.txt b/cmake/target/CMakeLists.txt index 5e5eb73c4..adb1e8fde 100644 --- a/cmake/target/CMakeLists.txt +++ b/cmake/target/CMakeLists.txt @@ -193,6 +193,37 @@ set(CFE_LINK_NORMAL_LIBS ${${TGTNAME}_STATIC_APPLIST} ) +# If EDS is enabled, then the generated dictionary objects are linked with CFE. +# This can be done statically or dynamically, depending on user preferences. +if (CFE_EDS_ENABLED_BUILD) + + # Determine EDS object linking mode for final executable. + # This should be configured via the toolchain file, + # with the default being FALSE (static link) + if (CFE_EDS_LINK_MODE STREQUAL GLOBAL) + + # In this mode the full EDS object is statically linked + # In addition, also pull in the runtime lib, which + # supports script language bindings and UI display + list(APPEND CFE_LINK_WHOLE_LIBS + cfe_edsdb_static + edslib_runtime_static + ) + + endif() + + list(APPEND CFE_LINK_WHOLE_LIBS + cfe_missionlib_runtime_static + cfe_missionlib_interfacedb_static + ) + + # Set a preprocessor define so the source will reference the right thing + target_compile_definitions(core-${TGTNAME} PRIVATE + CFE_EDS_LINK_MODE_${CFE_EDS_LINK_MODE} + ) + +endif(CFE_EDS_ENABLED_BUILD) + # Handle the list of "embedded files" that should be linked into CFE. # These are arbitrary files in the mission config that are converted # into C data structures and linked with the executable. This is @@ -276,4 +307,3 @@ target_link_libraries(core-${TGTNAME} # This is implemented in a separate function so # it may be overridden in an OS-specific manner if necessary. cfe_exec_do_install(${TGTNAME}) - diff --git a/cmake/target/inc/target_config.h b/cmake/target/inc/target_config.h index 3a18d33f4..a01baebb4 100644 --- a/cmake/target/inc/target_config.h +++ b/cmake/target/inc/target_config.h @@ -89,6 +89,12 @@ typedef const struct const void *Value; } CFE_ConfigKeyValue_t; +/** + * The "EdsLib_DatabaseObject" is an abstract structure here. + */ +typedef struct EdsLib_DatabaseObject CFE_EdsDbObject_t; +typedef struct CFE_MissionLib_SoftwareBus_Interface CFE_SbIntfDbObject_t; + /** * Core Flight Executive configuration information. */ @@ -196,6 +202,34 @@ typedef const struct CFE_ConfigName_t * CoreModuleList; /**< List of CFE core support module names that are statically linked */ CFE_ConfigName_t *StaticAppList; /**< List of additional CFS Applications that are statically linked into this binary */ + + /** + * Normal read-only EDS Database object + * + * This EDS DB object pointer is always initialized to be non-null. + * It is qualified as "const" and used for all EDS query requests. + */ + const CFE_EdsDbObject_t *EdsDb; + + /** + * Dynamic EDS Database object + * + * This provides a writable (non-const) pointer to the same EDS object as above, + * but only when when dynamic EDS link mode is selected. It will be set NULL + * when static EDS link mode is selected. + * + * This can checked by runtime code to determine the EDS link mode. If it is + * NULL this means the EDS DB is fixed/static and no runtime registration is needed. + * If this pointer is non-null then the EDS DB is dynamic and runtime registration + * is needed. + */ + CFE_EdsDbObject_t *DynamicEdsDb; + + /** + * Software bus interface EDS object (MsgId mappings) + */ + const CFE_SbIntfDbObject_t *SbIntfDb; + } Target_ConfigData; /** diff --git a/cmake/target/src/target_config.c b/cmake/target/src/target_config.c index 0b389f079..b5c1adf04 100644 --- a/cmake/target/src/target_config.c +++ b/cmake/target/src/target_config.c @@ -126,6 +126,78 @@ extern CFE_ConfigKeyValue_t CFE_MODULE_VERSION_TABLE[]; */ extern CFE_StaticModuleLoadEntry_t CFE_PSP_MODULE_LIST[]; +#ifdef CFE_EDS_ENABLED_BUILD + +#include "cfe_mission_eds_parameters.h" +#include "cfe_mission_eds_interface_parameters.h" + +#define CFE_SB_INTF_DB_PTR &CFE_SOFTWAREBUS_INTERFACE + +#endif /* CFE_EDS_ENABLED_BUILD */ + +/* + * Determine the proper values for populating the EDS-related + * fields of the configuration structure. This depends on the + * selected linkage mode (static or dynamic). + */ + +/* + * Static (const) EDS object link mode: + * Only the const pointer gets assigned to the EDS object, and the + * non-const pointer gets set NULL. There are no "write" operations + * in this mode -- registration and de-registration is not necessary. + */ +#ifdef CFE_EDS_LINK_MODE_GLOBAL + +/* This mode is simple, just point directly at the object defined in the external DB */ +#define CFE_CONST_EDS_DB_PTR &EDS_DATABASE + +#endif /* CFE_EDS_LINK_MODE_GLOBAL */ + +/* + * Dynamic (non-const) runtime EDS database object + * This is filled in as additional EDS datasheet objects are registered + */ +#ifdef CFE_EDS_LINK_MODE_LOCAL + +static EdsLib_DataTypeDB_t CFE_DYNAMIC_EDS_TABLE[EDS_MAX_DATASHEETS] = {NULL}; + +static EdsLib_DatabaseObject_t CFE_DYNAMIC_EDSDB_OBJECT = {.AppTableSize = EDS_MAX_DATASHEETS, + .DataTypeDB_Table = CFE_DYNAMIC_EDS_TABLE}; + +/* The object registered in config points at the local (empty) object */ +#define CFE_NONCONST_EDS_DB_PTR &CFE_DYNAMIC_EDSDB_OBJECT + +#endif /* CFE_EDS_LINK_MODE_LOCAL */ + +/* + * For all of these DB objects, use NULL if not defined. + * This covers the case where EDS is not being used. + */ +#ifndef CFE_NONCONST_EDS_DB_PTR +#define CFE_NONCONST_EDS_DB_PTR NULL +#endif + +/* + * Note that the non-const object can be used as a const object, + * but not the other way around. This can also be NULL. + */ +#ifndef CFE_CONST_EDS_DB_PTR +#define CFE_CONST_EDS_DB_PTR CFE_NONCONST_EDS_DB_PTR +#endif + +/* + * The SB intf DB serves as the lookup table for identification + * of the software bus messages. This can also be NULL if + * EDS is not being used. + */ +#ifndef CFE_SB_INTF_DB_PTR +#define CFE_SB_INTF_DB_PTR NULL +#endif + +/* Disable clang-format for the rest of this file, to preserve columns in the struct defs */ +/* clang-format off */ + /** * A structure that encapsulates all the CFE static configuration */ @@ -152,7 +224,9 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA = { .UserReservedSize = CFE_PLATFORM_ES_USER_RESERVED_SIZE, .RamDiskSectorSize = CFE_PLATFORM_ES_RAM_DISK_SECTOR_SIZE, - .RamDiskTotalSectors = CFE_PLATFORM_ES_RAM_DISK_NUM_SECTORS}; + .RamDiskTotalSectors = CFE_PLATFORM_ES_RAM_DISK_NUM_SECTORS +}; + /** * Instantiation of global system-wide configuration struct @@ -176,4 +250,8 @@ Target_ConfigData GLOBAL_CONFIGDATA = { .ModuleVersionList = CFE_MODULE_VERSION_TABLE, .CoreModuleList = CFE_CORE_MODULE_LIST, .StaticAppList = CFE_STATIC_APP_LIST, + .EdsDb = CFE_CONST_EDS_DB_PTR, + .DynamicEdsDb = CFE_NONCONST_EDS_DB_PTR, + .SbIntfDb = CFE_SB_INTF_DB_PTR }; + diff --git a/modules/config/fsw/src/cfe_config_init.c b/modules/config/fsw/src/cfe_config_init.c index 6791b45c4..e8cee9cc4 100644 --- a/modules/config/fsw/src/cfe_config_init.c +++ b/modules/config/fsw/src/cfe_config_init.c @@ -177,6 +177,10 @@ void CFE_Config_SetupBasicBuildInfo(void) KeyVal = CFE_Config_FindTargetKeyValue(GLOBAL_CONFIGDATA.ModuleVersionList, "MISSION"); CFE_Config_SetString(CFE_CONFIGID_MISSION_SRCVER, KeyVal); + /* Global mission EDS runtime DB */ + CFE_Config_SetObjPointer(CFE_CONFIGID_MISSION_EDS_DB, GLOBAL_CONFIGDATA.EdsDb); + CFE_Config_SetObjPointer(CFE_CONFIGID_MISSION_SBINTF_DB, GLOBAL_CONFIGDATA.SbIntfDb); + /* propagate the version numbers from version.h */ CFE_Config_SetValue(CFE_CONFIGID_CORE_VERSION_MAJOR, CFE_MAJOR_VERSION); CFE_Config_SetValue(CFE_CONFIGID_CORE_VERSION_MINOR, CFE_MINOR_VERSION); diff --git a/modules/config/mission_build.cmake b/modules/config/mission_build.cmake index a5a6d4551..c79774c46 100644 --- a/modules/config/mission_build.cmake +++ b/modules/config/mission_build.cmake @@ -18,6 +18,8 @@ set(GENERATED_IDNAME_MAP_LIST) list(APPEND CFE_CONFIG_IDS MISSION_NAME MISSION_SRCVER + MISSION_EDS_DB + MISSION_SBINTF_DB CORE_VERSION_MAJOR CORE_VERSION_MINOR diff --git a/modules/evs/fsw/src/cfe_evs_task.c b/modules/evs/fsw/src/cfe_evs_task.c index 2d5024784..59e8c1ce4 100644 --- a/modules/evs/fsw/src/cfe_evs_task.c +++ b/modules/evs/fsw/src/cfe_evs_task.c @@ -43,12 +43,6 @@ CFE_EVS_Global_t CFE_EVS_Global; /* Defines */ #define CFE_EVS_PANIC_DELAY 500 /**< \brief Task delay before PSP panic */ -/* -** Local function prototypes. -*/ -void CFE_EVS_ProcessGroundCommand(CFE_SB_Buffer_t *SBBufPtr, CFE_SB_MsgId_t MsgId); -bool CFE_EVS_VerifyCmdLength(CFE_MSG_Message_t *MsgPtr, size_t ExpectedLength); - /* Function Definitions */ /*---------------------------------------------------------------- diff --git a/modules/evs/ut-coverage/evs_UT.c b/modules/evs/ut-coverage/evs_UT.c index 7169e351d..5f3da04bd 100644 --- a/modules/evs/ut-coverage/evs_UT.c +++ b/modules/evs/ut-coverage/evs_UT.c @@ -277,7 +277,6 @@ void Test_Init(void) { CFE_EVS_EnablePortsCmd_t bitmaskcmd; CFE_EVS_EnableAppEventTypeCmd_t appbitcmd; - CFE_SB_MsgId_t msgid = CFE_SB_INVALID_MSG_ID; UtPrintf("Begin Test Init"); @@ -307,7 +306,7 @@ void Test_Init(void) UT_InitData_EVS(); /* Set unexpected message ID */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetupBasicMsgDispatch(&UT_TPID_CFE_EVS_INVALID_MID, 0, true); UT_EVS_DoGenericCheckEvents(CFE_EVS_TaskMain, &UT_EVS_EventBuf); CFE_UtAssert_SYSLOG(EVS_SYSLOG_MSGS[8]);