From 58abd38d04390cbe123d89b57819af013464d57f Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 2 Feb 2021 22:55:09 -0500 Subject: [PATCH] Fix #978, store task parameters in task record Implement a "CFE_ES_TaskStartParams_t" to complement the existing "CFE_ES_AppStartParams_t" and store this in the task record. This permits some nice cleanup: - All tasks can now use the same basic start function CFE_ES_StartAppTask() - No special/different logic is needed for main tasks/child tasks - Simplified APIs as parameters can be encapsulated in a single struct. - Fixes a race condition where child tasks may not be fully instantiated at the time the task function is invoked. --- fsw/cfe-core/src/es/cfe_es_api.c | 186 ++++++------- fsw/cfe-core/src/es/cfe_es_apps.c | 379 +++++++++++++------------- fsw/cfe-core/src/es/cfe_es_apps.h | 94 ++++--- fsw/cfe-core/src/es/cfe_es_objtab.c | 10 +- fsw/cfe-core/src/es/cfe_es_resource.h | 4 +- fsw/cfe-core/src/es/cfe_es_start.c | 20 +- fsw/cfe-core/src/es/cfe_es_start.h | 3 +- fsw/cfe-core/src/es/cfe_es_task.c | 39 ++- fsw/cfe-core/src/inc/cfe_es.h | 11 +- fsw/cfe-core/unit-test/es_UT.c | 292 +++++++++++--------- 10 files changed, 528 insertions(+), 510 deletions(-) diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index 916264a1d..54304aecb 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -1015,15 +1015,15 @@ int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, CFE_ES_AppId_t AppId) AppInfo->ResourceId = CFE_RESOURCEID_UNWRAP(AppId); /* make into a generic resource ID */ AppInfo->Type = AppRecPtr->Type; + strncpy(AppInfo->Name, CFE_ES_AppRecordGetName(AppRecPtr), sizeof(AppInfo->Name)-1); + CFE_ES_CopyModuleBasicInfo(&AppRecPtr->StartParams.BasicInfo, AppInfo); - CFE_ES_CopyModuleStatusInfo(&AppRecPtr->ModuleInfo, AppInfo); + CFE_ES_CopyModuleStatusInfo(&AppRecPtr->LoadStatus, AppInfo); - AppInfo->StackSize = AppRecPtr->StartParams.StackSize; AppInfo->ExceptionAction = AppRecPtr->StartParams.ExceptionAction; - AppInfo->Priority = AppRecPtr->StartParams.Priority; AppInfo->MainTaskId = AppRecPtr->MainTaskId; - ModuleId = AppRecPtr->ModuleInfo.ModuleId; + ModuleId = AppRecPtr->LoadStatus.ModuleId; /* ** Calculate the number of child tasks @@ -1042,6 +1042,10 @@ int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, CFE_ES_AppId_t AppId) strncpy(AppInfo->MainTaskName, TaskRecPtr->TaskName, sizeof(AppInfo->MainTaskName) - 1); AppInfo->MainTaskName[sizeof(AppInfo->MainTaskName) - 1] = '\0'; + + AppInfo->StackSize = TaskRecPtr->StartParams.StackSize; + AppInfo->Priority = TaskRecPtr->StartParams.Priority; + } else { @@ -1105,10 +1109,12 @@ int32 CFE_ES_GetLibInfo(CFE_ES_AppInfo_t *LibInfo, CFE_ES_LibId_t LibId) LibInfo->ResourceId = CFE_RESOURCEID_UNWRAP(LibId); /* make into generic ID */ LibInfo->Type = CFE_ES_AppType_LIBRARY; - CFE_ES_CopyModuleBasicInfo(&LibRecPtr->BasicInfo, LibInfo); - CFE_ES_CopyModuleStatusInfo(&LibRecPtr->ModuleInfo, LibInfo); + strncpy(LibInfo->Name, CFE_ES_LibRecordGetName(LibRecPtr), sizeof(LibInfo->Name)-1); - ModuleId = LibRecPtr->ModuleInfo.ModuleId; + CFE_ES_CopyModuleBasicInfo(&LibRecPtr->LoadParams, LibInfo); + CFE_ES_CopyModuleStatusInfo(&LibRecPtr->LoadStatus, LibInfo); + + ModuleId = LibRecPtr->LoadStatus.ModuleId; Status = CFE_SUCCESS; } @@ -1243,108 +1249,90 @@ int32 CFE_ES_CreateChildTask(CFE_ES_TaskId_t *TaskIdPtr, CFE_ES_TaskPriority_Atom_t Priority, uint32 Flags) { + int32 ReturnCode; + CFE_ES_AppRecord_t * AppRecPtr; + CFE_ES_AppId_t ParentAppId; + CFE_ES_TaskId_t SelfTaskId; + CFE_ES_TaskStartParams_t Params; - int32 Result; - CFE_ES_AppRecord_t *AppRecPtr; - CFE_ES_TaskRecord_t *TaskRecPtr; - int32 ReturnCode; - CFE_ES_TaskId_t SelfTaskId; - CFE_ES_TaskId_t LocalChildTaskId; - osal_id_t OsalId; + ParentAppId = CFE_ES_APPID_UNDEFINED; - /* - ** Validate some of the arguments - */ - if ( TaskIdPtr == NULL ) - { - if (TaskName == NULL) - { - CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Task Id and Name Pointer Parameters are NULL.\n"); - ReturnCode = CFE_ES_BAD_ARGUMENT; - } - else - { - CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Task Id Pointer Parameter is NULL for Task '%s'.\n",TaskName); - ReturnCode = CFE_ES_BAD_ARGUMENT; - } - } - else if ( TaskName == NULL ) - { - CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: TaskName Parameter is NULL\n"); - ReturnCode = CFE_ES_BAD_ARGUMENT; - } - else if ( FunctionPtr == NULL ) - { - CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Function Pointer Parameter is NULL for Task '%s'\n",TaskName); - ReturnCode = CFE_ES_BAD_ARGUMENT; - } - else - { - - CFE_ES_LockSharedData(__func__,__LINE__); + memset(&Params, 0, sizeof(Params)); + Params.Priority = Priority; + Params.StackSize = StackSize; - /* - ** Get the App Record of the calling Application - */ - AppRecPtr = CFE_ES_GetAppRecordByContext(); - if (AppRecPtr == NULL) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CreateChildTask: Invalid calling context when creating Task '%s'\n",TaskName); - ReturnCode = CFE_ES_ERR_RESOURCEID_NOT_VALID; - } - else /* else AppId is valid */ - { - /* - ** First, Make sure the Calling Task is a cFE Main task. - ** TaskID must be the same as the Parent Task ID. - */ - OsalId = OS_TaskGetId(); - SelfTaskId = CFE_ES_TaskId_FromOSAL(OsalId); - if ( CFE_RESOURCEID_TEST_EQUAL(SelfTaskId, AppRecPtr->MainTaskId) ) - { - /* - ** Step 2: Create the new task using the OS API call - */ - Result = OS_TaskCreate(&OsalId, TaskName, FunctionPtr, StackPtr, - StackSize, Priority, OS_FP_ENABLED ); - - /* - ** Step 3: Record the task information in the task table - */ - if ( Result == OS_SUCCESS ) - { - LocalChildTaskId = CFE_ES_TaskId_FromOSAL(OsalId); - TaskRecPtr = CFE_ES_LocateTaskRecordByID(LocalChildTaskId); + /* + ** Validate some of the arguments + */ + if (TaskIdPtr == NULL) + { + if (TaskName == NULL) + { + CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Task Id and Name Pointer Parameters are NULL.\n"); + ReturnCode = CFE_ES_BAD_ARGUMENT; + } + else + { + CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Task Id Pointer Parameter is NULL for Task '%s'.\n", + TaskName); + ReturnCode = CFE_ES_BAD_ARGUMENT; + } + } + else if (TaskName == NULL) + { + CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: TaskName Parameter is NULL\n"); + ReturnCode = CFE_ES_BAD_ARGUMENT; + } + else if (FunctionPtr == NULL) + { + CFE_ES_WriteToSysLog("CFE_ES_CreateChildTask: Function Pointer Parameter is NULL for Task '%s'\n", TaskName); + ReturnCode = CFE_ES_BAD_ARGUMENT; + } + else + { + /* + ** First, Make sure the Calling Task is a cFE Main task. + ** TaskID must be the same as the Parent Task ID. + */ + SelfTaskId = CFE_ES_TaskId_FromOSAL(OS_TaskGetId()); - CFE_ES_TaskRecordSetUsed(TaskRecPtr, CFE_RESOURCEID_UNWRAP(LocalChildTaskId)); - TaskRecPtr->AppId = CFE_ES_AppRecordGetID(AppRecPtr); - strncpy(TaskRecPtr->TaskName,TaskName,sizeof(TaskRecPtr->TaskName) - 1); - TaskRecPtr->TaskName[sizeof(TaskRecPtr->TaskName) - 1] = '\0'; - CFE_ES_Global.RegisteredTasks++; + CFE_ES_LockSharedData(__func__, __LINE__); - *TaskIdPtr = CFE_ES_TaskRecordGetID(TaskRecPtr); - ReturnCode = CFE_SUCCESS; - } - else - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CreateChildTask: Error calling OS_TaskCreate for Task '%s' RC = 0x%08X\n",TaskName,(unsigned int)Result); - ReturnCode = CFE_ES_ERR_CHILD_TASK_CREATE; - } - } - else - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CreateChildTask: Error: Cannot call from a Child Task (for Task '%s').\n",TaskName); + /* + ** Get the App Record of the calling Application + */ + AppRecPtr = CFE_ES_GetAppRecordByContext(); + if (AppRecPtr == NULL) + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CreateChildTask: Invalid calling context when creating Task '%s'\n", + TaskName); + ReturnCode = CFE_ES_ERR_RESOURCEID_NOT_VALID; + } + else if (!CFE_RESOURCEID_TEST_EQUAL(SelfTaskId, AppRecPtr->MainTaskId)) + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CreateChildTask: Error: Cannot call from a Child Task (for Task '%s').\n", + TaskName); ReturnCode = CFE_ES_ERR_CHILD_TASK_CREATE; + } + else + { + ParentAppId = CFE_ES_AppRecordGetID(AppRecPtr); + ReturnCode = CFE_SUCCESS; + } /* end If AppID is valid */ - } /* end if Calling task is a main task */ - - }/* end If AppID is valid */ + CFE_ES_UnlockSharedData(__func__, __LINE__); - CFE_ES_UnlockSharedData(__func__,__LINE__); + } /* end if parameter checking */ - } /* end if parameter checking */ + /* + ** Step 2: Create the new task if the parameter validation succeeded + */ + if (ReturnCode == CFE_SUCCESS) + { + ReturnCode = CFE_ES_StartAppTask(TaskIdPtr, TaskName, FunctionPtr, &Params, ParentAppId); + } - return(ReturnCode); + return (ReturnCode); } /* End of CFE_ES_CreateChildTask() */ diff --git a/fsw/cfe-core/src/es/cfe_es_apps.c b/fsw/cfe-core/src/es/cfe_es_apps.c index 8e825dfb3..fddb1203b 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.c +++ b/fsw/cfe-core/src/es/cfe_es_apps.c @@ -263,104 +263,98 @@ void CFE_ES_StartApplications(uint32 ResetType, const char *StartFilePath ) */ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens) { - const char *FileName; - const char *AppName; - const char *EntryPoint; - const char *EntryType; - unsigned long PriorityIn; - unsigned long StackSizeIn; - unsigned long ExceptionActionIn; - union - { + const char * ModuleName; + const char * EntryType; + unsigned long ParsedValue; + union + { CFE_ES_AppId_t AppId; CFE_ES_LibId_t LibId; - } IdBuf; - int32 CreateStatus = CFE_ES_ERR_APP_CREATE; + } IdBuf; + int32 CreateStatus = CFE_ES_ERR_APP_CREATE; + CFE_ES_AppStartParams_t ParamBuf; - /* - ** Check to see if the correct number of items were parsed - */ - if ( NumTokens < 8 ) - { - CFE_ES_WriteToSysLog("ES Startup: Invalid ES Startup file entry: %u\n",(unsigned int)NumTokens); - return (CreateStatus); - } + /* + ** Check to see if the correct number of items were parsed + */ + if (NumTokens < 8) + { + CFE_ES_WriteToSysLog("ES Startup: Invalid ES Startup file entry: %u\n", (unsigned int)NumTokens); + return (CreateStatus); + } - EntryType = TokenList[0]; - FileName = TokenList[1]; - EntryPoint = TokenList[2]; - AppName = TokenList[3]; + /* Get pointers to specific tokens that are simple strings used as-is */ + EntryType = TokenList[0]; + ModuleName = TokenList[3]; - /* - * NOTE: In previous CFE versions the sscanf() function was used to convert - * these string values into integers. This approach of using the pre-tokenized strings - * and strtoul() is safer but the side effect is that it will also be more "permissive" in - * what is accepted vs. rejected by this function. - * - * For instance if the startup script contains "123xyz", this will be converted to the value - * 123 instead of triggering a validation failure as it would have in CFE <= 6.5.0. - * - * This permissive parsing should not be relied upon, as it may become more strict again in - * future CFE revisions. - * - * Also note that this uses "unsigned long" as that is the defined output type of strtoul(). - * It will be converted to the correct type later. - */ - PriorityIn = strtoul(TokenList[4], NULL, 0); - StackSizeIn = strtoul(TokenList[5], NULL, 0); - ExceptionActionIn = strtoul(TokenList[7], NULL, 0); + /* + * Other tokens will need to be scrubbed/converted. + * Both Libraries and Apps use File Name (1) and Symbol Name (2) fields so copy those now + */ + memset(&ParamBuf, 0, sizeof(ParamBuf)); + strncpy(ParamBuf.BasicInfo.FileName, TokenList[1], sizeof(ParamBuf.BasicInfo.FileName) - 1); + strncpy(ParamBuf.BasicInfo.InitSymbolName, TokenList[2], sizeof(ParamBuf.BasicInfo.InitSymbolName) - 1); - if(strcmp(EntryType,"CFE_APP")==0) - { - CFE_ES_WriteToSysLog("ES Startup: Loading file: %s, APP: %s\n", - FileName, AppName); + if (strcmp(EntryType, "CFE_APP") == 0) + { + CFE_ES_WriteToSysLog("ES Startup: Loading file: %s, APP: %s\n", ParamBuf.BasicInfo.FileName, ModuleName); - /* - ** Validate Some parameters - ** Exception action should be 0 ( Restart App ) or - ** 1 ( Processor reset ). If it's non-zero, assume it means - ** reset CPU. - */ - if ( ExceptionActionIn > CFE_ES_ExceptionAction_RESTART_APP ) - { - ExceptionActionIn = CFE_ES_ExceptionAction_PROC_RESTART; - } + /* + * Priority and Exception action have limited ranges, which is checked here + * Task priority cannot be bigger than OS_MAX_TASK_PRIORITY + */ + ParsedValue = strtoul(TokenList[4], NULL, 0); + if (ParsedValue > OS_MAX_TASK_PRIORITY) + { + ParamBuf.MainTaskInfo.Priority = OS_MAX_TASK_PRIORITY; + } + else + { + /* convert parsed value to correct type */ + ParamBuf.MainTaskInfo.Priority = (CFE_ES_TaskPriority_Atom_t)ParsedValue; + } - /* - * Task priority cannot be bigger than OS_MAX_TASK_PRIORITY - */ - if ( PriorityIn > OS_MAX_TASK_PRIORITY ) - { - PriorityIn = OS_MAX_TASK_PRIORITY; - } + /* No specific upper/lower limit for stack size - will pass value through */ + ParamBuf.MainTaskInfo.StackSize = strtoul(TokenList[5], NULL, 0); - /* - ** Now create the application - */ - CreateStatus = CFE_ES_AppCreate(&IdBuf.AppId, FileName, - EntryPoint, AppName, - PriorityIn, - StackSizeIn, - ExceptionActionIn); - } - else if(strcmp(EntryType,"CFE_LIB")==0) - { - CFE_ES_WriteToSysLog("ES Startup: Loading shared library: %s\n",FileName); - /* - ** Now load the library - */ - CreateStatus = CFE_ES_LoadLibrary(&IdBuf.LibId, FileName, - EntryPoint, AppName); + /* + ** Validate Some parameters + ** Exception action should be 0 ( Restart App ) or + ** 1 ( Processor reset ). If it's non-zero, assume it means + ** reset CPU. + */ + ParsedValue = strtoul(TokenList[7], NULL, 0); + if (ParsedValue > CFE_ES_ExceptionAction_RESTART_APP) + { + ParamBuf.ExceptionAction = CFE_ES_ExceptionAction_PROC_RESTART; + } + else + { + /* convert parsed value to correct type */ + ParamBuf.ExceptionAction = (CFE_ES_ExceptionAction_Enum_t)ParsedValue; + } - } - else - { - CFE_ES_WriteToSysLog("ES Startup: Unexpected EntryType %s in startup file.\n",EntryType); - } + /* + ** Now create the application + */ + CreateStatus = CFE_ES_AppCreate(&IdBuf.AppId, ModuleName, &ParamBuf); + } + else if (strcmp(EntryType, "CFE_LIB") == 0) + { + CFE_ES_WriteToSysLog("ES Startup: Loading shared library: %s\n", ParamBuf.BasicInfo.FileName); - return (CreateStatus); + /* + ** Now load the library + */ + CreateStatus = CFE_ES_LoadLibrary(&IdBuf.LibId, ModuleName, &ParamBuf.BasicInfo); + } + else + { + CFE_ES_WriteToSysLog("ES Startup: Unexpected EntryType %s in startup file.\n", EntryType); + } + return (CreateStatus); } /* @@ -373,21 +367,21 @@ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens) ** **------------------------------------------------------------------------------------- */ -int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus) +int32 CFE_ES_LoadModule(CFE_ResourceId_t ParentResourceId, const char *ModuleName, const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus) { osal_id_t ModuleId; - cpuaddr StartAddr; + cpuaddr InitSymbolAddress; int32 ReturnCode; int32 StatusCode; uint32 LoadFlags; LoadFlags = 0; - StartAddr = 0; + InitSymbolAddress = 0; ReturnCode = CFE_SUCCESS; if (LoadParams->FileName[0] != 0) { - switch(CFE_ResourceId_GetBase(ResourceId)) + switch(CFE_ResourceId_GetBase(ParentResourceId)) { case CFE_ES_APPID_BASE: /* @@ -417,7 +411,7 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara * Load the module via OSAL. */ StatusCode = OS_ModuleLoad ( &ModuleId, - LoadParams->Name, + ModuleName, LoadParams->FileName, LoadFlags ); @@ -437,13 +431,13 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara /* * If the Load was OK, then lookup the address of the entry point */ - if (ReturnCode == CFE_SUCCESS && LoadParams->EntryPoint[0] != 0) + if (ReturnCode == CFE_SUCCESS && LoadParams->InitSymbolName[0] != 0) { - StatusCode = OS_ModuleSymbolLookup(ModuleId, &StartAddr, LoadParams->EntryPoint); + StatusCode = OS_ModuleSymbolLookup(ModuleId, &InitSymbolAddress, LoadParams->InitSymbolName); if (StatusCode != OS_SUCCESS) { CFE_ES_WriteToSysLog("ES Startup: Could not find symbol:%s. EC = 0x%08X\n", - LoadParams->EntryPoint, (unsigned int)StatusCode); + LoadParams->InitSymbolName, (unsigned int)StatusCode); ReturnCode = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; } } @@ -452,7 +446,7 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara { /* store the data in the app record after successful load+lookup */ LoadStatus->ModuleId = ModuleId; - LoadStatus->EntryAddress = StartAddr; + LoadStatus->InitSymbolAddress = InitSymbolAddress; } else if (OS_ObjectIdDefined(ModuleId)) { @@ -462,7 +456,7 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara 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); + ModuleName, (unsigned int)StatusCode); } } @@ -471,7 +465,7 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara /* **------------------------------------------------------------------------------------- -** Name: CFE_ES_GetAppEntryPoint +** Name: CFE_ES_GetTaskFunction ** ** 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 @@ -480,9 +474,11 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara ** **------------------------------------------------------------------------------------- */ -int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr) +int32 CFE_ES_GetTaskFunction(CFE_ES_TaskEntryFuncPtr_t *FuncPtr) { - CFE_ES_AppRecord_t *AppRecPtr; + CFE_ES_TaskRecord_t *TaskRecPtr; + CFE_ES_AppId_t AppId; + CFE_ES_TaskEntryFuncPtr_t EntryFunc; int32 ReturnCode; int32 Timeout; @@ -491,18 +487,23 @@ int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr) */ ReturnCode = CFE_ES_ERR_APP_REGISTER; Timeout = CFE_PLATFORM_ES_STARTUP_SCRIPT_TIMEOUT_MSEC; + AppId = CFE_ES_APPID_UNDEFINED; + EntryFunc = NULL; while(true) { OS_TaskDelay(CFE_PLATFORM_ES_STARTUP_SYNC_POLL_MSEC); CFE_ES_LockSharedData(__func__,__LINE__); - AppRecPtr = CFE_ES_GetAppRecordByContext(); - if (AppRecPtr != NULL) + TaskRecPtr = CFE_ES_GetTaskRecordByContext(); + if (TaskRecPtr != NULL) { - AppRecPtr->AppState = CFE_ES_AppState_EARLY_INIT; - *FuncPtr = (osal_task_entry)AppRecPtr->ModuleInfo.EntryAddress; - ReturnCode = CFE_SUCCESS; + AppId = TaskRecPtr->AppId; + EntryFunc = TaskRecPtr->EntryFunc; + if (CFE_RESOURCEID_TEST_DEFINED(AppId) && EntryFunc != 0) + { + ReturnCode = CFE_SUCCESS; + } } CFE_ES_UnlockSharedData(__func__,__LINE__); @@ -515,12 +516,18 @@ int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr) Timeout -= CFE_PLATFORM_ES_STARTUP_SYNC_POLL_MSEC; } + /* output function address to caller */ + if (FuncPtr != NULL) + { + *FuncPtr = EntryFunc; + } + return (ReturnCode); } /* **------------------------------------------------------------------------------------- -** Name: CFE_ES_AppEntryPoint +** Name: CFE_ES_TaskEntryPoint ** ** 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 @@ -529,11 +536,11 @@ int32 CFE_ES_GetAppEntryPoint(osal_task_entry *FuncPtr) ** **------------------------------------------------------------------------------------- */ -void CFE_ES_AppEntryPoint(void) +void CFE_ES_TaskEntryPoint(void) { - osal_task_entry RealEntryFunc; + CFE_ES_TaskEntryFuncPtr_t RealEntryFunc; - if (CFE_ES_GetAppEntryPoint(&RealEntryFunc) == CFE_SUCCESS && + if (CFE_ES_GetTaskFunction(&RealEntryFunc) == CFE_SUCCESS && RealEntryFunc != NULL) { (*RealEntryFunc)(); @@ -556,7 +563,7 @@ void CFE_ES_AppEntryPoint(void) ** **------------------------------------------------------------------------------------- */ -int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_AppId_t RefAppId, CFE_ES_TaskId_t *TaskIdPtr) +int32 CFE_ES_StartAppTask(CFE_ES_TaskId_t *TaskIdPtr, const char *TaskName, CFE_ES_TaskEntryFuncPtr_t EntryFunc, const CFE_ES_TaskStartParams_t* Params, CFE_ES_AppId_t ParentAppId) { CFE_ES_TaskRecord_t *TaskRecPtr; osal_id_t OsalTaskId; @@ -565,15 +572,15 @@ int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_App int32 ReturnCode; /* - ** Create the primary task for the newly loaded task + * 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 */ - OSAL_TASK_STACK_ALLOCATE, /* stack pointer (allocate) */ - StartParams->StackSize, /* stack size */ - StartParams->Priority, /* task priority */ - OS_FP_ENABLED); /* task options */ + StatusCode = OS_TaskCreate(&OsalTaskId, /* task id */ + TaskName, /* task name matches app name for main task */ + CFE_ES_TaskEntryPoint, /* task function pointer */ + OSAL_TASK_STACK_ALLOCATE, /* stack pointer (allocate) */ + Params->StackSize, /* stack size */ + Params->Priority, /* task priority */ + OS_FP_ENABLED); /* task options */ CFE_ES_LockSharedData(__func__,__LINE__); @@ -598,13 +605,17 @@ int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_App */ memset(TaskRecPtr, 0, sizeof(*TaskRecPtr)); - TaskRecPtr->AppId = RefAppId; - strncpy(TaskRecPtr->TaskName, StartParams->BasicInfo.Name, sizeof(TaskRecPtr->TaskName)-1); + TaskRecPtr->AppId = ParentAppId; + TaskRecPtr->EntryFunc = EntryFunc; + TaskRecPtr->StartParams = *Params; + + strncpy(TaskRecPtr->TaskName, TaskName, sizeof(TaskRecPtr->TaskName)-1); TaskRecPtr->TaskName[sizeof(TaskRecPtr->TaskName)-1] = 0; + CFE_ES_TaskRecordSetUsed(TaskRecPtr, CFE_RESOURCEID_UNWRAP(LocalTaskId)); /* - ** Increment the registered Task count. + * Increment the registered Task count. */ CFE_ES_Global.RegisteredTasks++; ReturnCode = CFE_SUCCESS; @@ -613,7 +624,7 @@ int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_App else { CFE_ES_SysLogWrite_Unsync("ES Startup: AppCreate Error: TaskCreate %s Failed. EC = 0x%08X!\n", - StartParams->BasicInfo.Name,(unsigned int)StatusCode); + TaskName,(unsigned int)StatusCode); ReturnCode = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; *TaskIdPtr = CFE_ES_TASKID_UNDEFINED; } @@ -634,28 +645,22 @@ int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_App ** **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, - const char *FileName, - const char *EntryPointName, - const char *AppName, - CFE_ES_TaskPriority_Atom_t Priority, - size_t StackSize, - CFE_ES_ExceptionAction_Enum_t ExceptionAction) +int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, const char *AppName, const CFE_ES_AppStartParams_t *Params) { CFE_Status_t Status; - CFE_ES_TaskId_t MainTaskId; CFE_ES_AppRecord_t *AppRecPtr; CFE_ResourceId_t PendingResourceId; /* - * The FileName must not be NULL + * The AppName must not be NULL */ - if (FileName == NULL || AppName == NULL) + if (AppName == NULL || Params == NULL) { return CFE_ES_BAD_ARGUMENT; } - if (strlen(AppName) >= OS_MAX_API_NAME) + /* Confirm name will fit inside the record */ + if (memchr(AppName,0,sizeof(AppRecPtr->AppName)) == NULL) { return CFE_ES_BAD_ARGUMENT; } @@ -705,27 +710,19 @@ int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, /* Fully clear the entry, just in case of stale data */ memset(AppRecPtr, 0, sizeof(*AppRecPtr)); + /* Store the app name from passed-in value */ + strncpy(AppRecPtr->AppName, AppName, sizeof(AppRecPtr->AppName)-1); + + AppRecPtr->Type = CFE_ES_AppType_EXTERNAL; + /* * Fill out the parameters in the StartParams sub-structure + * + * This contains all relevant info, including file name, entry point, + * main task info, etc. which is required to start the app now + * or in a future restart/reload request. */ - AppRecPtr->Type = CFE_ES_AppType_EXTERNAL; - strncpy(AppRecPtr->StartParams.BasicInfo.Name, AppName, - sizeof(AppRecPtr->StartParams.BasicInfo.Name)-1); - AppRecPtr->StartParams.BasicInfo.Name[sizeof(AppRecPtr->StartParams.BasicInfo.Name)-1] = '\0'; - strncpy(AppRecPtr->StartParams.BasicInfo.FileName, FileName, - sizeof(AppRecPtr->StartParams.BasicInfo.FileName)-1); - AppRecPtr->StartParams.BasicInfo.FileName[sizeof(AppRecPtr->StartParams.BasicInfo.FileName)-1] = '\0'; - if (EntryPointName != NULL && strcmp(EntryPointName, "NULL") != 0) - { - strncpy(AppRecPtr->StartParams.BasicInfo.EntryPoint, EntryPointName, - sizeof(AppRecPtr->StartParams.BasicInfo.EntryPoint)-1); - AppRecPtr->StartParams.BasicInfo.EntryPoint[ - sizeof(AppRecPtr->StartParams.BasicInfo.EntryPoint)-1] = '\0'; - } - - AppRecPtr->StartParams.StackSize = StackSize; - AppRecPtr->StartParams.ExceptionAction = ExceptionAction; - AppRecPtr->StartParams.Priority = Priority; + AppRecPtr->StartParams = *Params; /* * Fill out the Task State info @@ -753,18 +750,19 @@ int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, /* * Load the module based on StartParams configured above. */ - Status = CFE_ES_LoadModule(PendingResourceId, &AppRecPtr->StartParams.BasicInfo, &AppRecPtr->ModuleInfo); + Status = CFE_ES_LoadModule(PendingResourceId, AppName, &AppRecPtr->StartParams.BasicInfo, &AppRecPtr->LoadStatus); /* * If the Load was OK, then complete the initialization */ if (Status == CFE_SUCCESS) { - Status = CFE_ES_StartAppTask(&AppRecPtr->StartParams, CFE_ES_APPID_C(PendingResourceId), &MainTaskId); - } - else - { - MainTaskId = CFE_ES_TASKID_UNDEFINED; + Status = CFE_ES_StartAppTask(&AppRecPtr->MainTaskId, /* Task ID (output) stored in App Record as main task */ + AppName, /* Main Task name matches app name */ + (CFE_ES_TaskEntryFuncPtr_t)AppRecPtr->LoadStatus + .InitSymbolAddress, /* Init Symbol is main task entry point */ + &AppRecPtr->StartParams.MainTaskInfo, /* Main task parameters */ + CFE_ES_APPID_C(PendingResourceId)); /* Parent App ID */ } /* @@ -779,7 +777,6 @@ int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, * important - set the ID to its proper value * which turns this into a real/valid table entry */ - AppRecPtr->MainTaskId = MainTaskId; CFE_ES_AppRecordSetUsed(AppRecPtr, PendingResourceId); /* @@ -812,10 +809,7 @@ int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, ** **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, - const char *FileName, - const char *EntryPointName, - const char *LibName) +int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, const char *LibName, const CFE_ES_ModuleLoadParams_t *Params) { CFE_ES_LibraryEntryFuncPtr_t FunctionPointer; CFE_ES_LibRecord_t * LibSlotPtr; @@ -823,14 +817,15 @@ int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, CFE_ResourceId_t PendingResourceId; /* - * The FileName must not be NULL + * The LibName must not be NULL */ - if (FileName == NULL || LibName == NULL) + if (LibName == NULL || Params == NULL) { return CFE_ES_BAD_ARGUMENT; } - if (strlen(LibName) >= OS_MAX_API_NAME) + /* Confirm name will fit inside the record */ + if (memchr(LibName,0,sizeof(LibSlotPtr->LibName)) == NULL) { return CFE_ES_BAD_ARGUMENT; } @@ -889,18 +884,10 @@ int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, /* * Fill out the parameters in the AppStartParams sub-structure */ - strncpy(LibSlotPtr->BasicInfo.Name, LibName, - sizeof(LibSlotPtr->BasicInfo.Name)-1); - LibSlotPtr->BasicInfo.Name[sizeof(LibSlotPtr->BasicInfo.Name)-1] = '\0'; - strncpy(LibSlotPtr->BasicInfo.FileName, FileName, - sizeof(LibSlotPtr->BasicInfo.FileName)-1); - LibSlotPtr->BasicInfo.FileName[sizeof(LibSlotPtr->BasicInfo.FileName)-1] = '\0'; - if (EntryPointName != NULL && strcmp(EntryPointName, "NULL") != 0) - { - strncpy(LibSlotPtr->BasicInfo.EntryPoint, EntryPointName, - sizeof(LibSlotPtr->BasicInfo.EntryPoint)-1); - LibSlotPtr->BasicInfo.EntryPoint[sizeof(LibSlotPtr->BasicInfo.EntryPoint)-1] = '\0'; - } + strncpy(LibSlotPtr->LibName, LibName, + sizeof(LibSlotPtr->LibName)-1); + LibSlotPtr->LibName[sizeof(LibSlotPtr->LibName)-1] = '\0'; + LibSlotPtr->LoadParams = *Params; CFE_ES_LibRecordSetUsed(LibSlotPtr, CFE_RESOURCEID_RESERVED); CFE_ES_Global.LastLibId = PendingResourceId; @@ -923,10 +910,10 @@ int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, /* * Load the module based on StartParams configured above. */ - Status = CFE_ES_LoadModule(PendingResourceId, &LibSlotPtr->BasicInfo, &LibSlotPtr->ModuleInfo); + Status = CFE_ES_LoadModule(PendingResourceId, LibName, &LibSlotPtr->LoadParams, &LibSlotPtr->LoadStatus); if (Status == CFE_SUCCESS) { - FunctionPointer = (CFE_ES_LibraryEntryFuncPtr_t)LibSlotPtr->ModuleInfo.EntryAddress; + FunctionPointer = (CFE_ES_LibraryEntryFuncPtr_t)LibSlotPtr->LoadStatus.InitSymbolAddress; if (FunctionPointer != NULL) { Status = (*FunctionPointer)(CFE_ES_LIBID_C(PendingResourceId)); @@ -1112,7 +1099,8 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppId_t AppId) { CFE_ES_AppRecord_t *AppRecPtr; uint32 PendingControlReq; - CFE_ES_AppStartParams_t OrigStartParams; + CFE_ES_AppStartParams_t RestartParams; + char OrigAppName[OS_MAX_API_NAME]; CFE_Status_t CleanupStatus; CFE_Status_t StartupStatus; CFE_ES_AppId_t NewAppId; @@ -1129,8 +1117,11 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppId_t AppId) StartupStatus = CFE_SUCCESS; PendingControlReq = 0; NewAppId = CFE_ES_APPID_UNDEFINED; + OrigAppName[0] = 0; + memset(&RestartParams, 0, sizeof(RestartParams)); + AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); - memset(&OrigStartParams, 0, sizeof(OrigStartParams)); + /* @@ -1144,7 +1135,15 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppId_t AppId) if (CFE_ES_AppRecordIsMatch(AppRecPtr, AppId)) { PendingControlReq = AppRecPtr->ControlReq.AppControlRequest; - OrigStartParams = AppRecPtr->StartParams; + strncpy(OrigAppName, AppRecPtr->AppName, sizeof(OrigAppName)-1); + OrigAppName[sizeof(OrigAppName)-1] = 0; + + /* If a restart was requested, copy the parameters to re-use in new app */ + if ( PendingControlReq == CFE_ES_RunStatus_SYS_RESTART || + PendingControlReq == CFE_ES_RunStatus_SYS_RELOAD ) + { + RestartParams = AppRecPtr->StartParams; + } } CFE_ES_UnlockSharedData(__func__,__LINE__); @@ -1174,13 +1173,7 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppId_t AppId) 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); + StartupStatus = CFE_ES_AppCreate(&NewAppId, OrigAppName, &RestartParams); } /* @@ -1328,7 +1321,7 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppId_t AppId) } CFE_EVS_SendEvent(EventID, EventType, "%s Application %s %s", - ReqName, OrigStartParams.BasicInfo.Name, MessageDetail); + ReqName, OrigAppName, MessageDetail); } } /* End Function */ @@ -1379,7 +1372,7 @@ int32 CFE_ES_CleanUpApp(CFE_ES_AppId_t AppId) * * (this will be OS_OBJECT_ID_UNDEFINED if it was not loaded dynamically) */ - ModuleId = AppRecPtr->ModuleInfo.ModuleId; + ModuleId = AppRecPtr->LoadStatus.ModuleId; } /* @@ -1765,11 +1758,7 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_TaskId_t TaskId) */ void CFE_ES_CopyModuleBasicInfo(const CFE_ES_ModuleLoadParams_t *ParamsPtr, CFE_ES_AppInfo_t *AppInfoPtr) { - strncpy(AppInfoPtr->Name, ParamsPtr->Name, - sizeof(AppInfoPtr->Name)-1); - AppInfoPtr->Name[sizeof(AppInfoPtr->Name)-1] = '\0'; - - strncpy(AppInfoPtr->EntryPoint, ParamsPtr->EntryPoint, + strncpy(AppInfoPtr->EntryPoint, ParamsPtr->InitSymbolName, sizeof(AppInfoPtr->EntryPoint) - 1); AppInfoPtr->EntryPoint[sizeof(AppInfoPtr->EntryPoint) - 1] = '\0'; @@ -1790,7 +1779,7 @@ void CFE_ES_CopyModuleBasicInfo(const CFE_ES_ModuleLoadParams_t *ParamsPtr, CFE_ */ void CFE_ES_CopyModuleStatusInfo(const CFE_ES_ModuleLoadStatus_t *StatusPtr, CFE_ES_AppInfo_t *AppInfoPtr) { - AppInfoPtr->StartAddress = CFE_ES_MEMADDRESS_C(StatusPtr->EntryAddress); + AppInfoPtr->StartAddress = CFE_ES_MEMADDRESS_C(StatusPtr->InitSymbolAddress); } /* diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index abe038378..208a3b3d1 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -77,8 +77,7 @@ typedef struct */ typedef struct { - char Name[OS_MAX_API_NAME]; - char EntryPoint[OS_MAX_API_NAME]; + char InitSymbolName[OS_MAX_API_NAME]; char FileName[OS_MAX_PATH_LEN]; } CFE_ES_ModuleLoadParams_t; @@ -92,19 +91,31 @@ typedef struct */ typedef struct { - cpuaddr EntryAddress; osal_id_t ModuleId; + cpuaddr InitSymbolAddress; } CFE_ES_ModuleLoadStatus_t; +/* +** CFE_ES_TaskStartParams_t contains basic details about a CFE task +** +** This information needs to be specified when starting a task and is +** stored as part of the task record for future reference. +*/ +typedef struct +{ + size_t StackSize; + CFE_ES_TaskPriority_Atom_t Priority; + +} CFE_ES_TaskStartParams_t; + /* -** CFE_ES_AppStartParams_t is a structure of information used when an application is -** created in the system. +** CFE_ES_AppStartParams_t contains basic details about a CFE app. ** ** 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 +** about the main task and exception action. It is only used for apps, as libraries ** do not have a task associated. */ typedef struct @@ -112,30 +123,28 @@ typedef struct /* * Basic (static) information about the module */ - CFE_ES_ModuleLoadParams_t BasicInfo; + CFE_ES_ModuleLoadParams_t BasicInfo; - /* - * Extra information the pertains to applications only, not libraries. - */ - size_t StackSize; - CFE_ES_TaskPriority_Atom_t Priority; - CFE_ES_ExceptionAction_Enum_t ExceptionAction; + CFE_ES_TaskStartParams_t MainTaskInfo; + CFE_ES_ExceptionAction_Enum_t ExceptionAction; } CFE_ES_AppStartParams_t; + /* ** CFE_ES_AppRecord_t is an internal structure used to keep track of ** CFE Applications that are active in the system. */ typedef struct { - CFE_ES_AppId_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_TaskId_t MainTaskId; /* The Application's Main Task ID */ + CFE_ES_AppId_t AppId; /* The actual AppID of this entry, or undefined */ + char AppName[OS_MAX_API_NAME]; /* The name of the app */ + 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 LoadStatus; /* Runtime module information */ + CFE_ES_ControlReq_t ControlReq; /* The Control Request Record for External cFE Apps */ + CFE_ES_TaskId_t MainTaskId; /* The Application's Main Task ID */ } CFE_ES_AppRecord_t; @@ -146,11 +155,12 @@ typedef struct */ typedef struct { - CFE_ES_TaskId_t TaskId; /* The actual TaskID of this entry, or undefined */ - CFE_ES_AppId_t AppId; /* The parent Application's App ID */ - uint32 ExecutionCounter; /* The execution counter for the Child task */ - char TaskName[OS_MAX_API_NAME]; /* Task Name */ - + CFE_ES_TaskId_t TaskId; /* The actual TaskID of this entry, or undefined */ + char TaskName[OS_MAX_API_NAME]; /* Task Name */ + CFE_ES_AppId_t AppId; /* The parent Application's App ID */ + CFE_ES_TaskStartParams_t StartParams; /* The start parameters for the task */ + CFE_ES_TaskEntryFuncPtr_t EntryFunc; /* Task entry function */ + uint32 ExecutionCounter; /* The execution counter for the task */ } CFE_ES_TaskRecord_t; @@ -160,9 +170,11 @@ typedef struct */ typedef struct { - CFE_ES_LibId_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_LibId_t LibId; /* The actual LibID of this entry, or undefined */ + char LibName[OS_MAX_API_NAME]; /* Library Name */ + CFE_ES_ModuleLoadParams_t LoadParams; /* Basic (static) information about the module */ + CFE_ES_ModuleLoadStatus_t LoadStatus; /* Runtime information about the module */ + } CFE_ES_LibRecord_t; /* @@ -198,7 +210,7 @@ int32 CFE_ES_ParseFileEntry(const char **TokenList, uint32 NumTokens); ** This only loads the code and looks up relevent runtime information. ** It does not start any tasks. */ -int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus); +int32 CFE_ES_LoadModule(CFE_ResourceId_t ParentResourceId, const char *ModuleName, const CFE_ES_ModuleLoadParams_t* LoadParams, CFE_ES_ModuleLoadStatus_t *LoadStatus); /* ** Internal function to determine the entry point of an app. @@ -206,37 +218,29 @@ int32 CFE_ES_LoadModule(CFE_ResourceId_t ResourceId, const CFE_ES_ModuleLoadPara ** 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); +int32 CFE_ES_GetTaskFunction(CFE_ES_TaskEntryFuncPtr_t *FuncPtr); /* -** Intermediate entry point of an app. Determines the actual +** Intermediate entry point of all tasks. Determines the actual ** entry point from the global data structures. */ -void CFE_ES_AppEntryPoint(void); +void CFE_ES_TaskEntryPoint(void); /* -** Internal function to start the main task of an app. +** Internal function to start a task associated with an app. */ -int32 CFE_ES_StartAppTask(const CFE_ES_AppStartParams_t* StartParams, CFE_ES_AppId_t RefAppId, CFE_ES_TaskId_t *TaskIdPtr); +int32 CFE_ES_StartAppTask(CFE_ES_TaskId_t *TaskIdPtr, const char *TaskName, CFE_ES_TaskEntryFuncPtr_t EntryFunc, const CFE_ES_TaskStartParams_t* Params, CFE_ES_AppId_t ParentAppId); /* ** Internal function to create/start a new cFE app ** based on the parameters passed in */ -int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, - const char *FileName, - const char *EntryPointName, - const char *AppName, - CFE_ES_TaskPriority_Atom_t Priority, - size_t StackSize, - CFE_ES_ExceptionAction_Enum_t ExceptionAction); +int32 CFE_ES_AppCreate(CFE_ES_AppId_t *ApplicationIdPtr, const char *AppName, const CFE_ES_AppStartParams_t *Params); + /* ** Internal function to load a a new cFE shared Library */ -int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, - const char *FileName, - const char *EntryPointName, - const char *LibName); +int32 CFE_ES_LoadLibrary(CFE_ES_LibId_t *LibraryIdPtr, const char *LibName, const CFE_ES_ModuleLoadParams_t *Params); /* ** Scan the Application Table for actions to take diff --git a/fsw/cfe-core/src/es/cfe_es_objtab.c b/fsw/cfe-core/src/es/cfe_es_objtab.c index 88bca7540..18c4c3287 100644 --- a/fsw/cfe-core/src/es/cfe_es_objtab.c +++ b/fsw/cfe-core/src/es/cfe_es_objtab.c @@ -129,7 +129,7 @@ CFE_ES_ObjectTable_t CFE_ES_ObjectTable[CFE_PLATFORM_ES_OBJECT_TABLE_SIZE] = { .ObjectType = CFE_ES_CORE_TASK, .ObjectName = "CFE_EVS", - .FuncPtrUnion.MainAppPtr = CFE_EVS_TaskMain, + .FuncPtrUnion.MainTaskPtr = CFE_EVS_TaskMain, .ObjectPriority = CFE_PLATFORM_EVS_START_TASK_PRIORITY, .ObjectSize = CFE_PLATFORM_EVS_START_TASK_STACK_SIZE }, @@ -139,7 +139,7 @@ CFE_ES_ObjectTable_t CFE_ES_ObjectTable[CFE_PLATFORM_ES_OBJECT_TABLE_SIZE] = { .ObjectType = CFE_ES_CORE_TASK, .ObjectName = "CFE_SB", - .FuncPtrUnion.MainAppPtr = CFE_SB_TaskMain, + .FuncPtrUnion.MainTaskPtr = CFE_SB_TaskMain, .ObjectPriority = CFE_PLATFORM_SB_START_TASK_PRIORITY, .ObjectSize = CFE_PLATFORM_SB_START_TASK_STACK_SIZE }, @@ -149,7 +149,7 @@ CFE_ES_ObjectTable_t CFE_ES_ObjectTable[CFE_PLATFORM_ES_OBJECT_TABLE_SIZE] = { .ObjectType = CFE_ES_CORE_TASK, .ObjectName = "CFE_ES", - .FuncPtrUnion.MainAppPtr = CFE_ES_TaskMain, + .FuncPtrUnion.MainTaskPtr = CFE_ES_TaskMain, .ObjectPriority = CFE_PLATFORM_ES_START_TASK_PRIORITY, .ObjectSize = CFE_PLATFORM_ES_START_TASK_STACK_SIZE }, @@ -159,7 +159,7 @@ CFE_ES_ObjectTable_t CFE_ES_ObjectTable[CFE_PLATFORM_ES_OBJECT_TABLE_SIZE] = { .ObjectType = CFE_ES_CORE_TASK, .ObjectName = "CFE_TIME", - .FuncPtrUnion.MainAppPtr = CFE_TIME_TaskMain, + .FuncPtrUnion.MainTaskPtr = CFE_TIME_TaskMain, .ObjectPriority = CFE_PLATFORM_TIME_START_TASK_PRIORITY, .ObjectSize = CFE_PLATFORM_TIME_START_TASK_STACK_SIZE }, @@ -169,7 +169,7 @@ CFE_ES_ObjectTable_t CFE_ES_ObjectTable[CFE_PLATFORM_ES_OBJECT_TABLE_SIZE] = { .ObjectType = CFE_ES_CORE_TASK, .ObjectName = "CFE_TBL", - .FuncPtrUnion.MainAppPtr = CFE_TBL_TaskMain, + .FuncPtrUnion.MainTaskPtr = CFE_TBL_TaskMain, .ObjectPriority = CFE_PLATFORM_TBL_START_TASK_PRIORITY, .ObjectSize = CFE_PLATFORM_TBL_START_TASK_STACK_SIZE }, diff --git a/fsw/cfe-core/src/es/cfe_es_resource.h b/fsw/cfe-core/src/es/cfe_es_resource.h index 9cbaa840d..efdb8280a 100644 --- a/fsw/cfe-core/src/es/cfe_es_resource.h +++ b/fsw/cfe-core/src/es/cfe_es_resource.h @@ -173,7 +173,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.BasicInfo.Name; + return AppRecPtr->AppName; } @@ -266,7 +266,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->BasicInfo.Name; + return LibRecPtr->LibName; } diff --git a/fsw/cfe-core/src/es/cfe_es_start.c b/fsw/cfe-core/src/es/cfe_es_start.c index 5fcf246e7..da0538c4c 100644 --- a/fsw/cfe-core/src/es/cfe_es_start.c +++ b/fsw/cfe-core/src/es/cfe_es_start.c @@ -743,7 +743,6 @@ void CFE_ES_CreateObjects(void) uint16 i; CFE_ES_AppRecord_t *AppRecPtr; CFE_ResourceId_t PendingAppId; - CFE_ES_TaskId_t PendingTaskId; CFE_ES_WriteToSysLog("ES Startup: Starting Object Creation calls.\n"); @@ -767,15 +766,15 @@ void CFE_ES_CreateObjects(void) ** 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); - AppRecPtr->StartParams.BasicInfo.Name[sizeof(AppRecPtr->StartParams.BasicInfo.Name)-1] = '\0'; + + strncpy(AppRecPtr->AppName, CFE_ES_ObjectTable[i].ObjectName, + sizeof(AppRecPtr->AppName)-1); + AppRecPtr->AppName[sizeof(AppRecPtr->AppName)-1] = '\0'; /* FileName and EntryPoint is not valid for core apps */ - AppRecPtr->StartParams.StackSize = CFE_ES_ObjectTable[i].ObjectSize; + AppRecPtr->StartParams.MainTaskInfo.StackSize = CFE_ES_ObjectTable[i].ObjectSize; + AppRecPtr->StartParams.MainTaskInfo.Priority = CFE_ES_ObjectTable[i].ObjectPriority; 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 @@ -798,7 +797,11 @@ void CFE_ES_CreateObjects(void) ** Start the core app main task ** (core apps are already in memory - no loading needed) */ - ReturnCode = CFE_ES_StartAppTask(&AppRecPtr->StartParams, CFE_ES_APPID_C(PendingAppId), &PendingTaskId); + ReturnCode = CFE_ES_StartAppTask(&AppRecPtr->MainTaskId, + AppRecPtr->AppName, + CFE_ES_ObjectTable[i].FuncPtrUnion.MainTaskPtr, + &AppRecPtr->StartParams.MainTaskInfo, + CFE_ES_APPID_C(PendingAppId)); /* * Finalize data in the app table entry, which must be done under lock. @@ -809,7 +812,6 @@ void CFE_ES_CreateObjects(void) if ( ReturnCode == OS_SUCCESS ) { - AppRecPtr->MainTaskId = PendingTaskId; CFE_ES_AppRecordSetUsed(AppRecPtr, PendingAppId); /* diff --git a/fsw/cfe-core/src/es/cfe_es_start.h b/fsw/cfe-core/src/es/cfe_es_start.h index e98990cc8..119df0a5a 100644 --- a/fsw/cfe-core/src/es/cfe_es_start.h +++ b/fsw/cfe-core/src/es/cfe_es_start.h @@ -62,12 +62,11 @@ */ typedef int32 (*CFE_ES_EarlyInitFuncPtr_t)(void); /**< \brief Req'd prototype of Early Init Functions */ -typedef void (*CFE_ES_MainAppFuncPtr_t)(void); /**< \brief Req'd prototype of Application Main Functions */ typedef union { CFE_ES_EarlyInitFuncPtr_t FunctionPtr; - CFE_ES_MainAppFuncPtr_t MainAppPtr; + CFE_ES_TaskEntryFuncPtr_t MainTaskPtr; void *VoidPtr; } CFE_ES_FuncPtrUnion_t; diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 3f7696876..54de717ab 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -849,19 +849,18 @@ int32 CFE_ES_StartAppCmd(const CFE_ES_StartAppCmd_t *data) int32 FilenameLen; int32 AppEntryLen; int32 AppNameLen; - size_t AppStackSize; - char LocalFile[OS_MAX_PATH_LEN]; - char LocalEntryPt[OS_MAX_API_NAME]; char LocalAppName[OS_MAX_API_NAME]; + CFE_ES_AppStartParams_t StartParams; + /* Create local copies of all input strings and ensure null termination */ - FilenameLen = CFE_SB_MessageStringGet(LocalFile, (char *)cmd->AppFileName, NULL, - sizeof(LocalFile), sizeof(cmd->AppFileName)); + FilenameLen = CFE_SB_MessageStringGet(StartParams.BasicInfo.FileName, cmd->AppFileName, NULL, + sizeof(StartParams.BasicInfo.FileName), sizeof(cmd->AppFileName)); - AppEntryLen = CFE_SB_MessageStringGet(LocalEntryPt, (char *)cmd->AppEntryPoint, NULL, - sizeof(LocalEntryPt), sizeof(cmd->AppEntryPoint)); + AppEntryLen = CFE_SB_MessageStringGet(StartParams.BasicInfo.InitSymbolName, cmd->AppEntryPoint, NULL, + sizeof(StartParams.BasicInfo.InitSymbolName), sizeof(cmd->AppEntryPoint)); - AppNameLen = CFE_SB_MessageStringGet(LocalAppName, (char *)cmd->Application, NULL, + AppNameLen = CFE_SB_MessageStringGet(LocalAppName, cmd->Application, NULL, sizeof(LocalAppName), sizeof(cmd->Application)); /* @@ -872,19 +871,19 @@ int32 CFE_ES_StartAppCmd(const CFE_ES_StartAppCmd_t *data) CFE_ES_TaskData.CommandErrorCounter++; CFE_EVS_SendEvent(CFE_ES_START_INVALID_FILENAME_ERR_EID, CFE_EVS_EventType_ERROR, "CFE_ES_StartAppCmd: invalid filename: %s", - LocalFile); + StartParams.BasicInfo.FileName); } else if (AppEntryLen <= 0) { CFE_ES_TaskData.CommandErrorCounter++; CFE_EVS_SendEvent(CFE_ES_START_INVALID_ENTRY_POINT_ERR_EID, CFE_EVS_EventType_ERROR, - "CFE_ES_StartAppCmd: App Entry Point is NULL."); + "CFE_ES_StartAppCmd: App Entry Point is empty."); } else if (AppNameLen <= 0) { CFE_ES_TaskData.CommandErrorCounter++; CFE_EVS_SendEvent(CFE_ES_START_NULL_APP_NAME_ERR_EID, CFE_EVS_EventType_ERROR, - "CFE_ES_StartAppCmd: App Name is NULL."); + "CFE_ES_StartAppCmd: App Name is empty."); } else if (cmd->Priority > OS_MAX_PRIORITY) { @@ -906,22 +905,20 @@ int32 CFE_ES_StartAppCmd(const CFE_ES_StartAppCmd_t *data) /* If stack size was provided, use it, otherwise use default. */ if (cmd->StackSize == 0) { - AppStackSize = CFE_PLATFORM_ES_DEFAULT_STACK_SIZE; + StartParams.MainTaskInfo.StackSize = CFE_PLATFORM_ES_DEFAULT_STACK_SIZE; } else { - AppStackSize = cmd->StackSize; + StartParams.MainTaskInfo.StackSize = cmd->StackSize; } + StartParams.MainTaskInfo.Priority = cmd->Priority; + StartParams.ExceptionAction = cmd->ExceptionAction; + /* ** Invoke application loader/startup function. */ - Result = CFE_ES_AppCreate(&AppID, LocalFile, - LocalEntryPt, - LocalAppName, - cmd->Priority, - AppStackSize, - cmd->ExceptionAction); + Result = CFE_ES_AppCreate(&AppID, LocalAppName, &StartParams); /* ** Send appropriate event message @@ -931,14 +928,14 @@ int32 CFE_ES_StartAppCmd(const CFE_ES_StartAppCmd_t *data) CFE_ES_TaskData.CommandCounter++; CFE_EVS_SendEvent(CFE_ES_START_INF_EID, CFE_EVS_EventType_INFORMATION, "Started %s from %s, AppID = %lu", - LocalAppName, LocalFile, CFE_RESOURCEID_TO_ULONG(AppID)); + LocalAppName, StartParams.BasicInfo.FileName, CFE_RESOURCEID_TO_ULONG(AppID)); } else { CFE_ES_TaskData.CommandErrorCounter++; CFE_EVS_SendEvent(CFE_ES_START_ERR_EID, CFE_EVS_EventType_ERROR, "Failed to start %s from %s, RC = 0x%08X", - LocalAppName, LocalFile, (unsigned int)Result); + LocalAppName, StartParams.BasicInfo.FileName, (unsigned int)Result); } } /* End if -- command parameter validation */ diff --git a/fsw/cfe-core/src/inc/cfe_es.h b/fsw/cfe-core/src/inc/cfe_es.h index 499fe397f..23eaa9649 100644 --- a/fsw/cfe-core/src/inc/cfe_es.h +++ b/fsw/cfe-core/src/inc/cfe_es.h @@ -140,11 +140,18 @@ */ /* -** Child Task Main Function Prototype +** Entry Function Prototypes */ -typedef void (*CFE_ES_ChildTaskMainFuncPtr_t)(void); /**< \brief Required Prototype of Child Task Main Functions */ +typedef void (*CFE_ES_TaskEntryFuncPtr_t)(void); /**< \brief Required Prototype of Task Main Functions */ typedef int32 (*CFE_ES_LibraryEntryFuncPtr_t)(CFE_ES_LibId_t LibId); /**< \brief Required Prototype of Library Initialization Functions */ +/** + * \brief Compatible typedef for ES child task entry point. + * + * All ES task functions (main + child) use the same entry point type. + */ +typedef CFE_ES_TaskEntryFuncPtr_t CFE_ES_ChildTaskMainFuncPtr_t; + /** * @brief Type for the stack pointer of tasks. * diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 629abd399..800429ec8 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -275,6 +275,51 @@ CFE_ResourceId_t ES_UT_MakeCDSIdForIndex(uint32 ArrayIdx) return CFE_ResourceId_FromInteger(ArrayIdx + CFE_ES_CDSBLOCKID_BASE); } +/* + * A local stub that can serve as the user function for testing ES tasks + */ +void ES_UT_TaskFunction(void) +{ + UT_DEFAULT_IMPL(ES_UT_TaskFunction); +} + +/* + * Helper function to assemble basic bits of info into the "CFE_ES_ModuleLoadParams_t" struct + */ +void ES_UT_SetupModuleLoadParams(CFE_ES_ModuleLoadParams_t *Params, const char *FileName, const char *EntryName) +{ + char Empty = 0; + + if (FileName == NULL) + { + FileName = &Empty; + } + + if (EntryName == NULL) + { + EntryName = &Empty; + } + + strncpy(Params->FileName, FileName, sizeof(Params->FileName)); + strncpy(Params->InitSymbolName, EntryName, sizeof(Params->InitSymbolName)); +} + +/* + * Helper function to assemble basic bits of info into the "CFE_ES_AppStartParams_t" struct + */ +void ES_UT_SetupAppStartParams(CFE_ES_AppStartParams_t *Params, const char *FileName, const char *EntryName, + size_t StackSize, CFE_ES_TaskPriority_Atom_t Priority, + CFE_ES_ExceptionAction_Enum_t ExceptionAction) +{ + ES_UT_SetupModuleLoadParams(&Params->BasicInfo, FileName, EntryName); + Params->MainTaskInfo.StackSize = StackSize; + Params->MainTaskInfo.Priority = Priority; + Params->ExceptionAction = ExceptionAction; +} + + + + /* * Helper function to setup a single app ID in the given state, along with * a main task ID. A pointer to the App and Task record is output so the @@ -306,11 +351,9 @@ void ES_UT_SetupSingleAppId(CFE_ES_AppType_Enum_t AppType, CFE_ES_AppState_Enum_ if (AppName) { - 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); + strncpy(LocalAppPtr->AppName, AppName, sizeof(LocalAppPtr->AppName)-1); + LocalAppPtr->AppName[sizeof(LocalAppPtr->AppName)-1] = 0; + strncpy(LocalTaskPtr->TaskName, AppName, sizeof(LocalTaskPtr->TaskName)-1); LocalTaskPtr->TaskName[sizeof(LocalTaskPtr->TaskName)-1] = 0; } @@ -332,7 +375,7 @@ void ES_UT_SetupSingleAppId(CFE_ES_AppType_Enum_t AppType, CFE_ES_AppState_Enum_ ++CFE_ES_Global.RegisteredExternalApps; OS_ModuleLoad(&UtOsalId, NULL, NULL, 0); - LocalAppPtr->ModuleInfo.ModuleId = UtOsalId; + LocalAppPtr->LoadStatus.ModuleId = UtOsalId; } ++CFE_ES_Global.RegisteredTasks; } @@ -391,9 +434,9 @@ void ES_UT_SetupSingleLibId(const char *LibName, CFE_ES_LibRecord_t **OutLibRec) if (LibName) { - strncpy(LocalLibPtr->BasicInfo.Name, LibName, - sizeof(LocalLibPtr->BasicInfo.Name)-1); - LocalLibPtr->BasicInfo.Name[sizeof(LocalLibPtr->BasicInfo.Name)-1] = 0; + strncpy(LocalLibPtr->LibName, LibName, + sizeof(LocalLibPtr->LibName)-1); + LocalLibPtr->LibName[sizeof(LocalLibPtr->LibName)-1] = 0; } if (OutLibRec) @@ -1168,6 +1211,7 @@ void TestApps(void) CFE_ES_AppRecord_t *UtAppRecPtr; CFE_ES_MemPoolRecord_t *UtPoolRecPtr; char NameBuffer[OS_MAX_API_NAME+5]; + CFE_ES_AppStartParams_t StartParams; UtPrintf("Begin Test Apps"); @@ -1271,25 +1315,23 @@ void TestApps(void) /* Test application loading and creation with a task creation failure */ ES_ResetUnitTest(); UT_SetDefaultReturnValue(UT_KEY(OS_TaskCreate), OS_ERROR); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename", "EntryPoint", - "AppName", 170, 4096, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); 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 */ + /* Test application creation with NULL parameters */ ES_ResetUnitTest(); Return = CFE_ES_AppCreate(&AppId, - NULL, - "EntryPoint", "AppName", - 170, - 4096, - 1); + NULL); UT_Report(__FILE__, __LINE__, Return == CFE_ES_BAD_ARGUMENT, "CFE_ES_AppCreate", @@ -1298,13 +1340,15 @@ void TestApps(void) /* Test application creation with name too long */ memset(NameBuffer, 'x', sizeof(NameBuffer)-1); NameBuffer[sizeof(NameBuffer)-1] = 0; - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - NameBuffer, 170, 4096, 1); + Return = CFE_ES_AppCreate(&AppId, + NameBuffer, + &StartParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_BAD_ARGUMENT, "CFE_ES_AppCreate", @@ -1313,26 +1357,30 @@ void TestApps(void) /* Test successful application loading and creation */ ES_ResetUnitTest(); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS, "CFE_ES_AppCreate", "Application load/create; successful"); /* Test application loading of the same name again */ - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_ERR_DUPLICATE_NAME, "CFE_ES_AppCreate", @@ -1341,26 +1389,30 @@ void TestApps(void) /* Test application loading and creation where the file cannot be loaded */ UT_InitData(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleLoad), 1, -1); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName2", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName2", + &StartParams); 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(); UT_SetDefaultReturnValue(UT_KEY(CFE_ResourceId_FindNext), OS_ERROR); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_NO_RESOURCE_IDS_AVAILABLE && UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_NO_FREE_APP_SLOTS]), @@ -1378,13 +1430,15 @@ void TestApps(void) */ ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleSymbolLookup), 1, -1); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); UtAssert_NONZERO(UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_FIND_SYMBOL])); @@ -1395,13 +1449,15 @@ void TestApps(void) ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleSymbolLookup), 1, -1); UT_SetDeferredRetcode(UT_KEY(OS_ModuleUnload), 1, -1); - Return = CFE_ES_AppCreate(&AppId, + ES_UT_SetupAppStartParams(&StartParams, "ut/filename.x", "EntryPoint", - "AppName", 170, 8192, 1); + Return = CFE_ES_AppCreate(&AppId, + "AppName", + &StartParams); 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])); @@ -1487,15 +1543,12 @@ 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(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/Filename", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, - "NotNULL", sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/Filename", + "NotNULL", + 8192, + 255, + 0); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_EXIT; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1556,7 +1609,7 @@ 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->ModuleInfo.ModuleId, NULL, NULL, 0); + OS_ModuleLoad(&UtAppRecPtr->LoadStatus.ModuleId, NULL, NULL, 0); UT_SetDefaultReturnValue(UT_KEY(OS_TaskCreate), OS_ERROR); AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); CFE_ES_ProcessControlRequest(AppId); @@ -1587,7 +1640,7 @@ 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->ModuleInfo.ModuleId, NULL, NULL, 0); + OS_ModuleLoad(&UtAppRecPtr->LoadStatus.ModuleId, NULL, NULL, 0); UT_SetDefaultReturnValue(UT_KEY(OS_TaskCreate), OS_ERROR); AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); CFE_ES_ProcessControlRequest(AppId); @@ -1601,15 +1654,13 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/FileName", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", - sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/FileName", + "NULL", + 8192, + 255, + 0); + UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_ERROR; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1637,15 +1688,12 @@ 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(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/FileName", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", - sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/FileName", + "NULL", + 8192, + 255, + 0); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1658,15 +1706,12 @@ 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(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/FileName", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", - sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/FileName", + "NULL", + 8192, + 255, + 0); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RESTART; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1679,15 +1724,12 @@ 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(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/FileName", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) -1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) -1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", - sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/FileName", + "NULL", + 8192, + 255, + 0); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1702,15 +1744,12 @@ void TestApps(void) */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); - strncpy(UtAppRecPtr->StartParams.BasicInfo.FileName, - "/ram/FileName", sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1); - UtAppRecPtr->StartParams.BasicInfo.FileName[sizeof(UtAppRecPtr->StartParams.BasicInfo.FileName) - 1] = '\0'; - strncpy(UtAppRecPtr->StartParams.BasicInfo.EntryPoint, "NULL", - sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1); - UtAppRecPtr->StartParams.BasicInfo.EntryPoint[sizeof(UtAppRecPtr->StartParams.BasicInfo.EntryPoint) - 1] = '\0'; - UtAppRecPtr->StartParams.Priority = 255; - UtAppRecPtr->StartParams.StackSize = 8192; - UtAppRecPtr->StartParams.ExceptionAction = 0; + ES_UT_SetupAppStartParams(&UtAppRecPtr->StartParams, + "/ram/FileName", + "NULL", + 8192, + 255, + 0); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_EXCEPTION; AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -1781,7 +1820,7 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); ES_UT_SetupForOSCleanup(); - OS_ModuleLoad(&UtAppRecPtr->ModuleInfo.ModuleId, NULL, NULL, 0); + OS_ModuleLoad(&UtAppRecPtr->LoadStatus.ModuleId, NULL, NULL, 0); UT_SetDefaultReturnValue(UT_KEY(OS_TaskDelete), OS_ERROR); UT_SetDefaultReturnValue(UT_KEY(OS_close), OS_ERROR); AppId = CFE_ES_AppRecordGetID(UtAppRecPtr); @@ -2156,36 +2195,29 @@ void TestResourceID(void) void TestLibs(void) { CFE_ES_LibRecord_t *UtLibRecPtr; - char LongLibraryName[sizeof(UtLibRecPtr->BasicInfo.Name)+1]; + char LongLibraryName[sizeof(UtLibRecPtr->LibName)+1]; CFE_ES_LibId_t Id; int32 Return; + CFE_ES_ModuleLoadParams_t LoadParams; /* Test shared library loading and initialization where the initialization * routine returns an error */ ES_ResetUnitTest(); UT_SetDummyFuncRtn(-444); - Return = CFE_ES_LoadLibrary(&Id, - "filename", - "EntryPoint", - "LibName"); + ES_UT_SetupModuleLoadParams(&LoadParams, "filename", "entrypt"); + Return = CFE_ES_LoadLibrary(&Id, "LibName", &LoadParams); 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, - NULL, - "EntryPoint", - "LibName"); + Return = CFE_ES_LoadLibrary(&Id, "LibName", NULL); UT_Report(__FILE__, __LINE__, Return == CFE_ES_BAD_ARGUMENT, "CFE_ES_LoadLibrary", "Load shared library bad argument (NULL filename)"); - Return = CFE_ES_LoadLibrary(&Id, - "filename", - "EntryPoint", - NULL); + Return = CFE_ES_LoadLibrary(&Id, NULL, &LoadParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_BAD_ARGUMENT, "CFE_ES_LoadLibrary", @@ -2194,10 +2226,7 @@ void TestLibs(void) /* Test Load library returning an error on a too long library name */ memset(LongLibraryName, 'a', sizeof(LongLibraryName)-1); LongLibraryName[sizeof(LongLibraryName)-1] = '\0'; - Return = CFE_ES_LoadLibrary(&Id, - "filename", - "EntryPoint", - &LongLibraryName[0]); + Return = CFE_ES_LoadLibrary(&Id, LongLibraryName, &LoadParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_BAD_ARGUMENT, "CFE_ES_LoadLibrary", @@ -2206,10 +2235,7 @@ void TestLibs(void) /* Test successful shared library loading and initialization */ UT_InitData(); UT_SetDummyFuncRtn(OS_SUCCESS); - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle", - "TST_LIB_Init", - "TST_LIB"); + Return = CFE_ES_LoadLibrary(&Id, "TST_LIB", &LoadParams); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS, "CFE_ES_LoadLibrary", @@ -2220,10 +2246,7 @@ void TestLibs(void) UtAssert_True(CFE_ES_LibRecordIsUsed(UtLibRecPtr), "CFE_ES_LoadLibrary() record used"); /* Try loading same library again, should return the DUPLICATE code */ - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle", - "TST_LIB_Init", - "TST_LIB"); + Return = CFE_ES_LoadLibrary(&Id, "TST_LIB", &LoadParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_ERR_DUPLICATE_NAME, "CFE_ES_LoadLibrary", @@ -2236,10 +2259,7 @@ void TestLibs(void) */ ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleLoad), 1, -1); - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle", - "TST_LIB_Init", - "TST_LIB"); + Return = CFE_ES_LoadLibrary(&Id, "TST_LIB", &LoadParams); UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); /* Test shared library loading and initialization where the library @@ -2247,10 +2267,7 @@ void TestLibs(void) */ ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleSymbolLookup), 1, -1); - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle", - "TST_LIB_Init", - "TST_LIB"); + Return = CFE_ES_LoadLibrary(&Id, "TST_LIB", &LoadParams); UtAssert_INT32_EQ(Return, CFE_STATUS_EXTERNAL_RESOURCE_FAIL); /* Test shared library loading and initialization where the library @@ -2259,10 +2276,8 @@ void TestLibs(void) ES_ResetUnitTest(); UT_SetDefaultReturnValue(UT_KEY(OS_remove), OS_ERROR); /* for coverage of error path */ UT_SetDefaultReturnValue(UT_KEY(dummy_function), -555); - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle", - "dummy_function", - "TST_LIB"); + ES_UT_SetupModuleLoadParams(&LoadParams, "filename", "dummy_function"); + Return = CFE_ES_LoadLibrary(&Id, "TST_LIB", &LoadParams); UT_Report(__FILE__, __LINE__, Return == -555, "CFE_ES_LoadLibrary", @@ -2273,10 +2288,7 @@ void TestLibs(void) */ ES_ResetUnitTest(); UT_SetDefaultReturnValue(UT_KEY(CFE_ResourceId_FindNext), OS_ERROR); - Return = CFE_ES_LoadLibrary(&Id, - "filename", - "EntryPoint", - "LibName"); + Return = CFE_ES_LoadLibrary(&Id, "LibName", &LoadParams); UT_Report(__FILE__, __LINE__, Return == CFE_ES_NO_RESOURCE_IDS_AVAILABLE && UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_LIBRARY_SLOTS]), @@ -4870,7 +4882,7 @@ void TestAPI(void) 400, 0); UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_CHILD_TASK_CREATE, + Return == CFE_STATUS_EXTERNAL_RESOURCE_FAIL, "CFE_ES_ChildTaskCreate", "OS task create failed"); @@ -4962,6 +4974,26 @@ void TestAPI(void) Return == CFE_SUCCESS, "CFE_ES_CreateChildTask", "Create child task successful"); + /* Test common entry point */ + ES_ResetUnitTest(); + + /* + * Without no app/task set up the entry point will not be found. + * There is no return value to check here, it just will not do anything. + */ + CFE_ES_TaskEntryPoint(); + + /* Now set up an app+task */ + ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, &UtTaskRecPtr); + + /* Test with app/task set up but no entry point defined */ + CFE_ES_TaskEntryPoint(); + + /* Finally set entry point, nominal mode */ + UtTaskRecPtr->EntryFunc = ES_UT_TaskFunction; + CFE_ES_TaskEntryPoint(); + UtAssert_STUB_COUNT(ES_UT_TaskFunction, 1); + /* Test deleting a child task using a main task's ID */ ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, "UT", NULL, &UtTaskRecPtr);