diff --git a/cmake/sample_defs/sample_mission_cfg.h b/cmake/sample_defs/sample_mission_cfg.h index 99e93754a..85d57ad2f 100644 --- a/cmake/sample_defs/sample_mission_cfg.h +++ b/cmake/sample_defs/sample_mission_cfg.h @@ -459,6 +459,27 @@ */ #define CFE_MISSION_ES_PERF_MAX_IDS 128 +/** \cfeescfg Maximum number of block sizes in pool structures +** +** \par Description: +** The upper limit for the number of block sizes supported in the generic +** pool implementation, which in turn implements the memory pools and CDS. +** This definition is used as the array size with the pool stats structure, +** and therefore should be consistent across all CPUs in a mission, as well +** as with the ground station. +** +** There is also a platform-specific limit which may be fewer than this +** value. +** +** \par Limits: +** Must be at least one. No specific upper limit, but the number is +** anticipated to be reasonably small (i.e. tens, not hundreds). Large +** values have not been tested. +** +** + */ +#define CFE_MISSION_ES_POOL_MAX_BUCKETS 17 + /** ** \cfetblcfg Maximum Length of Full Table Name in messages ** @@ -589,7 +610,7 @@ ** This value should be kept as a multiple of 4, to maintain alignment of ** any possible neighboring fields without implicit padding. */ -#define CFE_MISSION_ES_CDS_MAX_NAME_LEN (CFE_MISSION_ES_CDS_MAX_NAME_LENGTH + CFE_MISSION_MAX_API_LEN + 4) +#define CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN (CFE_MISSION_ES_CDS_MAX_NAME_LENGTH + CFE_MISSION_MAX_API_LEN + 4) diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index 22cbbe1e5..9cda0f38d 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -1544,7 +1544,7 @@ int32 CFE_ES_RegisterCDS(CFE_ES_CDSHandle_t *CDSHandlePtr, CFE_ES_CDS_Offset_t B CFE_ES_ResourceID_t ThisAppId; char AppName[OS_MAX_API_NAME] = {"UNKNOWN"}; - char CDSName[CFE_ES_CDS_MAX_FULL_NAME_LEN] = {""}; + char CDSName[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN] = {""}; /* Initialize output to safe value, in case this fails */ *CDSHandlePtr = CFE_ES_RESOURCEID_UNDEFINED; diff --git a/fsw/cfe-core/src/es/cfe_es_cds.h b/fsw/cfe-core/src/es/cfe_es_cds.h index 926135a27..2f3ac1a63 100644 --- a/fsw/cfe-core/src/es/cfe_es_cds.h +++ b/fsw/cfe-core/src/es/cfe_es_cds.h @@ -115,7 +115,7 @@ typedef struct CFE_ES_ResourceID_t BlockID; /**< Abstract ID associated with this CDS block */ CFE_ES_CDS_Offset_t BlockOffset; /**< Start offset of the block in CDS memory */ CFE_ES_CDS_Offset_t BlockSize; /**< Size, in bytes, of the CDS memory block */ - char Name[CFE_ES_CDS_MAX_FULL_NAME_LEN]; + char Name[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN]; bool Table; /**< \brief Flag that indicates whether CDS contains a Critical Table */ } CFE_ES_CDS_RegRec_t; diff --git a/fsw/cfe-core/src/es/cfe_es_mempool.c b/fsw/cfe-core/src/es/cfe_es_mempool.c index 9c25d3ba7..d1d4d8042 100644 --- a/fsw/cfe-core/src/es/cfe_es_mempool.c +++ b/fsw/cfe-core/src/es/cfe_es_mempool.c @@ -61,7 +61,7 @@ ** Type Definitions */ -const CFE_ES_MemOffset_t CFE_ES_MemPoolDefSize[CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES] = +const CFE_ES_MemOffset_t CFE_ES_MemPoolDefSize[CFE_PLATFORM_ES_POOL_MAX_BUCKETS] = { CFE_PLATFORM_ES_MAX_BLOCK_SIZE, CFE_PLATFORM_ES_MEM_BLOCK_SIZE_16, @@ -138,7 +138,7 @@ int32 CFE_ES_PoolCreateNoSem(CFE_ES_MemHandle_t *PoolID, uint8 *MemPtr, CFE_ES_MemOffset_t Size ) { - return CFE_ES_PoolCreateEx(PoolID, MemPtr, Size, CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + return CFE_ES_PoolCreateEx(PoolID, MemPtr, Size, CFE_PLATFORM_ES_POOL_MAX_BUCKETS, &CFE_ES_MemPoolDefSize[0],CFE_ES_NO_MUTEX); } @@ -149,7 +149,7 @@ int32 CFE_ES_PoolCreate(CFE_ES_MemHandle_t *PoolID, uint8 *MemPtr, CFE_ES_MemOffset_t Size ) { - return CFE_ES_PoolCreateEx(PoolID, MemPtr, Size, CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + return CFE_ES_PoolCreateEx(PoolID, MemPtr, Size, CFE_PLATFORM_ES_POOL_MAX_BUCKETS, &CFE_ES_MemPoolDefSize[0],CFE_ES_USE_MUTEX); } @@ -195,9 +195,9 @@ int32 CFE_ES_PoolCreateEx(CFE_ES_MemHandle_t *PoolID, if (BlockSizes == NULL) { BlockSizes = CFE_ES_MemPoolDefSize; - if (NumBlockSizes == 0 || NumBlockSizes > CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES) + if (NumBlockSizes == 0 || NumBlockSizes > CFE_PLATFORM_ES_POOL_MAX_BUCKETS) { - NumBlockSizes = CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES; + NumBlockSizes = CFE_PLATFORM_ES_POOL_MAX_BUCKETS; } } @@ -636,7 +636,7 @@ int32 CFE_ES_GetMemPoolStats(CFE_ES_MemPoolStats_t *BufPtr, &BufPtr->NumBlocksRequested, &BufPtr->CheckErrCtr); - for (Idx = 0; Idx < CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES; ++Idx) + for (Idx = 0; Idx < CFE_MISSION_ES_POOL_MAX_BUCKETS; ++Idx) { CFE_ES_GenPoolGetBucketUsage(&PoolRecPtr->Pool, NumBuckets, &BufPtr->BlockStats[Idx]); diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 3540b3f2a..7365909fe 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -1680,10 +1680,10 @@ int32 CFE_ES_DeleteCDSCmd(const CFE_ES_DeleteCDS_t *data) { int32 Status; const CFE_ES_DeleteCDSCmd_Payload_t *cmd = &data->Payload; - char LocalCdsName[CFE_ES_CDS_MAX_FULL_NAME_LEN]; + char LocalCdsName[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN]; CFE_SB_MessageStringGet(LocalCdsName, (char *)cmd->CdsName, NULL, - CFE_ES_CDS_MAX_FULL_NAME_LEN, sizeof(cmd->CdsName)); + CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN, sizeof(cmd->CdsName)); Status = CFE_ES_DeleteCDS(LocalCdsName, false); @@ -1827,14 +1827,11 @@ int32 CFE_ES_DumpCDSRegistryCmd(const CFE_ES_DumpCDSRegistry_t *data) if ( CFE_ES_CDSBlockRecordIsUsed(RegRecPtr) ) { /* Fill CDS Registry Dump Record with relevant information */ + memset(&DumpRecord, 0, sizeof(DumpRecord)); DumpRecord.Size = CFE_ES_CDSBlockRecordGetUserSize(RegRecPtr); DumpRecord.Handle = CFE_ES_CDSBlockRecordGetID(RegRecPtr); DumpRecord.Table = RegRecPtr->Table; - DumpRecord.ByteAlignSpare1 = 0; - - /* strncpy will zero out any unused buffer - memset not necessary */ strncpy(DumpRecord.Name, RegRecPtr->Name, sizeof(DumpRecord.Name)-1); - DumpRecord.Name[sizeof(DumpRecord.Name)-1] = 0; /* Output Registry Dump Record to Registry Dump File */ Status = OS_write(FileDescriptor, diff --git a/fsw/cfe-core/src/es/cfe_es_verify.h b/fsw/cfe-core/src/es/cfe_es_verify.h index 51aaa2364..8434e077c 100644 --- a/fsw/cfe-core/src/es/cfe_es_verify.h +++ b/fsw/cfe-core/src/es/cfe_es_verify.h @@ -362,8 +362,8 @@ #if ((CFE_MISSION_ES_CDS_MAX_NAME_LENGTH % 4) != 0) #error CFE_MISSION_ES_CDS_MAX_NAME_LENGTH must be a multiple of 4 #endif -#if ((CFE_MISSION_ES_CDS_MAX_NAME_LEN % 4) != 0) - #error CFE_MISSION_ES_CDS_MAX_NAME_LEN must be a multiple of 4 +#if ((CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN % 4) != 0) + #error CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN must be a multiple of 4 #endif diff --git a/fsw/cfe-core/src/inc/cfe_es.h b/fsw/cfe-core/src/inc/cfe_es.h index ccf01e761..04ae847e7 100644 --- a/fsw/cfe-core/src/inc/cfe_es.h +++ b/fsw/cfe-core/src/inc/cfe_es.h @@ -39,6 +39,7 @@ ** Includes */ #include "cfe_es_extern_typedefs.h" +#include "cfe_es_msg.h" #include "cfe_mission_cfg.h" #include "cfe_perfids.h" #include "cfe_error.h" @@ -62,7 +63,32 @@ #define CFE_ES_DTEST(i,x) (((i) & CFE_ES_DBIT(x)) != 0) /* true iff bit x of i is set */ #define CFE_ES_TEST_LONG_MASK(m,s) (CFE_ES_DTEST(m[(s)/32],(s)%32)) /* Test a bit within an array of 32-bit integers. */ -#define CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES 17 /**< Default number of size divisions in a memory pool */ + +/** \name Resource ID predefined values */ +/** \{ */ + +/** + * @brief A resource ID value that represents an undefined/unused resource + * + * This constant may be used to initialize local variables of the + * CFE_ES_ResourceID_t type to a safe value that will not alias a valid ID. + * + * By design, this value is also the result of zeroing a CFE_ES_ResourceID_t + * type via standard functions like memset(), such that objects initialized + * using this method will also be set to safe values. + */ +#define CFE_ES_RESOURCEID_UNDEFINED ((CFE_ES_ResourceID_t)0) + +/** + * @brief A resource ID value that represents a reserved entry + * + * This is not a valid value for any resource type, but is used to mark + * table entries that are not available for use. For instance, this may + * be used while setting up an entry initially. + */ +#define CFE_ES_RESOURCEID_RESERVED ((CFE_ES_ResourceID_t)0xFFFFFFFF) + +/** \} */ /* ** Note about reset type and subtypes: @@ -85,9 +111,6 @@ /** \name Critical Data Store Macros */ /** \{ */ -/** Maximum length allowed for CDS name.
-** NOTE: "+2" is for NULL Character and "." (i.e. - "AppName.CDSName") */ -#define CFE_ES_CDS_MAX_FULL_NAME_LEN (CFE_MISSION_ES_CDS_MAX_NAME_LENGTH + CFE_MISSION_MAX_API_LEN + 2) #define CFE_ES_CDS_BAD_HANDLE CFE_ES_RESOURCEID_UNDEFINED /** \} */ @@ -101,65 +124,46 @@ ** Type Definitions */ -/** - * @brief A type that provides a common, abstract identifier for - * all ES managed resources (e.g. apps, tasks, counters, etc). - * - * Fundamentally an unsigned integer but users should treat it as - * opaque, and only go through the ES API for introspection. - * - * Simple operations are provided as inline functions, which - * should alleviate the need to do direct manipulation of the value: - * - * - Check for undefined ID value - * - Check for equality of two ID values - * - Convert ID to simple integer (typically for printing/logging) - * - Convert simple integer to ID (inverse of above) - */ -typedef uint32 CFE_ES_ResourceID_t; +/* +** Child Task Main Function Prototype +*/ +typedef void (*CFE_ES_ChildTaskMainFuncPtr_t)(void); /**< \brief Required Prototype of Child Task Main Functions */ +typedef int32 (*CFE_ES_LibraryEntryFuncPtr_t)(CFE_ES_ResourceID_t LibId); /**< \brief Required Prototype of Library Initialization Functions */ /** - * \brief Memory Handle type + * \brief Pool Alignement * - * Data type used to hold Handles of Memory Pools - * created via CFE_ES_PoolCreate and CFE_ES_PoolCreateNoSem + * Union that can be used for minimum memory alignment of ES memory pools on the target. + * It contains the longest native data types such that the alignment of this structure + * should reflect the largest possible alignment requirements for any data on this processor. */ -typedef CFE_ES_ResourceID_t CFE_ES_MemHandle_t; +typedef union CFE_ES_PoolAlign +{ + void *Ptr; /**< \brief Aligned pointer */ + /* note -- native types (int/double) are intentional here */ + long long int LongInt; /**< \brief Aligned Long Integer */ + long double LongDouble; /**< \brief Aligned Long Double */ +} CFE_ES_PoolAlign_t; /** - * Type used for memory pool offsets - * - * For backward compatibility with existing CFE code this can be uint32, - * but pools will be limited to 4GB in size as a result. - * - * On 64-bit platforms this can be a 64-bit value (e.g. size_t) which should - * allow larger pools. + * \brief Static Pool Type * - * In either case this _must_ be an unsigned type. + * A macro to help instantiate static memory pools that are correctly aligned. + * This resolves to a union type that contains a member called "Data" that will + * be correctly aligned to be a memory pool and sized according to the argument. */ -typedef uint32 CFE_ES_MemOffset_t; +#define CFE_ES_STATIC_POOL_TYPE(size) union { CFE_ES_PoolAlign_t Align; uint8 Data[size]; } +/*****************************************************************************/ +/* +** Exported Functions +*/ -/** - * @brief A resource ID value that represents an undefined/unused resource - * - * This constant may be used to initialize local variables of the - * CFE_ES_ResourceID_t type to a safe value that will not alias a valid ID. - * - * By design, this value is also the result of zeroing a CFE_ES_ResourceID_t - * type via standard functions like memset(), such that objects initialzed - * using this method will also be set to safe values. - */ -#define CFE_ES_RESOURCEID_UNDEFINED ((CFE_ES_ResourceID_t)0) +/*****************************************************************************/ -/** - * @brief A resource ID value that represents a reserved entry - * - * This is not a valid value for any resource type, but is used to mark - * table entries that are not available for use. For instance, this may - * be used while setting up an entry initially. +/** @defgroup CFEAPIESResourceID cFE Resource ID APIs + * @{ */ -#define CFE_ES_RESOURCEID_RESERVED ((CFE_ES_ResourceID_t)0xFFFFFFFF) /** * @brief Convert a resource ID to an integer. @@ -337,170 +341,8 @@ CFE_Status_t CFE_ES_TaskID_ToIndex(CFE_ES_ResourceID_t TaskID, uint32 *Idx); */ CFE_Status_t CFE_ES_CounterID_ToIndex(CFE_ES_ResourceID_t CounterID, uint32 *Idx); +/** @} */ -/** - * \brief Application Information - * - * Structure that is used to provide information about an app. - * It is primarily used for the QueryOne and QueryAll Commands. - */ -typedef struct CFE_ES_AppInfo -{ - CFE_ES_ResourceID_t AppId; /**< \cfetlmmnemonic \ES_APP_ID - \brief Application ID for this Application */ - uint32 Type; /**< \cfetlmmnemonic \ES_APPTYPE - \brief The type of App: CORE or EXTERNAL */ - - char Name[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_APPNAME - \brief The Registered Name of the Application */ - char EntryPoint[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_APPENTRYPT - \brief The Entry Point label for the Application */ - char FileName[CFE_MISSION_MAX_PATH_LEN]; /**< \cfetlmmnemonic \ES_APPFILENAME - \brief The Filename of the file containing the Application */ - - uint32 StackSize; /**< \cfetlmmnemonic \ES_STACKSIZE - \brief The Stack Size of the Application */ - osal_id_t ModuleId; /**< \cfetlmmnemonic \ES_MODULEID - \brief The ID of the Loadable Module for the Application */ - uint32 AddressesAreValid; /**< \cfetlmmnemonic \ES_ADDRVALID - \brief Indicates that the Code, Data, and BSS addresses/sizes are valid */ - uint32 CodeAddress; /**< \cfetlmmnemonic \ES_CODEADDR - \brief The Address of the Application Code Segment*/ - uint32 CodeSize; /**< \cfetlmmnemonic \ES_CODESIZE - \brief The Code Size of the Application */ - uint32 DataAddress; /**< \cfetlmmnemonic \ES_DATAADDR - \brief The Address of the Application Data Segment*/ - uint32 DataSize; /**< \cfetlmmnemonic \ES_DATASIZE - \brief The Data Size of the Application */ - uint32 BSSAddress; /**< \cfetlmmnemonic \ES_BSSADDR - \brief The Address of the Application BSS Segment*/ - uint32 BSSSize; /**< \cfetlmmnemonic \ES_BSSSIZE - \brief The BSS Size of the Application */ - uint32 StartAddress; /**< \cfetlmmnemonic \ES_STARTADDR - \brief The Start Address of the Application */ - uint16 ExceptionAction; /**< \cfetlmmnemonic \ES_EXCEPTNACTN - \brief What should occur if Application has an exception - (Restart Application OR Restart Processor) */ - uint16 Priority; /**< \cfetlmmnemonic \ES_PRIORITY - \brief The Priority of the Application */ - CFE_ES_ResourceID_t MainTaskId; /**< \cfetlmmnemonic \ES_MAINTASKID - \brief The Application's Main Task ID */ - uint32 ExecutionCounter; /**< \cfetlmmnemonic \ES_MAINTASKEXECNT - \brief The Application's Main Task Execution Counter */ - char MainTaskName[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_MAINTASKNAME - \brief The Application's Main Task ID */ - uint32 NumOfChildTasks; /**< \cfetlmmnemonic \ES_CHILDTASKS - \brief Number of Child tasks for an App */ - -} CFE_ES_AppInfo_t; - -/** - * \brief Task Info - */ -typedef struct CFE_ES_TaskInfo -{ - CFE_ES_ResourceID_t TaskId; /**< \brief Task Id */ - uint32 ExecutionCounter; /**< \brief Task Execution Counter */ - char TaskName[CFE_MISSION_MAX_API_LEN]; /**< \brief Task Name */ - CFE_ES_ResourceID_t AppId; /**< \brief Parent Application ID */ - char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Parent Application Name */ -} CFE_ES_TaskInfo_t; - -/** - * \brief Block statistics - */ -typedef struct CFE_ES_BlockStats -{ - CFE_ES_MemOffset_t BlockSize; /**< \brief Number of bytes in each of these blocks */ - uint32 NumCreated; /**< \brief Number of Memory Blocks of this size created */ - uint32 NumFree; /**< \brief Number of Memory Blocks of this size that are free */ -} CFE_ES_BlockStats_t; - -/** - * \brief Memory Pool Statistics - */ -typedef struct CFE_ES_MemPoolStats -{ - CFE_ES_MemOffset_t PoolSize; /**< \cfetlmmnemonic \ES_POOLSIZE - \brief Size of Memory Pool (in bytes) */ - uint32 NumBlocksRequested; /**< \cfetlmmnemonic \ES_BLKSREQ - \brief Number of times a memory block has been allocated */ - uint32 CheckErrCtr; /**< \cfetlmmnemonic \ES_BLKERRCTR - \brief Number of errors detected when freeing a memory block */ - CFE_ES_MemOffset_t NumFreeBytes; /**< \cfetlmmnemonic \ES_FREEBYTES - \brief Number of bytes never allocated to a block */ - CFE_ES_BlockStats_t BlockStats[CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES]; /**< \cfetlmmnemonic \ES_BLKSTATS - \brief Contains stats on each block size */ -} CFE_ES_MemPoolStats_t; - -/** - * \brief CDS Handle type - * - * Data type used to hold Handles of Critical Data Stores. See #CFE_ES_RegisterCDS - */ -typedef CFE_ES_ResourceID_t CFE_ES_CDSHandle_t; - -/** - * Type used for CDS sizes and offsets. - * - * This must match the type used in the PSP CDS API, e.g.: - * CFE_PSP_GetCDSSize() - * CFE_PSP_WriteToCDS() - * CFE_PSP_ReadFromCDS() - * - * It is defined separately from the CFE_ES_MemOffset_t as the type used in - * the PSP CDS access API may be different than the ES Pool API. - * - * In either case this _must_ be an unsigned type. - */ -typedef uint32 CFE_ES_CDS_Offset_t; - -/** - * \brief CDS Register Dump Record - */ -typedef struct CFE_ES_CDSRegDumpRec -{ - CFE_ES_CDSHandle_t Handle; /**< \brief Handle of CDS */ - uint32 Size; /**< \brief Size, in bytes, of the CDS memory block */ - bool Table; /**< \brief Flag that indicates whether CDS contains a Critical Table */ - char Name[CFE_ES_CDS_MAX_FULL_NAME_LEN]; /**< \brief Processor Unique Name of CDS */ - uint8 ByteAlignSpare1; /**< \brief Spare byte to insure structure size is multiple of 4 bytes */ -} CFE_ES_CDSRegDumpRec_t; - -/* -** Child Task Main Function Prototype -*/ -typedef void (*CFE_ES_ChildTaskMainFuncPtr_t)(void); /**< \brief Required Prototype of Child Task Main Functions */ -typedef int32 (*CFE_ES_LibraryEntryFuncPtr_t)(CFE_ES_ResourceID_t LibId); /**< \brief Required Prototype of Library Initialization Functions */ - -/** - * \brief Pool Alignement - * - * Union that can be used for minimum memory alignment of ES memory pools on the target. - * It contains the longest native data types such that the alignment of this structure - * should reflect the largest possible alignment requirements for any data on this processor. - */ -typedef union CFE_ES_PoolAlign -{ - void *Ptr; /**< \brief Aligned pointer */ - /* note -- native types (int/double) are intentional here */ - long long int LongInt; /**< \brief Aligned Long Integer */ - long double LongDouble; /**< \brief Aligned Long Double */ -} CFE_ES_PoolAlign_t; - -/** - * \brief Static Pool Type - * - * A macro to help instantiate static memory pools that are correctly aligned. - * This resolves to a union type that contains a member called "Data" that will - * be correctly aligned to be a memory pool and sized according to the argument. - */ -#define CFE_ES_STATIC_POOL_TYPE(size) union { CFE_ES_PoolAlign_t Align; uint8 Data[size]; } - -/*****************************************************************************/ -/* -** Exported Functions -*/ /*****************************************************************************/ diff --git a/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h b/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h index 2a5ce3f28..df5a610e7 100644 --- a/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h +++ b/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h @@ -325,6 +325,93 @@ enum CFE_ES_AppState typedef uint32 CFE_ES_AppState_Enum_t; + +/** + * @brief A type that provides a common, abstract identifier for + * all ES managed resources (e.g. apps, tasks, counters, etc). + * + * Fundamentally an unsigned integer but users should treat it as + * opaque, and only go through the ES API for introspection. + * + * Simple operations are provided as inline functions, which + * should alleviate the need to do direct manipulation of the value: + * + * - Check for undefined ID value + * - Check for equality of two ID values + * - Convert ID to simple integer (typically for printing/logging) + * - Convert simple integer to ID (inverse of above) + */ +typedef uint32 CFE_ES_ResourceID_t; + +/** + * @brief Memory Handle type + * + * Data type used to hold Handles of Memory Pools + * created via CFE_ES_PoolCreate and CFE_ES_PoolCreateNoSem + */ +typedef CFE_ES_ResourceID_t CFE_ES_MemHandle_t; + +/** + * @brief CDS Handle type + * + * Data type used to hold Handles of Critical Data Stores. See #CFE_ES_RegisterCDS + */ +typedef CFE_ES_ResourceID_t CFE_ES_CDSHandle_t; + +/** + * @brief Type used for memory sizes and offsets + * + * For backward compatibility with existing CFE code this should be uint32, + * but pools and other data structures will be limited to 4GB in size as a result. + * + * On 64-bit platforms this can be a 64-bit value which will allow larger + * memory objects, but this will break compatibility with existing control + * systems, and may also change the alignment/padding of messages. + * + * In either case this must be an unsigned type. + */ +typedef uint32 CFE_ES_MemOffset_t; + + +/** + * @brief Type used for memory addresses + * + * For backward compatibility with existing CFE code this should be uint32, + * but if running on a 64-bit platform, addresses in telemetry will be + * truncated to 32 bits and therefore will not be valid. + * + * On 64-bit platforms this can be a 64-bit address which will allow the + * full memory address in commands and telemetry, but this will break + * compatibility with existing control systems, and may also change + * the alignment/padding of messages. + * + * In either case this must be an unsigned type. + * + * FSW code should access this value via the macros provided, which + * converts to the native "cpuaddr" type provided by OSAL. This macro + * provides independence between the message representation and local + * representation of a memory address. + * + * @sa #CFE_SB_SET_MEMADDR, #CFE_SB_GET_MEMADDR + */ +typedef uint32 CFE_ES_MemAddress_t; + +/** + * @brief Type used for CDS sizes and offsets. + * + * This must match the type used in the PSP CDS API, e.g.: + * CFE_PSP_GetCDSSize() + * CFE_PSP_WriteToCDS() + * CFE_PSP_ReadFromCDS() + * + * It is defined separately from the CFE_ES_MemOffset_t as the type used in + * the PSP CDS access API may be different than the ES Pool API. + * + * In either case this must be an unsigned type. + */ +typedef uint32 CFE_ES_CDS_Offset_t; + + #endif /* CFE_EDS_ENABLED_BUILD */ #endif /* _CFE_ES_EXTERN_TYPEDEFS_H_ */ diff --git a/fsw/cfe-core/src/inc/cfe_es_msg.h b/fsw/cfe-core/src/inc/cfe_es_msg.h index 463e36928..5f6b71ff3 100644 --- a/fsw/cfe-core/src/inc/cfe_es_msg.h +++ b/fsw/cfe-core/src/inc/cfe_es_msg.h @@ -38,8 +38,10 @@ /* ** Includes */ -#include "cfe.h" -#include "cfe_es.h" +#include "cfe_es_extern_typedefs.h" + +/* The CFE_SB_CMD_HDR_SIZE and CFE_SB_TLM_HDR_SIZE are defined by cfe_sb.h */ +#include "cfe_sb.h" /* ** ES task command packet command codes @@ -1254,7 +1256,7 @@ typedef struct CFE_ES_SetMaxPRCount **/ typedef struct CFE_ES_DeleteCDSCmd_Payload { - char CdsName[CFE_MISSION_ES_CDS_MAX_NAME_LEN]; /**< \brief ASCII text string containing name of CDS to delete */ + char CdsName[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN]; /**< \brief ASCII text string containing name of CDS to delete */ } CFE_ES_DeleteCDSCmd_Payload_t; @@ -1377,6 +1379,144 @@ typedef struct CFE_ES_DumpCDSRegistry } CFE_ES_DumpCDSRegistry_t; /*************************************************************************/ + +/************************************/ +/* Telemetry Interface Data Formats */ +/************************************/ + +/** + * \brief Application Information + * + * Structure that is used to provide information about an app. + * It is primarily used for the QueryOne and QueryAll Commands. + */ +typedef struct CFE_ES_AppInfo +{ + CFE_ES_ResourceID_t AppId; /**< \cfetlmmnemonic \ES_APP_ID + \brief Application ID for this Application */ + uint32 Type; /**< \cfetlmmnemonic \ES_APPTYPE + \brief The type of App: CORE or EXTERNAL */ + + char Name[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_APPNAME + \brief The Registered Name of the Application */ + char EntryPoint[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_APPENTRYPT + \brief The Entry Point label for the Application */ + char FileName[CFE_MISSION_MAX_PATH_LEN]; /**< \cfetlmmnemonic \ES_APPFILENAME + \brief The Filename of the file containing the Application */ + + CFE_ES_MemOffset_t StackSize; /**< \cfetlmmnemonic \ES_STACKSIZE + \brief The Stack Size of the Application */ + osal_id_t ModuleId; /**< \cfetlmmnemonic \ES_MODULEID + \brief The ID of the Loadable Module for the Application */ + uint32 AddressesAreValid; /**< \cfetlmmnemonic \ES_ADDRVALID + \brief Indicates that the Code, Data, and BSS addresses/sizes are valid */ + CFE_ES_MemAddress_t CodeAddress; /**< \cfetlmmnemonic \ES_CODEADDR + \brief The Address of the Application Code Segment*/ + CFE_ES_MemOffset_t CodeSize; /**< \cfetlmmnemonic \ES_CODESIZE + \brief The Code Size of the Application */ + CFE_ES_MemAddress_t DataAddress; /**< \cfetlmmnemonic \ES_DATAADDR + \brief The Address of the Application Data Segment*/ + CFE_ES_MemOffset_t DataSize; /**< \cfetlmmnemonic \ES_DATASIZE + \brief The Data Size of the Application */ + CFE_ES_MemAddress_t BSSAddress; /**< \cfetlmmnemonic \ES_BSSADDR + \brief The Address of the Application BSS Segment*/ + CFE_ES_MemOffset_t BSSSize; /**< \cfetlmmnemonic \ES_BSSSIZE + \brief The BSS Size of the Application */ + CFE_ES_MemAddress_t StartAddress; /**< \cfetlmmnemonic \ES_STARTADDR + \brief The Start Address of the Application */ + uint16 ExceptionAction; /**< \cfetlmmnemonic \ES_EXCEPTNACTN + \brief What should occur if Application has an exception + (Restart Application OR Restart Processor) */ + uint16 Priority; /**< \cfetlmmnemonic \ES_PRIORITY + \brief The Priority of the Application */ + CFE_ES_ResourceID_t MainTaskId; /**< \cfetlmmnemonic \ES_MAINTASKID + \brief The Application's Main Task ID */ + uint32 ExecutionCounter; /**< \cfetlmmnemonic \ES_MAINTASKEXECNT + \brief The Application's Main Task Execution Counter */ + char MainTaskName[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \ES_MAINTASKNAME + \brief The Application's Main Task ID */ + uint32 NumOfChildTasks; /**< \cfetlmmnemonic \ES_CHILDTASKS + \brief Number of Child tasks for an App */ + +} CFE_ES_AppInfo_t; + +/** + * \brief Task Information + * + * Structure that is used to provide information about a task. It is primarily + * used for the Query All Tasks (#CFE_ES_QUERY_ALL_TASKS_CC) command. + * + * \note There is not currently a telemetry message directly containing this + * data structure, but it does define the format of the data file generated + * by the Query All Tasks command. Therefore it should be considered + * part of the overall telemetry interface. + */ +typedef struct CFE_ES_TaskInfo +{ + CFE_ES_ResourceID_t TaskId; /**< \brief Task Id */ + uint32 ExecutionCounter; /**< \brief Task Execution Counter */ + char TaskName[CFE_MISSION_MAX_API_LEN]; /**< \brief Task Name */ + CFE_ES_ResourceID_t AppId; /**< \brief Parent Application ID */ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Parent Application Name */ +} CFE_ES_TaskInfo_t; + +/** + * \brief CDS Register Dump Record + * + * Structure that is used to provide information about a critical data store. + * It is primarily used for the Dump CDS registry (#CFE_ES_DUMP_CDS_REGISTRY_CC) + * command. + * + * \note There is not currently a telemetry message directly containing this + * data structure, but it does define the format of the data file generated + * by the Dump CDS registry command. Therefore it should be considered + * part of the overall telemetry interface. + */ +typedef struct CFE_ES_CDSRegDumpRec +{ + CFE_ES_CDSHandle_t Handle; /**< \brief Handle of CDS */ + CFE_ES_CDS_Offset_t Size; /**< \brief Size, in bytes, of the CDS memory block */ + bool Table; /**< \brief Flag that indicates whether CDS contains a Critical Table */ + char Name[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN]; /**< \brief Processor Unique Name of CDS */ + uint8 ByteAlignSpare[3]; /**< \brief Spare bytes to ensure structure size is multiple of 4 bytes */ +} CFE_ES_CDSRegDumpRec_t; + +/** + * \brief Block statistics + * + * Sub-Structure that is used to provide information about a specific + * block size/bucket within a memory pool. + */ +typedef struct CFE_ES_BlockStats +{ + CFE_ES_MemOffset_t BlockSize; /**< \brief Number of bytes in each of these blocks */ + uint32 NumCreated; /**< \brief Number of Memory Blocks of this size created */ + uint32 NumFree; /**< \brief Number of Memory Blocks of this size that are free */ +} CFE_ES_BlockStats_t; + +/** + * \brief Memory Pool Statistics + * + * Structure that is used to provide information about a memory + * pool. Used by the Memory Pool Stats telemetry message. + * + * \sa #CFE_ES_SEND_MEM_POOL_STATS_CC + */ +typedef struct CFE_ES_MemPoolStats +{ + CFE_ES_MemOffset_t PoolSize; /**< \cfetlmmnemonic \ES_POOLSIZE + \brief Size of Memory Pool (in bytes) */ + uint32 NumBlocksRequested; /**< \cfetlmmnemonic \ES_BLKSREQ + \brief Number of times a memory block has been allocated */ + uint32 CheckErrCtr; /**< \cfetlmmnemonic \ES_BLKERRCTR + \brief Number of errors detected when freeing a memory block */ + CFE_ES_MemOffset_t NumFreeBytes; /**< \cfetlmmnemonic \ES_FREEBYTES + \brief Number of bytes never allocated to a block */ + CFE_ES_BlockStats_t BlockStats[CFE_MISSION_ES_POOL_MAX_BUCKETS]; /**< \cfetlmmnemonic \ES_BLKSTATS + \brief Contains stats on each block size */ +} CFE_ES_MemPoolStats_t; + + /**********************************/ /* Telemetry Message Data Formats */ /**********************************/ diff --git a/fsw/cfe-core/src/sb/cfe_sb_init.c b/fsw/cfe-core/src/sb/cfe_sb_init.c index 3a831269a..1118343cb 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_init.c +++ b/fsw/cfe-core/src/sb/cfe_sb_init.c @@ -47,7 +47,7 @@ ** External Declarations */ -const CFE_ES_MemOffset_t CFE_SB_MemPoolDefSize[CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES] = +const CFE_ES_MemOffset_t CFE_SB_MemPoolDefSize[CFE_PLATFORM_ES_POOL_MAX_BUCKETS] = { CFE_PLATFORM_SB_MAX_BLOCK_SIZE, CFE_PLATFORM_SB_MEM_BLOCK_SIZE_16, @@ -156,7 +156,7 @@ int32 CFE_SB_InitBuffers(void) { Stat = CFE_ES_PoolCreateEx(&CFE_SB.Mem.PoolHdl, CFE_SB.Mem.Partition.Data, CFE_PLATFORM_SB_BUF_MEMORY_BYTES, - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS, &CFE_SB_MemPoolDefSize[0], CFE_ES_NO_MUTEX); diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index fe99f690e..9c36de00e 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -5394,7 +5394,7 @@ void TestCDS() { uint32 CdsSize; uint8 *CdsPtr; - char CDSName[CFE_ES_CDS_MAX_FULL_NAME_LEN + 4]; + char CDSName[CFE_MISSION_ES_CDS_MAX_FULL_NAME_LEN + 4]; CFE_ES_CDSHandle_t CDSHandle; CFE_ES_CDS_RegRec_t *UtCDSRegRecPtr; uint32 i; @@ -6225,7 +6225,7 @@ void TestESMempool(void) CFE_ES_PoolCreateEx(&PoolID1, Buffer1, sizeof(CFE_ES_GenPoolBD_t) / 2, - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES - 2, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS - 2, BlockSizes, CFE_ES_USE_MUTEX) == CFE_ES_BAD_ARGUMENT, "CFE_ES_PoolCreateEx", @@ -6237,7 +6237,7 @@ void TestESMempool(void) CFE_ES_PoolCreateEx(NULL, Buffer1, sizeof(Buffer1), - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS, BlockSizes, CFE_ES_USE_MUTEX) == CFE_ES_BAD_ARGUMENT, "CFE_ES_PoolCreateEx", @@ -6247,7 +6247,7 @@ void TestESMempool(void) CFE_ES_PoolCreateEx(&PoolID1, NULL, sizeof(Buffer1), - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS, BlockSizes, CFE_ES_USE_MUTEX) == CFE_ES_BAD_ARGUMENT, "CFE_ES_PoolCreateEx", @@ -6272,7 +6272,7 @@ void TestESMempool(void) CFE_ES_PoolCreateEx(&PoolID1, Buffer1, sizeof(Buffer1), - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES - 2, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS - 2, BlockSizes, 2) == CFE_ES_BAD_ARGUMENT, "CFE_ES_PoolCreateEx", @@ -6292,7 +6292,7 @@ void TestESMempool(void) CFE_ES_PoolCreateEx(&PoolID1, Buffer1, sizeof(Buffer1), - CFE_ES_DEFAULT_MEMPOOL_BLOCK_SIZES, + CFE_PLATFORM_ES_POOL_MAX_BUCKETS, BlockSizes, CFE_ES_USE_MUTEX) == CFE_ES_NO_RESOURCE_IDS_AVAILABLE, "CFE_ES_PoolCreateEx",