diff --git a/cmake/generate_build_env.cmake b/cmake/generate_build_env.cmake
new file mode 100644
index 000000000..ea179281e
--- /dev/null
+++ b/cmake/generate_build_env.cmake
@@ -0,0 +1,48 @@
+##################################################################
+#
+# cFS version metadata collection script
+#
+# This small script runs at build time (as opposed to prep time)
+# and is intended to extract information about the current
+# build environment - this may change after initial makefile creation
+#
+##################################################################
+
+# All 3 of these may be passed via environment variables to force a particular
+# date, user, or hostname i.e. if hoping to reproduce an exact binary of a prior build
+# They are free-form strings, will be built/linked into the final CONFIGDATA object.
+
+# Get the current date and time
+set(BUILDDATE $ENV{BUILDDATE})
+if (NOT BUILDDATE)
+ execute_process(
+ COMMAND date "+%Y%m%d%H%M"
+ OUTPUT_VARIABLE BUILDDATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+endif(NOT BUILDDATE)
+
+# Get the build host
+set(BUILDHOST $ENV{HOSTNAME})
+if (NOT BUILDHOST)
+ execute_process(
+ COMMAND hostname
+ OUTPUT_VARIABLE BUILDHOST
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+endif (NOT BUILDHOST)
+
+# Get the user ID
+set(BUILDUSER $ENV{USER})
+if (NOT BUILDUSER)
+ execute_process(
+ COMMAND whoami
+ OUTPUT_VARIABLE BUILDUSER
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+endif (NOT BUILDUSER)
+
+# Use configure_file() command to generate the final output file because this can detect
+# and only update it if it changes.
+set(CFE_KEYVALUE_TABLE_NAME "CFE_BUILD_ENV_TABLE")
+configure_file(${BIN}/cfe_build_env.in ${BIN}/src/cfe_build_env_table.c @ONLY)
diff --git a/cmake/generate_git_module_version.cmake b/cmake/generate_git_module_version.cmake
new file mode 100644
index 000000000..7a2559324
--- /dev/null
+++ b/cmake/generate_git_module_version.cmake
@@ -0,0 +1,75 @@
+##################################################################
+#
+# cFS version metadata collection script
+#
+# This small script runs at build time (as opposed to prep time)
+# and is intended to extract version metadata from the current source
+# tree. It is done each time that the code is built, since the
+# metadata could change at any time (i.e. a different branch could
+# be checked out, or additional changes committed)
+#
+# Currently only git is supported as a version control source, however
+# it could be extended to others by adding the appropriate command
+#
+##################################################################
+
+set(GIT_EXECUTABLE git)
+
+function(get_version DEP)
+ if (DEP STREQUAL "MISSION")
+ set(NAME ${MISSION_NAME})
+ set(DIR ${MISSION_SOURCE_DIR})
+ else()
+ if(EXISTS ${${DEP}_MISSION_DIR}/version_info.cmake)
+ include(${${DEP}_MISSION_DIR}/version_info.cmake)
+ else()
+ set(NAME ${DEP})
+ endif()
+ set(DIR ${${DEP}_MISSION_DIR})
+ endif()
+ message("inside get_version for ${DEP}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
+ WORKING_DIRECTORY ${DIR}
+ OUTPUT_VARIABLE GIT_DESC_OUTPUT
+ RESULT_VARIABLE GIT_RESULT
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # Export output to parent scope
+ set(${DEP}_NAME "${NAME}" PARENT_SCOPE)
+
+ # If result was successful, then string-ify it, otherwise use NULL
+ if (GIT_RESULT EQUAL 0)
+ set(${DEP}_VERSION "\"git:${GIT_DESC_OUTPUT}\"" PARENT_SCOPE)
+ else()
+ set(${DEP}_VERSION "NULL" PARENT_SCOPE)
+ endif()
+
+endfunction()
+
+
+# First read in any variables that are passed in from the parent process
+# There may be many of these and they may not all be passable via -D options
+file(STRINGS "${BIN}/mission_vars.cache" PARENTVARS)
+set(VARNAME)
+foreach(PV ${PARENTVARS})
+ if (VARNAME)
+ set(${VARNAME} ${PV})
+ set(VARNAME)
+ else()
+ set(VARNAME ${PV})
+ endif()
+endforeach(PV ${PARENTVARS})
+
+# Get version for all mission apps/dependencies (they may be different)
+foreach(DEP "MISSION" ${MISSION_DEPS})
+ get_version(${DEP})
+endforeach()
+
+
+# Use configure_file() command to generate the final output file because this can detect
+# and only update it if it changes.
+set(CFE_KEYVALUE_TABLE_NAME "CFE_MODULE_VERSION_TABLE")
+configure_file(${BIN}/cfe_module_version.in ${BIN}/src/cfe_module_version_table.c @ONLY)
diff --git a/cmake/mission_build.cmake b/cmake/mission_build.cmake
index 66b0d43c1..7920af487 100644
--- a/cmake/mission_build.cmake
+++ b/cmake/mission_build.cmake
@@ -72,6 +72,95 @@ function(initialize_globals)
endfunction(initialize_globals)
+##################################################################
+#
+# FUNCTION: generate_build_version_templates
+#
+# Generates file templates for use with configure_file() which is
+# invoked at build time to get the required information.
+#
+# Note that some information may change between generation and build
+# times, hence why only a template can be generated here, the final
+# file content must be generated via a build rule.
+#
+function(generate_build_version_templates)
+
+ # File header for build info template (tag file as auto-generated)
+ string(CONCAT GENERATED_FILE_HEADER
+ "/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
+ "#include \"target_config.h\"\n"
+ "const CFE_ConfigKeyValue_t @CFE_KEYVALUE_TABLE_NAME@[] = {\n"
+ )
+
+ # File trailer for build info template
+ string(CONCAT GENERATED_FILE_TRAILER
+ "{ NULL, NULL } /* End of list */\n"
+ "};\n"
+ "/* End of file */\n"
+ )
+
+ # These variables are deferred until build time
+ foreach (VAR BUILDDATE BUILDUSER BUILDHOST)
+ list (APPEND GENERATED_FILE_CONTENT "{ \"${VAR}\", \"@${VAR}@\" },")
+ endforeach ()
+ string(REPLACE ";" "\n" GENERATED_FILE_CONTENT "${GENERATED_FILE_CONTENT}")
+
+ # Write a template for build/config information
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/cfe_build_env.in)
+
+ # Content for version info - all are deferred until build time
+ set(GENERATED_FILE_CONTENT)
+ foreach(DEP "MISSION" ${MISSION_DEPS})
+ list (APPEND GENERATED_FILE_CONTENT "{ \"${DEP}\", @${DEP}_VERSION@ },")
+ endforeach()
+ string(REPLACE ";" "\n" GENERATED_FILE_CONTENT "${GENERATED_FILE_CONTENT}")
+
+ # Write a template for version information
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/cfe_module_version.in)
+
+ # The actual version information (to fill out the template above) is obtained at build time
+ # via a script that is executed as a build target. If this script exists in the mission defs
+ # directory (user-supplied) then use that. Otherwise a pre-canned "git" version is included
+ # as a fallback, which should work for source trees assembled via git submodules or subtrees.
+ if (EXISTS "${MISSION_DEFS}/generate_module_version.cmake")
+ set(VERSION_SCRIPT "${MISSION_DEFS}/generate_module_version.cmake")
+ else()
+ set(VERSION_SCRIPT "${CFE_SOURCE_DIR}/cmake/generate_git_module_version.cmake")
+ endif()
+
+ add_custom_target(cfe-module-version
+ COMMAND
+ ${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
+ -P "${VERSION_SCRIPT}"
+ WORKING_DIRECTORY
+ ${CMAKE_SOURCE_DIR}
+ VERBATIM
+ )
+
+ add_custom_target(cfe-build-env
+ COMMAND
+ ${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
+ -P "${CFE_SOURCE_DIR}/cmake/generate_build_env.cmake"
+ WORKING_DIRECTORY
+ ${CMAKE_SOURCE_DIR}
+ VERBATIM
+ )
+
+ # Content for build info - these vars can be evaulated right now, no need to defer
+ set(GENERATED_FILE_HEADER "/* Automatically generated from CMake build system */")
+ string(CONCAT GENERATED_FILE_CONTENT
+ "const char CFE_MISSION_NAME[] = \"${MISSION_NAME}\";\n"
+ "const char CFE_MISSION_CONFIG[] = \"${MISSIONCONFIG}\";\n"
+ )
+ set(GENERATED_FILE_TRAILER "/* End of file */")
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/src/cfe_mission_strings.c)
+
+ add_custom_target(mission-version
+ DEPENDS cfe-module-version cfe-build-env
+ )
+
+endfunction(generate_build_version_templates)
+
##################################################################
#
@@ -267,17 +356,8 @@ function(prepare)
endif (NOT "${${VARL}}" STREQUAL "")
endforeach(VARL ${VARLIST})
file(WRITE "${CMAKE_BINARY_DIR}/mission_vars.cache" "${MISSION_VARCACHE}")
-
- # Generate version information for the executable file. This is done by executing a small CMAKE
- # at _build_ time (not at prep time since it might change between now and then) that collects
- # the info out of the version control system in use (git is currently assumed).
- add_custom_target(mission-version
- COMMAND
- ${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
- -P ${CFE_SOURCE_DIR}/cmake/version.cmake
- WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}
- )
+
+ generate_build_version_templates()
# Generate the tools for the native (host) arch
add_subdirectory(${MISSION_SOURCE_DIR}/tools tools)
diff --git a/cmake/target/CMakeLists.txt b/cmake/target/CMakeLists.txt
index 6ef722b6a..200f6cee7 100644
--- a/cmake/target/CMakeLists.txt
+++ b/cmake/target/CMakeLists.txt
@@ -21,30 +21,108 @@ if (NOT DEFINED ${TGTNAME}_PROCESSORID)
message(FATAL_ERROR "${TGTNAME}_PROCESSORID must be defined to link a final exe")
endif (NOT DEFINED ${TGTNAME}_PROCESSORID)
-# Create a file for the statically-linked module list for this target
-# do this for both PSP and CFS static modules
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp"
- "/* Automatically generated based on target config */\n")
+string(CONCAT GENERATED_FILE_HEADER
+ "/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
+ "#include \"target_config.h\"\n"
+)
+
+string(CONCAT GENERATED_FILE_TRAILER
+ "/* End of file */\n"
+)
+
+# Generate a list of PSP modules along with a pointer to its API structure/entry point
+set(GENERATED_EXTERNS)
+set(GENERATED_KEYVALS)
foreach(PSPMOD ${${TGTNAME}_PSP_MODULELIST})
- file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp" "LOAD_PSP_MODULE(${PSPMOD})\n")
+ list(APPEND GENERATED_EXTERNS "extern char CFE_PSP_${PSPMOD}_API;\n")
+ list(APPEND GENERATED_KEYVALS "{ .Name = \"${PSPMOD}\", .Api = &CFE_PSP_${PSPMOD}_API },\n")
endforeach(PSPMOD ${${TGTNAME}_PSP_MODULELIST})
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp"
- "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc")
-file (REMOVE "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp"
- "/* Automatically generated based on target config */\n")
+string(CONCAT GENERATED_FILE_CONTENT
+ ${GENERATED_EXTERNS}
+ "const CFE_StaticModuleLoadEntry_t CFE_PSP_MODULE_LIST[] = {\n"
+ ${GENERATED_KEYVALS}
+ "{ NULL } /* End of list */\n"
+ "};\n"
+)
+
+configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_psp_module_list.c)
+
+# Generate lists of modules that will be statically linked into this CFE core target
+set(GENERATED_ENTRIES_CORE_MODULES)
+foreach(DEP ${MISSION_CORE_MODULES})
+ list(APPEND GENERATED_ENTRIES_CORE_MODULES "\"{ ${DEP}\" },\n")
+endforeach()
+
+set(GENERATED_ENTRIES_STATIC_APPS)
+foreach(DEP ${${TGTNAME}_STATIC_APPLIST})
+ list(APPEND GENERATED_ENTRIES_STATIC_APPS "{ \"${DEP}\" },\n")
+endforeach()
+
+string(CONCAT GENERATED_FILE_CONTENT
+ "CFE_ConfigName_t CFE_CORE_MODULE_LIST[] = {\n"
+ ${GENERATED_ENTRIES_CORE_MODULES}
+ "NULL /* End of list */\n"
+ "};\n"
+ "CFE_ConfigName_t CFE_STATIC_APP_LIST[] = {\n"
+ ${GENERATED_ENTRIES_STATIC_APPS}
+ "NULL /* End of list */\n"
+ "};\n"
+)
+
+configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_module_list.c)
+
+# Generate a list of symbol names that must be known at runtime without OS loader support
+set(GENERATED_EXTERNS)
+set(GENERATED_KEYVALS)
foreach(CFSSYM ${${TGTNAME}_STATIC_SYMLIST})
- file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp" "STATIC_CFS_SYMBOL(${CFSSYM})\n")
+ string(REPLACE "," ";" CFSSYM "${CFSSYM}")
+ list(GET CFSSYM 0 SYM_NAME)
+ list(GET CFSSYM 1 SYM_MODULE)
+ list(APPEND GENERATED_EXTERNS "extern void ${SYM_NAME} (void);\n")
+ list(APPEND GENERATED_KEYVALS "{ .Name = \"${SYM_NAME}\", .Address = &{SYM_NAME}, .Module = \"${SYM_MODULE}\" },")
endforeach(CFSSYM ${${TGTNAME}_STATIC_SYMLIST})
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp"
- "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc")
-file (REMOVE "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp")
+
+string(CONCAT GENERATED_FILE_HEADER
+ "/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
+ "#include \"osapi-module.h\"\n"
+)
+
+string(CONCAT GENERATED_FILE_CONTENT
+ ${GENERATED_EXTERNS}
+ "OS_static_symbol_record_t OS_STATIC_SYMBOL_TABLE[] = {\n"
+ ${GENERATED_KEYVALS}
+ "{ NULL } /* End of list */\n"
+ "};\n"
+)
+
+configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_symbol_list.c)
+
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${MISSION_BINARY_DIR}/src/cfe_build_env_table.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
+ DEPENDS
+ ${MISSION_BINARY_DIR}/src/cfe_build_env_table.c
+)
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${MISSION_BINARY_DIR}/src/cfe_module_version_table.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
+ DEPENDS
+ ${MISSION_BINARY_DIR}/src/cfe_module_version_table.c
+)
# Target for the final executable
-add_executable(core-${TGTNAME} src/target_config.c)
+add_executable(core-${TGTNAME}
+ ${MISSION_BINARY_DIR}/src/cfe_mission_strings.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_psp_module_list.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_symbol_list.c
+ ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_module_list.c
+ src/target_config.c
+)
target_compile_definitions(core-${TGTNAME} PRIVATE
CFE_DEFAULT_MODULE_EXTENSION="${CMAKE_SHARED_MODULE_SUFFIX}"
@@ -54,8 +132,7 @@ target_compile_definitions(core-${TGTNAME} PRIVATE
CFE_CPU_ID_VALUE=${${TGTNAME}_PROCESSORID}
)
-target_include_directories(core-${TGTNAME} PRIVATE
- "${CMAKE_CURRENT_BINARY_DIR}"
+target_include_directories(core-${TGTNAME} PRIVATE
"${CMAKE_BINARY_DIR}/${CFE_CORE_TARGET}/inc"
)
diff --git a/cmake/target/inc/target_config.h b/cmake/target/inc/target_config.h
index c4af5307f..51935f396 100644
--- a/cmake/target/inc/target_config.h
+++ b/cmake/target/inc/target_config.h
@@ -76,6 +76,27 @@ typedef const struct
CFE_StaticModuleApi_t *Api;
} CFE_StaticModuleLoadEntry_t;
+/**
+ * A record containing a configuration name
+ * This is a single entry in a list of simple strings.
+ */
+typedef const struct
+{
+ const char *Name;
+} CFE_ConfigName_t;
+
+
+/**
+ * A record containing a configuration key-value pair
+ * The data are simple strings defined at compile time, and
+ * do not change until next build (always const).
+ */
+typedef const struct
+{
+ const char *Key;
+ const void *Value;
+} CFE_ConfigKeyValue_t;
+
/**
* Core Flight Executive configuration information.
*/
@@ -129,12 +150,30 @@ extern Target_CfeConfigData GLOBAL_CFE_CONFIGDATA;
*/
typedef const struct
{
- const char *MissionVersion; /**< Version string acquired from version control system at build time */
- const char *CfeVersion; /**< Version string acquired from version control system at build time */
- const char *OsalVersion; /**< Version string acquired from version control system at build time */
+ const char *MissionName; /**< The Mission Name from confguration */
+
+ /*
+ * Note: the version strings in these fields should reflect the administratively-assigned
+ * "semantic version" identifiers, typically from a "version.h" header file of
+ * some type which is manually updated at various points in the development cycle.
+ *
+ * This is separate/distinct from the source control based revision
+ * information, although it may be similar/related. All automatically
+ * obtained source revision info is in the "ModuleVersionList" below.
+ */
+ const char *MissionVersion; /**< Version string from mission source tree at build time (currently unused/unset) */
+ const char *CfeVersion; /**< Version string from CFE source tree at build time */
+ const char *OsalVersion; /**< Version string from OSAL source tree at build time */
+
const char *Config; /**< Configuration used for build */
- const char *Date; /**< Date and time of build */
- const char *User; /**< User ID and build machine */
+
+ /*
+ * Note: date and user info have been moved into the BuildEnvironment below,
+ * but these members must exist in this structure (for now) for compatibility.
+ * These pointers will be NULL at runtime.
+ */
+ const char *Date; /**< Not set. Get value from BuildEnvironment instead. */
+ const char *User; /**< Not set. Get value from BuildEnvironment instead. */
/*
* Default values for CPU ID and CPU Name
@@ -150,6 +189,11 @@ typedef const struct
Target_PspConfigData *PspConfig; /**< PSP configuration sub-structure */
CFE_StaticModuleLoadEntry_t *PspModuleList; /**< List of PSP modules (API structures) statically linked into the core EXE */
+ CFE_ConfigKeyValue_t *BuildEnvironment; /**< Environment details of build system at the last time CFE core was built */
+ CFE_ConfigKeyValue_t *ModuleVersionList; /**< List of module versions at the last time CFE core was built */
+ 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 */
+
} Target_ConfigData;
diff --git a/cmake/target/src/target_config.c b/cmake/target/src/target_config.c
index bbf33104b..ceb7494cd 100644
--- a/cmake/target/src/target_config.c
+++ b/cmake/target/src/target_config.c
@@ -38,8 +38,8 @@
#include "cfe_es.h"
#include "cfe_time.h"
#include "private/cfe_es_resetdata_typedef.h"
-#include "cfecfs_version_info.h"
-#include "cfecfs_build_info.h"
+#include "cfe_version.h" /* for CFE_VERSION_STRING */
+#include "osapi-version.h" /* for OS_VERSION_STRING */
#ifndef CFE_CPU_NAME_VALUE
@@ -62,6 +62,78 @@
#define CFE_DEFAULT_CORE_FILENAME ""
#endif
+/*
+ * Many configdata items are instantiated by the
+ * build system, where it generates a .c file containing
+ * the data, which is then compiled and linked with this file.
+ */
+
+extern const char CFE_MISSION_NAME[]; /**< Name of CFE mission */
+extern const char CFE_MISSION_CONFIG[]; /**< Configuration name used for build */
+
+/**
+ * A list of modules which are statically linked into CFE core.
+ *
+ * For module names which appear in this list, the code is directly
+ * linked into the core executable binary file, and therefore means
+ * several things:
+ *
+ * - the module code is guaranteed to be present
+ * - functions it provides may be used by CFE core apps
+ * - it cannot be updated/changed without rebuilding CFE core.
+ */
+extern CFE_ConfigName_t CFE_CORE_MODULE_LIST[];
+
+/**
+ * A list of CFS apps which are also statically linked with this binary.
+ *
+ * These apps can be started without dynamically loading any modules,
+ * however the entry point must be separately provided in order to avoid
+ * needing any support from the OS dynamic loader subsystem.
+ */
+extern CFE_ConfigName_t CFE_STATIC_APP_LIST[];
+
+/**
+ * A key-value table containing certain environment information from the build system
+ * at the time CFE core was built.
+ *
+ * This contains basic information such as the time of day, build host, and user.
+ */
+extern CFE_ConfigKeyValue_t CFE_BUILD_ENV_TABLE[];
+
+/**
+ * Version control (source code) versions of all modules
+ *
+ * This list includes all modules known to the build system as determined by the
+ * version control system in use (e.g. git). It is generated by a post-build step
+ * to query version control and should change automatically every time code is
+ * checked in or out.
+ *
+ * Notably this includes _all_ modules known to the build system at the time CFE
+ * core was built, regardless of whether those modules are configured for runtime
+ * (dynamic) or static linkage.
+ *
+ * For dynamic modules, this means the version info can become outdated if/when
+ * a single module is rebuilt/reloaded after the original CFE build. The keys in
+ * this table may be be checked against the CFE_STATIC_MODULE_LIST above to
+ * determine if static or dynamic linkage was used. In the case of dynamic linkage,
+ * then this table only represents the version of the module that was present at the
+ * time CFE was built, not necessarily the version on the target filesystem.
+ */
+extern CFE_ConfigKeyValue_t CFE_MODULE_VERSION_TABLE[];
+
+/**
+ * A list of PSP modules included in this build of CFE core.
+ *
+ * These are always statically linked, and this table contains a pointer
+ * to its API structure, which in turn contains its entry point.
+ */
+extern CFE_StaticModuleLoadEntry_t CFE_PSP_MODULE_LIST[];
+
+
+/**
+ * A structure that encapsulates all the CFE static configuration
+ */
Target_CfeConfigData GLOBAL_CFE_CONFIGDATA =
{
/*
@@ -88,47 +160,6 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA =
.RamDiskTotalSectors = CFE_PLATFORM_ES_RAM_DISK_NUM_SECTORS
};
-/*
- * PSP Static Module load section
- *
- * This is in here (the target-specific file) rather than the PSP config data structure
- * because it can be different for different targets even those that share the same basic PSP.
- *
- * For instance, if two boards use the same basic HW hardware but one of them has a special
- * timer interrupt for synchronization, only this second target would include a PSP module
- * to bind to that special interrupt.
- *
- * In order to reference the driver from a dynamically generated set,
- * two inclusions of the same file are done using different definitions
- * of the LOAD_PSP_MODULE() macro. The first pass creates "extern" references
- * to the API objects, the second pass generates a table of pointers to them.
- */
-
-/*
- * Definition of LOAD_*_MODULE for the first pass, creates an extern declaration
- * for the API object which must be named appropriately.
- */
-#define LOAD_PSP_MODULE(name) extern CFE_StaticModuleApi_t CFE_PSP_##name##_API;
-#include "psp_module_list.inc"
-#undef LOAD_PSP_MODULE
-
-/*
- * Definition of LOAD_PSP_MODULE for the second pass, creates an entry with
- * the name and a pointer to the API object.
- *
- * This is done here in the target file and NOT in the PSP because it is
- * configured specifically to each target. The contents of the "psp_module_list.inc"
- * file are generated by the build scripts and are different for each target.
- */
-#define LOAD_PSP_MODULE(name) { .Name = #name, .Api = &CFE_PSP_##name##_API },
-static CFE_StaticModuleLoadEntry_t GLOBAL_PSP_MODULELIST[] =
-{
-#include "psp_module_list.inc"
- { .Name = NULL }
-};
-#undef LOAD_PSP_MODULE
-
-
/**
* Instantiation of global system-wide configuration struct
* This contains build info plus pointers to the PSP and CFE
@@ -137,12 +168,10 @@ static CFE_StaticModuleLoadEntry_t GLOBAL_PSP_MODULELIST[] =
*/
Target_ConfigData GLOBAL_CONFIGDATA =
{
- .MissionVersion = MISSION_VERSION,
- .CfeVersion = CFE_VERSION,
- .OsalVersion = OSAL_VERSION,
- .Config = MISSION_CONFIG,
- .Date = MISSION_BUILDDATE,
- .User = MISSION_BUILDUSER "@" MISSION_BUILDHOST,
+ .MissionName = CFE_MISSION_NAME,
+ .CfeVersion = CFE_SRC_VERSION,
+ .OsalVersion = OS_VERSION,
+ .Config = CFE_MISSION_CONFIG,
.Default_CpuName = CFE_CPU_NAME_VALUE,
.Default_CpuId = CFE_CPU_ID_VALUE,
.Default_SpacecraftId = CFE_SPACECRAFT_ID_VALUE,
@@ -150,26 +179,10 @@ Target_ConfigData GLOBAL_CONFIGDATA =
.Default_CoreFilename = CFE_DEFAULT_CORE_FILENAME,
.CfeConfig = &GLOBAL_CFE_CONFIGDATA,
.PspConfig = &GLOBAL_PSP_CONFIGDATA,
- .PspModuleList = GLOBAL_PSP_MODULELIST,
+ .PspModuleList = CFE_PSP_MODULE_LIST,
+ .BuildEnvironment = CFE_BUILD_ENV_TABLE,
+ .ModuleVersionList = CFE_MODULE_VERSION_TABLE,
+ .CoreModuleList = CFE_CORE_MODULE_LIST,
+ .StaticAppList = CFE_STATIC_APP_LIST,
};
-
-
-/*
- * Instantiate a list of symbols that should be statically linked into the
- * final executable.
- *
- * This table is in turn used by OSAL if the OS_STATIC_LOADER feature is
- * enabled, such that OS_SymbolLookup may return values from this table
- * in lieu of an OS/library-provided dynamic lookup function.
- */
-#define STATIC_CFS_SYMBOL(n,m) extern void n (void);
-#include "cfs_static_symbol_list.inc"
-#undef STATIC_CFS_SYMBOL
-#define STATIC_CFS_SYMBOL(n,m) { .Name = #n, .Address = n, .Module = #m },
-OS_static_symbol_record_t OS_STATIC_SYMBOL_TABLE[] =
-{
-#include "cfs_static_symbol_list.inc"
- { NULL, NULL } /* End of list marker */
-};
-#undef STATIC_CFS_SYMBOL
diff --git a/cmake/version.cmake b/cmake/version.cmake
deleted file mode 100644
index 5a0bdb8c7..000000000
--- a/cmake/version.cmake
+++ /dev/null
@@ -1,133 +0,0 @@
-##################################################################
-#
-# cFS version metadata collection script
-#
-# This small script runs at build time (as opposed to prep time)
-# and is intended to extract version metadata from the current source
-# tree. It is done each time that the code is built, since the
-# metadata could change at any time (i.e. a different branch could
-# be checked out, or additional changes committed)
-#
-# This generates two header files:
-# cfecfs_version_info.h -- contains version control metadata
-# cfecfs_build_info.h -- contains build information (user,host,etc)
-#
-# Currently only git is supported as a version control source, however
-# it could be extended to others by adding the appropriate command
-#
-##################################################################
-
-set(GIT_EXECUTABLE git)
-
-function(get_version DEP)
- if (DEP STREQUAL "MISSION")
- set(NAME ${MISSION_NAME})
- set(DIR ${MISSION_SOURCE_DIR})
- else()
- if(EXISTS ${${DEP}_MISSION_DIR}/version_info.cmake)
- include(${${DEP}_MISSION_DIR}/version_info.cmake)
- else()
- set(NAME ${DEP})
- endif()
- set(DIR ${${DEP}_MISSION_DIR})
- endif()
- execute_process(
- COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
- WORKING_DIRECTORY ${DIR}
- OUTPUT_VARIABLE GIT_DESC_OUTPUT
- RESULT_VARIABLE GIT_RESULT
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- if (NOT GIT_RESULT EQUAL 0)
- set(GIT_DESC_OUTPUT "error/unknown")
- endif()
- set(${DEP}_NAME "${NAME}" PARENT_SCOPE)
- set(${DEP}_VERSION "${GIT_DESC_OUTPUT}" PARENT_SCOPE)
-endfunction()
-
-
-# First read in any variables that are passed in from the parent process
-# There may be many of these and they may not all be passable via -D options
-file(STRINGS "${BIN}/mission_vars.cache" PARENTVARS)
-set(VARNAME)
-foreach(PV ${PARENTVARS})
- if (VARNAME)
- set(${VARNAME} ${PV})
- set(VARNAME)
- else()
- set(VARNAME ${PV})
- endif()
-endforeach(PV ${PARENTVARS})
-
-# Set other well-known locations
-set(OSAL_MISSION_DIR ${MISSION_SOURCE_DIR}/osal)
-
-# Start the template for configure_file() --
-# see below why it is done this way and not written directly
-file(WRITE ${BIN}/cfecfs_version_info.h.in
- "/* Auto-generated version information file */\n"
- "#define MISSION_CONFIG \"\@MISSIONCONFIG\@\"\n"
- "#define MISSION_NAME \"\@MISSION_NAME\@\"\n")
-
-# Get version for all mission apps/dependencies (they may be different)
-foreach(DEP "MISSION" ${MISSION_DEPS})
- get_version(${DEP})
- string(TOUPPER ${${DEP}_NAME} MACRONAME)
- string(REGEX REPLACE "[^A-Z0-9_]+" "_" MACRONAME "${MACRONAME}")
- file(APPEND ${BIN}/cfecfs_version_info.h.in "#define ${MACRONAME}_VERSION \"\@${DEP}_VERSION\@\"\n")
-endforeach()
-
-string(TOUPPER ${MISSION_NAME} MACRONAME)
-file(APPEND ${BIN}/cfecfs_version_info.h.in "\n#define MISSION_VERSION ${MACRONAME}_VERSION\n\n /* end */\n")
-
-# Same for build information -
-# note this is done separately because the build time might change often -
-# only the final target EXE should include build.h (nothing else in the mission) to minimize rebuilds
-file(WRITE ${BIN}/cfecfs_build_info.h.in
- "/* Auto-generated build information file */\n"
- "#define MISSION_BUILDDATE \"\@BUILDDATE\@\"\n"
- "#define MISSION_BUILDUSER \"\@USERNAME\@\"\n"
- "#define MISSION_BUILDHOST \"\@HOSTNAME\@\"\n\n")
-
-# OVERRIDE NOTE:
-# All 3 of these may be passed via environment variables to force a particular
-# date, user, or hostname i.e. if hoping to reproduce an exact binary of a prior build
-# They are actually free-form strings so they can be anything up to 64 chars.
-
-# Get the current date and time
-set(BUILDDATE $ENV{BUILDDATE})
-if (NOT BUILDDATE)
- execute_process(
- COMMAND date "+%Y%m%d%H%M"
- OUTPUT_VARIABLE BUILDDATE
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-endif(NOT BUILDDATE)
-
-# Get the build host
-set(HOSTNAME $ENV{HOSTNAME})
-if (NOT HOSTNAME)
- execute_process(
- COMMAND hostname
- OUTPUT_VARIABLE HOSTNAME
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-endif (NOT HOSTNAME)
-
-# Get the user ID
-set(USERNAME $ENV{USER})
-if (NOT USERNAME)
- execute_process(
- COMMAND whoami
- OUTPUT_VARIABLE USERNAME
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-endif (NOT USERNAME)
-
-# Use configure_file() command to generate the final output file because this can detect
-# and only update it if it changes.
-configure_file(${BIN}/cfecfs_version_info.h.in ${BIN}/inc/cfecfs_version_info.h @ONLY)
-configure_file(${BIN}/cfecfs_build_info.h.in ${BIN}/inc/cfecfs_build_info.h @ONLY)
-
-
diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c
index 75bae1b7e..b2e84665e 100644
--- a/fsw/cfe-core/src/es/cfe_es_task.c
+++ b/fsw/cfe-core/src/es/cfe_es_task.c
@@ -184,6 +184,155 @@ void CFE_ES_TaskMain(void)
} /* End of CFE_ES_TaskMain() */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* */
+/* CFE_ES_FindConfigKeyValue() -- Find value for given config key */
+/* */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+const char *CFE_ES_FindConfigKeyValue(const CFE_ConfigKeyValue_t *ConfigList, const char *KeyName)
+{
+ const char *ValuePtr;
+
+ ValuePtr = NULL;
+ if (KeyName != NULL && ConfigList != NULL)
+ {
+ while (ConfigList->Key != NULL)
+ {
+ if (strcmp(KeyName, ConfigList->Key) == 0)
+ {
+ ValuePtr = ConfigList->Value;
+ break;
+ }
+
+ ++ConfigList;
+ }
+ }
+
+ return ValuePtr;
+}
+
+int32 CFE_ES_GenerateSingleVersionEvent(const char *ModuleType, const char *ModuleName)
+{
+ int32 Status;
+ const char *VersionString;
+
+ /* The mission version which should appear in the version list under the mission name */
+ VersionString = CFE_ES_FindConfigKeyValue(GLOBAL_CONFIGDATA.ModuleVersionList, ModuleName);
+
+ /* If NULL that means the source code was either uncontrolled or there was no way to determine its version */
+ if (VersionString == NULL)
+ {
+ VersionString = "[unknown]";
+ }
+
+ /*
+ * Advertise the mission version information
+ */
+ Status = CFE_EVS_SendEvent(CFE_ES_VERSION_INF_EID, CFE_EVS_EventType_INFORMATION,
+ "Version Info: %s %s, version %s",
+ ModuleType, ModuleName, VersionString);
+
+ return Status;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* */
+/* CFE_ES_GenerateVersionEvents() -- Send CFE_ES_VERSION_INF_EID's */
+/* */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void CFE_ES_GenerateVersionEvents(void)
+{
+ int32 Status;
+ CFE_ConfigName_t *ModuleNamePtr;
+ CFE_StaticModuleLoadEntry_t *StaticModulePtr;
+
+ /*
+ * Advertise the mission version information
+ */
+ Status = CFE_ES_GenerateSingleVersionEvent("Mission", GLOBAL_CONFIGDATA.MissionName);
+ if ( Status != CFE_SUCCESS )
+ {
+ CFE_ES_WriteToSysLog("ES:Error sending mission version event:RC=0x%08X\n", (unsigned int)Status);
+ }
+
+ /*
+ * Also Advertise the version information for all statically-linked core modules.
+ * Send a separate CFE_ES_VERSION_INF_EID for every component.
+ */
+ ModuleNamePtr = GLOBAL_CONFIGDATA.CoreModuleList;
+ if (ModuleNamePtr != NULL)
+ {
+ while (Status == CFE_SUCCESS && ModuleNamePtr->Name != NULL)
+ {
+ Status = CFE_ES_GenerateSingleVersionEvent("Core Module", ModuleNamePtr->Name);
+ if ( Status != CFE_SUCCESS )
+ {
+ CFE_ES_WriteToSysLog("ES:Error sending core module version event:RC=0x%08X\n", (unsigned int)Status);
+ }
+ ++ModuleNamePtr;
+ }
+ }
+
+ /*
+ * Advertise PSP module versions
+ */
+ StaticModulePtr = GLOBAL_CONFIGDATA.PspModuleList;
+ if (StaticModulePtr != NULL)
+ {
+ while (Status == CFE_SUCCESS && StaticModulePtr->Name != NULL)
+ {
+ Status = CFE_ES_GenerateSingleVersionEvent("PSP Module", StaticModulePtr->Name);
+ if ( Status != CFE_SUCCESS )
+ {
+ CFE_ES_WriteToSysLog("ES:Error sending PSP module version event:RC=0x%08X\n", (unsigned int)Status);
+ }
+ ++StaticModulePtr;
+ }
+ }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* */
+/* CFE_ES_GenerateBuildInfoEvents() -- Send CFE_ES_BUILD_INF_EID */
+/* */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void CFE_ES_GenerateBuildInfoEvents(void)
+{
+ int32 Status;
+ const char *BuildDate;
+ const char *BuildUser;
+ const char *BuildHost;
+
+ BuildDate = CFE_ES_FindConfigKeyValue(GLOBAL_CONFIGDATA.BuildEnvironment, "BUILDDATE");
+ BuildUser = CFE_ES_FindConfigKeyValue(GLOBAL_CONFIGDATA.BuildEnvironment, "BUILDUSER");
+ BuildHost = CFE_ES_FindConfigKeyValue(GLOBAL_CONFIGDATA.BuildEnvironment, "BUILDHOST");
+
+ /* Ensure all strings are set to something non-NULL */
+ if (BuildDate == NULL)
+ {
+ BuildDate = "[unknown]";
+ }
+
+ if (BuildUser == NULL)
+ {
+ BuildUser = "[unknown]";
+ }
+
+ if (BuildHost == NULL)
+ {
+ BuildHost = "[unknown]";
+ }
+
+ Status = CFE_EVS_SendEvent(CFE_ES_BUILD_INF_EID, CFE_EVS_EventType_INFORMATION,
+ "Build %s by %s@%s, config %s", BuildDate, BuildUser, BuildHost, GLOBAL_CONFIGDATA.Config);
+ if ( Status != CFE_SUCCESS )
+ {
+ CFE_ES_WriteToSysLog("ES:Error sending build info event:RC=0x%08X\n", (unsigned int)Status);
+ }
+}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
@@ -196,9 +345,6 @@ int32 CFE_ES_TaskInit(void)
int32 Status;
uint32 SizeofCfeSegment;
cpuaddr CfeSegmentAddr;
- char EventBuffer[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH];
- char VersionBuffer[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH];
- uint32 Remaining;
/*
** Register the Application
@@ -329,74 +475,21 @@ int32 CFE_ES_TaskInit(void)
return(Status);
}
-#ifdef CFE_PSP_VERSION
-
- Status = CFE_EVS_SendEvent(CFE_ES_INITSTATS_INF_EID, CFE_EVS_EventType_INFORMATION,
- "%s%s. cFE chksm %d",
- CFS_VERSIONS, CFE_PSP_VERSION, (int)CFE_ES_TaskData.HkPacket.Payload.CFECoreChecksum);
-
-#else /* if CFE_PSP_VERSION not defined use integer version macros*/
- Status = CFE_EVS_SendEvent(CFE_ES_INITSTATS_INF_EID, CFE_EVS_EventType_INFORMATION,
- "\n%sv%d.%d.%d.%d\n cFE chksm %d",
- CFS_VERSIONS,
- CFE_PSP_MAJOR_VERSION, CFE_PSP_MINOR_VERSION, CFE_PSP_REVISION, CFE_PSP_MISSION_REV,
- (int)CFE_ES_TaskData.HkPacket.Payload.CFECoreChecksum);
-
-#endif /* CFE_PSP_VERSION */
+ Status = CFE_EVS_SendEvent(CFE_ES_INITSTATS_INF_EID, CFE_EVS_EventType_INFORMATION,
+ "cFS Versions: cfe %s, osal %s, psp %s. cFE chksm %d",
+ GLOBAL_CONFIGDATA.CfeVersion, GLOBAL_CONFIGDATA.OsalVersion, CFE_PSP_VERSION, (int)CFE_ES_TaskData.HkPacket.Payload.CFECoreChecksum);
if ( Status != CFE_SUCCESS )
{
- CFE_ES_WriteToSysLog("ES:Error sending version event:RC=0x%08X\n", (unsigned int)Status);
+ CFE_ES_WriteToSysLog("ES:Error sending init stats event:RC=0x%08X\n", (unsigned int)Status);
return(Status);
}
/*
- ** Advertise the build and version information at start up
- ** If unique and non-error, reports component information
+ * Generate all module version and build info events.
*/
- if (strstr(GLOBAL_CONFIGDATA.MissionVersion, "error"))
- {
- snprintf(EventBuffer, sizeof(EventBuffer), "Mission %s", GLOBAL_CONFIGDATA.Config);
- }
- else
- {
- snprintf(EventBuffer, sizeof(EventBuffer), "Mission %s.%s",
- GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.Config);
- }
- Remaining = sizeof(EventBuffer)-strlen(EventBuffer)-1;
- if(Remaining > 0 && strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.CfeVersion))
- {
- snprintf(VersionBuffer, sizeof(VersionBuffer), ", CFE git version: %s",
- GLOBAL_CONFIGDATA.CfeVersion);
- VersionBuffer[Remaining] = 0;
- strcat(EventBuffer, VersionBuffer);
- Remaining = sizeof(EventBuffer)-strlen(EventBuffer)-1;
- }
- if(Remaining > 0 && strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.OsalVersion))
- {
- snprintf(VersionBuffer, sizeof(VersionBuffer), ", OSAL git version: %s",
- GLOBAL_CONFIGDATA.OsalVersion);
- VersionBuffer[Remaining] = 0;
- strcat(EventBuffer, VersionBuffer);
- }
-
- Status = CFE_EVS_SendEvent(CFE_ES_VERSION_INF_EID,
- CFE_EVS_EventType_INFORMATION, "%s", EventBuffer);
- if ( Status != CFE_SUCCESS )
- {
- CFE_ES_WriteToSysLog("ES:Error sending version event:RC=0x%08X\n", (unsigned int)Status);
- return(Status);
- }
-
- Status = CFE_EVS_SendEvent(CFE_ES_BUILD_INF_EID,
- CFE_EVS_EventType_INFORMATION,
- "Build %s %s",
- GLOBAL_CONFIGDATA.Date, GLOBAL_CONFIGDATA.User);
- if ( Status != CFE_SUCCESS )
- {
- CFE_ES_WriteToSysLog("ES:Error sending build info event:RC=0x%08X\n", (unsigned int)Status);
- return(Status);
- }
+ CFE_ES_GenerateVersionEvents();
+ CFE_ES_GenerateBuildInfoEvents();
/*
* Initialize the "background task" which is a low priority child task
@@ -757,30 +850,17 @@ int32 CFE_ES_NoopCmd(const CFE_ES_NoopCmd_t *Cmd)
** For unit testing purposes, it helps to put this first - the UT
** is checking for the last event sent to be NOOP_INF_EID.
*/
- CFE_EVS_SendEvent(CFE_ES_BUILD_INF_EID,
- CFE_EVS_EventType_INFORMATION,
- "Build %s %s",
- GLOBAL_CONFIGDATA.Date, GLOBAL_CONFIGDATA.User);
+ CFE_ES_GenerateBuildInfoEvents();
/*
** This command will always succeed.
*/
CFE_ES_TaskData.CommandCounter++;
-
-#ifdef CFE_PSP_VERSION
- CFE_EVS_SendEvent(CFE_ES_NOOP_INF_EID, CFE_EVS_EventType_INFORMATION,
- "No-op command:\n %s%s",
- CFS_VERSIONS, CFE_PSP_VERSION);
-
-#else /* CFE_PSP_VERSION */
-
CFE_EVS_SendEvent(CFE_ES_NOOP_INF_EID, CFE_EVS_EventType_INFORMATION,
- "No-op command:\n %sv%d.%d.%d.%d",
- CFS_VERSIONS,
- CFE_PSP_MAJOR_VERSION, CFE_PSP_MINOR_VERSION, CFE_PSP_REVISION, CFE_PSP_MISSION_REV);
+ "No-op command:\n cFS Versions: cfe %s, osal %s, psp %s",
+ GLOBAL_CONFIGDATA.CfeVersion, GLOBAL_CONFIGDATA.OsalVersion, CFE_PSP_VERSION);
-#endif /* CFE_PSP_VERSION */
return CFE_SUCCESS;
} /* End of CFE_ES_NoopCmd() */
diff --git a/fsw/cfe-core/src/inc/cfe_es_events.h b/fsw/cfe-core/src/inc/cfe_es_events.h
index 29cbe4312..1d2d3d93a 100644
--- a/fsw/cfe-core/src/inc/cfe_es_events.h
+++ b/fsw/cfe-core/src/inc/cfe_es_events.h
@@ -1409,24 +1409,30 @@
#define CFE_ES_TASKINFO_WR_ERR_EID 90
-/** \brief 'Mission %s.%s, %s, %s'
-** \event 'Mission %s.%s, %s, %s'
+/** \brief 'Version Info: %s, %s'
+** \event 'Version Info: %s, %s'
**
** \par Type: INFORMATION
**
** \par Cause:
**
** This event message is always automatically issued when the Executive Services
-** Task completes its Initialization
+** Task completes its Initialization and as part of the Noop command
**
-** The \c Mission field identifies the tagged build identifiers and configuration name.
-** If available, this will also indicate the revision control identifiers for CFE and OSAL
-** that this binary was built with.
+** A separate version info event will be generated for every module which is statically
+** linked into the CFE core executable (e.g. OSAL, PSP, MSG, SBR, etc).
+**
+** The version information reported in this event is derived from the source revision
+** control system at build time, as opposed to manually-assigned semantic version numbers.
+** It is intendended to uniquely identify the actual source code that is currently running,
+** to the extent this is possible.
+**
+** The \c Mission version information also identifies the build configuration name, if available.
**/
#define CFE_ES_VERSION_INF_EID 91
-/** \brief 'Build %s %s'
-** \event 'Build %s %s'
+/** \brief 'Build %s by %s@%s, config %s'
+** \event 'Build %s by %s@%s, config %s'
**
** \par Type: INFORMATION
**
@@ -1439,6 +1445,9 @@
** the build host machine for the current running binary. The first string is the
** build date/time, and the second string is formatted as "user@hostname"
**
+** This additionally reports the configuration name that was selected by the user,
+** which may affect various platform/mission limits.
+**
** By default, if not specified/overridden, the default values of these variables will be:
** BUILDDATE ==> the output of "date +%Y%m%d%H%M"
** HOSTNAME ==> the output of "hostname"