diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index 22cbbe1e5..3955160bd 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -256,7 +256,7 @@ int32 CFE_ES_ReloadApp(CFE_ES_ResourceID_t AppID, const char *AppFileName) { CFE_ES_SysLogWrite_Unsync("CFE_ES_ReloadApp: Reload Application %s Initiated. New filename = %s\n", CFE_ES_AppRecordGetName(AppRecPtr), AppFileName); - strncpy((char *)AppRecPtr->StartParams.FileName, AppFileName, OS_MAX_PATH_LEN); + strncpy(AppRecPtr->StartParams.BasicInfo.FileName, AppFileName, OS_MAX_PATH_LEN); AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; } else @@ -965,8 +965,10 @@ int32 CFE_ES_GetTaskName(char *TaskName, CFE_ES_ResourceID_t TaskId, uint32 Buff */ int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, CFE_ES_ResourceID_t AppId) { - int32 ReturnCode = CFE_SUCCESS; CFE_ES_AppRecord_t *AppRecPtr; + CFE_ES_TaskRecord_t *TaskRecPtr; + int32 Status; + uint32 i; if ( AppInfo == NULL ) { @@ -976,73 +978,233 @@ int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, CFE_ES_ResourceID_t AppId) memset(AppInfo, 0, sizeof(*AppInfo)); - /* - ** Get App Record - */ AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); - if ( AppRecPtr == NULL ) + + CFE_ES_LockSharedData(__func__,__LINE__); + + if ( !CFE_ES_AppRecordIsMatch(AppRecPtr, AppId) ) { - CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: App ID Invalid: %lu\n", + /* + * Log a message if called with an invalid ID. + */ + CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: App ID not active: %lu\n", CFE_ES_ResourceID_ToInteger(AppId)); - return CFE_ES_ERR_RESOURCEID_NOT_VALID; - } + + Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; + } + else + { + AppInfo->AppId = AppId; + AppInfo->Type = AppRecPtr->Type; + + CFE_ES_CopyModuleBasicInfo(&AppRecPtr->StartParams.BasicInfo, AppInfo); + CFE_ES_CopyModuleStatusInfo(&AppRecPtr->ModuleInfo, AppInfo); + + AppInfo->StackSize = AppRecPtr->StartParams.StackSize; + AppInfo->ExceptionAction = AppRecPtr->StartParams.ExceptionAction; + AppInfo->Priority = AppRecPtr->StartParams.Priority; + AppInfo->MainTaskId = AppRecPtr->MainTaskId; + + /* + ** Calculate the number of child tasks + */ + AppInfo->NumOfChildTasks = 0; + TaskRecPtr = CFE_ES_Global.TaskTable; + for (i=0; iAppId, AppId)) + { + if (CFE_ES_ResourceID_Equal(CFE_ES_TaskRecordGetID(TaskRecPtr), AppInfo->MainTaskId)) + { + /* This is the main task - capture its name and execution count */ + AppInfo->ExecutionCounter = TaskRecPtr->ExecutionCounter; + strncpy(AppInfo->MainTaskName, TaskRecPtr->TaskName, + sizeof(AppInfo->MainTaskName) - 1); + AppInfo->MainTaskName[sizeof(AppInfo->MainTaskName) - 1] = '\0'; + } + else + { + /* This is a child task, no extra info, just increment count */ + ++AppInfo->NumOfChildTasks; + } + } + ++TaskRecPtr; + } + + Status = CFE_SUCCESS; + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); /* - * Note - cannot check if the AppID is active here, - * as the table is not locked. The internal function - * should lock and check. - */ - ReturnCode = CFE_ES_GetAppInfoInternal(AppRecPtr, AppInfo); - if (ReturnCode != CFE_SUCCESS) + ** Get the address information from the OSAL + */ + if (Status == CFE_SUCCESS) { - CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: App ID Not Active: %lu\n", - CFE_ES_ResourceID_ToInteger(AppId)); + CFE_ES_CopyModuleAddressInfo(AppInfo->ModuleId, AppInfo); } - return(ReturnCode); + return Status; +} + +/* +** Function: CFE_ES_GetLibInfo - See API and header file for details +*/ +int32 CFE_ES_GetLibInfo(CFE_ES_AppInfo_t *LibInfo, CFE_ES_ResourceID_t LibId) +{ + int32 Status; + CFE_ES_LibRecord_t *LibRecPtr; + + if ( LibInfo == NULL ) + { + CFE_ES_WriteToSysLog("CFE_ES_GetLibInfo: Invalid Parameter ( Null Pointer )\n"); + return CFE_ES_ERR_BUFFER; + } + + LibRecPtr = CFE_ES_LocateLibRecordByID(LibId); + + CFE_ES_LockSharedData(__func__,__LINE__); + + if ( !CFE_ES_LibRecordIsMatch(LibRecPtr, LibId) ) + { + /* + * Log a message if called with an invalid ID. + */ + CFE_ES_SysLogWrite_Unsync("CFE_ES_GetLibInfo: Lib ID not active: %lu\n", + CFE_ES_ResourceID_ToInteger(LibId)); + + Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; + } + else + { + LibInfo->AppId = CFE_ES_LibRecordGetID(LibRecPtr);; + LibInfo->Type = CFE_ES_AppType_LIBRARY; + + CFE_ES_CopyModuleBasicInfo(&LibRecPtr->BasicInfo, LibInfo); + CFE_ES_CopyModuleStatusInfo(&LibRecPtr->ModuleInfo, LibInfo); + + Status = CFE_SUCCESS; + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); + + /* + ** Get the address information from the OSAL + */ + if (Status == CFE_SUCCESS) + { + CFE_ES_CopyModuleAddressInfo(LibInfo->ModuleId, LibInfo); + } + + return Status; +} + +/* +** Function: CFE_ES_GetModuleInfo - See API and header file for details +*/ +int32 CFE_ES_GetModuleInfo(CFE_ES_AppInfo_t *ModuleInfo, CFE_ES_ResourceID_t ResourceId) +{ + uint32 ResourceType; + int32 Status; + + ResourceType = CFE_ES_ResourceID_ToInteger(ResourceId); + ResourceType -= ResourceType & CFE_ES_RESOURCEID_MAX; + switch(ResourceType) + { + case CFE_ES_APPID_BASE: + Status = CFE_ES_GetAppInfo(ModuleInfo, ResourceId); + break; + case CFE_ES_LIBID_BASE: + Status = CFE_ES_GetLibInfo(ModuleInfo, ResourceId); + break; + default: + /* + * Log a message if called with an invalid ID. + */ + CFE_ES_WriteToSysLog("CFE_ES_GetModuleInfo: Resource ID not valid: %lu\n", + CFE_ES_ResourceID_ToInteger(ResourceId)); + Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; + break; + + } + + return(Status); -} /* End of CFE_ES_GetAppInfo() */ +} /* End of CFE_ES_GetModuleInfo() */ /* ** Function: CFE_ES_GetTaskInfo - See API and header file for details */ int32 CFE_ES_GetTaskInfo(CFE_ES_TaskInfo_t *TaskInfo, CFE_ES_ResourceID_t TaskId) { - CFE_ES_TaskRecord_t *TaskRecPtr; - int32 ReturnCode; + CFE_ES_TaskRecord_t *TaskRecPtr; + CFE_ES_AppRecord_t *AppRecPtr; + int32 Status; - if ( TaskInfo == NULL ) - { - CFE_ES_WriteToSysLog("CFE_ES_GetTaskInfo: Invalid Parameter ( Null Pointer )\n"); - return CFE_ES_ERR_BUFFER; - } + if ( TaskInfo == NULL ) + { + CFE_ES_WriteToSysLog("CFE_ES_GetTaskInfo: Invalid Parameter ( Null Pointer )\n"); + return CFE_ES_ERR_BUFFER; + } - memset(TaskInfo, 0, sizeof(*TaskInfo)); + memset(TaskInfo, 0, sizeof(*TaskInfo)); - /* - ** Get Task Record - */ - TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskId); - if ( TaskRecPtr == NULL ) - { - CFE_ES_WriteToSysLog("CFE_ES_GetTaskInfo: Task ID Not Valid: %lu\n", - CFE_ES_ResourceID_ToInteger(TaskId)); - return CFE_ES_ERR_RESOURCEID_NOT_VALID; - } + TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskId); - /* - * Note - cannot check if the TaskID is active here, - * as the table is not locked. The internal function - * should lock and check. - */ - ReturnCode = CFE_ES_GetTaskInfoInternal(TaskRecPtr, TaskInfo); - if (ReturnCode != CFE_SUCCESS) - { - CFE_ES_WriteToSysLog("CFE_ES_GetTaskInfo: Task ID Not Active: %lu\n", - CFE_ES_ResourceID_ToInteger(TaskId)); - } + CFE_ES_LockSharedData(__func__,__LINE__); - return(ReturnCode); + if ( !CFE_ES_TaskRecordIsMatch(TaskRecPtr, TaskId) ) + { + /* task ID is bad */ + Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; + CFE_ES_SysLogWrite_Unsync("CFE_ES_GetTaskInfo: Task ID Not Active: %lu\n", + CFE_ES_ResourceID_ToInteger(TaskId)); + } + else + { + + /* + ** Get the Application ID and Task Name + */ + TaskInfo->AppId = TaskRecPtr->AppId; + strncpy(TaskInfo->TaskName, + CFE_ES_TaskRecordGetName(TaskRecPtr), + sizeof(TaskInfo->TaskName)-1); + TaskInfo->TaskName[sizeof(TaskInfo->TaskName)-1] = '\0'; + + /* + ** Store away the Task ID ( for the QueryAllTasks Cmd ) + */ + TaskInfo->TaskId = CFE_ES_TaskRecordGetID(TaskRecPtr); + + /* + ** Get the Execution counter for the task + */ + TaskInfo->ExecutionCounter = TaskRecPtr->ExecutionCounter; + + /* + ** Get the Application Details + */ + AppRecPtr = CFE_ES_LocateAppRecordByID(TaskRecPtr->AppId); + if (CFE_ES_AppRecordIsMatch(AppRecPtr, TaskRecPtr->AppId)) + { + strncpy(TaskInfo->AppName, + CFE_ES_AppRecordGetName(AppRecPtr), + sizeof(TaskInfo->AppName)-1); + TaskInfo->AppName[sizeof(TaskInfo->AppName)-1] = '\0'; + Status = CFE_SUCCESS; + } + else + { + /* task ID was OK but parent app ID is bad */ + Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; + } + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); + + return(Status); } /* End of CFE_ES_GetTaskInfo() */ diff --git a/fsw/cfe-core/src/es/cfe_es_apps.c b/fsw/cfe-core/src/es/cfe_es_apps.c index ebd7916de..3800a898c 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.c +++ b/fsw/cfe-core/src/es/cfe_es_apps.c @@ -343,6 +343,236 @@ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens) } +/* +**------------------------------------------------------------------------------------- +** Name: CFE_ES_LoadModule +** +** Helper function to load + configure (but not start) a new app/lib module +** +** Loads the module file via OSAL and stores all relevant info in the table entry as necessary. +** +**------------------------------------------------------------------------------------- +*/ +int32 CFE_ES_LoadModule(const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus) +{ + osal_id_t ModuleId; + cpuaddr StartAddr; + int32 ReturnCode; + int32 StatusCode; + + StartAddr = 0; + ReturnCode = CFE_SUCCESS; + + if (LoadParams->FileName[0] != 0) + { + /* + ** Load the module via OSAL. + */ + StatusCode = OS_ModuleLoad ( &ModuleId, + LoadParams->Name, + LoadParams->FileName ); + + if (StatusCode != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("ES Startup: Could not load file:%s. EC = 0x%08X\n", + LoadParams->FileName, (unsigned int)StatusCode); + ModuleId = OS_OBJECT_ID_UNDEFINED; + ReturnCode = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } + } + else + { + ModuleId = OS_OBJECT_ID_UNDEFINED; + } + + /* + ** If the Load was OK, then lookup the address of the entry point + */ + if (ReturnCode == CFE_SUCCESS && LoadParams->EntryPoint[0] != 0) + { + StatusCode = OS_SymbolLookup(&StartAddr, LoadParams->EntryPoint); + if (StatusCode != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("ES Startup: Could not find symbol:%s. EC = 0x%08X\n", + LoadParams->EntryPoint, (unsigned int)StatusCode); + ReturnCode = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + } + } + + if ( ReturnCode == CFE_SUCCESS ) + { + /* store the data in the app record after successful load+lookup */ + LoadStatus->ModuleId = ModuleId; + LoadStatus->EntryAddress = StartAddr; + } + else if (OS_ObjectIdDefined(ModuleId)) + { + /* If the module had been successfully loaded, then unload it, + * so that it does not consume resources */ + StatusCode = OS_ModuleUnload(ModuleId); + if ( StatusCode != OS_SUCCESS ) /* There's not much we can do except notify */ + { + CFE_ES_WriteToSysLog("ES Startup: Failed to unload: %s. EC = 0x%08X\n", + LoadParams->Name, (unsigned int)StatusCode); + } + } + + return ReturnCode; +} + +/* +**------------------------------------------------------------------------------------- +** Name: CFE_ES_GetAppEntryPoint +** +** Helper function to act as the intermediate entry point of an app +** This is to support starting apps before having a fully completed entry in the +** global app table. The app startup will delay until the app creation is completed +** and verified, then the actual entry point will be determined. +** +**------------------------------------------------------------------------------------- +*/ +int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr) +{ + CFE_ES_AppRecord_t *AppRecPtr; + int32 ReturnCode; + int32 Timeout; + + /* + * Use the same timeout as was used for the startup script itself. + */ + ReturnCode = CFE_ES_ERR_APP_REGISTER; + Timeout = CFE_PLATFORM_ES_STARTUP_SCRIPT_TIMEOUT_MSEC; + + while(true) + { + OS_TaskDelay(CFE_PLATFORM_ES_STARTUP_SYNC_POLL_MSEC); + + CFE_ES_LockSharedData(__func__,__LINE__); + AppRecPtr = CFE_ES_GetAppRecordByContext(); + if (AppRecPtr != NULL) + { + AppRecPtr->AppState = CFE_ES_AppState_EARLY_INIT; + *FuncPtr = (osal_task_entry)AppRecPtr->ModuleInfo.EntryAddress; + ReturnCode = CFE_SUCCESS; + } + CFE_ES_UnlockSharedData(__func__,__LINE__); + + if (ReturnCode == CFE_SUCCESS || Timeout <= 0) + { + /* end of loop condition */ + break; + } + + Timeout -= CFE_PLATFORM_ES_STARTUP_SYNC_POLL_MSEC; + } + + return (ReturnCode); +} + +/* +**------------------------------------------------------------------------------------- +** Name: CFE_ES_AppEntryPoint +** +** Helper function to act as the intermediate entry point of an app +** This is to support starting apps before having a fully completed entry in the +** global app table. The app startup will delay until the app creation is completed +** and verified, then the actual entry point will be determined. +** +**------------------------------------------------------------------------------------- +*/ +void CFE_ES_AppEntryPoint(void) +{ + osal_task_entry RealEntryFunc; + + if (CFE_ES_GetAppEntryPoint(&RealEntryFunc) == CFE_SUCCESS && + RealEntryFunc != NULL) + { + (*RealEntryFunc)(); + } +} + +/* +**------------------------------------------------------------------------------------- +** Name: CFE_ES_StartMainTask +** +** Helper function to start (but not load) a new app/lib module +** +** Note that OSAL does not separate the action of creating and start a task, providing +** only OS_TaskCreate which does both. But there is a potential race condition if +** the real task code starts and calls e.g. CFE_ES_RegisterApp() or any other function +** that depends on having an AppID context, before its fully registered in the global app table. +** +** Therefore this calls a dedicated CFE_ES_AppEntryPoint which then will wait until +** the task is fully registered in the global, before calling the actual app entry point. +** +**------------------------------------------------------------------------------------- +*/ +int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_ResourceID_t RefAppId, CFE_ES_ResourceID_t *TaskIdPtr) +{ + CFE_ES_TaskRecord_t *TaskRecPtr; + osal_id_t OsalTaskId; + CFE_ES_ResourceID_t TaskId; + int32 StatusCode; + int32 ReturnCode; + + /* + ** Create the primary task for the newly loaded task + */ + StatusCode = OS_TaskCreate(&OsalTaskId, /* task id */ + StartParams->BasicInfo.Name, /* task name */ + CFE_ES_AppEntryPoint, /* task function pointer */ + NULL, /* stack pointer (allocate) */ + StartParams->StackSize, /* stack size */ + StartParams->Priority, /* task priority */ + OS_FP_ENABLED); /* task options */ + + CFE_ES_LockSharedData(__func__,__LINE__); + + if ( StatusCode == OS_SUCCESS ) + { + /* + * As this is a newly-created task, this shouldn't fail. + * The entry is not (yet) matching the task ID - it will be + * initialized here. + */ + TaskId = CFE_ES_ResourceID_FromOSAL(OsalTaskId); + TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskId); + if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) ) + { + CFE_ES_SysLogWrite_Unsync("ES Startup: Error: ES_TaskTable slot for ID %lx in use at task creation!\n", + OS_ObjectIdToInteger(OsalTaskId)); + } + + /* + * Clear any other/stale data that might be in the entry, + * and reset all fields to the correct value. + */ + memset(TaskRecPtr, 0, sizeof(*TaskRecPtr)); + + TaskRecPtr->AppId = RefAppId; + strncpy(TaskRecPtr->TaskName, StartParams->BasicInfo.Name, sizeof(TaskRecPtr->TaskName)-1); + CFE_ES_TaskRecordSetUsed(TaskRecPtr, TaskId); + + /* + ** Increment the registered Task count. + */ + CFE_ES_Global.RegisteredTasks++; + ReturnCode = CFE_SUCCESS; + *TaskIdPtr = TaskId; + } + else + { + CFE_ES_SysLogWrite_Unsync("ES Startup: AppCreate Error: TaskCreate %s Failed. EC = 0x%08X!\n", + StartParams->BasicInfo.Name,(unsigned int)StatusCode); + ReturnCode = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; + *TaskIdPtr = CFE_ES_RESOURCEID_UNDEFINED; + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); + + return ReturnCode; +} + /* **--------------------------------------------------------------------------------------- ** Name: ES_AppCreate @@ -356,19 +586,15 @@ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens) */ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, const char *FileName, - const void *EntryPointData, + const char *EntryPointName, const char *AppName, uint32 Priority, uint32 StackSize, uint32 ExceptionAction) { - cpuaddr StartAddr; - int32 ReturnCode; CFE_Status_t Status; - osal_id_t ModuleId; - osal_id_t MainTaskId; + CFE_ES_ResourceID_t MainTaskId; CFE_ES_AppRecord_t *AppRecPtr; - CFE_ES_TaskRecord_t *TaskRecPtr; CFE_ES_ResourceID_t PendingAppId; /* @@ -428,6 +654,31 @@ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, { /* Fully clear the entry, just in case of stale data */ memset(AppRecPtr, 0, sizeof(*AppRecPtr)); + + /* + * Fill out the parameters in the StartParams sub-structure + */ + AppRecPtr->Type = CFE_ES_AppType_EXTERNAL; + strncpy(AppRecPtr->StartParams.BasicInfo.Name, AppName, + sizeof(AppRecPtr->StartParams.BasicInfo.Name)-1); + strncpy(AppRecPtr->StartParams.BasicInfo.FileName, FileName, + sizeof(AppRecPtr->StartParams.BasicInfo.FileName)-1); + if (EntryPointName != NULL && strcmp(EntryPointName, "NULL") != 0) + { + strncpy(AppRecPtr->StartParams.BasicInfo.EntryPoint, EntryPointName, + sizeof(AppRecPtr->StartParams.BasicInfo.EntryPoint)-1); + } + + AppRecPtr->StartParams.StackSize = StackSize; + AppRecPtr->StartParams.ExceptionAction = ExceptionAction; + AppRecPtr->StartParams.Priority = Priority; + + /* + * Fill out the Task State info + */ + AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN; + AppRecPtr->ControlReq.AppTimerMsec = 0; + CFE_ES_AppRecordSetUsed(AppRecPtr, CFE_ES_RESOURCEID_RESERVED); CFE_ES_Global.LastAppId = PendingAppId; Status = CFE_SUCCESS; @@ -437,142 +688,63 @@ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, CFE_ES_UnlockSharedData(__func__,__LINE__); /* - ** If a slot was found, create the application - */ - if (Status == CFE_SUCCESS) + * If ID allocation was not successful, return now. + * A message regarding the issue should have already been logged + */ + if (Status != CFE_SUCCESS) { - /* - ** Load the module - */ - ReturnCode = OS_ModuleLoad ( &ModuleId, AppName, FileName ); - - /* - ** If the Load was OK, then lookup the address of the entry point - */ - if ( ReturnCode == OS_SUCCESS ) - { - ReturnCode = OS_SymbolLookup( &StartAddr, (const char*)EntryPointData ); - if ( ReturnCode != OS_SUCCESS ) - { - CFE_ES_WriteToSysLog("ES Startup: Could not find symbol:%s. EC = 0x%08X\n", - (const char*)EntryPointData, (unsigned int)ReturnCode); - - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_AppRecordSetFree(AppRecPtr); /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - - /* Unload the module from memory, so that it does not consume resources */ - ReturnCode = OS_ModuleUnload(ModuleId); - if ( ReturnCode != OS_SUCCESS ) /* There's not much we can do except notify */ - { - CFE_ES_WriteToSysLog("ES Startup: Failed to unload APP: %s. EC = 0x%08X\n", - AppName, (unsigned int)ReturnCode); - } - - return(CFE_ES_ERR_APP_CREATE); - } - } - else /* load not successful */ - { - CFE_ES_WriteToSysLog("ES Startup: Could not load cFE application file:%s. EC = 0x%08X\n", - FileName, (unsigned int)ReturnCode); - - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_AppRecordSetFree(AppRecPtr); /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - - return(CFE_ES_ERR_APP_CREATE); - } - - /* - ** If the EntryPoint symbol was found, then start creating the App - */ - CFE_ES_LockSharedData(__func__,__LINE__); - /* - ** Allocate and populate the ES_AppTable entry - */ - AppRecPtr->Type = CFE_ES_AppType_EXTERNAL; - - /* - ** Fill out the parameters in the AppStartParams sub-structure - */ - strncpy((char *)AppRecPtr->StartParams.Name, AppName, OS_MAX_API_NAME); - AppRecPtr->StartParams.Name[OS_MAX_API_NAME - 1] = '\0'; - - strncpy((char *)AppRecPtr->StartParams.EntryPoint, (const char *)EntryPointData, OS_MAX_API_NAME); - AppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; - strncpy((char *)AppRecPtr->StartParams.FileName, FileName, OS_MAX_PATH_LEN); - AppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - - AppRecPtr->StartParams.StackSize = StackSize; - - AppRecPtr->StartParams.StartAddress = StartAddr; - AppRecPtr->StartParams.ModuleId = ModuleId; - - AppRecPtr->StartParams.ExceptionAction = ExceptionAction; - AppRecPtr->StartParams.Priority = Priority; - - /* - ** Fill out the Task State info - */ - AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN; - AppRecPtr->ControlReq.AppTimerMsec = 0; - - /* - ** Create the primary task for the newly loaded task - */ - ReturnCode = OS_TaskCreate(&MainTaskId, /* task id */ - AppName, /* task name */ - (osal_task_entry)StartAddr, /* task function pointer */ - NULL, /* stack pointer */ - StackSize, /* stack size */ - Priority, /* task priority */ - OS_FP_ENABLED); /* task options */ - + return Status; + } - if(ReturnCode != OS_SUCCESS) - { - CFE_ES_SysLogWrite_Unsync("ES Startup: AppCreate Error: TaskCreate %s Failed. EC = 0x%08X!\n", - AppName,(unsigned int)ReturnCode); + /* + * Load the module based on StartParams configured above. + */ + Status = CFE_ES_LoadModule(&AppRecPtr->StartParams.BasicInfo, &AppRecPtr->ModuleInfo); - CFE_ES_AppRecordSetFree(AppRecPtr); /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); + /* + * If the Load was OK, then complete the initialization + */ + if (Status == CFE_SUCCESS) + { + Status = CFE_ES_StartAppTask(&AppRecPtr->StartParams, PendingAppId, &MainTaskId); + } + else + { + MainTaskId = CFE_ES_RESOURCEID_UNDEFINED; + } - Status = CFE_ES_ERR_APP_CREATE; - } - else - { + /* + * Finalize data in the app table entry, which must be done under lock. + * This transitions the entry from being RESERVED to the real ID. + */ + CFE_ES_LockSharedData(__func__,__LINE__); - /* - ** Record the ES_TaskTable entry - */ - AppRecPtr->MainTaskId = CFE_ES_ResourceID_FromOSAL(MainTaskId); - TaskRecPtr = CFE_ES_LocateTaskRecordByID(AppRecPtr->MainTaskId); + if ( Status == CFE_SUCCESS ) + { + /* + * important - set the ID to its proper value + * which turns this into a real/valid table entry + */ + AppRecPtr->MainTaskId = MainTaskId; + CFE_ES_AppRecordSetUsed(AppRecPtr, PendingAppId); - if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) ) - { - CFE_ES_SysLogWrite_Unsync("ES Startup: Error: ES_TaskTable slot in use at task creation!\n"); - } - CFE_ES_TaskRecordSetUsed(TaskRecPtr,AppRecPtr->MainTaskId); - TaskRecPtr->AppId = PendingAppId; - /* The main task name is the same as the app name */ - strncpy(TaskRecPtr->TaskName, AppName, - sizeof(TaskRecPtr->TaskName)-1); - TaskRecPtr->TaskName[sizeof(TaskRecPtr->TaskName)-1]='\0'; - CFE_ES_AppRecordSetUsed(AppRecPtr, PendingAppId); - CFE_ES_SysLogWrite_Unsync("ES Startup: %s loaded and created\n", AppName); - *ApplicationIdPtr = PendingAppId; - - /* - ** Increment the registered App and Registered External Task variables. - */ - CFE_ES_Global.RegisteredTasks++; - CFE_ES_Global.RegisteredExternalApps++; + /* + ** Increment the registered App counter. + */ + CFE_ES_Global.RegisteredExternalApps++; + } + else + { + /* + * Set the table entry back to free + */ + CFE_ES_AppRecordSetFree(AppRecPtr); + PendingAppId = CFE_ES_RESOURCEID_UNDEFINED; + } - CFE_ES_UnlockSharedData(__func__,__LINE__); + CFE_ES_UnlockSharedData(__func__,__LINE__); - } /* End If OS_TaskCreate */ - } + *ApplicationIdPtr = PendingAppId; return Status; @@ -587,15 +759,13 @@ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, */ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, const char *FileName, - const void *EntryPointData, + const char *EntryPointName, const char *LibName) { CFE_ES_LibraryEntryFuncPtr_t FunctionPointer; CFE_ES_LibRecord_t * LibSlotPtr; int32 Status; CFE_ES_ResourceID_t PendingLibId; - osal_id_t ModuleId; - bool IsModuleLoaded; /* * The FileName must not be NULL @@ -613,11 +783,8 @@ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, /* ** Allocate an ES_LibTable entry */ - IsModuleLoaded = false; FunctionPointer = NULL; - ModuleId = OS_OBJECT_ID_UNDEFINED; PendingLibId = CFE_ES_RESOURCEID_UNDEFINED; - Status = CFE_ES_ERR_LOAD_LIB; /* error that will be returned if no slots found */ /* ** Find an ES AppTable entry, and set to RESERVED @@ -663,7 +830,20 @@ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, { /* Fully clear the entry, just in case of stale data */ memset(LibSlotPtr, 0, sizeof(*LibSlotPtr)); - strcpy(LibSlotPtr->LibName, LibName); /* Size already checked */ + + /* + * Fill out the parameters in the AppStartParams sub-structure + */ + strncpy(LibSlotPtr->BasicInfo.Name, LibName, + sizeof(LibSlotPtr->BasicInfo.Name)-1); + strncpy(LibSlotPtr->BasicInfo.FileName, FileName, + sizeof(LibSlotPtr->BasicInfo.FileName)-1); + if (EntryPointName != NULL && strcmp(EntryPointName, "NULL") != 0) + { + strncpy(LibSlotPtr->BasicInfo.EntryPoint, EntryPointName, + sizeof(LibSlotPtr->BasicInfo.EntryPoint)-1); + } + CFE_ES_LibRecordSetUsed(LibSlotPtr, CFE_ES_RESOURCEID_RESERVED); CFE_ES_Global.LastLibId = PendingLibId; Status = CFE_SUCCESS; @@ -683,128 +863,51 @@ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, } /* - * ------------------- - * IMPORTANT: - * - * there is now a reserved entry in the global library table, - * which must be freed if something goes wrong hereafter. - * - * Avoid any inline "return" statements - all paths must proceed to - * the end of this function where the cleanup will be done. - * - * Record sufficient breadcrumbs along the way, such that proper - * cleanup can be done in case it is necessary. - * ------------------- - */ - - /* - * STAGE 2: - * Do the OS_ModuleLoad() if is called for (i.e. ModuleLoadFile is NOT null) + * Load the module based on StartParams configured above. */ - if (Status == CFE_SUCCESS && FileName != NULL) + Status = CFE_ES_LoadModule(&LibSlotPtr->BasicInfo, &LibSlotPtr->ModuleInfo); + if (Status == CFE_SUCCESS) { - Status = OS_ModuleLoad( &ModuleId, LibName, FileName ); - if (Status == OS_SUCCESS) - { - Status = CFE_SUCCESS; /* just in case CFE_SUCCESS is different than OS_SUCCESS */ - IsModuleLoaded = true; - } - else - { - /* load not successful. Note OS errors are better displayed as decimal integers. */ - CFE_ES_WriteToSysLog("ES Startup: Could not load cFE Shared Library: %d\n", (int)Status); - Status = CFE_ES_ERR_LOAD_LIB; /* convert OS error to CFE error code */ - } + FunctionPointer = (CFE_ES_LibraryEntryFuncPtr_t)LibSlotPtr->ModuleInfo.EntryAddress; + if (FunctionPointer != NULL) + { + Status = (*FunctionPointer)(PendingLibId); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("ES Startup: Load Shared Library Init Error = 0x%08x\n", + (unsigned int)Status); + } + } } /* - * STAGE 3: - * Figure out the Entry point / Initialization function. - * - * This depends on whether it is a dynamically loaded or a statically linked library, - * or it could be omitted altogether for libraries which do not require an init function. - * - * For dynamically loaded objects where FileName is non-NULL, the - * "EntryPointData" is a normal C string (const char *) with the name of the function. - * - * If the name of the function is the string "NULL" -- then treat this as no function - * needed and skip the lookup entirely (this is to support startup scripts where some - * string must be in the entry point field). + * Finalize data in the app table entry, which must be done under lock. + * This transitions the entry from being RESERVED to the real type, + * either MAIN_TASK (success) or returning to INVALID (failure). */ - if (Status == CFE_SUCCESS && EntryPointData != NULL) - { - if (strcmp(EntryPointData, "NULL") != 0) - { - /* - * If the entry point is explicitly set as NULL, - * this means the library has no init function - skip the lookup. - * Otherwise lookup the address of the entry point - */ - cpuaddr StartAddr; - - Status = OS_SymbolLookup( &StartAddr, EntryPointData ); - if (Status == OS_SUCCESS) - { - Status = CFE_SUCCESS; /* just in case CFE_SUCCESS is different than OS_SUCCESS */ - FunctionPointer = (CFE_ES_LibraryEntryFuncPtr_t)StartAddr; - } - else - { - /* could not find symbol. Note OS errors are better displayed as decimal integers */ - CFE_ES_WriteToSysLog("ES Startup: Could not find Library Init symbol:%s. EC = %d\n", - (const char *)EntryPointData, (int)Status); - Status = CFE_ES_ERR_LOAD_LIB; /* convert OS error to CFE error code */ - } - } - } + CFE_ES_LockSharedData(__func__,__LINE__); - /* - * STAGE 4: - * Call the Initialization function, if one was identified during the previous stage - */ - if (Status == CFE_SUCCESS && FunctionPointer != NULL) + if ( Status == CFE_SUCCESS ) { - /* - ** Call the library initialization routine + /* + * important - set the ID to its proper value + * which turns this into a real/valid table entry */ - Status = (*FunctionPointer)(*LibraryIdPtr); - if (Status != CFE_SUCCESS) - { - CFE_ES_WriteToSysLog("ES Startup: Load Shared Library Init Error = 0x%08x\n", (unsigned int)Status); - } - } + CFE_ES_LibRecordSetUsed(LibSlotPtr, PendingLibId); - /* - * LAST STAGE: - * Do final clean-up - * - * If fully successful, then increment the "RegisteredLibs" counter. - * Otherwise in case of an error, do clean up based on the breadcrumbs - */ - if(Status == CFE_SUCCESS) - { - /* Increment the counter, which needs to be done under lock */ - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_LibRecordSetUsed(LibSlotPtr, PendingLibId); - CFE_ES_Global.RegisteredLibs++; - CFE_ES_UnlockSharedData(__func__,__LINE__); + /* + * Increment the registered Lib counter. + */ + CFE_ES_Global.RegisteredLibs++; } else { - /* - * If the above code had loaded a module, then unload it - */ - if (IsModuleLoaded) - { - OS_ModuleUnload( ModuleId ); - } - - /* Release Slot - No need to lock as it is resetting just a single value */ - CFE_ES_LibRecordSetFree(LibSlotPtr); - - PendingLibId = CFE_ES_RESOURCEID_UNDEFINED; + CFE_ES_LibRecordSetFree(LibSlotPtr); + PendingLibId = CFE_ES_RESOURCEID_UNDEFINED; } + CFE_ES_UnlockSharedData(__func__,__LINE__); + *LibraryIdPtr = PendingLibId; return(Status); @@ -822,9 +925,11 @@ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, */ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) { - uint32 i; - CFE_ES_AppRecord_t *AppPtr; CFE_ES_AppTableScanState_t *State = (CFE_ES_AppTableScanState_t *)Arg; + uint32 i; + CFE_ES_AppRecord_t *AppPtr; + CFE_ES_ResourceID_t AppTimeoutList[CFE_PLATFORM_ES_MAX_APPLICATIONS]; + uint32 NumAppTimeouts; if (State->PendingAppStateChanges == 0) { @@ -845,6 +950,7 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) * reset the background scan timer to the full value, * and take a snapshot of the the command counter. */ + NumAppTimeouts = 0; State->BackgroundScanTimer = CFE_PLATFORM_ES_APP_SCAN_RATE; State->LastScanCommandCount = CFE_ES_TaskData.CommandCounter; State->PendingAppStateChanges = 0; @@ -888,14 +994,10 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) { AppPtr->ControlReq.AppTimerMsec = 0; - /* - * Temporarily unlock the table, and invoke the - * control request function for this app. - */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - CFE_ES_ProcessControlRequest(AppPtr); - CFE_ES_LockSharedData(__func__,__LINE__); - } /* end if */ + /* Add it to the list to be processed later */ + AppTimeoutList[NumAppTimeouts] = CFE_ES_AppRecordGetID(AppPtr); + ++NumAppTimeouts; + } } else if (AppPtr->AppState == CFE_ES_AppState_RUNNING && AppPtr->ControlReq.AppControlRequest > CFE_ES_RunStatus_APP_RUN) @@ -915,6 +1017,22 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) CFE_ES_UnlockSharedData(__func__,__LINE__); + + /* + * Now invoke the CFE_ES_ProcessControlRequest() routine for any app + * which has reached that point. + */ + for ( i = 0; i < NumAppTimeouts; i++ ) + { + /* + * Call CFE_ES_ProcessControlRequest() with a reference to + * the _copies_ of the app record details. (This avoids + * needing to access the global records outside of the lock). + */ + CFE_ES_ProcessControlRequest(AppTimeoutList[i]); + } + + /* * This state machine is considered active if there are any * pending app state changes. Returning "true" will cause this job @@ -932,180 +1050,228 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) ** Purpose: This function will perform the requested control action for an application. **--------------------------------------------------------------------------------------- */ -void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr) +void CFE_ES_ProcessControlRequest(CFE_ES_ResourceID_t AppId) { + CFE_ES_AppRecord_t *AppRecPtr; + uint32 PendingControlReq; + CFE_ES_AppStartParams_t OrigStartParams; + CFE_Status_t CleanupStatus; + CFE_Status_t StartupStatus; + CFE_ES_ResourceID_t NewAppId; + const char *ReqName; + char MessageDetail[48]; + uint16 EventID; + CFE_EVS_EventType_Enum_t EventType; + + /* Init/clear all local state variables */ + ReqName = NULL; + MessageDetail[0] = 0; + EventID = 0; + EventType = 0; + StartupStatus = CFE_SUCCESS; + PendingControlReq = 0; + NewAppId = CFE_ES_RESOURCEID_UNDEFINED; + AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); + memset(&OrigStartParams, 0, sizeof(OrigStartParams)); - int32 Status; - CFE_ES_AppStartParams_t AppStartParams; - CFE_ES_ResourceID_t NewAppId; - /* - ** First get a copy of the Apps Start Parameters - */ - memcpy(&AppStartParams, &(AppRecPtr->StartParams), sizeof(CFE_ES_AppStartParams_t)); + /* + * Take a local snapshot of the important app record data + * This way it becomes private and can be accessed without + * concerns about other threads/tasks, even after the global + * data records are eventually cleared. + */ + CFE_ES_LockSharedData(__func__,__LINE__); - /* - ** Now, find out what kind of Application control is being requested - */ - switch ( AppRecPtr->ControlReq.AppControlRequest ) - { + if (CFE_ES_AppRecordIsMatch(AppRecPtr, AppId)) + { + PendingControlReq = AppRecPtr->ControlReq.AppControlRequest; + OrigStartParams = AppRecPtr->StartParams; + } - case CFE_ES_RunStatus_APP_EXIT: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + CFE_ES_UnlockSharedData(__func__,__LINE__); - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_EXIT_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Exit Application %s Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_EXIT_APP_ERR_EID, CFE_EVS_EventType_ERROR, - "Exit Application %s Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + /* + * All control requests start by deleting the app/task and + * all associated resources. + * + * The reload/restart requests will start it again, and it gets + * a new appID. For other requests it just leaves it deleted. + * + * Note that Cleanup can fail for a variety of reasons, including + * situations where e.g. a task ID had become stale because the task + * already exited itself. In most cases these are minor errors and + * reflect problems with the consistency of the old app record. + * + * Even when this happens the cleanup should still do its best effort + * to release all relevant global data entries. So it should not + * prevent starting the new app, if a restart/reload is indicated. + */ + CleanupStatus = CFE_ES_CleanUpApp(AppId); - case CFE_ES_RunStatus_APP_ERROR: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + /* + * Attempt to restart the app if the request indicated to do so, + * regardless of the CleanupStatus. + */ + if ( PendingControlReq == CFE_ES_RunStatus_SYS_RESTART || + PendingControlReq == CFE_ES_RunStatus_SYS_RELOAD ) + { + StartupStatus = CFE_ES_AppCreate(&NewAppId, + OrigStartParams.BasicInfo.FileName, + OrigStartParams.BasicInfo.EntryPoint, + OrigStartParams.BasicInfo.Name, + OrigStartParams.Priority, + OrigStartParams.StackSize, + OrigStartParams.ExceptionAction); + } - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_ERREXIT_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Exit Application %s on Error Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_ERREXIT_APP_ERR_EID, CFE_EVS_EventType_ERROR, - "Exit Application %s on Error Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + /* + * Determine the event ID associated with the control request, + * which indicates the success/failure of the operation and + * any other relevant detail. + * + * Note that the specific event ID that gets generated is the only + * other difference between all these control request types. + */ + switch ( PendingControlReq ) + { + case CFE_ES_RunStatus_APP_EXIT: + ReqName = "Exit"; + if (CleanupStatus != CFE_SUCCESS) + { + /* error event for this request */ + EventID = CFE_ES_EXIT_APP_ERR_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_EXIT_APP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_DELETE: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + case CFE_ES_RunStatus_APP_ERROR: + ReqName = "Exit"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_ERREXIT_APP_ERR_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_ERREXIT_APP_INF_EID; + } + break; - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_STOP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Stop Application %s Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_STOP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Stop Application %s Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + case CFE_ES_RunStatus_SYS_DELETE: + ReqName = "Stop"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_STOP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_STOP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_RESTART: - /* - ** Kill the app - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + case CFE_ES_RunStatus_SYS_RESTART: + ReqName = "Restart"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RESTART_APP_ERR4_EID; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RESTART_APP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_RESTART_APP_INF_EID; + } + break; - if ( Status == CFE_SUCCESS ) - { - /* - ** And start it back up again - */ - Status = CFE_ES_AppCreate(&NewAppId, (char *)AppStartParams.FileName, - (char *)AppStartParams.EntryPoint, - (char *)AppStartParams.Name, - AppStartParams.Priority, - AppStartParams.StackSize, - AppStartParams.ExceptionAction); - - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Restart Application %s Completed.", AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Restart Application %s Failed: AppCreate Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - } - else - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_ERR4_EID, CFE_EVS_EventType_ERROR, - "Restart Application %s Failed: CleanUpApp Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - break; + case CFE_ES_RunStatus_SYS_RELOAD: + ReqName = "Reload"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RELOAD_APP_ERR4_EID; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RELOAD_APP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_RELOAD_APP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_RELOAD: - /* - ** Kill the app + /* + * These two cases below should never occur so they are always + * reported as errors, but the CFE_ES_CleanUpApp() should hopefully + * have fixed it either way. */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + case CFE_ES_RunStatus_SYS_EXCEPTION: + ReqName = "ES_ProcControlReq: Invalid State"; + EventID = CFE_ES_PCR_ERR1_EID; + snprintf(MessageDetail, sizeof(MessageDetail), "EXCEPTION"); + break; - if ( Status == CFE_SUCCESS ) - { - /* - ** And start it back up again - */ - Status = CFE_ES_AppCreate(&NewAppId, (char *)AppStartParams.FileName, - (char *)AppStartParams.EntryPoint, - (char *)AppStartParams.Name, - AppStartParams.Priority, - AppStartParams.StackSize, - AppStartParams.ExceptionAction); - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Reload Application %s Completed.", AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Reload Application %s Failed: AppCreate Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - } - else - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_ERR4_EID, CFE_EVS_EventType_ERROR, - "Reload Application %s Failed: CleanUpApp Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } + default: + ReqName = "ES_ProcControlReq: Unknown State"; + EventID = CFE_ES_PCR_ERR2_EID; + snprintf(MessageDetail, sizeof(MessageDetail), "( %lu )", + (unsigned long)PendingControlReq); + break; + } - break; - - case CFE_ES_RunStatus_SYS_EXCEPTION: - - CFE_EVS_SendEvent(CFE_ES_PCR_ERR1_EID, CFE_EVS_EventType_ERROR, - "ES_ProcControlReq: Invalid State (EXCEPTION) Application %s.", - AppStartParams.Name); - /* - * Bug #58: This message/event keeps repeating itself indefinitely. - * - * Change the request state to DELETE so the next scan will clean - * up this table entry. - */ - AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; - break; - - default: - - CFE_EVS_SendEvent(CFE_ES_PCR_ERR2_EID, CFE_EVS_EventType_ERROR, - "ES_ProcControlReq: Unknown State ( %d ) Application %s.", - (int)AppRecPtr->ControlReq.AppControlRequest, AppStartParams.Name); - - /* - * Bug #58: This message/event keeps repeating itself indefinitely. - * - * Change the request state to DELETE so the next scan will clean - * up this table entry. - */ - AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; - break; + if (EventID != 0 && ReqName != NULL) + { + if ( MessageDetail[0] != 0 ) + { + /* Detail message already set, assume it is an error event */ + EventType = CFE_EVS_EventType_ERROR; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* Make detail message for event containing startup error code */ + EventType = CFE_EVS_EventType_ERROR; + snprintf(MessageDetail, sizeof(MessageDetail), + "Failed: AppCreate Error 0x%08X.",(unsigned int)StartupStatus); + } + else if ( CleanupStatus != CFE_SUCCESS ) + { + /* Make detail message for event containing cleanup error code */ + EventType = CFE_EVS_EventType_ERROR; + snprintf(MessageDetail, sizeof(MessageDetail), + "Failed: CleanUpApp Error 0x%08X.",(unsigned int)CleanupStatus); + } + else if (CFE_ES_ResourceID_IsDefined(NewAppId)) + { + /* Record success message for event where app is restarted */ + EventType = CFE_EVS_EventType_INFORMATION; + snprintf(MessageDetail, sizeof(MessageDetail), "Completed, AppID=%lu", + CFE_ES_ResourceID_ToInteger(NewAppId)); + } + else + { + /* Record success message for event */ + EventType = CFE_EVS_EventType_INFORMATION; + snprintf(MessageDetail, sizeof(MessageDetail), "Completed."); + } - } + CFE_EVS_SendEvent(EventID, EventType, "%s Application %s %s", + ReqName, OrigStartParams.BasicInfo.Name, MessageDetail); + } } /* End Function */ @@ -1116,154 +1282,248 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr) ** Purpose: Delete an application by cleaning up all of it's resources. **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_CleanUpApp(CFE_ES_AppRecord_t *AppRecPtr) +int32 CFE_ES_CleanUpApp(CFE_ES_ResourceID_t AppId) { - uint32 i; - int32 Status; - CFE_ES_ResourceID_t MainTaskId; - CFE_ES_ResourceID_t CurrTaskId; - int32 ReturnCode = CFE_SUCCESS; - CFE_ES_TaskRecord_t *TaskRecPtr; - CFE_ES_MemPoolRecord_t *MemPoolRecPtr; - CFE_ES_MemHandle_t PoolId; - CFE_ES_ResourceID_t AppId; + uint32 i; + int32 Status; + int32 ReturnCode; + CFE_ES_ResourceID_t TaskList[OS_MAX_TASKS]; + CFE_ES_MemHandle_t PoolList[CFE_PLATFORM_ES_MAX_MEMORY_POOLS]; + osal_id_t ModuleId; + uint32 NumTasks; + uint32 NumPools; + CFE_ES_AppRecord_t *AppRecPtr; + CFE_ES_TaskRecord_t *TaskRecPtr; + CFE_ES_MemPoolRecord_t *MemPoolRecPtr; - /* - * Retrieve the abstract AppID for calling cleanup - * routine in _other_ modules. - */ - AppId = CFE_ES_AppRecordGetID(AppRecPtr); - /* - ** Call the Table Clean up function - */ -#ifndef EXCLUDE_CFE_TBL - CFE_TBL_CleanUpApp(AppId); -#endif - /* - ** Call the Software Bus clean up function - */ - CFE_SB_CleanUpApp(AppId); + NumTasks = 0; + NumPools = 0; + ModuleId = OS_OBJECT_ID_UNDEFINED; + ReturnCode = CFE_SUCCESS; - /* - ** Call the TIME Clean up function - */ - CFE_TIME_CleanUpApp(AppId); + AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); - /* - ** Call the EVS Clean up function - */ - Status = CFE_EVS_CleanUpApp(AppId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Call to CFE_EVS_CleanUpApp returned Error: 0x%08X\n",(unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } + /* + * Collect a list of resources previously owned by this app, which + * must be done while the global data is locked. + */ + CFE_ES_LockSharedData(__func__,__LINE__); + if (CFE_ES_AppRecordIsMatch(AppRecPtr, AppId)) + { + if (AppRecPtr->Type == CFE_ES_AppType_EXTERNAL) + { + CFE_ES_Global.RegisteredExternalApps--; - /* - ** Delete the ES Resources - */ - CFE_ES_LockSharedData(__func__,__LINE__); + /* + * Get the Module ID, if it was an external app + * + * (this will be OS_OBJECT_ID_UNDEFINED if it was not loaded dynamically) + */ + ModuleId = AppRecPtr->ModuleInfo.ModuleId; + } - /* - ** Get Main Task ID - */ - MainTaskId = AppRecPtr->MainTaskId; + /* + * Collect all tasks associated with this app + */ + TaskRecPtr = CFE_ES_Global.TaskTable; + for ( i = 0; i < OS_MAX_TASKS; i++ ) + { + if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) && + CFE_ES_ResourceID_Equal(TaskRecPtr->AppId, AppId)) + { + TaskList[NumTasks] = CFE_ES_TaskRecordGetID(TaskRecPtr); - /* - ** Delete any child tasks associated with this app - */ - TaskRecPtr = CFE_ES_Global.TaskTable; - for ( i = 0; i < OS_MAX_TASKS; i++ ) - { - /* delete only CHILD tasks - not the MainTaskId, which will be deleted later (below) */ - if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) && - CFE_ES_ResourceID_Equal(TaskRecPtr->AppId, AppId)) - { - CurrTaskId = CFE_ES_TaskRecordGetID(TaskRecPtr); - if (!CFE_ES_ResourceID_Equal(CurrTaskId, MainTaskId)) - { - Status = CFE_ES_CleanupTaskResources(CurrTaskId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(CurrTaskId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - } /* end if */ - } + /* Store the main task ID at index 0 (swap with whatever was there) */ + if (CFE_ES_ResourceID_Equal(TaskList[NumTasks], AppRecPtr->MainTaskId) && + NumTasks != 0) + { + TaskList[NumTasks] = TaskList[0]; + TaskList[0] = AppRecPtr->MainTaskId; + } - ++TaskRecPtr; - } /* end for */ + /* Mark record for removal */ + CFE_ES_TaskRecordSetUsed(TaskRecPtr, CFE_ES_RESOURCEID_RESERVED); + ++NumTasks; + } - /* - ** Delete all of the OS resources, close files, and delete the main task - */ - Status = CFE_ES_CleanupTaskResources(MainTaskId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(MainTaskId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; + ++TaskRecPtr; + } /* end for */ - } + CFE_ES_Global.RegisteredTasks -= NumTasks; - /* - ** Remove the app from the AppTable - */ - if ( AppRecPtr->Type == CFE_ES_AppType_EXTERNAL ) - { - /* - ** Unload the module only if it is an external app - */ - Status = OS_ModuleUnload(AppRecPtr->StartParams.ModuleId); - if ( Status == OS_ERROR ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: Module (ID:0x%08lX) Unload failed. RC=0x%08X\n", - OS_ObjectIdToInteger(AppRecPtr->StartParams.ModuleId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - CFE_ES_Global.RegisteredExternalApps--; - } + /* + * Collect memory pools associated with this app + */ + MemPoolRecPtr = CFE_ES_Global.MemPoolTable; + for ( i = 0; i < CFE_PLATFORM_ES_MAX_MEMORY_POOLS; i++ ) + { + if ( CFE_ES_MemPoolRecordIsUsed(MemPoolRecPtr) && + CFE_ES_ResourceID_Equal(MemPoolRecPtr->OwnerAppID, AppId)) + { + PoolList[NumPools] = CFE_ES_MemPoolRecordGetID(MemPoolRecPtr); + ++NumPools; + } - CFE_ES_AppRecordSetFree(AppRecPtr); + ++MemPoolRecPtr; + } /* end for */ - /* - ** Delete any memory pools associated with this app - */ - MemPoolRecPtr = CFE_ES_Global.MemPoolTable; - for ( i = 0; i < CFE_PLATFORM_ES_MAX_MEMORY_POOLS; i++ ) - { - if ( CFE_ES_MemPoolRecordIsUsed(MemPoolRecPtr) && - CFE_ES_ResourceID_Equal(MemPoolRecPtr->OwnerAppID, AppId)) - { - PoolId = CFE_ES_MemPoolRecordGetID(MemPoolRecPtr); + /* + * Set the record to RESERVED. + * + * This prevents reallocation of this slot while the remainder + * of resources are freed. + */ + CFE_ES_AppRecordSetUsed(AppRecPtr, CFE_ES_RESOURCEID_RESERVED); - /* - * This needs to release the lock first because - * CFE_ES_PoolDelete acquires the lock. - */ - CFE_ES_UnlockSharedData(__func__, __LINE__); - Status = CFE_ES_PoolDelete(PoolId); - CFE_ES_LockSharedData(__func__, __LINE__); - - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_MemPoolCleanupApp: delete pool %lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(PoolId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - } + ReturnCode = CFE_SUCCESS; + } + else + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: AppID %lu is not valid for deletion\n", + CFE_ES_ResourceID_ToInteger(AppId)); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } - ++MemPoolRecPtr; - } /* end for */ + CFE_ES_UnlockSharedData(__func__, __LINE__); + if (ReturnCode != CFE_SUCCESS) + { + return ReturnCode; + } - CFE_ES_UnlockSharedData(__func__,__LINE__); + /* + * Now actually delete all the resources associated with the task. + * + * Most of this involves calling into other subsystems, so it is + * done while the ES global data is UNLOCKED to avoid holding more + * than one lock at a time. + */ - return(ReturnCode); + /* + ** Call the Table Clean up function + */ + CFE_TBL_CleanUpApp(AppId); + + /* + ** Call the Software Bus clean up function + */ + CFE_SB_CleanUpApp(AppId); + + /* + ** Call the TIME Clean up function + */ + CFE_TIME_CleanUpApp(AppId); + + /* + ** Call the EVS Clean up function + */ + Status = CFE_EVS_CleanUpApp(AppId); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Call to CFE_EVS_CleanUpApp returned Error: 0x%08X\n",(unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + + /* + * Delete all tasks. + * + * Note that the main task is always positioned at index 0 in this list. + * + * This iterates the list in reverse order, such that the child + * tasks are deleted first (in any order) and main task is deleted last. + */ + i = NumTasks; + while (i > 0) + { + --i; + Status = CFE_ES_CleanupTaskResources(TaskList[i]); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", + CFE_ES_ResourceID_ToInteger(TaskList[i]), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + * Delete all mem pools. + */ + for (i=0; i < NumPools; ++i) + { + Status = CFE_ES_PoolDelete(PoolList[i]); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_MemPoolCleanupApp: delete pool %lu returned Error: 0x%08X\n", + CFE_ES_ResourceID_ToInteger(PoolList[i]), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + ** Unload the module, if applicable + */ + if ( OS_ObjectIdDefined(ModuleId) ) + { + /* + ** Unload the module only if it is an external app + */ + Status = OS_ModuleUnload(ModuleId); + if ( Status != OS_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Module (ID:0x%08lX) Unload failed. RC=0x%08X\n", + OS_ObjectIdToInteger(ModuleId), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + * Finally, re-acquire the ES lock and set all + * table entries free for re-use. + */ + CFE_ES_LockSharedData(__func__,__LINE__); + +#ifdef jphfix + /* + * This just confirms that the main task ID associated with this app was properly + * located and deleted during the previous process. + * + * If not, display a log message about it - this indicates table corruption or a + * bug with the record keeping. + */ + if (NumTasks == 0 || !CFE_ES_ResourceID_Equal(TaskList[0], AppRecPtr->MainTaskId)) + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: MainTask ID:%lu not found when deleting AppID %lu\n", + CFE_ES_ResourceID_ToInteger(AppRecPtr->MainTaskId), CFE_ES_ResourceID_ToInteger(AppId)); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } +#endif + + /* + * Free all task records. + */ + for (i=0; i < NumTasks; ++i) + { + TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskList[i]); + if (CFE_ES_TaskRecordIsMatch(TaskRecPtr, CFE_ES_RESOURCEID_RESERVED)) + { + CFE_ES_TaskRecordSetFree(TaskRecPtr); + } + } + + /* + * Now finally delete the record and allow re-use of the slot. + */ + if (CFE_ES_AppRecordIsMatch(AppRecPtr, CFE_ES_RESOURCEID_RESERVED)) + { + CFE_ES_AppRecordSetFree(AppRecPtr); + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); + + return(ReturnCode); } /* end function */ @@ -1387,13 +1647,14 @@ void CFE_ES_CleanupObjectCallback(osal_id_t ObjectId, void *arg) ** Name: CFE_ES_CleanupTaskResources ** ** Purpose: Clean up the OS resources associated with an individual Task +** Note: This is called when the ES global is UNLOCKED - so it should not touch +** any ES global data structures. It should only clean up at the OSAL level. **--------------------------------------------------------------------------------------- */ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) { CFE_ES_CleanupState_t CleanState; int32 Result; - CFE_ES_TaskRecord_t *TaskRecPtr; osal_id_t OsalId; /* Get the Task ID for calling OSAL APIs (convert type) */ @@ -1424,16 +1685,15 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) CleanState.DeletedObjects = 0; } - /* - * Locate the ES Task table entry - */ - TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskId); - /* ** Delete the task itself + ** + ** Note, if the task self exited, then the ID becomes invalid. + ** In this case the OS_ERR_INVALID_ID status is returned, but + ** that is OK, there is nothing else needed to do. */ Result = OS_TaskDelete(OsalId); - if (Result == OS_SUCCESS) + if (Result == OS_SUCCESS || Result == OS_ERR_INVALID_ID) { Result = CleanState.OverallStatus; if (Result == CFE_SUCCESS && CleanState.FoundObjects > 0) @@ -1447,22 +1707,13 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) Result = CFE_ES_TASK_DELETE_ERR; } - /* - ** Invalidate ES Task Table entry - */ - if (TaskRecPtr != NULL) - { - CFE_ES_TaskRecordSetFree(TaskRecPtr); - } - - CFE_ES_Global.RegisteredTasks--; return(Result); } /* **--------------------------------------------------------------------------------------- -** Name: CFE_ES_GetAppInfoInternal +** Name: CFE_ES_CopyModuleBasicInfo ** ** Purpose: Populate the cFE_ES_AppInfo structure with the data for an app. ** @@ -1470,181 +1721,71 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) ** to check the return code and log any relevant errors based on the context. **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_GetAppInfoInternal(CFE_ES_AppRecord_t *AppRecPtr, CFE_ES_AppInfo_t *AppInfoPtr ) +void CFE_ES_CopyModuleBasicInfo(const CFE_ES_ModuleLoadParams_t *ParamsPtr, CFE_ES_AppInfo_t *AppInfoPtr) { - int32 Status; - int32 ReturnCode; - OS_module_prop_t ModuleInfo; - uint32 i; - CFE_ES_TaskRecord_t *TaskRecPtr; - CFE_ES_ResourceID_t AppId; - - CFE_ES_LockSharedData(__func__,__LINE__); - - if ( !CFE_ES_AppRecordIsUsed(AppRecPtr) ) - { - Status = CFE_ES_ERR_RESOURCEID_NOT_VALID; - } - else - { - Status = CFE_SUCCESS; - - AppId = CFE_ES_AppRecordGetID(AppRecPtr); - AppInfoPtr->AppId = AppId; - AppInfoPtr->Type = AppRecPtr->Type; - strncpy(AppInfoPtr->Name, - CFE_ES_AppRecordGetName(AppRecPtr), - sizeof(AppInfoPtr->Name)-1); - AppInfoPtr->Name[sizeof(AppInfoPtr->Name)-1] = '\0'; - - strncpy((char *)AppInfoPtr->EntryPoint, - AppRecPtr->StartParams.EntryPoint, - sizeof(AppInfoPtr->EntryPoint) - 1); - AppInfoPtr->EntryPoint[sizeof(AppInfoPtr->EntryPoint) - 1] = '\0'; - - strncpy((char *)AppInfoPtr->FileName, (char *)AppRecPtr->StartParams.FileName, - sizeof(AppInfoPtr->FileName) - 1); - AppInfoPtr->FileName[sizeof(AppInfoPtr->FileName) - 1] = '\0'; - - AppInfoPtr->ModuleId = AppRecPtr->StartParams.ModuleId; - AppInfoPtr->StackSize = AppRecPtr->StartParams.StackSize; - CFE_SB_SET_MEMADDR(AppInfoPtr->StartAddress, AppRecPtr->StartParams.StartAddress); - AppInfoPtr->ExceptionAction = AppRecPtr->StartParams.ExceptionAction; - AppInfoPtr->Priority = AppRecPtr->StartParams.Priority; - - AppInfoPtr->MainTaskId = AppRecPtr->MainTaskId; - - /* - ** Calculate the number of child tasks - */ - AppInfoPtr->NumOfChildTasks = 0; - TaskRecPtr = CFE_ES_Global.TaskTable; - for (i=0; iAppId, AppId) && - !CFE_ES_ResourceID_Equal(CFE_ES_TaskRecordGetID(TaskRecPtr), AppInfoPtr->MainTaskId) ) - { - AppInfoPtr->NumOfChildTasks++; - } - ++TaskRecPtr; - } - - /* - ** Get the execution counter for the main task - */ - TaskRecPtr = CFE_ES_LocateTaskRecordByID(AppInfoPtr->MainTaskId); - if (CFE_ES_TaskRecordIsMatch(TaskRecPtr,AppInfoPtr->MainTaskId)) - { - AppInfoPtr->ExecutionCounter = TaskRecPtr->ExecutionCounter; - strncpy(AppInfoPtr->MainTaskName, TaskRecPtr->TaskName, - sizeof(AppInfoPtr->MainTaskName) - 1); - AppInfoPtr->MainTaskName[sizeof(AppInfoPtr->MainTaskName) - 1] = '\0'; - } + strncpy(AppInfoPtr->Name, ParamsPtr->Name, + sizeof(AppInfoPtr->Name)-1); + AppInfoPtr->Name[sizeof(AppInfoPtr->Name)-1] = '\0'; - /* - ** Get the address information from the OSAL - */ - ReturnCode = OS_ModuleInfo ( AppInfoPtr->ModuleId, &ModuleInfo ); - if ( ReturnCode == OS_SUCCESS ) - { - AppInfoPtr->AddressesAreValid = - (sizeof(ModuleInfo.addr.code_address) <= sizeof(AppInfoPtr->CodeAddress)) && - ModuleInfo.addr.valid; - CFE_SB_SET_MEMADDR(AppInfoPtr->CodeAddress, ModuleInfo.addr.code_address); - CFE_SB_SET_MEMADDR(AppInfoPtr->CodeSize, ModuleInfo.addr.code_size); - CFE_SB_SET_MEMADDR(AppInfoPtr->DataAddress, ModuleInfo.addr.data_address); - CFE_SB_SET_MEMADDR(AppInfoPtr->DataSize, ModuleInfo.addr.data_size); - CFE_SB_SET_MEMADDR(AppInfoPtr->BSSAddress, ModuleInfo.addr.bss_address); - CFE_SB_SET_MEMADDR(AppInfoPtr->BSSSize, ModuleInfo.addr.bss_size); - } - else - { - AppInfoPtr->AddressesAreValid = false; - AppInfoPtr->CodeAddress = 0; - AppInfoPtr->CodeSize = 0; - AppInfoPtr->DataAddress = 0; - AppInfoPtr->DataSize = 0; - AppInfoPtr->BSSAddress = 0; - AppInfoPtr->BSSSize = 0; - } - - } + strncpy(AppInfoPtr->EntryPoint, ParamsPtr->EntryPoint, + sizeof(AppInfoPtr->EntryPoint) - 1); + AppInfoPtr->EntryPoint[sizeof(AppInfoPtr->EntryPoint) - 1] = '\0'; - CFE_ES_UnlockSharedData(__func__,__LINE__); - - return Status; - -} /* end function */ + strncpy(AppInfoPtr->FileName, ParamsPtr->FileName, + sizeof(AppInfoPtr->FileName) - 1); + AppInfoPtr->FileName[sizeof(AppInfoPtr->FileName) - 1] = '\0'; +} /* **--------------------------------------------------------------------------------------- -** Name: CFE_ES_GetAppInfoInternal +** Name: CFE_ES_CopyModuleStatusInfo ** -** Purpose: Populate the cFE_ES_TaskInfo structure with the data for a task. +** Purpose: Populate the cFE_ES_AppInfo structure with the data for an app. ** ** This internal function does not log any errors/events. The caller is expected ** to check the return code and log any relevant errors based on the context. **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_GetTaskInfoInternal(CFE_ES_TaskRecord_t *TaskRecPtr, CFE_ES_TaskInfo_t *TaskInfoPtr) +void CFE_ES_CopyModuleStatusInfo(const CFE_ES_ModuleLoadStatus_t *StatusPtr, CFE_ES_AppInfo_t *AppInfoPtr) { - CFE_ES_AppRecord_t *AppRecPtr; - int32 ReturnCode; - - CFE_ES_LockSharedData(__func__,__LINE__); - - if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) ) - { - - /* - ** Get the Application ID and Task Name - */ - TaskInfoPtr->AppId = TaskRecPtr->AppId; - strncpy(TaskInfoPtr->TaskName, - CFE_ES_TaskRecordGetName(TaskRecPtr), - sizeof(TaskInfoPtr->TaskName)-1); - TaskInfoPtr->TaskName[sizeof(TaskInfoPtr->TaskName)-1] = '\0'; - - /* - ** Store away the Task ID ( for the QueryAllTasks Cmd ) - */ - TaskInfoPtr->TaskId = CFE_ES_TaskRecordGetID(TaskRecPtr); - - /* - ** Get the Execution counter for the task - */ - TaskInfoPtr->ExecutionCounter = TaskRecPtr->ExecutionCounter; - - /* - ** Get the Application Details - */ - AppRecPtr = CFE_ES_LocateAppRecordByID(TaskRecPtr->AppId); - if (CFE_ES_AppRecordIsMatch(AppRecPtr, TaskRecPtr->AppId)) - { - strncpy(TaskInfoPtr->AppName, - CFE_ES_AppRecordGetName(AppRecPtr), - sizeof(TaskInfoPtr->AppName)-1); - TaskInfoPtr->AppName[sizeof(TaskInfoPtr->AppName)-1] = '\0'; - ReturnCode = CFE_SUCCESS; - } - else - { - /* task ID was OK but parent app ID is bad */ - ReturnCode = CFE_ES_ERR_RESOURCEID_NOT_VALID; - } - } - else - { - /* task ID is bad */ - ReturnCode = CFE_ES_ERR_RESOURCEID_NOT_VALID; - } - - CFE_ES_UnlockSharedData(__func__,__LINE__); + AppInfoPtr->ModuleId = StatusPtr->ModuleId; + CFE_SB_SET_MEMADDR(AppInfoPtr->StartAddress, StatusPtr->EntryAddress); +} - return(ReturnCode); +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_CopyModuleAddressInfo +** +** Purpose: Populate the cFE_ES_AppInfo structure with the data for an app. +** +** This internal function does not log any errors/events. The caller is expected +** to check the return code and log any relevant errors based on the context. +**--------------------------------------------------------------------------------------- +*/ +void CFE_ES_CopyModuleAddressInfo(osal_id_t ModuleId, CFE_ES_AppInfo_t *AppInfoPtr) +{ + OS_module_prop_t ModuleInfo; + int32 ReturnCode; -} /* End of CFE_ES_GetTaskInfoInternal() */ + ReturnCode = OS_ModuleInfo ( ModuleId, &ModuleInfo ); + if ( ReturnCode == OS_SUCCESS ) + { + AppInfoPtr->AddressesAreValid = + (sizeof(ModuleInfo.addr.code_address) <= sizeof(AppInfoPtr->CodeAddress)) && + ModuleInfo.addr.valid; + } + else + { + AppInfoPtr->AddressesAreValid = false; + memset(&ModuleInfo, 0, sizeof(ModuleInfo)); + } + CFE_SB_SET_MEMADDR(AppInfoPtr->CodeAddress, ModuleInfo.addr.code_address); + CFE_SB_SET_MEMADDR(AppInfoPtr->CodeSize, ModuleInfo.addr.code_size); + CFE_SB_SET_MEMADDR(AppInfoPtr->DataAddress, ModuleInfo.addr.data_address); + CFE_SB_SET_MEMADDR(AppInfoPtr->DataSize, ModuleInfo.addr.data_size); + CFE_SB_SET_MEMADDR(AppInfoPtr->BSSAddress, ModuleInfo.addr.bss_address); + CFE_SB_SET_MEMADDR(AppInfoPtr->BSSSize, ModuleInfo.addr.bss_size); +} diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index fa29774b4..e9aaa7562 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -65,21 +65,61 @@ typedef struct /* -** CFE_ES_AppStartParams_t is a structure of information used when an application is -** created in the system. It is stored in the cFE ES App Table +** CFE_ES_ModuleLoadParams_t contains the information used when a module +** (library or app) load request initially processed in the system. It captures +** the fundamental information - the name, the file to load, its entry point. +** It contains information directly provided by the user, not runtime status or +** other derived information. +** +** This information should remain fairly constant after initial allocation, even +** if the application is restarted for some reason. The major exception is the +** ReloadApp command, which can change the FileName. +*/ +typedef struct +{ + char Name[OS_MAX_API_NAME]; + char EntryPoint[OS_MAX_API_NAME]; + char FileName[OS_MAX_PATH_LEN]; + +} CFE_ES_ModuleLoadParams_t; + +/* +** CFE_ES_ModuleLoadStatus_t is a structure of information used when a module +** (library or app) is actually loaded in the system. It captures the +** runtime information - the module ID and starting address. +** +** This information may change if the module is reloaded. */ typedef struct { - char Name[OS_MAX_API_NAME]; - char EntryPoint[OS_MAX_API_NAME]; - char FileName[OS_MAX_PATH_LEN]; + cpuaddr EntryAddress; + osal_id_t ModuleId; + +} CFE_ES_ModuleLoadStatus_t; - uint32 StackSize; - cpuaddr StartAddress; - osal_id_t ModuleId; - uint16 ExceptionAction; - uint16 Priority; + +/* +** CFE_ES_AppStartParams_t is a structure of information used when an application is +** created in the system. +** +** This is an extension of the CFE_ES_ModuleLoadParams_t which adds information +** about the task stack size and priority. It is only used for apps, as libraries +** do not have a task associated. +*/ +typedef struct +{ + /* + * Basic (static) information about the module + */ + CFE_ES_ModuleLoadParams_t BasicInfo; + + /* + * Extra information the pertains to applications only, not libraries. + */ + cpusize StackSize; + uint16 Priority; + CFE_ES_ExceptionAction_Enum_t ExceptionAction; } CFE_ES_AppStartParams_t; @@ -89,12 +129,13 @@ typedef struct */ typedef struct { - CFE_ES_ResourceID_t AppId; /* The actual AppID of this entry, or undefined */ - 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 */ - CFE_ES_ResourceID_t MainTaskId; /* The Application's Main Task ID */ + CFE_ES_ResourceID_t AppId; /* The actual AppID of this entry, or undefined */ + CFE_ES_AppState_Enum_t AppState; /* Is the app running, or stopped, or waiting? */ + CFE_ES_AppType_Enum_t Type; /* The type of App: CORE or EXTERNAL */ + CFE_ES_AppStartParams_t StartParams; /* The start parameters for an App */ + CFE_ES_ModuleLoadStatus_t ModuleInfo; /* Runtime module information */ + CFE_ES_ControlReq_t ControlReq; /* The Control Request Record for External cFE Apps */ + CFE_ES_ResourceID_t MainTaskId; /* The Application's Main Task ID */ } CFE_ES_AppRecord_t; @@ -119,8 +160,9 @@ typedef struct */ typedef struct { - CFE_ES_ResourceID_t LibId; /* The actual LibID of this entry, or undefined */ - char LibName[OS_MAX_API_NAME]; /* Library Name */ + CFE_ES_ResourceID_t LibId; /* The actual LibID of this entry, or undefined */ + CFE_ES_ModuleLoadParams_t BasicInfo; /* Basic (static) information about the module */ + CFE_ES_ModuleLoadStatus_t ModuleInfo; /* Runtime information about the module */ } CFE_ES_LibRecord_t; /* @@ -151,13 +193,39 @@ void CFE_ES_StartApplications(uint32 ResetType, const char *StartFilePath ); */ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens); +/* +** Internal function to load a module (app or library) +** This only loads the code and looks up relevent runtime information. +** It does not start any tasks. +*/ +int32 CFE_ES_LoadModule(const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus); + +/* +** Internal function to determine the entry point of an app. +** If the app isn't fully registered in the global app table, +** then this delays until the app is completely configured and the entry point is +** confirmed to be valid. +*/ +int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr); + +/* +** Intermediate entry point of an app. Determines the actual +** entry point from the global data structures. +*/ +void CFE_ES_AppEntryPoint(void); + +/* +** Internal function to start the main task of an app. +*/ +int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_ResourceID_t RefAppId, CFE_ES_ResourceID_t *TaskIdPtr); + /* ** Internal function to create/start a new cFE app ** based on the parameters passed in */ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, const char *FileName, - const void *EntryPointData, + const char *EntryPointName, const char *AppName, uint32 Priority, uint32 StackSize, @@ -167,7 +235,7 @@ int32 CFE_ES_AppCreate(CFE_ES_ResourceID_t *ApplicationIdPtr, */ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, const char *FileName, - const void *EntryPointData, + const char *EntryPointName, const char *LibName); /* @@ -199,30 +267,45 @@ bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg); /* ** Perform the requested control action for an application */ -void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr); +void CFE_ES_ProcessControlRequest(CFE_ES_ResourceID_t AppId); /* ** Clean up all app resources and delete it */ -int32 CFE_ES_CleanUpApp(CFE_ES_AppRecord_t *AppRecPtr); +int32 CFE_ES_CleanUpApp(CFE_ES_ResourceID_t AppId); /* ** Clean up all Task resources and detete the task */ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId); + /* -** Populate the cFE_ES_AppInfo structure with the data for an app -** This is an internal function for use in ES. -** The newer external API is : CFE_ES_GetAppInfo +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_CopyModuleBasicInfo +** +** Purpose: Populate the cFE_ES_AppInfo structure from the CFE_ES_ModuleLoadParams_t data +**--------------------------------------------------------------------------------------- */ -int32 CFE_ES_GetAppInfoInternal(CFE_ES_AppRecord_t *AppRecPtr, CFE_ES_AppInfo_t *AppInfoPtr ); +void CFE_ES_CopyModuleBasicInfo(const CFE_ES_ModuleLoadParams_t *ParamsPtr, 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 ); +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_CopyModuleStatusInfo +** +** Purpose: Populate the cFE_ES_AppInfo structure from the CFE_ES_ModuleLoadStatus_t data +**--------------------------------------------------------------------------------------- +*/ +void CFE_ES_CopyModuleStatusInfo(const CFE_ES_ModuleLoadStatus_t *StatusPtr, CFE_ES_AppInfo_t *AppInfoPtr); + +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_CopyModuleAddressInfo +** +** Purpose: Populate the cFE_ES_AppInfo structure with address information from OSAL. +**--------------------------------------------------------------------------------------- +*/ +void CFE_ES_CopyModuleAddressInfo(osal_id_t ModuleId, CFE_ES_AppInfo_t *AppInfoPtr); + #endif /* _cfe_es_apps_ */ diff --git a/fsw/cfe-core/src/es/cfe_es_resource.h b/fsw/cfe-core/src/es/cfe_es_resource.h index 9ca10533f..82c936cd3 100644 --- a/fsw/cfe-core/src/es/cfe_es_resource.h +++ b/fsw/cfe-core/src/es/cfe_es_resource.h @@ -214,7 +214,7 @@ static inline bool CFE_ES_AppRecordIsMatch(const CFE_ES_AppRecord_t *AppRecPtr, */ static inline const char* CFE_ES_AppRecordGetName(const CFE_ES_AppRecord_t *AppRecPtr) { - return AppRecPtr->StartParams.Name; + return AppRecPtr->StartParams.BasicInfo.Name; } @@ -307,7 +307,7 @@ static inline bool CFE_ES_LibRecordIsMatch(const CFE_ES_LibRecord_t *LibRecPtr, */ static inline const char* CFE_ES_LibRecordGetName(const CFE_ES_LibRecord_t *LibRecPtr) { - return LibRecPtr->LibName; + return LibRecPtr->BasicInfo.Name; } diff --git a/fsw/cfe-core/src/es/cfe_es_start.c b/fsw/cfe-core/src/es/cfe_es_start.c index 9f8c8eb66..2a883ef13 100644 --- a/fsw/cfe-core/src/es/cfe_es_start.c +++ b/fsw/cfe-core/src/es/cfe_es_start.c @@ -753,10 +753,9 @@ void CFE_ES_CreateObjects(void) { int32 ReturnCode; uint16 i; - osal_id_t OsalId; CFE_ES_AppRecord_t *AppRecPtr; - CFE_ES_TaskRecord_t *TaskRecPtr; CFE_ES_ResourceID_t PendingAppId; + CFE_ES_ResourceID_t PendingTaskId; CFE_ES_WriteToSysLog("ES Startup: Starting Object Creation calls.\n"); @@ -776,7 +775,27 @@ void CFE_ES_CreateObjects(void) AppRecPtr = CFE_ES_LocateAppRecordByID(PendingAppId); if (AppRecPtr != NULL) { + /* + ** Fill out the parameters in the AppStartParams sub-structure + */ + AppRecPtr->Type = CFE_ES_AppType_CORE; + strncpy(AppRecPtr->StartParams.BasicInfo.Name, CFE_ES_ObjectTable[i].ObjectName, + sizeof(AppRecPtr->StartParams.BasicInfo.Name)-1); + + /* FileName and EntryPoint is not valid for core apps */ + AppRecPtr->StartParams.StackSize = CFE_ES_ObjectTable[i].ObjectSize; + AppRecPtr->StartParams.ExceptionAction = CFE_ES_ExceptionAction_PROC_RESTART; + AppRecPtr->StartParams.Priority = CFE_ES_ObjectTable[i].ObjectPriority; + AppRecPtr->ModuleInfo.EntryAddress = (cpuaddr)CFE_ES_ObjectTable[i].FuncPtrUnion.VoidPtr; + + /* + ** Fill out the Task State info + */ + AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN; + AppRecPtr->ControlReq.AppTimerMsec = 0; + CFE_ES_AppRecordSetUsed(AppRecPtr, CFE_ES_RESOURCEID_RESERVED); + CFE_ES_Global.LastAppId = PendingAppId; } CFE_ES_UnlockSharedData(__func__,__LINE__); @@ -786,111 +805,60 @@ void CFE_ES_CreateObjects(void) */ if (AppRecPtr != NULL) { - - CFE_ES_LockSharedData(__func__,__LINE__); - - AppRecPtr->Type = CFE_ES_AppType_CORE; - - /* - ** Fill out the parameters in the AppStartParams sub-structure - */ - strncpy((char *)AppRecPtr->StartParams.Name, (char *)CFE_ES_ObjectTable[i].ObjectName, OS_MAX_API_NAME); - AppRecPtr->StartParams.Name[OS_MAX_API_NAME - 1] = '\0'; - /* EntryPoint field is not valid here for base apps */ - /* FileName is not valid for base apps, either */ - AppRecPtr->StartParams.StackSize = CFE_ES_ObjectTable[i].ObjectSize; - AppRecPtr->StartParams.StartAddress = (cpuaddr)CFE_ES_ObjectTable[i].FuncPtrUnion.VoidPtr; - AppRecPtr->StartParams.ExceptionAction = CFE_ES_ExceptionAction_PROC_RESTART; - AppRecPtr->StartParams.Priority = CFE_ES_ObjectTable[i].ObjectPriority; - - - /* - ** Create the task - */ - ReturnCode = OS_TaskCreate(&OsalId, /* task id */ - CFE_ES_ObjectTable[i].ObjectName, /* task name */ - CFE_ES_ObjectTable[i].FuncPtrUnion.MainAppPtr, /* task function pointer */ - NULL, /* stack pointer */ - CFE_ES_ObjectTable[i].ObjectSize, /* stack size */ - CFE_ES_ObjectTable[i].ObjectPriority, /* task priority */ - OS_FP_ENABLED); /* task options */ - - if(ReturnCode != OS_SUCCESS) - { - CFE_ES_AppRecordSetFree(AppRecPtr); - CFE_ES_UnlockSharedData(__func__,__LINE__); - - CFE_ES_WriteToSysLog("ES Startup: OS_TaskCreate error creating core App: %s: EC = 0x%08X\n", - CFE_ES_ObjectTable[i].ObjectName, (unsigned int)ReturnCode); - - /* - ** Delay to allow the message to be read - */ - OS_TaskDelay(CFE_ES_PANIC_DELAY); - - /* - ** cFE Cannot continue to start up. - */ - CFE_PSP_Panic(CFE_PSP_PANIC_CORE_APP); - - } - else - { - AppRecPtr->MainTaskId = CFE_ES_ResourceID_FromOSAL(OsalId); - TaskRecPtr = CFE_ES_LocateTaskRecordByID(AppRecPtr->MainTaskId); - - /* - ** Allocate and populate the CFE_ES_Global.TaskTable entry - */ - if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) ) - { - CFE_ES_SysLogWrite_Unsync("ES Startup: CFE_ES_Global.TaskTable record used error for App: %s, continuing.\n", - CFE_ES_ObjectTable[i].ObjectName); - } - CFE_ES_TaskRecordSetUsed(TaskRecPtr, AppRecPtr->MainTaskId); - TaskRecPtr->AppId = PendingAppId; - strncpy(TaskRecPtr->TaskName, CFE_ES_ObjectTable[i].ObjectName, sizeof(TaskRecPtr->TaskName)-1); - TaskRecPtr->TaskName[sizeof(TaskRecPtr->TaskName)-1] = '\0'; - - CFE_ES_SysLogWrite_Unsync("ES Startup: Core App: %s created. App ID: %lu\n", - CFE_ES_ObjectTable[i].ObjectName, - CFE_ES_ResourceID_ToInteger(PendingAppId)); + /* + ** Start the core app main task + ** (core apps are already in memory - no loading needed) + */ + ReturnCode = CFE_ES_StartAppTask(&AppRecPtr->StartParams, PendingAppId, &PendingTaskId); - CFE_ES_AppRecordSetUsed(AppRecPtr, PendingAppId); - - /* - ** Increment the registered App and Registered External Task variables. - */ - CFE_ES_Global.RegisteredTasks++; - CFE_ES_Global.RegisteredCoreApps++; - - CFE_ES_UnlockSharedData(__func__,__LINE__); - - } + /* + * Finalize data in the app table entry, which must be done under lock. + * This transitions the entry from being RESERVED to the real type, + * either MAIN_TASK (success) or returning to INVALID (failure). + */ + CFE_ES_LockSharedData(__func__,__LINE__); + + if ( ReturnCode == OS_SUCCESS ) + { + AppRecPtr->MainTaskId = PendingTaskId; + CFE_ES_AppRecordSetUsed(AppRecPtr, PendingAppId); + + /* + ** Increment the Core App counter. + */ + CFE_ES_Global.RegisteredCoreApps++; + ReturnCode = CFE_SUCCESS; + } + else + { + /* failure mode - just clear the whole app table entry. + * This will set the AppType back to CFE_ES_ResourceType_INVALID (0), + * as well as clearing any other data that had been written */ + memset(AppRecPtr, 0, sizeof(*AppRecPtr)); + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); } - else /* appSlot not found -- This should never happen!*/ + else { - CFE_ES_WriteToSysLog("ES Startup: Error, No free application slots available for CORE App!\n"); - /* - ** Delay to allow the message to be read - */ - OS_TaskDelay(CFE_ES_PANIC_DELAY); - - /* - ** cFE Cannot continue to start up. - */ - CFE_PSP_Panic(CFE_PSP_PANIC_CORE_APP); - + /* appSlot not found -- This should never happen!*/ + CFE_ES_WriteToSysLog("ES Startup: Error, No free application slots available for CORE App!\n"); + ReturnCode = CFE_ES_ERR_APP_CREATE; } - /* - * CFE_ES_MainTaskSyncDelay() will delay this thread until the - * newly-started thread calls CFE_ES_WaitForSystemState() - */ - if (CFE_ES_MainTaskSyncDelay(CFE_ES_AppState_RUNNING, CFE_PLATFORM_CORE_MAX_STARTUP_MSEC) != CFE_SUCCESS) + if ( ReturnCode == CFE_SUCCESS ) + { + /* + * CFE_ES_MainTaskSyncDelay() will delay this thread until the + * newly-started thread calls CFE_ES_WaitForSystemState() + */ + ReturnCode = CFE_ES_MainTaskSyncDelay(CFE_ES_AppState_RUNNING, CFE_PLATFORM_CORE_MAX_STARTUP_MSEC*1000); + } + + if ( ReturnCode != CFE_SUCCESS ) { - CFE_ES_WriteToSysLog("ES Startup: Core App %s did not complete initialization\n", - CFE_ES_ObjectTable[i].ObjectName); + CFE_ES_WriteToSysLog("ES Startup: OS_TaskCreate error creating core App: %s: EC = 0x%08X\n", + CFE_ES_ObjectTable[i].ObjectName, (unsigned int)ReturnCode); /* ** Delay to allow the message to be read diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 3540b3f2a..8411d3ac7 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -41,6 +41,7 @@ #include "cfe_version.h" #include "cfe_es_global.h" #include "cfe_es_apps.h" +#include "cfe_es_resource.h" #include "cfe_es_events.h" #include "cfe_es_verify.h" #include "cfe_es_task.h" @@ -1118,16 +1119,21 @@ int32 CFE_ES_QueryOneCmd(const CFE_ES_QueryOne_t *data) { const CFE_ES_AppNameCmd_Payload_t *cmd = &data->Payload; char LocalApp[OS_MAX_API_NAME]; - CFE_ES_ResourceID_t AppID; + CFE_ES_ResourceID_t ResourceID; int32 Result; CFE_SB_MessageStringGet(LocalApp, (char *)cmd->Application, NULL, OS_MAX_API_NAME, sizeof(cmd->Application)); - Result = CFE_ES_GetAppIDByName(&AppID, LocalApp); + Result = CFE_ES_GetAppIDByName(&ResourceID, LocalApp); + if (Result == CFE_ES_ERR_NAME_NOT_FOUND) + { + /* Also check for a matching library name */ + Result = CFE_ES_GetLibIDByName(&ResourceID, LocalApp); + } if (Result == CFE_SUCCESS) { - Result = CFE_ES_GetAppInfo(&(CFE_ES_TaskData.OneAppPacket.Payload.AppInfo), AppID); + Result = CFE_ES_GetModuleInfo(&(CFE_ES_TaskData.OneAppPacket.Payload.AppInfo), ResourceID); } /* @@ -1182,7 +1188,10 @@ int32 CFE_ES_QueryAllCmd(const CFE_ES_QueryAll_t *data) CFE_ES_AppInfo_t AppInfo; const CFE_ES_FileNameCmd_Payload_t *CmdPtr = &data->Payload; char QueryAllFilename[OS_MAX_PATH_LEN]; + CFE_ES_ResourceID_t ResourceList[CFE_ES_QUERY_ALL_MAX_ENTRIES]; + uint32 NumResources; CFE_ES_AppRecord_t *AppRecPtr; + CFE_ES_LibRecord_t *LibRecPtr; /* ** Copy the commanded filename into local buffer to ensure size limitation and to allow for modification @@ -1190,6 +1199,38 @@ int32 CFE_ES_QueryAllCmd(const CFE_ES_QueryAll_t *data) CFE_SB_MessageStringGet(QueryAllFilename, (char *)CmdPtr->FileName, CFE_PLATFORM_ES_DEFAULT_APP_LOG_FILE, OS_MAX_PATH_LEN, sizeof(CmdPtr->FileName)); + /* + * Collect list of active resource IDs. + * + * This should be done while locked, but the actual writing + * of the AppInfo data should be done while NOT locked. + */ + CFE_ES_LockSharedData(__func__, __LINE__); + NumResources = 0; + AppRecPtr = CFE_ES_Global.AppTable; + for(i=0; i < CFE_PLATFORM_ES_MAX_APPLICATIONS && + NumResources < CFE_ES_QUERY_ALL_MAX_ENTRIES; ++i) + { + if (CFE_ES_AppRecordIsUsed(AppRecPtr)) + { + ResourceList[NumResources] = CFE_ES_AppRecordGetID(AppRecPtr); + ++NumResources; + } + ++AppRecPtr; + } + LibRecPtr = CFE_ES_Global.LibTable; + for(i=0; i < CFE_PLATFORM_ES_MAX_LIBRARIES && + NumResources < CFE_ES_QUERY_ALL_MAX_ENTRIES; ++i) + { + if (CFE_ES_LibRecordIsUsed(LibRecPtr)) + { + ResourceList[NumResources] = CFE_ES_LibRecordGetID(LibRecPtr); + ++NumResources; + } + ++LibRecPtr; + } + CFE_ES_UnlockSharedData(__func__, __LINE__); + /* ** Check to see if the file already exists */ @@ -1240,21 +1281,13 @@ int32 CFE_ES_QueryAllCmd(const CFE_ES_QueryAll_t *data) /* ** Loop through the ES AppTable for main applications */ - AppRecPtr = CFE_ES_Global.AppTable; - for(i=0;iPayload; char QueryAllFilename[OS_MAX_PATH_LEN]; + CFE_ES_ResourceID_t TaskList[OS_MAX_TASKS]; + uint32 NumTasks; CFE_ES_TaskRecord_t *TaskRecPtr; + /* ** Copy the commanded filename into local buffer to ensure size limitation and to allow for modification */ CFE_SB_MessageStringGet(QueryAllFilename, (char *)CmdPtr->FileName, CFE_PLATFORM_ES_DEFAULT_TASK_LOG_FILE, OS_MAX_PATH_LEN, sizeof(CmdPtr->FileName)); + /* + * Collect list of active task IDs. + * + * This should be done while locked, but the actual writing + * of the AppInfo data should be done while NOT locked. + */ + CFE_ES_LockSharedData(__func__, __LINE__); + NumTasks = 0; + TaskRecPtr = CFE_ES_Global.TaskTable; + for(i=0; i < OS_MAX_TASKS; ++i) + { + if (CFE_ES_TaskRecordIsUsed(TaskRecPtr)) + { + TaskList[NumTasks] = CFE_ES_TaskRecordGetID(TaskRecPtr); + ++NumTasks; + } + ++TaskRecPtr; + } + CFE_ES_UnlockSharedData(__func__, __LINE__); + /* ** Check to see if the file already exists */ @@ -1371,20 +1427,13 @@ int32 CFE_ES_QueryAllTasksCmd(const CFE_ES_QueryAllTasks_t *data) /* ** Loop through the ES AppTable for main applications */ - TaskRecPtr = CFE_ES_Global.TaskTable; - for(i=0;i 'Restart Application \%s Completed.' -** \event 'Restart Application \%s Completed.' +/** \brief 'Restart Application \%s Completed, AppID=%lu' +** \event 'Restart Application \%s Completed, AppID=%lu' ** ** \par Type: INFORMATION ** @@ -178,7 +178,8 @@ ** That was started when the \link #CFE_ES_RESTART_APP_CC Restart Application command \endlink ** was issued. ** -** The \c 's' field identifies the name of the Application that was reloaded. +** The \c 's' field identifies the name of the Application that was restarted, and +** the %lu field identifies the new Application ID */ #define CFE_ES_RESTART_APP_INF_EID 10 @@ -202,8 +203,8 @@ #define CFE_ES_RELOAD_APP_DBG_EID 11 -/** \brief 'Reload Application \%s Completed.' -** \event 'Reload Application \%s Completed.' +/** \brief 'Reload Application \%s Completed, AppID=%lu' +** \event 'Reload Application \%s Completed, AppID=%lu' ** ** \par Type: INFORMATION ** @@ -213,7 +214,8 @@ ** That was started when the \link #CFE_ES_RELOAD_APP_CC Restart Application command \endlink ** was issued. ** -** The \c 's' field identifies the name of the Application that was reloaded. +** The \c 's' field identifies the name of the Application that was reloaded, and +** the %lu field identifies the new Application ID */ #define CFE_ES_RELOAD_APP_INF_EID 12 diff --git a/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h b/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h index 2a5ce3f28..47456a0dc 100644 --- a/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h +++ b/fsw/cfe-core/src/inc/cfe_es_extern_typedefs.h @@ -99,7 +99,12 @@ enum CFE_ES_AppType /** * @brief CFE external application */ - CFE_ES_AppType_EXTERNAL = 2 + CFE_ES_AppType_EXTERNAL = 2, + + /** + * @brief CFE library + */ + CFE_ES_AppType_LIBRARY = 3 }; /** diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index fe99f690e..951918a1b 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -278,9 +278,9 @@ void ES_UT_SetupSingleAppId(CFE_ES_AppType_Enum_t AppType, CFE_ES_AppState_Enum_ if (AppName) { - strncpy(LocalAppPtr->StartParams.Name, AppName, - sizeof(LocalAppPtr->StartParams.Name)-1); - LocalAppPtr->StartParams.Name[sizeof(LocalAppPtr->StartParams.Name)-1] = 0; + strncpy(LocalAppPtr->StartParams.BasicInfo.Name, AppName, + sizeof(LocalAppPtr->StartParams.BasicInfo.Name)-1); + LocalAppPtr->StartParams.BasicInfo.Name[sizeof(LocalAppPtr->StartParams.BasicInfo.Name)-1] = 0; strncpy(LocalTaskPtr->TaskName, AppName, sizeof(LocalTaskPtr->TaskName)-1); LocalTaskPtr->TaskName[sizeof(LocalTaskPtr->TaskName)-1] = 0; @@ -360,9 +360,9 @@ void ES_UT_SetupSingleLibId(const char *LibName, CFE_ES_LibRecord_t **OutLibRec) if (LibName) { - strncpy(LocalLibPtr->LibName, LibName, - sizeof(LocalLibPtr->LibName)-1); - LocalLibPtr->LibName[sizeof(LocalLibPtr->LibName)-1] = 0; + strncpy(LocalLibPtr->BasicInfo.Name, LibName, + sizeof(LocalLibPtr->BasicInfo.Name)-1); + LocalLibPtr->BasicInfo.Name[sizeof(LocalLibPtr->BasicInfo.Name)-1] = 0; } if (OutLibRec) @@ -986,10 +986,11 @@ void TestStartupErrorPaths(void) ++TaskRecPtr; } + UT_SetHookFunction(UT_KEY(OS_TaskCreate), ES_UT_SetAppStateHook, NULL); CFE_ES_CreateObjects(); UT_Report(__FILE__, __LINE__, UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_RECORD_USED]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 23, + UT_GetStubCount(UT_KEY(OS_printf)) == 13, "CFE_ES_CreateObjects", "Record used error"); @@ -1008,11 +1009,12 @@ void TestStartupErrorPaths(void) } UT_SetDeferredRetcode(UT_KEY(CFE_TBL_EarlyInit), 1, -1); + UT_SetHookFunction(UT_KEY(OS_TaskCreate), ES_UT_SetAppStateHook, NULL); CFE_ES_CreateObjects(); UT_Report(__FILE__, __LINE__, UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_RECORD_USED]) && UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_EARLYINIT]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 24, + UT_GetStubCount(UT_KEY(OS_printf)) == 14, "CFE_ES_CreateObjects", "Error returned when calling function"); @@ -1022,10 +1024,11 @@ void TestStartupErrorPaths(void) ES_ResetUnitTest(); UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); UT_SetForceFail(UT_KEY(OS_BinSemCreate), OS_ERROR); + UT_SetHookFunction(UT_KEY(OS_TaskCreate), ES_UT_SetAppStateHook, NULL); CFE_ES_CreateObjects(); UT_Report(__FILE__, __LINE__, UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CORE_APP_CREATE]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 13, + UT_GetStubCount(UT_KEY(OS_printf)) == 18, "CFE_ES_CreateObjects", "Error creating core application"); @@ -1175,12 +1178,9 @@ void TestApps(void) UT_SetReadBuffer(StartupScript, NumBytes); CFE_ES_StartApplications(CFE_PSP_RST_TYPE_PROCESSOR, CFE_PLATFORM_ES_NONVOL_STARTUP_FILE); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_FILE_LINE_TOO_LONG]) && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_ES_APP_STARTUP_OPEN]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 8, - "CFE_ES_StartApplications", - "Line too long"); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_FILE_LINE_TOO_LONG])); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_ES_APP_STARTUP_OPEN])); + UtAssert_UINT32_EQ(UT_GetStubCount(UT_KEY(OS_printf)), 5); /* Create a valid startup script for subsequent tests */ strncpy(StartupScript, @@ -1232,13 +1232,11 @@ void TestApps(void) /* Test successfully starting an application */ ES_ResetUnitTest(); UT_SetReadBuffer(StartupScript, NumBytes); + UT_SetHookFunction(UT_KEY(OS_TaskCreate), ES_UT_SetAppStateHook, NULL); CFE_ES_StartApplications(CFE_PSP_RST_TYPE_PROCESSOR, CFE_PLATFORM_ES_NONVOL_STARTUP_FILE); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_ES_APP_STARTUP_OPEN]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 8, - "CFE_ES_StartApplications", - "Start application; successful"); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_ES_APP_STARTUP_OPEN])); + UtAssert_UINT32_EQ(UT_GetStubCount(UT_KEY(OS_printf)), 5); /* Test parsing the startup script with an unknown entry type */ ES_ResetUnitTest(); @@ -1277,11 +1275,8 @@ void TestApps(void) 170, 4096, 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_APP_CREATE]), - "CFE_ES_AppCreate", - "Task create failure"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_APP_CREATE])); /* Test application creation with NULL file name */ ES_ResetUnitTest(); @@ -1350,11 +1345,8 @@ void TestApps(void) 170, 8192, 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_EXTRACT_FILENAME_UT55]), - "CFE_ES_AppCreate", - "File load failure"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_EXTRACT_FILENAME_UT55])); /* Test application loading and creation where all app slots are taken */ ES_ResetUnitTest(); @@ -1390,11 +1382,8 @@ void TestApps(void) 170, 8192, 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_FIND_SYMBOL]), - "CFE_ES_AppCreate", - "Entry point symbol lookup failure"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_FIND_SYMBOL])); /* Test application loading and creation where the entry point symbol @@ -1410,12 +1399,9 @@ void TestApps(void) 170, 8192, 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_FIND_SYMBOL]) && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_MODULE_UNLOAD_FAILED]), - "CFE_ES_AppCreate", - "Module unload failure after entry point lookup failure"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_FIND_SYMBOL])); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_MODULE_UNLOAD_FAILED])); /* * Set up a situation where attempting to get appID by context, @@ -1437,8 +1423,7 @@ void TestApps(void) CFE_ES_RunAppTableScan(0, &CFE_ES_TaskData.BackgroundAppScanState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID) && - UtAppRecPtr->ControlReq.AppTimerMsec == 0 && - UtAppRecPtr->ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_DELETE, + UtAppRecPtr->ControlReq.AppTimerMsec == 0, "CFE_ES_RunAppTableScan", "Waiting; process control request"); @@ -1466,7 +1451,6 @@ void TestApps(void) CFE_ES_RunAppTableScan(0, &CFE_ES_TaskData.BackgroundAppScanState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID) && - UtAppRecPtr->ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_DELETE && UtAppRecPtr->ControlReq.AppTimerMsec == 0, "CFE_ES_RunAppTableScan", "Stopped; process control request"); @@ -1490,7 +1474,8 @@ void TestApps(void) ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = 0x12345; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID), "CFE_ES_ProcessControlRequest", @@ -1499,20 +1484,21 @@ void TestApps(void) /* Test a successful control action request to exit an application */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/Filename", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NotNULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_EXIT; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_EXIT_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1525,8 +1511,9 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_EXIT; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_EXIT_APP_ERR_EID), "CFE_ES_ProcessControlRequest", @@ -1540,8 +1527,9 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_STOP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1555,8 +1543,9 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RESTART; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_ERR4_EID), "CFE_ES_ProcessControlRequest", @@ -1569,9 +1558,10 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RESTART; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1584,9 +1574,10 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_ERR4_EID), "CFE_ES_ProcessControlRequest", @@ -1599,9 +1590,10 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1612,20 +1604,21 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/FileName", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, "NULL", + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_ERROR; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_ERREXIT_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1639,8 +1632,9 @@ void TestApps(void) UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_ERROR; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_ERREXIT_APP_ERR_EID), "CFE_ES_ProcessControlRequest", @@ -1649,20 +1643,21 @@ void TestApps(void) /* Test a successful control action request to stop an application */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/FileName", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, "NULL", + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_STOP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1671,20 +1666,21 @@ void TestApps(void) /* Test a successful control action request to restart an application */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/FileName", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, "NULL", + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RESTART; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1693,20 +1689,21 @@ void TestApps(void) /* Test a successful control action request to reload an application */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/FileName", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, "NULL", + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1717,20 +1714,21 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy((char *) UtAppRecPtr->StartParams.FileName, + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.FileName, "/ram/FileName", OS_MAX_PATH_LEN); - UtAppRecPtr->StartParams.FileName[OS_MAX_PATH_LEN - 1] = '\0'; - strncpy((char *) UtAppRecPtr->StartParams.EntryPoint, "NULL", + UtAppRecPtr->StartParams.BasicInfo.FileName[OS_MAX_PATH_LEN - 1] = '\0'; + strncpy((char *) UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", OS_MAX_API_NAME); - UtAppRecPtr->StartParams.EntryPoint[OS_MAX_API_NAME - 1] = + UtAppRecPtr->StartParams.BasicInfo.EntryPoint[OS_MAX_API_NAME - 1] = '\0'; UtAppRecPtr->StartParams.Priority = 255; UtAppRecPtr->StartParams.StackSize = 8192; UtAppRecPtr->StartParams.ExceptionAction = 0; UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_EXCEPTION; - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR1_EID), "CFE_ES_ProcessControlRequest", @@ -1797,11 +1795,12 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); ES_UT_SetupForOSCleanup(); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskDelete), OS_ERROR); UT_SetForceFail(UT_KEY(OS_close), OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Task OS delete and close failure"); @@ -1810,12 +1809,13 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, NULL, NULL); ES_UT_SetupForOSCleanup(); UT_SetDeferredRetcode(UT_KEY(OS_MutSemDelete), 1, OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Task mutex delete failure"); @@ -1824,10 +1824,11 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(OS_ModuleUnload), 1, OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Module unload failure"); @@ -1836,10 +1837,11 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "EVS application cleanup failure"); @@ -2007,16 +2009,17 @@ void TestApps(void) ES_ResetUnitTest(); /* Setup an entry which will be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); /* Setup a second entry which will NOT be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, NULL, &UtTaskRecPtr); ES_UT_SetupMemPoolId(&UtPoolRecPtr); UtPoolRecPtr->OwnerAppID = CFE_ES_AppRecordGetID(UtAppRecPtr); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); /* Associate a child task with the app to be deleted */ ES_UT_SetupChildTaskId(UtAppRecPtr, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS, + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS, "CFE_ES_CleanUpApp", "Main task ID matches task ID, nominal"); UT_Report(__FILE__, __LINE__, @@ -2034,12 +2037,13 @@ void TestApps(void) ES_ResetUnitTest(); /* Setup an entry which will be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); ES_UT_SetupMemPoolId(&UtPoolRecPtr); UtPoolRecPtr->OwnerAppID = CFE_ES_AppRecordGetID(UtAppRecPtr); UtPoolRecPtr->PoolID = CFE_ES_ResourceID_FromInteger(99999); /* Mismatch */ + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Mem Pool delete error"); UT_Report(__FILE__, __LINE__, @@ -2054,10 +2058,10 @@ void TestApps(void) /* Setup an entry which will be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); /* Setup a second entry which will NOT be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, NULL, &UtTaskRecPtr); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL); /* Associate a child task with the app to be deleted */ ES_UT_SetupChildTaskId(UtAppRecPtr, NULL, NULL); @@ -2065,12 +2069,13 @@ void TestApps(void) UtAppRecPtr->MainTaskId = CFE_ES_TaskRecordGetID(UtTaskRecPtr); UT_SetForceFail(UT_KEY(OS_TaskDelete), OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Main task ID doesn't match task ID, CFE_ES_APP_CLEANUP_ERR"); UT_Report(__FILE__, __LINE__, - !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), + CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), "CFE_ES_CleanUpApp", "Main task ID doesn't match task ID, second task unchanged"); @@ -2087,14 +2092,15 @@ void TestApps(void) /* switch the main task association (makes it wrong) */ UtAppRecPtr->MainTaskId = CFE_ES_TaskRecordGetID(UtTaskRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS, + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS, "CFE_ES_CleanUpApp", "Application ID mismatch; core application"); UT_Report(__FILE__, __LINE__, - !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), + CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), "CFE_ES_CleanUpApp", "Application ID mismatch; core application"); @@ -2111,10 +2117,11 @@ void TestApps(void) /* Setup an entry which will be deleted */ ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, &UtTaskRecPtr); - OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, "UT", + OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, "UT", "ut-module"); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS && + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS && !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr) && CFE_ES_Global.RegisteredExternalApps == 0, "CFE_ES_CleanUpApp", @@ -2181,7 +2188,7 @@ void TestResourceID(void) void TestLibs(void) { CFE_ES_LibRecord_t *UtLibRecPtr; - char LongLibraryName[sizeof(UtLibRecPtr->LibName)+1]; + char LongLibraryName[sizeof(UtLibRecPtr->BasicInfo.Name)+1]; CFE_ES_ResourceID_t Id; uint32 j; int32 Return; @@ -2195,11 +2202,8 @@ void TestLibs(void) "filename", "EntryPoint", "LibName"); - UT_Report(__FILE__, __LINE__, - Return == -444 && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_SHARED_LIBRARY_INIT]), - "CFE_ES_LoadLibrary", - "Load shared library initialization failure"); + UtAssert_INT32_EQ(Return, -444); + UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_SHARED_LIBRARY_INIT])); /* Test Load library returning an error on a null pointer argument */ Return = CFE_ES_LoadLibrary(&Id, @@ -2221,8 +2225,8 @@ void TestLibs(void) "Load shared library bad argument (NULL library name)"); /* Test Load library returning an error on a too long library name */ - memset(&LongLibraryName[0], 'a', sizeof(UtLibRecPtr->LibName)); - LongLibraryName[sizeof(UtLibRecPtr->LibName)] = '\0'; + memset(&LongLibraryName[0], 'a', sizeof(LongLibraryName)-1); + LongLibraryName[sizeof(LongLibraryName)-1] = '\0'; Return = CFE_ES_LoadLibrary(&Id, "filename", "EntryPoint", @@ -2269,10 +2273,7 @@ void TestLibs(void) "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_LOAD_LIB, - "CFE_ES_LoadLibrary", - "Load shared library failure"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); /* Test shared library loading and initialization where the library * entry point symbol cannot be found @@ -2283,10 +2284,7 @@ void TestLibs(void) "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_LOAD_LIB, - "CFE_ES_LoadLibrary", - "Could not find library initialization symbol"); + UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); /* Test shared library loading and initialization where the library * initialization function fails and then must be cleaned up diff --git a/fsw/cfe-core/unit-test/ut_osprintf_stubs.c b/fsw/cfe-core/unit-test/ut_osprintf_stubs.c index 6face1351..facd86a3c 100644 --- a/fsw/cfe-core/unit-test/ut_osprintf_stubs.c +++ b/fsw/cfe-core/unit-test/ut_osprintf_stubs.c @@ -93,7 +93,7 @@ const char *UT_OSP_MESSAGES[] = /* ES Startup: Error Re-Formating Volatile(RAM) Volume. EC = 0x~ */ [UT_OSP_REFORMAT_VOLATILE] = "ES Startup: Error Re-Formating Volatile(RAM) Volume. EC = 0x%08X\n", /* ES Startup: Could not load cFE application file:ut/filename.x. EC = 0x~ */ - [UT_OSP_EXTRACT_FILENAME_UT55] = "ES Startup: Could not load cFE application file:%s. EC = 0x%08X\n", + [UT_OSP_EXTRACT_FILENAME_UT55] = "ES Startup: Could not load file:%s. EC = 0x%08X\n", /* ES Startup: Unable to extract filename from path: ut46/ */ [UT_OSP_EXTRACT_FILENAME_UT46] = "ES Startup: Unable to extract filename from path: %s.\n", /* ES Startup: No free application slots available */ @@ -123,7 +123,7 @@ const char *UT_OSP_MESSAGES[] = /* ES Startup: Error Creating Volatile(RAM) Volume. EC = 0x~ */ [UT_OSP_CREATE_VOLATILE] = "ES Startup: Error Creating Volatile(RAM) Volume. EC = 0x%08X\n", /* ES Startup: Failed to unload APP: AppName. EC = 0x~ */ - [UT_OSP_MODULE_UNLOAD_FAILED] = "ES Startup: Failed to unload APP: %s. EC = 0x%08X\n", + [UT_OSP_MODULE_UNLOAD_FAILED] = "ES Startup: Failed to unload: %s. EC = 0x%08X\n", /* POWERON RESET called from CFE_ES_ResetCFE (Commanded). */ [UT_OSP_POR_COMMANDED] = "POWERON RESET called from CFE_ES_ResetCFE (Commanded).\n", /* ES Startup: Error Re-Mounting Volatile(RAM) Volume. EC = 0x~ */ @@ -159,7 +159,7 @@ const char *UT_OSP_MESSAGES[] = /* ES Startup: Error, No free application slots available for CORE App! */ [UT_OSP_NO_FREE_CORE_APP_SLOTS] = "ES Startup: Error, No free application slots available for CORE App!\n", /* ES Startup: CFE_ES_Global.TaskTable record used error for App: CFE_EVS, continuing. */ - [UT_OSP_RECORD_USED] = "ES Startup: CFE_ES_Global.TaskTable record used error for App: %s, continuing.\n", + [UT_OSP_RECORD_USED] = "ES Startup: Error: ES_TaskTable slot for ID %lx in use at task creation!\n", /* CFE_ES_ExitChildTask called from invalid task context */ [UT_OSP_TASKEXIT_BAD_CONTEXT] = "CFE_ES_ExitChildTask called from invalid task context\n", };