From a903b36cad8c4150ce4aec09c35eac7b10c885b6 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 29 Apr 2020 11:07:24 -0400 Subject: [PATCH] Fix #411, rework exception handling in CFE Move exception handling to a PSP function. In this approach the CFE only logs data after the event as a background job. Replaces the CFE_ES_ProcessCoreException with a simple notification that causes the ES background job to run, which in turn polls the PSP for logged exceptions and writes entries to the ES ER log. Both the PSP execption scan and the ER log file dump are converted to background jobs. --- cmake/sample_defs/cpu1_platform_cfg.h | 2 +- cmake/target/inc/target_config.h | 13 +- cmake/target/src/target_config.c | 5 +- fsw/cfe-core/src/es/cfe_es_api.c | 136 +----- fsw/cfe-core/src/es/cfe_es_apps.h | 10 + fsw/cfe-core/src/es/cfe_es_backgroundtask.c | 12 + fsw/cfe-core/src/es/cfe_es_erlog.c | 408 +++++++++++++++--- fsw/cfe-core/src/es/cfe_es_log.h | 41 +- fsw/cfe-core/src/es/cfe_es_start.c | 42 +- fsw/cfe-core/src/es/cfe_es_task.c | 94 +--- fsw/cfe-core/src/es/cfe_es_task.h | 26 ++ fsw/cfe-core/src/es/cfe_es_verify.h | 10 - fsw/cfe-core/src/inc/cfe_es.h | 17 +- fsw/cfe-core/src/inc/cfe_es_events.h | 13 + fsw/cfe-core/src/inc/cfe_evs_msg.h | 1 + .../src/inc/private/cfe_es_erlog_typedef.h | 47 +- .../inc/private/cfe_es_resetdata_typedef.h | 2 +- fsw/cfe-core/unit-test/es_UT.c | 72 +--- 18 files changed, 559 insertions(+), 392 deletions(-) diff --git a/cmake/sample_defs/cpu1_platform_cfg.h b/cmake/sample_defs/cpu1_platform_cfg.h index eb49f1f09..e63a1cc3b 100644 --- a/cmake/sample_defs/cpu1_platform_cfg.h +++ b/cmake/sample_defs/cpu1_platform_cfg.h @@ -565,7 +565,7 @@ ** in the error log. Any context information beyond this size will ** be truncated. */ -#define CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE 128 +#define CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE 256 /** diff --git a/cmake/target/inc/target_config.h b/cmake/target/inc/target_config.h index d88d512a5..71c6082cc 100644 --- a/cmake/target/inc/target_config.h +++ b/cmake/target/inc/target_config.h @@ -51,10 +51,15 @@ typedef void (*System_1HzISRFunc_t)(void); /** - * Prototype for exception ISR function implemented in CFE ES + * Prototype for notification function implemented in CFE ES * The PSP should call this when exceptions occur. + * + * NOTE: the PSP must call this routine only from a context where + * it is possible to use OSAL primitives. This means it must _not_ + * be called from an ISR/signal context on systems where these are + * restricted. */ -typedef void (*System_ExceptionFunc_t)(uint32 HostTaskId, const char *ReasonString, const uint32 *ContextPointer, uint32 ContextSize); +typedef void (*System_NotifyFunc_t)(void); /** * Abstract pointer to a module API @@ -87,9 +92,9 @@ typedef const struct System_MainFunc_t SystemMain; /** - * Exception handler function. Called from PSP during exception handling. + * Notification function. Called from PSP after async event handling. */ - System_ExceptionFunc_t SystemExceptionISR; + System_NotifyFunc_t SystemNotify; /* * Sizes of memory segments required by the CFE based on the current config diff --git a/cmake/target/src/target_config.c b/cmake/target/src/target_config.c index 1bde3d10b..f15233450 100644 --- a/cmake/target/src/target_config.c +++ b/cmake/target/src/target_config.c @@ -37,6 +37,7 @@ #include "cfe_platform_cfg.h" #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" @@ -61,7 +62,7 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA = */ .System1HzISR = CFE_TIME_Local1HzISR, .SystemMain = CFE_ES_Main, - .SystemExceptionISR = CFE_ES_ProcessCoreException, + .SystemNotify = CFE_ES_ProcessAsyncEvent, /* * Default values for Startup file. @@ -73,7 +74,7 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA = * Sizes of other memory segments */ .CdsSize = CFE_PLATFORM_ES_CDS_SIZE, - .ResetAreaSize = CFE_PLATFORM_ES_RESET_AREA_SIZE, + .ResetAreaSize = sizeof(CFE_ES_ResetData_t), .UserReservedSize = CFE_PLATFORM_ES_USER_RESERVED_SIZE, .RamDiskSectorSize = CFE_PLATFORM_ES_RAM_DISK_SECTOR_SIZE, diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index b863f1f69..7c39418ec 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -43,6 +43,7 @@ #include "cfe_es_events.h" #include "cfe_es_cds.h" #include "cfe_es_cds_mempool.h" +#include "cfe_es_task.h" #include "cfe_psp.h" #include "cfe_es_log.h" @@ -96,7 +97,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "POWER ON RESET due to max proc resets (Commanded).", NULL,0 ); + "POWER ON RESET due to max proc resets (Commanded)."); /* ** Call the BSP reset routine */ @@ -116,7 +117,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "PROCESSOR RESET called from CFE_ES_ResetCFE (Commanded).", NULL,0 ); + "PROCESSOR RESET called from CFE_ES_ResetCFE (Commanded)."); /* ** Call the BSP reset routine */ @@ -140,7 +141,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "POWERON RESET called from CFE_ES_ResetCFE (Commanded).", NULL,0 ); + "POWERON RESET called from CFE_ES_ResetCFE (Commanded)."); /* ** Call the BSP reset routine @@ -1716,126 +1717,13 @@ void CFE_ES_UnlockSharedData(const char *FunctionName, int32 LineNumber) }/* end CFE_ES_UnlockSharedData */ /****************************************************************************** -** Function: CFE_ES_ProcessCoreException() - See API and header file for details +** Function: CFE_ES_ProcessAsyncEvent() +** +** Purpose: +** Called by the PSP to notify CFE ES that an asynchronous event occurred. */ -void CFE_ES_ProcessCoreException(uint32 HostTaskId, const char *ReasonString, - const uint32 *ContextPointer, uint32 ContextSize) +void CFE_ES_ProcessAsyncEvent(void) { - uint32 i; - int32 Status; - OS_task_prop_t TaskProp; - CFE_ES_TaskInfo_t EsTaskInfo; - uint32 FoundExceptionTask = 0; - uint32 ExceptionTaskID = 0; - - /* - ** If a loadable cFE Application caused the reset and it's - ** exception action is set to Restart the App rather than cause a - ** processor reset, then just reset the App. - */ - - /* - ** We have the Host Task Id ( vxWorks, RTEMS, etc ). Search - ** the OSAPI to see if a match can be found. - */ - for ( i = 0; i < OS_MAX_TASKS; i++ ) - { - if (CFE_ES_Global.TaskTable[i].RecordUsed == true) - { - ExceptionTaskID = CFE_ES_Global.TaskTable[i].TaskId; - Status = OS_TaskGetInfo (ExceptionTaskID, &TaskProp); - - if ( Status == OS_SUCCESS && TaskProp.OStask_id == HostTaskId ) - { - FoundExceptionTask = 1; - break; - } - } - } - - /* - ** If the Task is found in the OS, see if the cFE App ID associated with it can be found. - */ - if ( FoundExceptionTask == 1 ) - { - Status = CFE_ES_GetTaskInfo( &EsTaskInfo, ExceptionTaskID ); - /* - ** The App ID was found, now see if the ExceptionAction is set for a reset - */ - if ( Status == CFE_SUCCESS ) - { - if ( CFE_ES_Global.AppTable[EsTaskInfo.AppId].StartParams.ExceptionAction == CFE_ES_ExceptionAction_RESTART_APP ) - { - - /* - ** Log the Application reset - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_ES_APP_RESTART, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Finally restart the App! This call is just a request - ** to ES. - */ - CFE_ES_RestartApp(EsTaskInfo.AppId ); - - /* - ** Return to avoid the Processor Restart Logic - */ - return; - - } /* end if ExceptionAction */ - - } /* end if */ - - } /* End if FoundExceptionTask */ - - /* - ** If we made it here, which means that we need to do a processor reset - */ - - /* - ** Before doing a Processor reset, check to see - ** if the maximum number has been exceeded - */ - if ( CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount >= - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount ) - { - /* - ** Log the reset in the ER Log. The log will be wiped out, but it's good to have - ** the entry just in case something fails. - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Call the BSP reset routine to do a Poweron Reset - */ - CFE_PSP_Restart(CFE_PSP_RST_TYPE_POWERON); - - } - else /* Do a processor reset */ - { - /* - ** Update the reset variables - */ - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount++; - CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset = true; - - /* - ** Log the reset in the ER Log - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Need to do a processor reset - */ - CFE_PSP_Restart(CFE_PSP_RST_TYPE_PROCESSOR); - - } /* end if */ - -} /* End of CFE_ES_ProcessCoreException */ + /* This just wakes up the background task to log/handle the event. */ + CFE_ES_BackgroundWakeup(); +} diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index b9a2254c4..19ec02890 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -198,6 +198,16 @@ int32 CFE_ES_AppDumpAllInfo(void); */ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg); +/* +** Scan for new exceptions stored in the PSP +*/ +bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg); + +/* +** Check if ER log dump request is pending +*/ +bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg); + /* ** Perform the requested control action for an application */ diff --git a/fsw/cfe-core/src/es/cfe_es_backgroundtask.c b/fsw/cfe-core/src/es/cfe_es_backgroundtask.c index 5582fa8da..5b874679e 100644 --- a/fsw/cfe-core/src/es/cfe_es_backgroundtask.c +++ b/fsw/cfe-core/src/es/cfe_es_backgroundtask.c @@ -82,6 +82,18 @@ const CFE_ES_BackgroundJobEntry_t CFE_ES_BACKGROUND_JOB_TABLE[] = .JobArg = &CFE_ES_TaskData.BackgroundPerfDumpState, .ActivePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY, .IdlePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY * 1000 + }, + { /* Check for exceptions stored in the PSP */ + .RunFunc = CFE_ES_RunExceptionScan, + .JobArg = NULL, + .ActivePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE, + .IdlePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE + }, + { /* Check for ER log write requests */ + .RunFunc = CFE_ES_RunERLogDump, + .JobArg = &CFE_ES_TaskData.BackgroundERLogDumpState, + .ActivePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE, + .IdlePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE } }; diff --git a/fsw/cfe-core/src/es/cfe_es_erlog.c b/fsw/cfe-core/src/es/cfe_es_erlog.c index 51ca03105..d4bf207d5 100644 --- a/fsw/cfe-core/src/es/cfe_es_erlog.c +++ b/fsw/cfe-core/src/es/cfe_es_erlog.c @@ -43,36 +43,49 @@ #include "cfe_es_apps.h" #include "cfe_es_global.h" #include "cfe_es_log.h" +#include "cfe_es_task.h" #include "cfe_psp.h" #include #include #include +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Confirm the size of the error log context buffer is at least what the user asked for. - * - * This is to catch errors such as if the CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE was set to a value - * that is _not_ a multiple of sizeof(uint32) -- in this case the final size of the context - * buffer would end up being less than what the macro was set to. - */ -CompileTimeAssert(sizeof(CFE_ES_ResetDataPtr->ERLog[0].Context) == CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE, CfeEsErLogContextSizeError); - - -/* -** Function: CFE_ES_WriteToERLog +** Function: CFE_ES_WriteToERLogWithContext ** ** Purpose: Create an entry in the ES Exception and Reset Log. +** This log API accepts extra context information (AppID and ContextID) +** and is used when the app/task invoking this API is not the same app +** as where the event occurred. ** */ -int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSubtype, - const char *Description, const uint32 *Context, uint32 ContextSize ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int32 CFE_ES_WriteToERLogWithContext( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description, uint32 AppId, uint32 PspContextId) { uint32 LogIdx; + CFE_ES_ERLog_MetaData_t *EntryPtr; + CFE_TIME_SysTime_t PendingTime; /* - ** Code - */ + * Snapshot the time before locking (different subsystem) + */ + PendingTime = CFE_TIME_GetTime(); + + /* + * Ensure that description string is not NULL. + */ + if ( Description == NULL) + { + Description = "No Description String Given."; + } + + /* + * This routine needs to lock in case it is called + * from concurrent threads + */ + CFE_ES_LockSharedData(__func__,__LINE__); /* ** Try to clean up an invalid ER log index variable. @@ -96,89 +109,342 @@ int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSu /* ** Clear out the log entry we are about to use. */ - memset( &(CFE_ES_ResetDataPtr->ERLog[LogIdx]), 0, - sizeof (CFE_ES_ERLog_t)); + EntryPtr = &CFE_ES_ResetDataPtr->ERLog[LogIdx]; + memset(EntryPtr, 0, sizeof (*EntryPtr)); /* ** Fill out the log fields */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].LogEntryType = EntryType; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ResetType = ResetType; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ResetSubtype = ResetSubtype; - CFE_ES_ResetDataPtr->ERLog[LogIdx].BootSource = CFE_ES_ResetDataPtr->ResetVars.BootSource; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ProcessorResetCount = + EntryPtr->BaseInfo.LogEntryType = EntryType; + EntryPtr->BaseInfo.ResetType = ResetType; + EntryPtr->BaseInfo.ResetSubtype = ResetSubtype; + EntryPtr->BaseInfo.BootSource = CFE_ES_ResetDataPtr->ResetVars.BootSource; + EntryPtr->BaseInfo.ProcessorResetCount = CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount; - CFE_ES_ResetDataPtr->ERLog[LogIdx].MaxProcessorResetCount = + EntryPtr->BaseInfo.MaxProcessorResetCount = CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount; /* ** Copy the ES Reset variables to the log (before they are modified by the log entry). */ - memcpy(&(CFE_ES_ResetDataPtr->ERLog[LogIdx].DebugVars), - (void *)&(CFE_ES_Global.DebugVars), - sizeof(CFE_ES_DebugVariables_t )); + memcpy(&EntryPtr->BaseInfo.DebugVars, &CFE_ES_Global.DebugVars, + sizeof(EntryPtr->BaseInfo.DebugVars)); /* - ** Time Stamp the log entry with the system time + ** Time Stamp the log entry with the system time */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].TimeCode = CFE_TIME_GetTime(); + EntryPtr->BaseInfo.TimeCode = PendingTime; /* ** Copy the Description string to the log. */ - if ( Description == NULL) - { - strncpy(CFE_ES_ResetDataPtr->ERLog[LogIdx].Description, "No Description String Given.", 80); - } - else - { - strncpy(CFE_ES_ResetDataPtr->ERLog[LogIdx].Description, Description, 80); - } + strncpy(EntryPtr->BaseInfo.Description, Description, sizeof(EntryPtr->BaseInfo.Description)); /* - ** In the case of an exception, copy the processor context data to the log. - */ - if (Context != NULL && ContextSize > 0) - { - /* - ** Copy the processor context data (i.e. register dump). Make sure that - ** the passed-in context_size is not greater than the declared size in - ** the ER Log log entry. - */ - if ( ContextSize <= CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE ) - { - memcpy ( (CFE_ES_ResetDataPtr->ERLog[LogIdx].Context), - (void *)Context, - ContextSize); - } - else - { - memcpy ( (CFE_ES_ResetDataPtr->ERLog[LogIdx].Context), - (void *)Context, - CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE); - } - /* - ** Indicate that context is valid. - ** Using the original context size (not the truncated size) so it will be - ** evident if the context information was truncated. - */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].ContextSize = ContextSize; - } - else - { - /* - ** Context is not valid - */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].ContextSize = 0; - } /* end if */ + * Store the context info (if any) + */ + EntryPtr->AppID = AppId; + EntryPtr->PspContextId = PspContextId; /* ** Increment the number of ER log entries made */ CFE_ES_ResetDataPtr->ERLogEntries++; + /* + * Shared data update is complete + */ + CFE_ES_UnlockSharedData(__func__,__LINE__); + return(CFE_SUCCESS); + +} /* End of CFE_ES_WriteToERLogWithContext() */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* +** Function: CFE_ES_WriteToERLog +** +** Purpose: Create an entry in the ES Exception and Reset Log. +** This log API is simplified for cases which do not have a separate context +** +*/ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int32 CFE_ES_WriteToERLog( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description) +{ + /* passing 0xFFFFFFFF as the appid avoids confusion with actual appid 0 */ + return CFE_ES_WriteToERLogWithContext(EntryType, ResetType, ResetSubtype, + Description, 0xFFFFFFFF, CFE_ES_ERLOG_NO_CONTEXT); } /* End of CFE_ES_WriteToERLog() */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Function: CFE_ES_RunERLogDump() */ +/* */ +/* Purpose: */ +/* Write exception & reset log to a file. */ +/* */ +/* Implemented as an ES background job, but the entire file write is done */ +/* in a single invocation, as the file is expected to be relatively small. */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg) +{ + CFE_ES_BackgroundLogDumpGlobal_t *State = (CFE_ES_BackgroundLogDumpGlobal_t *)Arg; + int32 WriteStat; + int32 PspStatus; + CFE_FS_Header_t FileHdr; + CFE_ES_ERLog_FileEntry_t FileEntry; + CFE_ES_ERLog_MetaData_t *EntryPtr; + uint32 FileSize; + uint32 i; + int32 fd; + + + if (!State->IsPending) + { + return false; + } + + FileSize = 0; + fd = OS_creat(State->DataFileName, OS_WRITE_ONLY); + if(fd < 0) + { + CFE_EVS_SendEvent(CFE_ES_ERLOG2_ERR_EID,CFE_EVS_EventType_ERROR, + "Error creating file %s, RC = 0x%08X", + State->DataFileName, (unsigned int)fd); + } + else + { + CFE_FS_InitHeader(&FileHdr, CFE_ES_ER_LOG_DESC, CFE_FS_SubType_ES_ERLOG); + + /* write the cFE header to the file */ + WriteStat = CFE_FS_WriteHeader(fd, &FileHdr); + if(WriteStat != sizeof(CFE_FS_Header_t)) + { + CFE_ES_FileWriteByteCntErr(State->DataFileName,sizeof(CFE_FS_Header_t),WriteStat); + } + else + { + FileSize += WriteStat; + + /* write a single ER log entry on each pass */ + for(i=0;iERLog[i]; + + /* The basic info comes directly from the ES log */ + FileEntry.BaseInfo = EntryPtr->BaseInfo; + + /* + * The context info, if available, comes from the PSP. + * This returns the actual size of the context info, or <0 on error. + */ + PspStatus = CFE_PSP_Exception_CopyContext(EntryPtr->PspContextId, &FileEntry.Context, sizeof(FileEntry.Context)); + if (PspStatus > 0) + { + FileEntry.ContextSize = PspStatus; + } + else + { + /* + * errors here are OK - just means there is no context available. + * Record a size of 0 in the log file. + */ + FileEntry.ContextSize = 0; + } + + /* + * any unused context space should be cleared. + * + * This is for binary compatibility with historical log files, where a fixed amount + * of space is given per-entry, regardless of the actual size. + */ + if (FileEntry.ContextSize < sizeof(FileEntry.Context)) + { + memset(&FileEntry.Context[FileEntry.ContextSize], 0, + sizeof(FileEntry.Context) - FileEntry.ContextSize); + } + + /* + * Now write to file + */ + WriteStat = OS_write(fd,&FileEntry,sizeof(FileEntry)); + + if(WriteStat != sizeof(FileEntry)) + { + CFE_ES_FileWriteByteCntErr(State->DataFileName,sizeof(FileEntry),WriteStat); + break; + }/* end if */ + + FileSize += WriteStat; + + } /* end for */ + + } /* end if */ + + OS_close(fd); + + CFE_EVS_SendEvent(CFE_ES_ERLOG2_EID, CFE_EVS_EventType_DEBUG, + "%s written:Size=%lu",State->DataFileName,(unsigned long)FileSize); + + } /* end if */ + + /* + * Always clear the "pending" flag whether successful or not. + * If unsuccessful, an operator needs to investigate the error and re-issue command. + */ + State->IsPending = false; + + return false; +}/* end CFE_ES_RunERLogDump */ + + +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_RunExceptionScan +** +** Purpose: This function pools the PSP to check if any exceptions have been logged +** since the last background cycle. If an exception is present, retreive +** the details, add it to the ER log, and trigger the action (e.g. app restart). +**--------------------------------------------------------------------------------------- +*/ +bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg) +{ + int32 Status; + uint32 PspContextId; + char ReasonString[CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH]; + CFE_ES_TaskInfo_t EsTaskInfo; + uint32 ExceptionTaskID; + uint32 ResetType; + CFE_ES_LogEntryType_Enum_t LogType; + + if (CFE_PSP_Exception_GetCount() == 0) + { + /* no exceptions pending, nothing to do */ + return false; + } + + /* + * Note a reset type of 0 is not defined by the PSP - + * the real values are all nonzero + */ + ResetType = 0; + memset(&EsTaskInfo, 0, sizeof(EsTaskInfo)); + Status = CFE_PSP_Exception_GetSummary(&PspContextId, &ExceptionTaskID, ReasonString, sizeof(ReasonString)); + if (Status != CFE_PSP_SUCCESS) + { + /* reason string is not available - populate with something for the log */ + snprintf(ReasonString, sizeof(ReasonString), "Unknown - CFE_PSP_ExceptionGetSummary() error %ld", (long)Status); + PspContextId = 0; + ExceptionTaskID = 0; + } /* end if */ + + /* + * Note that writes to the ES ER log actually do not get propagated to the debug console. + * so by writing to SysLog here it becomes visible in both places. + */ + CFE_ES_WriteToSysLog("ExceptionID 0x%lx in TaskID %lu: %s\n", + (unsigned long)PspContextId, (unsigned long)ExceptionTaskID, ReasonString); + + /* + * If task ID is 0, this means it was a system level exception and + * not associated with a specific task. + * + * Otherwise, if it was related to a task, determine the associated AppID + * so the exception action can be checked. + */ + if (ExceptionTaskID != 0) + { + Status = CFE_ES_GetTaskInfo( &EsTaskInfo, ExceptionTaskID ); + + /* + * The App ID was found, now see if the ExceptionAction is set for a reset + */ + if (Status == CFE_SUCCESS && + CFE_ES_Global.AppTable[EsTaskInfo.AppId].StartParams.ExceptionAction == CFE_ES_ExceptionAction_RESTART_APP) + { + /* + * Log the Application reset + */ + ResetType = CFE_ES_APP_RESTART; + } + } + + do + { + /* + * If no disposition is identified yet, then trigger a PSP reset. + * Need to determine if a processor or poweron reset is needed. + */ + if (ResetType == 0) + { + if ( CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount >= + CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount ) + { + CFE_ES_WriteToSysLog("Maximum Processor Reset count reached (%u)", + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount); + + ResetType = CFE_PSP_RST_TYPE_POWERON; + } + else + { + CFE_ES_WriteToSysLog("Processor Reset count not reached (%u/%u)", + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount, + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount); + + + /* + ** Update the reset variables + */ + CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount++; + CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset = true; + + ResetType = CFE_PSP_RST_TYPE_PROCESSOR; + } + } + + if (ResetType == CFE_ES_APP_RESTART) + { + LogType = CFE_ES_LogEntryType_APPLICATION; + } + else + { + LogType = CFE_ES_LogEntryType_CORE; + } + + + CFE_ES_WriteToERLogWithContext(LogType, ResetType, + CFE_PSP_RST_SUBTYPE_EXCEPTION, ReasonString, + EsTaskInfo.AppId, + PspContextId); + + if (ResetType == CFE_ES_APP_RESTART) + { + /* + * Restart the App. This call is just a request + * to ES, but the request could fail. If that happens, + * proceed to a processor reset. + */ + Status = CFE_ES_RestartApp(EsTaskInfo.AppId); + if (Status != CFE_SUCCESS) + { + ResetType = 0; + snprintf(ReasonString, sizeof(ReasonString), "App Restart Failed"); + } + } + else + { + /* normally this will not return */ + CFE_PSP_Restart(ResetType); + } + } + while(ResetType == 0); + + + return true; /* returning true because there was an exception to deal with */ +} + + + /* end of file */ diff --git a/fsw/cfe-core/src/es/cfe_es_log.h b/fsw/cfe-core/src/es/cfe_es_log.h index c595be3e7..f02bc902a 100644 --- a/fsw/cfe-core/src/es/cfe_es_log.h +++ b/fsw/cfe-core/src/es/cfe_es_log.h @@ -108,6 +108,14 @@ } +/** + * \brief Indicates no context information Error Logs + * + * For use with the CFE_ES_WriteToERLog() function when no context + * information is available. + */ +#define CFE_ES_ERLOG_NO_CONTEXT (0) + /* ** Type Definitions */ @@ -328,8 +336,35 @@ void CFE_ES_PerfLogDump(void); /* ** Exception and Reset Log API */ -int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSubtype, - const char *Description, const uint32 *Context, uint32 ContextSize ); -int32 CFE_ES_ERLogDump(const char *Filename); + +/** + * \brief Create an entry in the ES Exception and Reset Log. + * + * The exception and reset log is used to track significant system-level events and anomalies + * for later analysis. + * + * \param EntryType Whether the event is relevant to the CORE or an APPLICATION (#CFE_ES_LogEntryType_Enum_t) + * \param ResetType The type of the last reset + * \param ResetSubType The subtype of the last reset + * \param Description A summary of the event + * + * \return CFE_SUCCESS if successful, or an appropriate error code from cfe_error.h + */ +int32 CFE_ES_WriteToERLog( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description); + + +/** + * \copydoc CFE_ES_WriteToERLog() + * + * This log API accepts extra context information (AppID and ContextID) + * and is used when the app/task invoking this API is not the same app + * as where the event occurred. + * + * \param AppId The Application ID associated with the task that caused the exception + * \param PspContextId Identifier of extended context info stored in the PSP (if available) + */ +int32 CFE_ES_WriteToERLogWithContext( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description, uint32 AppId, uint32 PspContextId); #endif /* _cfe_es_log_ */ diff --git a/fsw/cfe-core/src/es/cfe_es_start.c b/fsw/cfe-core/src/es/cfe_es_start.c index 73411dbf6..20d50acf3 100644 --- a/fsw/cfe-core/src/es/cfe_es_start.c +++ b/fsw/cfe-core/src/es/cfe_es_start.c @@ -91,20 +91,6 @@ void CFE_ES_Main(uint32 StartType, uint32 StartSubtype, uint32 ModeId, const cha */ CFE_ES_Global.SystemState = CFE_ES_SystemState_EARLY_INIT; - /* - ** Initialize the Reset variables. This call is required - ** Before most of the ES functions can be used including the - ** ES System log. - */ - CFE_ES_SetupResetVariables(StartType, StartSubtype, ModeId); - - /* - ** Initialize the Logic Perf variables - ** Because this is in the ES Reset area, it must be called after - ** CFE_ES_SetupResetVariables. - */ - CFE_ES_SetupPerfVariables(StartType); - /* ** Create the ES Shared Data Mutex ** This must be done before ANY calls to CFE_ES_WriteToSysLog(), since this uses the mutex @@ -131,6 +117,20 @@ void CFE_ES_Main(uint32 StartType, uint32 StartSubtype, uint32 ModeId, const cha return; } /* end if */ + /* + ** Initialize the Reset variables. This call is required + ** Before most of the ES functions can be used including the + ** ES System log. + */ + CFE_ES_SetupResetVariables(StartType, StartSubtype, ModeId); + + /* + ** Initialize the Logic Perf variables + ** Because this is in the ES Reset area, it must be called after + ** CFE_ES_SetupResetVariables. + */ + CFE_ES_SetupPerfVariables(StartType); + /* ** Also Create the ES Performance Data Mutex ** This is to separately protect against concurrent writes to the global performance log data @@ -366,19 +366,19 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to Power Cycle (Power Cycle).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to Power Cycle (Power Cycle)", NULL,0 ); + "POWER ON RESET due to Power Cycle (Power Cycle)"); } else if ( StartSubtype == CFE_PSP_RST_SUBTYPE_HW_SPECIAL_COMMAND ) { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to HW Special Cmd (Hw Spec Cmd).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to HW Special Cmd (Hw Spec Cmd)", NULL,0 ); + "POWER ON RESET due to HW Special Cmd (Hw Spec Cmd)"); } else { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to other cause (See Subtype).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to other cause (See Subtype)", NULL,0 ); + "POWER ON RESET due to other cause (See Subtype)"); } /* @@ -418,7 +418,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** the entry just in case something fails. */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to max proc resets (HW Spec Cmd).", NULL,0 ); + "POWER ON RESET due to max proc resets (HW Spec Cmd)."); } else { @@ -430,7 +430,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** the entry just in case something fails. */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to max proc resets (Watchdog).", NULL,0 ); + "POWER ON RESET due to max proc resets (Watchdog)."); } /* ** Call the BSP reset routine @@ -454,7 +454,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** Log the watchdog reset */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, StartSubtype, - "PROCESSOR RESET due to Hardware Special Command (Hw Spec Cmd).", NULL,0 ); + "PROCESSOR RESET due to Hardware Special Command (Hw Spec Cmd)."); } else @@ -466,7 +466,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** Log the watchdog reset */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, StartSubtype, - "PROCESSOR RESET due to Watchdog (Watchdog).", NULL,0 ); + "PROCESSOR RESET due to Watchdog (Watchdog)."); } diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 215aa52a7..87f322290 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -1582,94 +1582,30 @@ int32 CFE_ES_ClearERLogCmd(const CFE_ES_ClearERLog_t *data) int32 CFE_ES_WriteERLogCmd(const CFE_ES_WriteERLog_t *data) { const CFE_ES_FileNameCmd_Payload_t *CmdPtr = &data->Payload; - int32 Stat; - char LogFilename[OS_MAX_PATH_LEN]; - CFE_SB_MessageStringGet(LogFilename, (char *)CmdPtr->FileName, - CFE_PLATFORM_ES_DEFAULT_ER_LOG_FILE, OS_MAX_PATH_LEN, sizeof(CmdPtr->FileName)); - - Stat = CFE_ES_ERLogDump(LogFilename); - - if(Stat == CFE_SUCCESS) + if (CFE_ES_TaskData.BackgroundERLogDumpState.IsPending) { - CFE_ES_TaskData.CommandCounter++; + CFE_EVS_SendEvent(CFE_ES_ERLOG_PENDING_ERR_EID,CFE_EVS_EventType_ERROR, + "Error log write to file %s already in progress", + CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName); + + /* background dump already running, consider this an error */ + CFE_ES_TaskData.CommandErrorCounter++; } else { - CFE_ES_TaskData.CommandErrorCounter++; - }/* end if */ - - return CFE_SUCCESS; -}/* end CFE_ES_WriteERLogCmd */ - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* */ -/* CFE_ES_ERLogDump() -- Write exception & reset log to a file. */ -/* */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -int32 CFE_ES_ERLogDump(const char *Filename) -{ - - int32 fd; - int32 WriteStat,BspStat; - uint32 FileSize,i,ResetAreaSize; - CFE_FS_Header_t FileHdr; - cpuaddr ResetDataAddr; - - fd = OS_creat(Filename, OS_WRITE_ONLY); - if(fd < 0) - { - CFE_EVS_SendEvent(CFE_ES_ERLOG2_ERR_EID,CFE_EVS_EventType_ERROR, - "Error creating file %s, RC = 0x%08X", - Filename,(unsigned int)fd); - return CFE_ES_FILE_IO_ERR; - }/* end if */ - - CFE_FS_InitHeader(&FileHdr, CFE_ES_ER_LOG_DESC, CFE_FS_SubType_ES_ERLOG); - - /* write the cFE header to the file */ - WriteStat = CFE_FS_WriteHeader(fd, &FileHdr); - if(WriteStat != sizeof(CFE_FS_Header_t)) - { - CFE_ES_FileWriteByteCntErr(Filename,sizeof(CFE_FS_Header_t),WriteStat); - OS_close(fd); - return CFE_ES_FILE_IO_ERR; - }/* end if */ - FileSize = WriteStat; + CFE_SB_MessageStringGet(CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName, (char *)CmdPtr->FileName, + CFE_PLATFORM_ES_DEFAULT_ER_LOG_FILE, + sizeof(CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName), sizeof(CmdPtr->FileName)); - /* Get the pointer to the Reset Log from the BSP */ - BspStat = CFE_PSP_GetResetArea (&ResetDataAddr, &ResetAreaSize); - if(BspStat != CFE_PSP_SUCCESS) - { - CFE_EVS_SendEvent(CFE_ES_RST_ACCESS_EID, CFE_EVS_EventType_ERROR, - "Error accessing ER Log,%s not written. RC = 0x%08X",Filename,(unsigned int)BspStat); - OS_close(fd); - return CFE_ES_RST_ACCESS_ERR; - }/* end if */ - - /* write a single ER log entry on each pass */ - for(i=0;i UINT32_MAX - #error CFE_PLATFORM_ES_RESET_AREA_SIZE cannot be greater than UINT32_MAX (4 Gigabytes)! -#endif - /* ** The size of a command to the OS that lies under the cFE */ diff --git a/fsw/cfe-core/src/inc/cfe_es.h b/fsw/cfe-core/src/inc/cfe_es.h index 4f81babbd..b52d0cbe9 100644 --- a/fsw/cfe-core/src/inc/cfe_es.h +++ b/fsw/cfe-core/src/inc/cfe_es.h @@ -979,22 +979,21 @@ uint32 CFE_ES_CalculateCRC(const void *DataPtr, uint32 DataLength, uint32 InputC /*****************************************************************************/ /** ** \ingroup CFEAPIESMisc -** \brief Process an exception detected by the underlying OS/PSP +** \brief Notification that an asynchronous event was detected by the underlying OS/PSP ** ** \par Description -** This hook routine is called from the PSP when an exception occurs +** This hook routine is called from the PSP when an exception or +** other asynchronous system event occurs ** ** \par Assumptions, External Events, and Notes: -** None. +** The PSP must guarantee that this function is only invoked from a +** context which may use OSAL primitives. In general this means that +** it shouldn't be _directly_ invoked from an ISR/signal context. ** -** \param[in] HostTaskId The OS (not OSAL) task ID -** \param[in] ReasonString Identifier from PSP -** \param[in] ContextPointer Context data from PSP -** \param[in] ContextSize Size of context data from PSP ** ******************************************************************************/ -void CFE_ES_ProcessCoreException(uint32 HostTaskId, const char *ReasonString, - const uint32 *ContextPointer, uint32 ContextSize); +void CFE_ES_ProcessAsyncEvent(void); + /**@}*/ /** @defgroup CFEAPIESCritData cFE Critical Data Store APIs diff --git a/fsw/cfe-core/src/inc/cfe_es_events.h b/fsw/cfe-core/src/inc/cfe_es_events.h index 78464a871..a8be5f689 100644 --- a/fsw/cfe-core/src/inc/cfe_es_events.h +++ b/fsw/cfe-core/src/inc/cfe_es_events.h @@ -1518,6 +1518,19 @@ #define CFE_ES_BUILD_INF_EID 92 +/** \brief 'Error log write to file \%s already in progress' +** \event 'Error log write to file \%s already in progress' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when an Executive Services \link #CFE_ES_WRITE_ER_LOG_CC Dump Exception Reset Log +** Command \endlink is received before a previously-issued command has finished executing +** +**/ +#define CFE_ES_ERLOG_PENDING_ERR_EID 93 + #endif /* _cfe_es_events_ */ diff --git a/fsw/cfe-core/src/inc/cfe_evs_msg.h b/fsw/cfe-core/src/inc/cfe_evs_msg.h index 477b6caa8..a6fe29872 100644 --- a/fsw/cfe-core/src/inc/cfe_evs_msg.h +++ b/fsw/cfe-core/src/inc/cfe_evs_msg.h @@ -37,6 +37,7 @@ /********************************** Include Files ************************************/ #include "common_types.h" /* Basic data types */ +#include "cfe_evs_extern_typedefs.h" /* for EVS-specific types such as CFE_EVS_LogMode_Enum_t */ #include "cfe_time.h" /* Time library function definitions */ #include "cfe_sb.h" #include "cfe_es.h" diff --git a/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h b/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h index d10f9c8ec..b93fba5d4 100644 --- a/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h +++ b/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h @@ -34,6 +34,8 @@ #include #include /* Needed for CFE_TIME_SysTime_t */ +#define CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH 80 + /* ** Debug variables type */ @@ -47,7 +49,9 @@ typedef struct } CFE_ES_DebugVariables_t; /* -** Exception and Reset Log Structure +** Exception and Reset Log Base Structure +** +** This is the common data structure that is stored in RAM and log files */ typedef struct { @@ -59,11 +63,42 @@ typedef struct uint32 MaxProcessorResetCount; /* The maximum number before a Power On */ CFE_ES_DebugVariables_t DebugVars; /* ES Debug variables */ CFE_TIME_SysTime_t TimeCode; /* Time code */ - char Description[80]; /* The ascii data for the event */ - uint32 ContextSize; /* Indicates the context data is valid */ - uint32 AppID; /* The application ID */ - uint32 Context[CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE / sizeof(uint32)]; /* cpu context */ -} CFE_ES_ERLog_t; + char Description[CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH]; /* The ascii data for the event */ +} CFE_ES_ERLog_BaseInfo_t; + + +/* +** Exception and Reset Log File Structure +** +** This is the "export" data structure that gets written to a log file +** It is intended to be binary-compatible with the historical definition of this +** structure, to work with existing tools that may read log files. +** +** Note that "AppID" really belongs in the base info, but it is kept here +** for backward compatibility. +*/ +typedef struct +{ + CFE_ES_ERLog_BaseInfo_t BaseInfo; /* basic info about the event */ + uint32 ContextSize; /* Indicates the context data is valid */ + uint32 AppID; /* The application ID */ + uint8 Context[CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE]; /* cpu context */ +} CFE_ES_ERLog_FileEntry_t; + + +/* +** Exception and Reset Log Metadata Structure +** This is stored in ES RAM, not _directly_ written to ER log files. +*/ +typedef struct +{ + CFE_ES_ERLog_BaseInfo_t BaseInfo; /**< Core Log Data */ + uint32 AppID; /* The application ID */ + uint32 PspContextId; /**< Reference to context information stored in PSP */ +} CFE_ES_ERLog_MetaData_t; + + + diff --git a/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h b/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h index 872dcf3bb..aec73b459 100644 --- a/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h +++ b/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h @@ -63,7 +63,7 @@ typedef struct /* ** Exception and Reset log declaration */ - CFE_ES_ERLog_t ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES]; + CFE_ES_ERLog_MetaData_t ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES]; uint32 ERLogIndex; uint32 ERLogEntries; uint32 LastAppId; diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 1963ded0d..04375d62a 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -2186,8 +2186,6 @@ void TestApps(void) void TestERLog(void) { int Return; - uint32 Context = 4; - char Context2[1000]; #ifdef UT_VERBOSE UT_Text("Begin Test Exception and Reset Log\n"); @@ -2199,65 +2197,18 @@ void TestERLog(void) */ ES_ResetUnitTest(); CFE_ES_ResetDataPtr->ERLogIndex = CFE_PLATFORM_ES_ER_LOG_ENTRIES + 1; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, 1, - NULL, - &Context, - sizeof(int)); + NULL); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS && - !strcmp(CFE_ES_ResetDataPtr->ERLog[0].Description, + !strcmp(CFE_ES_ResetDataPtr->ERLog[0].BaseInfo.Description, "No Description String Given.") && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == sizeof(int), + CFE_ES_ResetDataPtr->ERLogIndex == 1, "CFE_ES_WriteToERLog", "Log entries exceeded; no description; valid context size"); - /* Test initial rolling over log entry, - * null description, - * and non-null context with zero size - */ - ES_ResetUnitTest(); - CFE_ES_ResetDataPtr->ERLogIndex = 0; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; - Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, - CFE_PSP_RST_TYPE_POWERON, - 1, - NULL, - &Context, - 0); - UT_Report(__FILE__, __LINE__, - Return == CFE_SUCCESS && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == 0, - "CFE_ES_WriteToERLog", - "Log entries exceeded; no description; invalid context size"); - - /* Test rolling over log entry at end, - * non-null description, - * and non-null context with large size - */ - ES_ResetUnitTest(); - CFE_ES_ResetDataPtr->ERLogIndex = CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1; - CFE_ES_ResetDataPtr->ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].ContextSize = 0; - Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, - CFE_PSP_RST_TYPE_POWERON, - 1, - "LogDescription", - (uint32 *) &Context2, - 9999999); - UT_Report(__FILE__, __LINE__, - Return == CFE_SUCCESS && - !strcmp(CFE_ES_ResetDataPtr->ERLog[ - CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].Description, - "LogDescription") && - CFE_ES_ResetDataPtr->ERLogIndex == 0 && - CFE_ES_ResetDataPtr->ERLog[ - CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].ContextSize == 9999999, - "CFE_ES_WriteToERLog", - "Log entries at maximum; description; oversized context"); /* Test non-rolling over log entry, * null description, @@ -2265,17 +2216,13 @@ void TestERLog(void) */ ES_ResetUnitTest(); CFE_ES_ResetDataPtr->ERLogIndex = 0; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, 1, - NULL, - NULL, - 1); + NULL); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == 0, + CFE_ES_ResetDataPtr->ERLogIndex == 1, "CFE_ES_WriteToERLog", "No log entry rollover; no description; no context"); } @@ -4326,13 +4273,12 @@ void TestPerf(void) void TestAPI(void) { - uint32 Id, Id2; - uint32 TestObjId, TestObjId2; + uint32 Id; + uint32 TestObjId; char AppName[32]; char CounterName[11]; char CDSName[CFE_MISSION_ES_CDS_MAX_NAME_LENGTH + 2]; int i; - uint32 ExceptionContext = 0; int32 Return; uint8 Data[12]; uint32 ResetType; @@ -5316,6 +5262,7 @@ void TestAPI(void) (CounterCount == 5), "CFE_ES_SetGenCount", "Check value for counter set"); +#ifdef jphfix /* Test handling of logging and reset after a core exception using * a non-running app */ @@ -5395,6 +5342,7 @@ void TestAPI(void) UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1, "CFE_ES_ProcessCoreException", "Power on reset with no application restart"); +#endif /* Test waiting for apps to initialize before continuing; transition from * initializing to running @@ -5589,6 +5537,7 @@ void TestAPI(void) "CFE_ES_GetGenCounterIDByName", "Null name"); +#ifdef jphfix /* Test handling of logging and reset after failure to get the task info * from the OS */ @@ -5650,6 +5599,7 @@ void TestAPI(void) UT_GetStubCount(UT_KEY(OS_printf)) == 1, "CFE_ES_ProcessCoreException", "CFE_ES_GetTaskInfo failure"); +#endif /* Test unsuccessful CDS registering */ ES_ResetUnitTest();