diff --git a/cmake/sample_defs/cpu1_platform_cfg.h b/cmake/sample_defs/cpu1_platform_cfg.h
index 3e85be30c..167eedd53 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
/**
@@ -1205,52 +1205,6 @@
*/
#define CFE_PLATFORM_ES_DEFAULT_STACK_SIZE 8192
-/**
-** \cfeescfg Define cFE Core Exception Function
-**
-** \par Description:
-** This parameter defines the function-to-call when a CPU or floating point exception
-** occurs. The parameter is defaulted to call the ES API function #CFE_ES_ProcessCoreException
-** which handles the logging and reset from a system or cFE core exception.
-**
-** Note: Exception interrupts are trapped at the Platform Support Package (PSP)
-** layer. In order to initiate the cFE platform defined response to an exception, this
-** platform defined callback function must be prototyped and called from the PSP
-** exception hook API function #CFE_PSP_ExceptionHook. For example:
-**
-** -- cfe_psp.h --
-**
-** .... Prototype for exception ISR function implemented in CFE ....
-**
-** typedef void (*System_ExceptionFunc_t)(uint32 HostTaskId,
-** const char *ReasonString,
-** const uint32 *ContextPointer,
-** uint32 ContextSize);
-**
-** -- cfe_pspexception.c --
-**
-** .... Setup function pointer to CFE exception ISR callback ....
-**
-** static const System_ExceptionFunc_t CFE_ExceptionCallback = CFE_PLATFORM_ES_EXCEPTION_FUNCTION;
-**
-** void CFE_PSP_ExceptionHook (int task_id, int vector, uint8 *pEsf )
-** {
-** .... platform-specific logic ....
-**
-** .... Use function pointer to call cFE routine to finish processing the exception ....
-**
-** CFE_ExceptionCallback((uint32)task_id,
-** CFE_PSP_ExceptionReasonString,
-** (uint32 *)&CFE_PSP_ExceptionContext,
-** sizeof(CFE_PSP_ExceptionContext_t));
-**
-** }
-**
-** \par Limits
-** Must be a valid function name.
-*/
-#define CFE_PLATFORM_ES_EXCEPTION_FUNCTION CFE_ES_ProcessCoreException
-
/**
** \cfeescfg Define EVS Task Priority
**
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/docs/src/main.dox b/docs/src/main.dox
index d3d583d84..d2cdf1efc 100644
--- a/docs/src/main.dox
+++ b/docs/src/main.dox
@@ -472,7 +472,7 @@
- #CFE_ES_CalculateCRC - \copybrief CFE_ES_CalculateCRC
- #CFE_ES_WriteToSysLog - \copybrief CFE_ES_WriteToSysLog
-
- #CFE_ES_ProcessCoreException - \copybrief CFE_ES_ProcessCoreException
+
- #CFE_ES_ProcessAsyncEvent - \copybrief CFE_ES_ProcessAsyncEvent
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 e1ccc24a9..5d73fc64c 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 2f750536e..303ccfb2c 100644
--- a/fsw/cfe-core/src/es/cfe_es_task.c
+++ b/fsw/cfe-core/src/es/cfe_es_task.c
@@ -1589,94 +1589,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..03da2eb37 100644
--- a/fsw/cfe-core/src/inc/cfe_es_events.h
+++ b/fsw/cfe-core/src/inc/cfe_es_events.h
@@ -1214,21 +1214,6 @@
**/
#define CFE_ES_FILEWRITE_ERR_EID 74
-/** \brief 'Error accessing ER Log,\%s not written.Stat=0x\%08x'
-** \event 'Error accessing ER Log,\%s not written.Stat=0x\%08x'
-**
-** \par Type: ERROR
-**
-** \par Cause:
-**
-** This event message is generated in response to an Exception Reset Log Dump command and there is
-** an error obtaining the contents of the ER Log.
-**
-** The \c 's' field identifies the filename of the file to which the data failed to write,
-** the \c Stat field specifies, in hex, the error status returned from #CFE_PSP_GetResetArea.
-**/
-#define CFE_ES_RST_ACCESS_EID 75
-
/** \brief 'Error while deleting '\%s' from CDS, See SysLog.(Err=0x\%08X)'
** \event 'Error while deleting '\%s' from CDS, See SysLog.(Err=0x\%08X)'
**
@@ -1518,6 +1503,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 e0a7a7ab3..125415600 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");
}
@@ -2460,6 +2407,7 @@ void TestTask(void)
uint32 Id;
uint32 TestObjId;
uint32 ResetType;
+ uint32 UT_ContextBuffer;
union
{
CFE_SB_Msg_t Msg;
@@ -3264,64 +3212,157 @@ void TestTask(void)
"Clear E&R log");
/* Test successful writing of the E&R log */
+ /* In the current implementation, it does not directly write the file,
+ * this just sets a flag for the background task */
ES_ResetUnitTest();
memset(&CmdBuf, 0, sizeof(CmdBuf));
strncpy(CmdBuf.WriteERlogCmd.Payload.FileName, "filename",
sizeof(CmdBuf.WriteERlogCmd.Payload.FileName));
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = false;
+ UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
+ UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
+ UT_Report(__FILE__, __LINE__,
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending,
+ "CFE_ES_WriteERLogCmd",
+ "Write E&R log command; pending");
+ UT_Report(__FILE__, __LINE__,
+ !UT_EventIsInHistory(CFE_ES_ERLOG_PENDING_ERR_EID),
+ "CFE_ES_WriteERLogCmd",
+ "Write E&R log command; no events");
+
+ /* sending the same command a second time should fail with an event
+ * indicating a file write is already pending. */
UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
UT_Report(__FILE__, __LINE__,
- UT_EventIsInHistory(CFE_ES_ERLOG2_EID),
+ UT_EventIsInHistory(CFE_ES_ERLOG_PENDING_ERR_EID),
+ "CFE_ES_WriteERLogCmd",
+ "Write E&R log command; already pending event");
+
+ /* calling the background job when no write pending should immediately return false, no event */
+ ES_ResetUnitTest();
+ memset(&CFE_ES_TaskData.BackgroundERLogDumpState, 0, sizeof(CFE_ES_TaskData.BackgroundERLogDumpState));
+ UT_Report(__FILE__, __LINE__,
+ !CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState),
+ "CFE_ES_RunERLogDump",
+ "Write E&R log; not pending");
+ UT_Report(__FILE__, __LINE__,
+ !UT_EventIsInHistory(CFE_ES_ERLOG2_EID),
+ "CFE_ES_WriteERLogCmd",
+ "Write E&R log command; no file written event");
+
+ /* nominal condition - still returns false, but generates event */
+ ES_ResetUnitTest();
+ UT_ContextBuffer = 42;
+ UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_CopyContext),&UT_ContextBuffer, sizeof(UT_ContextBuffer), false);
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true;
+ CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState);
+ UT_Report(__FILE__, __LINE__,
+ !CFE_ES_TaskData.BackgroundERLogDumpState.IsPending,
+ "CFE_ES_RunERLogDump",
+ "Write E&R log; nominal, clear flag");
+ UT_Report(__FILE__, __LINE__,
+ UT_EventIsInHistory(CFE_ES_ERLOG2_EID),
"CFE_ES_WriteERLogCmd",
- "Write E&R log; success");
+ "Write E&R log command; file written event");
/* Test writing the E&R log with an OS create failure */
ES_ResetUnitTest();
- memset(&CmdBuf, 0, sizeof(CmdBuf));
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true;
UT_SetForceFail(UT_KEY(OS_creat), OS_ERROR);
- strncpy((char *) CmdBuf.WriteERlogCmd.Payload.FileName, "",
- sizeof(CmdBuf.WriteERlogCmd.Payload.FileName));
- UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
- UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
+ CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState);
UT_Report(__FILE__, __LINE__,
UT_EventIsInHistory(CFE_ES_ERLOG2_ERR_EID),
- "CFE_ES_WriteERLogCmd",
+ "CFE_ES_RunERLogDump",
"Write E&R log; OS create");
/* Test writing the E&R log with an OS write failure */
ES_ResetUnitTest();
- memset(&CmdBuf, 0, sizeof(CmdBuf));
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true;
UT_SetForceFail(UT_KEY(OS_write), OS_ERROR);
- strncpy((char *) CmdBuf.WriteERlogCmd.Payload.FileName, "n",
- sizeof(CmdBuf.WriteERlogCmd.Payload.FileName));
- UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
- UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
+ CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState);
UT_Report(__FILE__, __LINE__,
UT_EventIsInHistory(CFE_ES_FILEWRITE_ERR_EID),
- "CFE_ES_WriteERLogCmd",
+ "CFE_ES_RunERLogDump",
"Write E&R log; OS write");
/* Test writing the E&R log with a write header failure */
ES_ResetUnitTest();
- memset(&CmdBuf, 0, sizeof(CmdBuf));
+ CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true;
UT_SetDeferredRetcode(UT_KEY(CFE_FS_WriteHeader), 1, OS_ERROR);
- UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
- UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
+ CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState);
UT_Report(__FILE__, __LINE__,
UT_EventIsInHistory(CFE_ES_FILEWRITE_ERR_EID),
"CFE_ES_WriteERLogCmd",
"Write E&R log; write header");
- /* Test writing the E&R log with a reset area failure */
+ /* Test scan for exceptions in the PSP, should invoke a Processor Reset */
ES_ResetUnitTest();
- memset(&CmdBuf, 0, sizeof(CmdBuf));
- UT_SetStatusBSPResetArea(OS_ERROR, 0, CFE_TIME_ToneSignalSelect_PRIMARY);
- UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t),
- UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC);
+ UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetCount), 1);
+ CFE_ES_RunExceptionScan(0, NULL);
UT_Report(__FILE__, __LINE__,
- UT_EventIsInHistory(CFE_ES_RST_ACCESS_EID),
- "CFE_ES_WriteERLogCmd",
- "Write E&R log; reset area");
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; processor restart");
+
+ ES_ResetUnitTest();
+ CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0;
+ CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 1;
+ UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetCount), 1);
+ CFE_ES_RunExceptionScan(0, NULL);
+ /* first time should do a processor restart (limit reached) */
+ UT_Report(__FILE__, __LINE__,
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; processor restart");
+ /* next time should do a poweron restart (limit reached) */
+ CFE_ES_RunExceptionScan(0, NULL);
+ UT_Report(__FILE__, __LINE__,
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 2,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; poweron restart");
+
+ /* nominal for app restart - associate exception with a task ID */
+ OS_TaskCreate(&UT_ContextBuffer, "UT", NULL, NULL, 0, 0, 0);
+ UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_GetSummary), &UT_ContextBuffer, sizeof(UT_ContextBuffer), false);
+ CFE_ES_Global.TaskTable[1].RecordUsed = true;
+ CFE_ES_Global.TaskTable[1].AppId = 0;
+ CFE_ES_Global.TaskTable[1].TaskId = UT_ContextBuffer;
+ CFE_ES_Global.AppTable[0].AppState = CFE_ES_AppState_RUNNING;
+ CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN;
+ CFE_ES_Global.AppTable[0].ControlReq.AppTimerMsec = 0;
+ CFE_ES_Global.AppTable[0].Type = CFE_ES_AppType_EXTERNAL;
+ CFE_ES_Global.AppTable[0].StartParams.ExceptionAction = CFE_ES_ExceptionAction_RESTART_APP;
+ CFE_ES_RunExceptionScan(0, NULL);
+ /* should have changed AppControlRequest from RUN to SYS_RESTART,
+ * and the call to CFE_PSP_Restart should NOT increment */
+ UT_Report(__FILE__, __LINE__,
+ CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_RESTART,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; app restart request pending");
+
+ UT_Report(__FILE__, __LINE__,
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 2,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; no psp restart");
+
+ /* repeat, but for a CORE app, which cannot be restarted */
+ UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_GetSummary), &UT_ContextBuffer, sizeof(UT_ContextBuffer), false);
+ CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN;
+ CFE_ES_Global.AppTable[0].Type = CFE_ES_AppType_CORE;
+ CFE_ES_RunExceptionScan(0, NULL);
+ UT_Report(__FILE__, __LINE__,
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 3,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; core app, psp restart");
+
+ /* check failure of getting summary data */
+ UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetSummary), CFE_PSP_NO_EXCEPTION_DATA);
+ CFE_ES_RunExceptionScan(0, NULL);
+ UT_Report(__FILE__, __LINE__,
+ UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 4,
+ "CFE_ES_RunExceptionScan",
+ "Scan for exceptions; fail to get context");
/* Test clearing the log with a bad size in the verify command
* length call
@@ -4338,13 +4379,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;
@@ -5328,86 +5368,6 @@ void TestAPI(void)
(CounterCount == 5), "CFE_ES_SetGenCount",
"Check value for counter set");
- /* Test handling of logging and reset after a core exception using
- * a non-running app
- */
- ES_ResetUnitTest();
- OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0);
- Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId);
- OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0);
- Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2);
- strncpy((char *)CFE_ES_Global.AppTable[Id].StartParams.Name, "appName",
- sizeof(CFE_ES_Global.AppTable[Id].StartParams.Name));
- CFE_ES_Global.TaskTable[Id].RecordUsed = true;
- CFE_ES_Global.AppTable[Id].Type = CFE_ES_AppType_EXTERNAL;
- CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_EARLY_INIT;
- CFE_ES_Global.TaskTable[Id2].RecordUsed = true;
- CFE_ES_Global.TaskTable[Id2].AppId = Id;
- OS_TaskCreate(&CFE_ES_Global.TaskTable[Id2].TaskId, NULL, NULL, NULL,
- 0, 0, 0);
- CFE_ES_Global.AppTable[Id].StartParams.ExceptionAction =
- CFE_ES_ExceptionAction_RESTART_APP;
- CFE_ES_ProcessCoreException(TestObjId & 0xFFFF,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_RESTART_APP]) &&
- UT_GetStubCount(UT_KEY(OS_printf)) == 1,
- "CFE_ES_ProcessCoreException",
- "Cannot restart a non-running application");
-
- /* Test handling of logging and reset after a core exception; processor
- * reset with no app restart
- */
- ES_ResetUnitTest();
- UT_SetDataBuffer(UT_KEY(CFE_PSP_Restart), &ResetType, sizeof(ResetType), false);
- OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0);
- Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId);
- OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0);
- Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2);
-// memset(CFE_ES_Global.TaskTable, 0, sizeof(CFE_ES_Global.TaskTable));
-// memset(CFE_ES_Global.AppTable, 0, sizeof(CFE_ES_Global.AppTable));
- strncpy((char *)CFE_ES_Global.AppTable[Id].StartParams.Name, "appName",
- sizeof(CFE_ES_Global.AppTable[Id].StartParams.Name));
- CFE_ES_Global.TaskTable[Id2].RecordUsed = true;
- CFE_ES_Global.TaskTable[Id2].AppId = Id;
- OS_TaskCreate(&CFE_ES_Global.TaskTable[Id2].TaskId, NULL, NULL, NULL,
- 0, 0, 0);
- CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING;
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0;
- CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5;
- CFE_ES_Global.AppTable[3].StartParams.ExceptionAction =
- CFE_ES_ExceptionAction_RESTART_APP + 1;
- CFE_ES_ProcessCoreException(TestObjId2 & 0xFFFF,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- ResetType == CFE_PSP_RST_TYPE_PROCESSOR &&
- UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1,
- "CFE_ES_ProcessCoreException",
- "Processor reset with no application restart");
-
- /* Test handling of logging and reset after a core exception; power on
- * reset with no app restart
- */
- ES_ResetUnitTest();
- UT_SetDataBuffer(UT_KEY(CFE_PSP_Restart), &ResetType, sizeof(ResetType), false);
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 100;
- CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5;
- CFE_ES_Global.AppTable[3].StartParams.ExceptionAction =
- CFE_ES_ExceptionAction_RESTART_APP + 1;
- CFE_ES_ProcessCoreException(OS_MAX_TASKS - 1,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- ResetType == CFE_PSP_RST_TYPE_POWERON &&
- UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1,
- "CFE_ES_ProcessCoreException",
- "Power on reset with no application restart");
-
/* Test waiting for apps to initialize before continuing; transition from
* initializing to running
*/
@@ -5601,68 +5561,6 @@ void TestAPI(void)
"CFE_ES_GetGenCounterIDByName",
"Null name");
- /* Test handling of logging and reset after failure to get the task info
- * from the OS
- */
- ES_ResetUnitTest();
- UT_SetDeferredRetcode(UT_KEY(OS_TaskGetInfo), 1, OS_INVALID_POINTER);
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0;
- CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5;
- CFE_ES_ProcessCoreException(0xFFFFFFFF,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount == 1 &&
- CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset == true,
- "CFE_ES_ProcessCoreException",
- "Failure to get task info from OS");
-
- /* Test handling of logging and reset where the host ID doesn't match
- * the OS task ID
- */
- ES_ResetUnitTest();
- OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0);
- Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId);
- CFE_ES_Global.TaskTable[Id].RecordUsed = true;
- CFE_ES_Global.TaskTable[Id].AppId = Id;
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0;
- CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5;
- CFE_ES_Global.AppTable[Id].StartParams.ExceptionAction =
- CFE_ES_ExceptionAction_RESTART_APP;
- CFE_ES_ProcessCoreException(0,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- UT_GetStubCount(UT_KEY(OS_printf)) == 0,
- "CFE_ES_ProcessCoreException",
- "Host ID doesn't match OS task ID");
-
- /* Test handling of logging and reset where CFE_ES_GetTaskInfo fails */
- ES_ResetUnitTest();
- OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0);
- Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId);
- OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0);
- Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2);
- CFE_ES_Global.TaskTable[Id].RecordUsed = true;
- CFE_ES_Global.TaskTable[Id].AppId = Id;
- CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0;
- CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5;
- CFE_ES_Global.TaskTable[Id].RecordUsed = true;
- CFE_ES_Global.TaskTable[Id].AppId = Id2;
- CFE_ES_Global.AppTable[Id2].AppState = CFE_ES_AppState_UNDEFINED;
- CFE_ES_Global.AppTable[Id2].StartParams.ExceptionAction =
- CFE_ES_ExceptionAction_RESTART_APP;
- CFE_ES_ProcessCoreException(Id,
- "Reason String",
- &ExceptionContext,
- sizeof(ExceptionContext));
- UT_Report(__FILE__, __LINE__,
- UT_GetStubCount(UT_KEY(OS_printf)) == 1,
- "CFE_ES_ProcessCoreException",
- "CFE_ES_GetTaskInfo failure");
-
/* Test unsuccessful CDS registering */
ES_ResetUnitTest();
OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0);