Skip to content

Commit

Permalink
Fix #797, refactor internal table/id management in ES
Browse files Browse the repository at this point in the history
Introduce wrapper/accessor functions to look up table
entries by ID for Executive Services subsystem.

__Do not use AppID as a table index__.

Note - This does not change existing external APIs and AppIDs
are still zero-based uint32.  This only changes the internal
structures to remove use of ID as an array index, and to use a lookup
function to locate the table entry from an ID.  All entry access
is then performed via the table entry pointer, rather than
as an array index.

This provides the groundwork for abstract IDs without actually
changing anything fundamental about resource IDs.
  • Loading branch information
jphickey committed Sep 2, 2020
1 parent 08f6eab commit 4d3c809
Show file tree
Hide file tree
Showing 16 changed files with 2,178 additions and 1,649 deletions.
635 changes: 410 additions & 225 deletions fsw/cfe-core/src/es/cfe_es_api.c

Large diffs are not rendered by default.

404 changes: 259 additions & 145 deletions fsw/cfe-core/src/es/cfe_es_apps.c

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions fsw/cfe-core/src/es/cfe_es_apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ typedef struct
*/
typedef struct
{
CFE_ES_AppState_Enum_t AppState; /* Is the app running, or stopped, or waiting? */
CFE_ES_AppState_Enum_t AppState; /* Is the app running, or stopped, or waiting? */
uint32 Type; /* The type of App: CORE or EXTERNAL */
CFE_ES_AppStartParams_t StartParams; /* The start parameters for an App */
CFE_ES_ControlReq_t ControlReq; /* The Control Request Record for External cFE Apps */
Expand Down Expand Up @@ -211,12 +211,12 @@ bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg);
/*
** Perform the requested control action for an application
*/
void CFE_ES_ProcessControlRequest(uint32 AppID);
void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr);

/*
** Clean up all app resources and delete it
*/
int32 CFE_ES_CleanUpApp(uint32 AppId);
int32 CFE_ES_CleanUpApp(CFE_ES_AppRecord_t *AppRecPtr);

/*
** Clean up all Task resources and detete the task
Expand All @@ -228,6 +228,13 @@ int32 CFE_ES_CleanupTaskResources(uint32 TaskId);
** This is an internal function for use in ES.
** The newer external API is : CFE_ES_GetAppInfo
*/
void CFE_ES_GetAppInfoInternal(uint32 AppId, CFE_ES_AppInfo_t *AppInfoPtr );
int32 CFE_ES_GetAppInfoInternal(CFE_ES_AppRecord_t *AppRecPtr, CFE_ES_AppInfo_t *AppInfoPtr );

/*
* Populate the CFE_ES_TaskInfo_t structure with the data for a task
* This is an internal function for use in ES.
* (Equivalent pattern to CFE_ES_GetAppInfoInternal() but for tasks)
*/
int32 CFE_ES_GetTaskInfoInternal(CFE_ES_TaskRecord_t *TaskRecPtr, CFE_ES_TaskInfo_t *TaskInfoPtr );

#endif /* _cfe_es_apps_ */
29 changes: 0 additions & 29 deletions fsw/cfe-core/src/es/cfe_es_cds.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,35 +528,6 @@ int32 CFE_ES_UpdateCDSRegistry(void)
return Status;
}

/*******************************************************************
**
** CFE_ES_CDS_ValidateAppID
**
** NOTE: For complete prolog information, see 'cfe_es_cds.h'
********************************************************************/

int32 CFE_ES_CDS_ValidateAppID(uint32 *AppIdPtr)
{
int32 Status = CFE_ES_GetAppID(AppIdPtr);

if (Status == CFE_SUCCESS)
{
if (*AppIdPtr >= CFE_PLATFORM_ES_MAX_APPLICATIONS)
{
Status = CFE_ES_ERR_APPID;

CFE_ES_WriteToSysLog("CFE_CDS:ValidateAppID-AppId=%d > Max Apps (%d)\n",
(int)(*AppIdPtr), CFE_PLATFORM_ES_MAX_APPLICATIONS);
}
}
else
{
CFE_ES_WriteToSysLog("CFE_CDS:ValidateAppID-GetAppID failed (Stat=0x%08X)\n", (unsigned int)Status);
}

return Status;
} /* End of CFE_ES_CDS_ValidateAppID() */


/*******************************************************************
**
Expand Down
21 changes: 0 additions & 21 deletions fsw/cfe-core/src/es/cfe_es_cds.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,27 +111,6 @@ int32 CFE_ES_CDS_EarlyInit(void);
int32 CFE_ES_UpdateCDSRegistry(void);


/*****************************************************************************/
/**
** \brief Validates the Application ID associated with calling Application
**
** \par Description
** Validates Application ID of calling App. Validation
** consists of ensuring the AppID is between zero and
** #CFE_PLATFORM_ES_MAX_APPLICATIONS.
**
** \par Assumptions, External Events, and Notes:
** None
**
** \param[in, out] AppIdPtr Pointer to value that will hold AppID on return. *AppIdPtr is the AppID as obtained from #CFE_ES_GetAppID.
**
**
** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS
** \retval #CFE_ES_ERR_APPID \copydoc CFE_ES_ERR_APPID
**
******************************************************************************/
int32 CFE_ES_CDS_ValidateAppID(uint32 *AppIdPtr);


/*****************************************************************************/
/**
Expand Down
19 changes: 13 additions & 6 deletions fsw/cfe-core/src/es/cfe_es_erlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg)
uint32 ExceptionTaskID;
uint32 ResetType;
CFE_ES_LogEntryType_Enum_t LogType;
CFE_ES_AppRecord_t *AppRecPtr;

if (CFE_PSP_Exception_GetCount() == 0)
{
Expand Down Expand Up @@ -361,13 +362,19 @@ bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg)
/*
* 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)
if (Status == CFE_SUCCESS)
{
/*
* Log the Application reset
*/
ResetType = CFE_ES_APP_RESTART;
AppRecPtr = CFE_ES_LocateAppRecordByID(EsTaskInfo.AppId);
CFE_ES_LockSharedData(__func__,__LINE__);
if (CFE_ES_AppRecordIsMatch(AppRecPtr, EsTaskInfo.AppId) &&
AppRecPtr->StartParams.ExceptionAction == CFE_ES_ExceptionAction_RESTART_APP)
{
/*
* Log the Application reset
*/
ResetType = CFE_ES_APP_RESTART;
}
CFE_ES_UnlockSharedData(__func__,__LINE__);
}
}

Expand Down
215 changes: 215 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,221 @@ extern CFE_ES_Global_t CFE_ES_Global;
*/
extern CFE_ES_ResetData_t *CFE_ES_ResetDataPtr;

/**
* @brief Locate the app table entry correlating with a given app ID.
*
* This only returns a pointer to the table entry and does _not_
* otherwise check/validate the entry.
*
* @param[in] AppID the app ID to locate
* @return pointer to App Table entry for the given app ID
*/
extern CFE_ES_AppRecord_t* CFE_ES_LocateAppRecordByID(uint32 AppID);

/**
* @brief Locate the task table entry correlating with a given task ID.
*
* This only returns a pointer to the table entry and does _not_
* otherwise check/validate the entry.
*
* @param[in] TaskID the task ID to locate
* @return pointer to Task Table entry for the given task ID
*/
extern CFE_ES_TaskRecord_t* CFE_ES_LocateTaskRecordByID(uint32 TaskID);

/**
* @brief Check if an app record is in use or free/empty
*
* This routine checks if the App table entry is in use or if it is free
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] AppRecPtr pointer to app table entry
* @returns true if the entry is in use/configured, or false if it is free/empty
*/
static inline bool CFE_ES_AppRecordIsUsed(const CFE_ES_AppRecord_t *AppRecPtr)
{
return (AppRecPtr->AppState != CFE_ES_AppState_UNDEFINED);
}

/**
* @brief Get the ID value from an app table entry
*
* This routine converts the table entry back to an abstract ID.
*
* @param[in] AppRecPtr pointer to app table entry
* @returns AppID of entry
*/
static inline uint32 CFE_ES_AppRecordGetID(const CFE_ES_AppRecord_t *AppRecPtr)
{
/*
* The initial implementation does not store the ID in the entry;
* the ID is simply the zero-based index into the table.
*/
return (AppRecPtr - CFE_ES_Global.AppTable);
}

/**
* @brief Marks an app table entry as used (not free)
*
* This sets the internal field(s) within this entry, and marks
* it as being associated with the given app ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] AppRecPtr pointer to app table entry
* @param[in] AppID the app ID of this entry
*/
static inline void CFE_ES_AppRecordSetUsed(CFE_ES_AppRecord_t *AppRecPtr, uint32 AppID)
{
AppRecPtr->AppState = CFE_ES_AppState_EARLY_INIT;
}

/**
* @brief Set an app record table entry free (not used)
*
* This clears the internal field(s) within this entry, and allows the
* memory to be re-used in the future.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] AppRecPtr pointer to app table entry
*/
static inline void CFE_ES_AppRecordSetFree(CFE_ES_AppRecord_t *AppRecPtr)
{
AppRecPtr->AppState = CFE_ES_AppState_UNDEFINED;
}

/**
* @brief Check if an app record is a match for the given AppID
*
* This routine confirms that the previously-located record is valid
* and matches the expected app ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] AppRecPtr pointer to app table entry
* @param[in] AppID expected app ID
* @returns true if the entry matches the given app ID
*/
static inline bool CFE_ES_AppRecordIsMatch(const CFE_ES_AppRecord_t *AppRecPtr, uint32 AppID)
{
return (AppRecPtr != NULL && CFE_ES_AppRecordIsUsed(AppRecPtr) &&
CFE_ES_AppRecordGetID(AppRecPtr) == AppID);
}

/**
* @brief Get the ID value from an Task table entry
*
* This routine converts the table entry back to an abstract ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] TaskRecPtr pointer to Task table entry
* @returns TaskID of entry
*/
static inline uint32 CFE_ES_TaskRecordGetID(const CFE_ES_TaskRecord_t *TaskRecPtr)
{
return (TaskRecPtr->TaskId);
}

/**
* @brief Check if a Task record is in use or free/empty
*
* This routine checks if the Task table entry is in use or if it is free
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] TaskRecPtr pointer to task table entry
* @returns true if the entry is in use/configured, or false if it is free/empty
*/
static inline bool CFE_ES_TaskRecordIsUsed(const CFE_ES_TaskRecord_t *TaskRecPtr)
{
return (TaskRecPtr->RecordUsed);
}

/**
* @brief Marks an Task table entry as used (not free)
*
* This sets the internal field(s) within this entry, and marks
* it as being associated with the given Task ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] TaskRecPtr pointer to Task table entry
* @param[in] TaskID the Task ID of this entry
*/
static inline void CFE_ES_TaskRecordSetUsed(CFE_ES_TaskRecord_t *TaskRecPtr, uint32 TaskID)
{
TaskRecPtr->TaskId = TaskID;
TaskRecPtr->RecordUsed = true;
}

/**
* @brief Set a Task record table entry free
*
* This allows the table entry to be re-used by another Task.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] TaskRecPtr pointer to task table entry
* @returns true if the entry is in use/configured, or false if it is free/empty
*/
static inline void CFE_ES_TaskRecordSetFree(CFE_ES_TaskRecord_t *TaskRecPtr)
{
TaskRecPtr->TaskId = 0;
TaskRecPtr->RecordUsed = false;
}

/**
* @brief Check if a Task record is a match for the given TaskID
*
* This routine confirms that the previously-located record is valid
* and matches the expected Task ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] TaskRecPtr pointer to task table entry
* @returns true if the entry matches the given task ID
*/
static inline bool CFE_ES_TaskRecordIsMatch(const CFE_ES_TaskRecord_t *TaskRecPtr, uint32 TaskID)
{
return (TaskRecPtr != NULL && CFE_ES_TaskRecordIsUsed(TaskRecPtr) &&
CFE_ES_TaskRecordGetID(TaskRecPtr) == TaskID);
}

/**
* Locate and validate the app record for the calling context.
*
* Finds and validates the ES AppTable entry corresponding to the
* caller. This confirms that the fields within the table entry match the
* expected value(s), otherwise NULL is returned if no matching entry
* is found.
*
* The global data lock should be obtained prior to invoking this function.
*/
extern CFE_ES_AppRecord_t* CFE_ES_GetAppRecordByContext(void);

/**
* Locate and validate the task record for the calling context.
*
* Finds and validates the ES TaskTable entry corresponding to the
* caller. This confirms that the fields within the table entry match the
* expected value(s), otherwise NULL is returned if no matching entry
* is found.
*
* The global data lock should be obtained prior to invoking this function.
*/
extern CFE_ES_TaskRecord_t* CFE_ES_GetTaskRecordByContext(void);

/*
** Functions used to lock/unlock shared data
Expand Down
Loading

0 comments on commit 4d3c809

Please sign in to comment.