Skip to content

Commit

Permalink
Merge pull request nasa#653 from jphickey/fix-411-exceptions
Browse files Browse the repository at this point in the history
Fix nasa#411, rework exception handling in CFE
  • Loading branch information
astrogeco authored May 8, 2020
2 parents 2a0494e + 87b87c8 commit 733eb94
Show file tree
Hide file tree
Showing 19 changed files with 675 additions and 621 deletions.
48 changes: 1 addition & 47 deletions cmake/sample_defs/cpu1_platform_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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


/**
Expand Down Expand Up @@ -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
**
Expand Down
13 changes: 9 additions & 4 deletions cmake/target/inc/target_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions cmake/target/src/target_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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.
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main.dox
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@
<UL>
<LI> #CFE_ES_CalculateCRC - \copybrief CFE_ES_CalculateCRC
<LI> #CFE_ES_WriteToSysLog - \copybrief CFE_ES_WriteToSysLog
<LI> #CFE_ES_ProcessCoreException - \copybrief CFE_ES_ProcessCoreException
<LI> #CFE_ES_ProcessAsyncEvent - \copybrief CFE_ES_ProcessAsyncEvent
</UL>
</UL>

Expand Down
136 changes: 12 additions & 124 deletions fsw/cfe-core/src/es/cfe_es_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
*/
Expand All @@ -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
*/
Expand All @@ -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
Expand Down Expand Up @@ -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();
}
10 changes: 10 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
12 changes: 12 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_backgroundtask.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
};

Expand Down
Loading

0 comments on commit 733eb94

Please sign in to comment.