From 221803661e56b2d76c1866b4fbd374265c2e7e1d Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 20 May 2020 14:39:11 -0400 Subject: [PATCH 1/8] Fix #479, add name association to stub arguments Add the capability to store parameter names in addtion to pointers as part of the stub argument context data. Macroize the UT_Stub_RegisterContext function utstubs.h to also pass the parameter name in addition to the pointer. Also add hook-side accessor functions/macros to make it easier and more reliable to get this information from the context data. --- ut_assert/inc/utstubs.h | 102 ++++++++++++++++++++++++++++++++++++- ut_assert/src/utstubs.c | 109 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 4 deletions(-) diff --git a/ut_assert/inc/utstubs.h b/ut_assert/inc/utstubs.h index 765fd506d..afe0fb170 100644 --- a/ut_assert/inc/utstubs.h +++ b/ut_assert/inc/utstubs.h @@ -53,8 +53,29 @@ typedef cpuaddr UT_EntryKey_t; * Maximum size of a callback hook context list * * This is the maximum number of function arguments that can be passed to a hook + * Note that OS_TaskCreate() has (possibly) the highest parameter count in OSAL with 7 parameters */ -#define UT_STUBCONTEXT_MAXSIZE 4 +#define UT_STUBCONTEXT_MAXSIZE 8 + +/** + * Identifies the type of value stored in the ArgPtr field of a UT_StubContext_t object + */ +typedef enum +{ + UT_STUBCONTEXT_ARG_TYPE_UNSPECIFIED = 0, + UT_STUBCONTEXT_ARG_TYPE_DIRECT, /**< Indicates "ArgPtr" is a direct copy of the actual parameter value */ + UT_STUBCONTEXT_ARG_TYPE_INDIRECT /**< Indicates "ArgPtr" is a pointer to the argument value on the stack */ +} UT_StubContext_Arg_Type_t; + +/** + * Complete Metadata associated with a context argument + */ +typedef struct +{ + UT_StubContext_Arg_Type_t Type; + const char *Name; + size_t Size; +} UT_StubArgMetaData_t; /** * Structure to hold context data for callback hooks @@ -63,6 +84,7 @@ typedef struct { uint32 ArgCount; const void *ArgPtr[UT_STUBCONTEXT_MAXSIZE]; + UT_StubArgMetaData_t Meta[UT_STUBCONTEXT_MAXSIZE]; } UT_StubContext_t; /** @@ -311,10 +333,70 @@ uint32 UT_Stub_CopyFromLocal(UT_EntryKey_t FuncKey, const void *LocalBuffer, uin * passed as "void *" pointers to the actual stack values. The user code must * then cast them to the right type again. * + * This is now implemented as a macro which calls UT_Stub_RegisterContextWithMetaData + * to associate the name of the argument as well as the pointer. + * * \param FuncKey The stub function to entry to use. * \param Parameter Arbitrary parameter to pass. */ -void UT_Stub_RegisterContext(UT_EntryKey_t FuncKey, const void *Parameter); +#define UT_Stub_RegisterContext(FuncKey, Parameter) \ + UT_Stub_RegisterContextWithMetaData(FuncKey, #Parameter, UT_STUBCONTEXT_ARG_TYPE_UNSPECIFIED, Parameter, 0) + +/** + * Registers a single value argument into the context for the hook callback + * + * A pointer to the stack value is actually stored into the context, + * which can be dereferenced in the hook. + */ +#define UT_Stub_RegisterContextGenericArg(FuncKey, Parameter) \ + UT_Stub_RegisterContextWithMetaData(FuncKey, #Parameter, UT_STUBCONTEXT_ARG_TYPE_INDIRECT, &Parameter, sizeof(Parameter)) + +/** + * Registers a single context element for the hook callback + * + * Stubs may pass up to UT_STUBCONTEXT_MAXSIZE arguments to a user-defined + * hook function. These arguments are opaque to the stub function and generally + * passed as "void *" pointers to the actual stack values. The user code must + * then cast them to the right type again. + * + * \param FuncKey The stub function to entry to use. + * \param Name Argument name to associate with the pointer + * \param ParamType The type of parameter (direct, indirect, or unknown) + * \param ParamPtr Pointer to argument data + * \param ParamSize The size of the object pointed to, or zero if not known + */ +void UT_Stub_RegisterContextWithMetaData(UT_EntryKey_t FuncKey, const char *Name, + UT_StubContext_Arg_Type_t ParamType, const void *ParamPtr, size_t ParamSize); + +/** + * Retrieve a context argument value by name + * + * This returns a pointer to a buffer containing the value, rather than the + * value itself, even if the argument was registered originally as a direct value. + * + * If the name is not found, this logs a UT assert failure message, as it + * indicates a mismatch between the hook and stub functions with respect to argument + * names and (possibly) types that needs to be corrected. If possible, a buffer + * containing all zeros may be used as a substitute. + * + * This does not return NULL, such that the returned value can always be dereferenced. + * + * \param ContextPtr The context structure containing arguments + * \param Name Argument name to find + * \param ExpectedSize The size of the expected object type + * \returns Pointer to buffer containing the value. + */ +const void* UT_Hook_GetArgPtr(const UT_StubContext_t *ContextPtr, const char *Name, size_t ExpectedTypeSize); + +/** + * Macro which retrieves a value argument by name. + * + * This is a convenience method to easily use UT_Hook_GetArgPtr() to get the value + * associated with an argument as the correct/expected type. + * + */ +#define UT_Hook_GetArgValueByName(ContextPtr,Name,Type) \ + (*(Type const *)UT_Hook_GetArgPtr(ContextPtr,Name,sizeof(Type))) /** * Default implementation for a stub function that takes a va_list of arguments. @@ -390,6 +472,22 @@ int32 UT_DefaultStubImpl(const char *FunctionName, UT_EntryKey_t FuncKey, int32 */ #define UT_DEFAULT_IMPL_RC_ARGS(FuncName,Rc,...) UT_DefaultStubImpl(#FuncName, UT_KEY(FuncName), Rc, __VA_ARGS__) +/** + * Macro to simplify usage of the UT_DefaultStubImplWithArgs() function + * + * This function accepts a list of arguments as a va_list + */ +#define UT_DEFAULT_IMPL_VARARGS(FuncName,va) UT_DefaultStubImplWithArgs(#FuncName, UT_KEY(FuncName), 0, va) + +/** + * Macro to simplify usage of the UT_DefaultStubImplWithArgs() function + * + * This function accepts a list of arguments as a va_list and + * a nonzero default return code + */ +#define UT_DEFAULT_IMPL_RC_VARARGS(FuncName,Rc,va) UT_DefaultStubImplWithArgs(#FuncName, UT_KEY(FuncName), Rc, va) + + /** * Macro to simplify usage of the UT_DefaultStubImpl() function * diff --git a/ut_assert/src/utstubs.c b/ut_assert/src/utstubs.c index 569fd0f51..2e660f23a 100644 --- a/ut_assert/src/utstubs.c +++ b/ut_assert/src/utstubs.c @@ -591,9 +591,73 @@ void UT_SetVaHookFunction(UT_EntryKey_t FuncKey, UT_VaHookFunc_t HookFunc, void UT_DoSetHookFunction(FuncKey, Value, UserObj, true); } -void UT_Stub_RegisterContext(UT_EntryKey_t FuncKey, const void *Parameter) +const void* UT_Hook_GetArgPtr(const UT_StubContext_t *ContextPtr, const char *Name, size_t ExpectedTypeSize) +{ + uint32 i; + const void* Result; + const UT_StubArgMetaData_t *MetaPtr; + + static const union + { + uintmax_t AsInt; + void *AsPtr; + double AsFloat; + } ARG_DEFAULT_ZERO_VALUE = { 0 }; + + Result = NULL; + for (i = 0; i < ContextPtr->ArgCount; ++i) + { + MetaPtr = &ContextPtr->Meta[i]; + if (MetaPtr->Name != NULL) + { + if (strcmp(MetaPtr->Name, Name) == 0 && + (MetaPtr->Size == 0 || MetaPtr->Size == ExpectedTypeSize)) + { + if (MetaPtr->Type == UT_STUBCONTEXT_ARG_TYPE_DIRECT) + { + Result = &ContextPtr->ArgPtr[i]; + } + else if (MetaPtr->Type == UT_STUBCONTEXT_ARG_TYPE_INDIRECT) + { + Result = ContextPtr->ArgPtr[i]; + } + break; + } + } + } + + /* + * If no suitable result pointer was found, this means a mismatch + * between the stub and test case, such as a change in argument/parameter names. + * This is an error that should be corrected, so report it as a failure. + */ + if (Result == NULL) + { + UtAssert_Failed("Requested parameter %s of size %lu which was not provided by the stub", + Name, (unsigned long)ExpectedTypeSize); + + if (ExpectedTypeSize <= sizeof(ARG_DEFAULT_ZERO_VALUE)) + { + Result = &ARG_DEFAULT_ZERO_VALUE; + } + else + { + /* + * As the caller will likely dereference the returned pointer, should + * never return NULL. Just abort here. + */ + UtAssert_Abort("No value for parameter"); + } + } + + return Result; +} + +void UT_Stub_RegisterContextWithMetaData(UT_EntryKey_t FuncKey, const char *Name, + UT_StubContext_Arg_Type_t ParamType, const void *ParamPtr, size_t ParamSize) { UT_StubTableEntry_t *StubPtr; + UT_StubArgMetaData_t *MetaPtr; /* * First find an existing context entry for the function. @@ -616,7 +680,48 @@ void UT_Stub_RegisterContext(UT_EntryKey_t FuncKey, const void *Parameter) StubPtr->EntryType = UT_ENTRYTYPE_CALLBACK_CONTEXT; if (StubPtr->Data.Context.ArgCount < UT_STUBCONTEXT_MAXSIZE) { - StubPtr->Data.Context.ArgPtr[StubPtr->Data.Context.ArgCount] = Parameter; + StubPtr->Data.Context.ArgPtr[StubPtr->Data.Context.ArgCount] = ParamPtr; + + MetaPtr = &StubPtr->Data.Context.Meta[StubPtr->Data.Context.ArgCount]; + MetaPtr->Size = ParamSize; + MetaPtr->Type = ParamType; + + /* + * If name was specified, then trim any leading address operator (&) + * and/or whitespace, keeping only the actual name part. + */ + if (Name != NULL) + { + /* + * If the _address_ of the stack variable was actually passed in, + * the mark this as indirect (i.e. hook must dereference ArgPtr + * to get actual parameter value). Otherwise assume it as direct. + */ + MetaPtr->Name = Name; + while (*MetaPtr->Name != 0) + { + if (*MetaPtr->Name == '&') + { + /* this means its a pointer to the value, not the value itself */ + if (MetaPtr->Type == UT_STUBCONTEXT_ARG_TYPE_UNSPECIFIED) + { + MetaPtr->Type = UT_STUBCONTEXT_ARG_TYPE_INDIRECT; + } + } + else if (*MetaPtr->Name != ' ') + { + /* stop at non-whitespace */ + break; + } + ++MetaPtr->Name; + } + + if (MetaPtr->Type == UT_STUBCONTEXT_ARG_TYPE_UNSPECIFIED) + { + MetaPtr->Type = UT_STUBCONTEXT_ARG_TYPE_DIRECT; + } + + } ++StubPtr->Data.Context.ArgCount; } } From 473175523db79e8b92ba2e0e6fea7635cd05a879 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Thu, 21 May 2020 11:15:46 -0400 Subject: [PATCH 2/8] Fix #380, Add OS_TimeBase Api Functional Tests --- .../time-base-api-test/time-base-api-test.c | 278 ++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 src/tests/time-base-api-test/time-base-api-test.c diff --git a/src/tests/time-base-api-test/time-base-api-test.c b/src/tests/time-base-api-test/time-base-api-test.c new file mode 100644 index 000000000..2f30782c7 --- /dev/null +++ b/src/tests/time-base-api-test/time-base-api-test.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2020, United States government as represented by the + * administrator of the National Aeronautics Space Administration. + * All rights reserved. This software was created at NASA Goddard + * Space Flight Center pursuant to government contracts. + * + * This is governed by the NASA Open Source Agreement and may be used, + * distributed and modified only according to the terms of that agreement. + */ + +/* + * Filename: time-base-api-test.c + * + * Purpose: This file contains functional tests for "osapi-timebase" + * + */ + +#include +#include +#include + +#include "common_types.h" +#include "osapi.h" +#include "utassert.h" +#include "uttest.h" +#include "utbsp.h" + +static uint32 TimerSyncCount = 0; +static uint32 TimerSyncRetVal = 0; + +static uint32 UT_TimerSync(uint32 timer_id) +{ + ++TimerSyncCount; + return TimerSyncRetVal; +} + + +/* *************************************** MAIN ************************************** */ + +void TestTimeBaseApi(void) +{ + int32 expected; + int32 actual; + int32 TimeBaseNum; + uint32 freerun; + uint32 objid; + uint32 time_base_id; + uint32 time_base_id2; + char maxTimeBase[12]; + char overMaxTimeBase[12]; + OS_timebase_prop_t timebase_prop; + + /* + * Test Case For: + * int32 OS_TimeBaseCreate(uint32 *timer_id, const char *timebase_name, OS_TimerSync_t external_sync) + */ + + /* Test for nominal inputs */ + expected = OS_SUCCESS; + + actual= OS_TimeBaseCreate(&time_base_id, "TimeBase", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + actual = OS_TimeBaseCreate(&time_base_id2, "TimeBase2", NULL); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + actual = OS_TimeBaseCreate(&time_base_id, "TimeBase3", UT_TimerSync); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + /* Test for nominal, max/min cases */ + objid = 0xFFFFFFFF; + actual = OS_TimeBaseCreate(&objid, "TimeBase4", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + /* + * Note: OS_MAX_TIMEBASES = 5, so no more than 5 TimeBase IDs are allowed + * Checking for OS_MAX_TIMEBASES: + */ + TimeBaseNum = OS_MAX_TIMEBASES; + snprintf(maxTimeBase, 12, "TimeBase%d", TimeBaseNum); + objid = 0x00000000; + actual = OS_TimeBaseCreate(&objid, "maxTimeBase", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + + /* Test for invalid inputs */ + expected = OS_INVALID_POINTER; + actual = OS_TimeBaseCreate(NULL, NULL, NULL); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_INVALID_POINTER", (long)actual); + + expected = OS_INVALID_POINTER; + actual = OS_TimeBaseCreate(NULL, "TimeBase6", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_INVALID_POINTER", (long)actual); + + expected = OS_INVALID_POINTER; + actual = OS_TimeBaseCreate(&time_base_id, NULL, 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_INVALID_POINTER", (long)actual); + + expected = OS_ERR_NAME_TAKEN; + actual= OS_TimeBaseCreate(&time_base_id, "TimeBase", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); + + /* OS_MAX_TIMEBASES + 1 */ + TimeBaseNum = OS_MAX_TIMEBASES+1; + snprintf(overMaxTimeBase, 12, "TimeBase%d", TimeBaseNum); + expected = OS_ERR_NO_FREE_IDS; + actual= OS_TimeBaseCreate(&time_base_id, "overMaxTimeBase", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NO_FREE_IDS", (long)actual); + + + /* + * Test Case For: + * int32 OS_TimeBaseSet(uint32 timer_id, uint32 start_time, uint32 interval_time) + */ + + /* Test for nominal inputs */ + expected = OS_SUCCESS; + actual = OS_TimeBaseSet(time_base_id, 1000, 1000); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_SUCCESS", (long)actual); + + expected = OS_SUCCESS; + actual = OS_TimeBaseSet(time_base_id, 0, 0); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_SUCCESS", (long)actual); + + /* Test for invalid inputs */ + /* overflow on input */ + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimeBaseSet(time_base_id, UINT32_MAX, UINT32_MAX); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimeBaseSet(time_base_id, -1000, -1000); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimeBaseSet(time_base_id, 1000, -1000); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimeBaseSet(time_base_id, -1000, 1000); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_ERR_INVALID_ID; + actual = OS_TimeBaseSet(0, 1000, 1000); + UtAssert_True(actual == expected, "OS_TimeBaseSet() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + + /* + * Test Case For: + * int32 OS_TimeBaseDelete(uint32 timer_id) + */ + + /* Test for nominal inputs */ + expected = OS_SUCCESS; + actual = OS_TimeBaseDelete(time_base_id); + UtAssert_True(actual == expected, "OS_TimeBaseDelete() (%ld) == OS_SUCCESS", (long)actual); + + /* Test for invalid inputs */ + expected = OS_ERR_INVALID_ID; + actual = OS_TimeBaseDelete(0x0000000); + UtAssert_True(actual == expected, "OS_TimeBaseDelete() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + expected = OS_ERR_INVALID_ID; + actual = OS_TimeBaseDelete(0xFFFFFFF); + UtAssert_True(actual == expected, "OS_TimeBaseDelete() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + /* + * Test Case For: + * int32 OS_TimeBaseGetIdByName (uint32 *timer_id, const char *timebase_name) + */ + + /* Test for nominal inputs */ + /* Note: TimeBase2 was created above using TimeBaseCreate and id was set to time_base_id2 */ + expected = OS_SUCCESS; + objid = 0; + actual = OS_TimeBaseGetIdByName(&objid, "TimeBase2"); + UtAssert_True(actual == expected, "OS_TimeBaseGetIdByName() (%ld) == OS_SUCCESS", (long)actual); + UtAssert_True(objid == time_base_id2, "OS_TimeBaseGetIdByName() objid (%lu) Matches!", (unsigned long)objid); + + + /* Test for invalid inputs */ + expected = OS_ERR_NAME_NOT_FOUND; + objid = 0; + actual = OS_TimeBaseGetIdByName(&objid, "NF"); + UtAssert_True(actual == expected, "OS_TimeBaseGetIdByName() (%ld) == OS_ERR_NAME_NOT_FOUND",(long)actual); + UtAssert_True(objid == 0, "OS_TimeBaseGetIdByName() objid (%lu) still 0", (unsigned long)objid); + + expected = OS_INVALID_POINTER; + actual = OS_TimeBaseGetIdByName(NULL, NULL); + UtAssert_True(actual == expected, "OS_TimeBaseGetIdByName() (%ld) == OS_INVALID_POINTER", (long)actual); + + + /* + * Test Case For: + * int32 OS_TimeBaseGetInfo (uint32 timebase_id, OS_timebase_prop_t *timebase_prop) + */ + expected = OS_SUCCESS; + + /* Test for nominal inputs */ + /* Note: TimeBase2 was created above using TimeBaseCreate */ + + /* Initializing timebase_prop values to something other than time_base_id2 to ensure they have changed */ + timebase_prop.creator = 1111; + strncpy(timebase_prop.name, "ABC", sizeof( +timebase_prop.name)); + timebase_prop.nominal_interval_time = 2222; + timebase_prop.freerun_time = 3333; + timebase_prop.accuracy = 0; + + actual = OS_TimeBaseGetInfo(time_base_id2, &timebase_prop); + + UtAssert_True(actual == expected, "OS_TimeBaseGetInfo() (%ld) == OS_SUCCESS", (long)actual); + + UtAssert_True(timebase_prop.creator == 0, "timebase_prop.creator (%lu) == 0", + (unsigned long)timebase_prop.creator); + UtAssert_True(strcmp(timebase_prop.name, "TimeBase2") == 0, "timebase_prop.name (%s) == TimeBase2", + timebase_prop.name); + UtAssert_True(timebase_prop.nominal_interval_time == 0, + "timebase_prop.nominal_interval_time (%lu) == 0", + (unsigned long)timebase_prop.nominal_interval_time); + UtAssert_True(timebase_prop.freerun_time == 0, + "timebase_prop.freerun_time (%lu) == 0", + (unsigned long)timebase_prop.freerun_time); + UtAssert_True(timebase_prop.accuracy >= 0, + "timebase_prop.accuracy (%lu) >= 0", + (unsigned long)timebase_prop.accuracy); + + /* Test for invalid inputs */ + expected = OS_ERR_INVALID_ID; + actual = OS_TimeBaseGetInfo(1, &timebase_prop); + UtAssert_True(actual == expected, "OS_TimeBaseGetInfo() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + expected = OS_INVALID_POINTER; + actual = OS_TimeBaseGetInfo(time_base_id2, NULL); + UtAssert_True(actual == expected, "OS_TimeBaseGetInfo() (%ld) == OS_INVALID_POINTER", (long)actual); + + /* + * Test Case For: + * int32 OS_TimeBaseGetFreeRun (uint32 timebase_id, uint32 *freerun_val) + */ + + /* Test for nominal inputs */ + /* Note: TimeBase2 was created above using TimeBaseCreate */ + expected = OS_SUCCESS; + + freerun = 0xFFFFFFFF; + actual = OS_TimeBaseGetFreeRun(time_base_id2, &freerun); + UtAssert_True(actual == expected, "OS_TimeBaseGetFreeRun() (%ld) == OS_SUCCESS", (long)actual); + + freerun = 0x0000000; + actual = OS_TimeBaseGetFreeRun(time_base_id2, &freerun); + UtAssert_True(actual == expected, "OS_TimeBaseGetFreeRun() (%ld) == OS_SUCCESS", (long)actual); + + /* Test for invalid inputs */ + expected = OS_ERR_INVALID_ID; + freerun = 0xFFFFFFFF; + actual = OS_TimeBaseGetFreeRun(1, &freerun); + UtAssert_True(actual == expected, "OS_TimeBaseGetFreeRun() (%ld) == OS_SUCCESS", (long)actual); + + + + +} /* end TestTimeBaseApi */ + + +void UtTest_Setup(void) +{ + if (OS_API_Init() != OS_SUCCESS) + { + UtAssert_Abort("OS_API_Init() failed"); + } + + /* + * Register the test setup and check routines in UT assert + */ + UtTest_Add(TestTimeBaseApi, NULL, NULL, "TestTimeBaseApi"); +} + From 1d351ceb2c0d0bfda30365a181935ecc2170a155 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Tue, 12 May 2020 21:06:12 -0400 Subject: [PATCH 3/8] Fix #381, Add OS_TimerAdd functional test --- .../timer-add-api-test/timer-add-api-test.c | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/tests/timer-add-api-test/timer-add-api-test.c diff --git a/src/tests/timer-add-api-test/timer-add-api-test.c b/src/tests/timer-add-api-test/timer-add-api-test.c new file mode 100644 index 000000000..f81b421cd --- /dev/null +++ b/src/tests/timer-add-api-test/timer-add-api-test.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#include "common_types.h" +#include "osapi.h" +#include "utassert.h" +#include "uttest.h" +#include "utbsp.h" + +#define NUMBER_OF_TIMERS 4 +#define TASK_1_ID 1 +#define TASK_1_STACK_SIZE 4096 +#define TASK_1_PRIORITY 101 + +OS_time_t StartTime; +OS_time_t EndTime; +uint32 TimerStart[NUMBER_OF_TIMERS] = {1000, 2000000, 3000000, 4000000 }; +uint32 TimerInterval[NUMBER_OF_TIMERS] = {500000, 400000, 800000, 600000 }; + +uint32 TimerTestTaskStack[TASK_1_STACK_SIZE]; +int32 timer_counter[NUMBER_OF_TIMERS]; +uint32 timer_idlookup[OS_MAX_TIMERS]; + +/* +** Test timer function. +** Note: For some Host OSs, this is the equivalent of an ISR, so the calls available are limited. +** For example, Linux and vxWorks can call functions like printf, but RTEMS cannot. +*/ +void test_func(uint32 timer_id , void *arg) +{ + OS_ConvertToArrayIndex(timer_id, &timer_id); + timer_counter[timer_idlookup[timer_id]]++; +} + +/* *************************************** MAIN ************************************** */ + +void TestTimerAddApi(void) +{ + /* + * Test Case For: + * int32 OS_TimerAdd(uint32 *timer_id, const char *timer_name, uint32 timebase_ref_id, OS_ArgCallback_t callback_ptr, void *callback_arg) + */ + + int32 actual; + int32 expected; + uint32 timer_id; + char arg = 'a'; + uint32 time_base_id; + int i = 0; + int32 TimerStatus[NUMBER_OF_TIMERS]; + uint32 TableId; + uint32 TimerID[NUMBER_OF_TIMERS]; + char TimerName[NUMBER_OF_TIMERS][20] = {"TIMER1","TIMER2","TIMER3","TIMER4"}; + uint32 microsecs; + + OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); + OS_TimeBaseSet(time_base_id, 10000, 10000); //ms + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &test_func, &arg); + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d Created RC=%d ID=%d", i, (int)TimerStatus[i], (int)TimerID[i]); + + OS_ConvertToArrayIndex(TimerID[i], &TableId); + timer_idlookup[TableId] = i; + } + + /* Sample the clock now, before starting any timer */ + OS_GetLocalTime(&StartTime); + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + /* + * to ensure that all timers are started as closely as possible, + * this just stores the result and does not assert/printf now + */ + TimerStatus[i] = OS_TimerSet(TimerID[i], TimerStart[i], TimerInterval[i]); + } + + /* + * Now the actual OS_TimerSet() return code can be checked. + */ + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d programmed RC=%d", i, (int)TimerStatus[i]); + } + + /* + ** Let the main thread sleep + */ + UtPrintf("Starting Delay loop.\n"); + for (i = 0 ; i < 30; i++ ) + { + /* + ** Even though this sleep call is for 1 second, + ** the sigalarm timer for the 1hz will keep waking + ** it up. Keep that in mind when setting the timer down + ** to something very small. + */ + OS_TaskDelay(1000); + } + + OS_GetLocalTime(&EndTime); + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + TimerStatus[i] = OS_TimerDelete(TimerID[i]); + } + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d delete RC=%d. Count total = %d", + i, (int)TimerStatus[i], (int)timer_counter[i]); + } + + /* + * Time limited test + */ + microsecs = 1000000 * (EndTime.seconds - StartTime.seconds); + if (EndTime.microsecs < StartTime.microsecs) + { + microsecs -= StartTime.microsecs - EndTime.microsecs; + } + else + { + microsecs += EndTime.microsecs - StartTime.microsecs; + } + + /* Make sure the ratio of the timers are OK */ + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + /* + * Expect one tick after the start time (i.e. first tick) + * Plus one tick for every interval that occurred during the test + */ + expected = 1 + (microsecs - TimerStart[i]) / TimerInterval[i]; + UtAssert_True(expected > 0, "Expected ticks = %u", (unsigned int)expected); + + /* + * Since all these counts are affected by test system load, + * allow for some fudge factor before declaring failure + */ + UtAssert_True(timer_counter[i] >= (expected - 3), "Timer %d count >= %d", (int)i, (int)(expected - 3)); + UtAssert_True(timer_counter[i] <= (expected + 3), "Timer %d count <= %d", (int)i, (int)(expected + 3)); + } + + /* Test nominal inputs */ + expected = OS_SUCCESS; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_SUCCESS", (long)actual); + + /* Test invalid inputs */ + expected = OS_INVALID_POINTER; + actual = OS_TimerAdd(NULL, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); + + expected = OS_ERR_INVALID_ID; + actual = OS_TimerAdd(&timer_id, "Timer", 1, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_ERR_NAME_TAKEN; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); + + expected = OS_INVALID_POINTER; + actual = OS_TimerAdd(&timer_id, 0, time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); + + +} /* end TestTimerAddApi */ + + +void UtTest_Setup(void) +{ + if (OS_API_Init() != OS_SUCCESS) + { + UtAssert_Abort("OS_API_Init() failed"); + } + + /* + * Register the test setup and check routines in UT assert + */ + UtTest_Add(TestTimerAddApi, NULL, NULL, "TestTimerAddApi"); +} + From 7a644f8d8d2cd356a6a330f5fc53749b9c1e8297 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Thu, 28 May 2020 11:18:03 -0400 Subject: [PATCH 4/8] Fix #381, Updated functional tests to implement all changes requested on Github --- .../timer-add-api-test/timer-add-api-test.c | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/tests/timer-add-api-test/timer-add-api-test.c b/src/tests/timer-add-api-test/timer-add-api-test.c index f81b421cd..d897848b8 100644 --- a/src/tests/timer-add-api-test/timer-add-api-test.c +++ b/src/tests/timer-add-api-test/timer-add-api-test.c @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2020, United States government as represented by the + * administrator of the National Aeronautics Space Administration. + * All rights reserved. This software was created at NASA Goddard + * Space Flight Center pursuant to government contracts. + * + * This is governed by the NASA Open Source Agreement and may be used, + * distributed and modified only according to the terms of that agreement. + */ + +/* + * Filename: timer-add-api-test.c + * + * Purpose: This file contains functional tests for "osapi-timer" + * + */ + #include #include #include @@ -19,18 +36,18 @@ uint32 TimerStart[NUMBER_OF_TIMERS] = {1000, 2000000, 3000000, 4000000 uint32 TimerInterval[NUMBER_OF_TIMERS] = {500000, 400000, 800000, 600000 }; uint32 TimerTestTaskStack[TASK_1_STACK_SIZE]; -int32 timer_counter[NUMBER_OF_TIMERS]; -uint32 timer_idlookup[OS_MAX_TIMERS]; +uint32 timer_counter[NUMBER_OF_TIMERS]; -/* -** Test timer function. -** Note: For some Host OSs, this is the equivalent of an ISR, so the calls available are limited. -** For example, Linux and vxWorks can call functions like printf, but RTEMS cannot. -*/ -void test_func(uint32 timer_id , void *arg) + +void counter_func(uint32 timer_id , void *arg) { - OS_ConvertToArrayIndex(timer_id, &timer_id); - timer_counter[timer_idlookup[timer_id]]++; + uint32 *counter = arg; + ++(*counter); +} + +void null_func(uint32 timer_id , void *arg) +{ + } /* *************************************** MAIN ************************************** */ @@ -44,26 +61,32 @@ void TestTimerAddApi(void) int32 actual; int32 expected; + int32 tbc_ret_val; + int32 tbs_ret_val; uint32 timer_id; - char arg = 'a'; uint32 time_base_id; int i = 0; int32 TimerStatus[NUMBER_OF_TIMERS]; - uint32 TableId; uint32 TimerID[NUMBER_OF_TIMERS]; char TimerName[NUMBER_OF_TIMERS][20] = {"TIMER1","TIMER2","TIMER3","TIMER4"}; uint32 microsecs; - OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); - OS_TimeBaseSet(time_base_id, 10000, 10000); //ms + /* Create and set the TimeBase obj and verify success */ + + tbc_ret_val = OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); + expected = OS_SUCCESS; + UtAssert_True(tbc_ret_val == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)tbc_ret_val); + + tbs_ret_val = OS_TimeBaseSet(time_base_id, 10000, 10000); /* ms */ + expected = OS_SUCCESS; + UtAssert_True(tbs_ret_val == expected, "OS_TimeBaseSet() (%ld) == OS_SUCCESS", (long)tbs_ret_val); + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) { - TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &test_func, &arg); + TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &counter_func, &timer_counter[i]); UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d Created RC=%d ID=%d", i, (int)TimerStatus[i], (int)TimerID[i]); - OS_ConvertToArrayIndex(TimerID[i], &TableId); - timer_idlookup[TableId] = i; } /* Sample the clock now, before starting any timer */ @@ -145,29 +168,29 @@ void TestTimerAddApi(void) } /* Test nominal inputs */ - expected = OS_SUCCESS; - actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + expected = OS_SUCCESS; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_SUCCESS", (long)actual); /* Test invalid inputs */ expected = OS_INVALID_POINTER; - actual = OS_TimerAdd(NULL, "Timer", time_base_id, test_func, &arg); + actual = OS_TimerAdd(NULL, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); expected = OS_ERR_INVALID_ID; - actual = OS_TimerAdd(&timer_id, "Timer", 1, test_func, &arg); + actual = OS_TimerAdd(&timer_id, "Timer", 1, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_INVALID_ID", (long)actual); expected = OS_TIMER_ERR_INVALID_ARGS; - actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, &arg); + actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); expected = OS_ERR_NAME_TAKEN; - actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); expected = OS_INVALID_POINTER; - actual = OS_TimerAdd(&timer_id, 0, time_base_id, test_func, &arg); + actual = OS_TimerAdd(&timer_id, 0, time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); From 11a489903bead8e02400568f0ea894843a9efb40 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 13 May 2020 19:43:47 -0400 Subject: [PATCH 5/8] Fix #449, Make Linux+VxWorks BSPs generic These adaptor layers can be used on a variety of boards. Renaming the directory reflects that. Note - not renaming pc-rtems at this time, as that still has some non-generic aspects to it. --- .travis.yml | 2 +- .../CMakeLists.txt | 12 ++++----- .../build_options.cmake | 2 +- .../src/bsp_console.c | 4 +-- .../src/bsp_start.c | 8 +++--- .../src/generic_linux_bsp_internal.h} | 14 +++++----- src/bsp/generic-vxworks/CMakeLists.txt | 14 ++++++++++ .../build_options.cmake | 4 +-- .../src/bsp_console.c | 2 +- .../src/bsp_start.c | 2 +- .../src/generic_vxworks_bsp_internal.h} | 10 +++---- src/bsp/mcp750-vxworks/CMakeLists.txt | 27 ------------------- src/bsp/mcp750-vxworks/src/bsp.mak | 21 --------------- 13 files changed, 43 insertions(+), 79 deletions(-) rename src/bsp/{pc-linux => generic-linux}/CMakeLists.txt (73%) rename src/bsp/{pc-linux => generic-linux}/build_options.cmake (95%) rename src/bsp/{pc-linux => generic-linux}/src/bsp_console.c (97%) rename src/bsp/{pc-linux => generic-linux}/src/bsp_start.c (95%) rename src/bsp/{pc-linux/src/pclinux_bsp_internal.h => generic-linux/src/generic_linux_bsp_internal.h} (70%) create mode 100644 src/bsp/generic-vxworks/CMakeLists.txt rename src/bsp/{mcp750-vxworks => generic-vxworks}/build_options.cmake (59%) rename src/bsp/{mcp750-vxworks => generic-vxworks}/src/bsp_console.c (97%) rename src/bsp/{mcp750-vxworks => generic-vxworks}/src/bsp_start.c (97%) rename src/bsp/{mcp750-vxworks/src/mcp750_bsp_internal.h => generic-vxworks/src/generic_vxworks_bsp_internal.h} (72%) delete mode 100644 src/bsp/mcp750-vxworks/CMakeLists.txt delete mode 100644 src/bsp/mcp750-vxworks/src/bsp.mak diff --git a/.travis.yml b/.travis.yml index d73c8d0ba..17b4806e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ _functional_test: &functional_test - cd build # Prep and build - - cmake -DENABLE_UNIT_TESTS=true -DOSAL_SYSTEM_BSPTYPE=pc-linux -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=TRUE .. + - cmake -DENABLE_UNIT_TESTS=true -DOSAL_SYSTEM_BSPTYPE=generic-linux -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=TRUE .. - make # lcov capture pre-execution diff --git a/src/bsp/pc-linux/CMakeLists.txt b/src/bsp/generic-linux/CMakeLists.txt similarity index 73% rename from src/bsp/pc-linux/CMakeLists.txt rename to src/bsp/generic-linux/CMakeLists.txt index 40b0aaca7..180e73840 100644 --- a/src/bsp/pc-linux/CMakeLists.txt +++ b/src/bsp/generic-linux/CMakeLists.txt @@ -1,14 +1,12 @@ ###################################################################### # -# CMAKE build recipe for PC-LINUX Board Support Package (BSP) +# CMAKE build recipe for LINUX Board Support Package (BSP) # ###################################################################### -# NOTE: Although this is traditionally called "pc-linux", it is generic -# enough to be applied to non-PC systems running embedded Linux, such -# as Raspberry Pi, BeagleBoard, Zync, or custom hardware. - -add_library(osal_pc-linux_impl OBJECT +# This basic implementation library should be generic enough to use +# on any Linux-based processor board, as well as a standard development PC. +add_library(osal_generic-linux_impl OBJECT src/bsp_start.c src/bsp_console.c ) @@ -23,7 +21,7 @@ add_library(osal_pc-linux_impl OBJECT # # See http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html # for a more detailed description of the feature test macros and available values -target_compile_definitions(osal_pc-linux_impl PUBLIC +target_compile_definitions(osal_generic-linux_impl PUBLIC _XOPEN_SOURCE=600 ) diff --git a/src/bsp/pc-linux/build_options.cmake b/src/bsp/generic-linux/build_options.cmake similarity index 95% rename from src/bsp/pc-linux/build_options.cmake rename to src/bsp/generic-linux/build_options.cmake index bf1d3c356..dcffd5a57 100644 --- a/src/bsp/pc-linux/build_options.cmake +++ b/src/bsp/generic-linux/build_options.cmake @@ -1,6 +1,6 @@ ########################################################################## # -# Build options for "pc-linux" BSP +# Build options for "generic-linux" BSP # ########################################################################## diff --git a/src/bsp/pc-linux/src/bsp_console.c b/src/bsp/generic-linux/src/bsp_console.c similarity index 97% rename from src/bsp/pc-linux/src/bsp_console.c rename to src/bsp/generic-linux/src/bsp_console.c index 61c1d620d..deaa340d3 100644 --- a/src/bsp/pc-linux/src/bsp_console.c +++ b/src/bsp/generic-linux/src/bsp_console.c @@ -20,7 +20,7 @@ #include #include -#include "pclinux_bsp_internal.h" +#include "generic_linux_bsp_internal.h" #include "bsp-impl.h" /*---------------------------------------------------------------- @@ -88,7 +88,7 @@ void OS_BSP_ConsoleSetMode_Impl(uint32 ModeBits) { char param[32]; - if (OS_BSP_PcLinuxGlobal.EnableTermControl) + if (OS_BSP_GenericLinuxGlobal.EnableTermControl) { if (ModeBits == OS_BSP_CONSOLEMODE_NORMAL) { diff --git a/src/bsp/pc-linux/src/bsp_start.c b/src/bsp/generic-linux/src/bsp_start.c similarity index 95% rename from src/bsp/pc-linux/src/bsp_start.c rename to src/bsp/generic-linux/src/bsp_start.c index a67be73fd..4f01c8846 100644 --- a/src/bsp/pc-linux/src/bsp_start.c +++ b/src/bsp/generic-linux/src/bsp_start.c @@ -25,9 +25,9 @@ #include #include -#include "pclinux_bsp_internal.h" +#include "generic_linux_bsp_internal.h" -OS_BSP_PcLinuxGlobalData_t OS_BSP_PcLinuxGlobal; +OS_BSP_GenericLinuxGlobalData_t OS_BSP_GenericLinuxGlobal; /* --------------------------------------------------------- OS_BSP_Initialize() @@ -130,7 +130,7 @@ int main(int argc, char *argv[]) * Initially clear the global objects */ memset(&OS_BSP_Global, 0, sizeof(OS_BSP_Global)); - memset(&OS_BSP_PcLinuxGlobal, 0, sizeof(OS_BSP_PcLinuxGlobal)); + memset(&OS_BSP_GenericLinuxGlobal, 0, sizeof(OS_BSP_GenericLinuxGlobal)); /* * Save the argc/argv arguments for future use. @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) */ if (getenv("TERM") != NULL) { - OS_BSP_PcLinuxGlobal.EnableTermControl = isatty(STDOUT_FILENO); + OS_BSP_GenericLinuxGlobal.EnableTermControl = isatty(STDOUT_FILENO); } /* diff --git a/src/bsp/pc-linux/src/pclinux_bsp_internal.h b/src/bsp/generic-linux/src/generic_linux_bsp_internal.h similarity index 70% rename from src/bsp/pc-linux/src/pclinux_bsp_internal.h rename to src/bsp/generic-linux/src/generic_linux_bsp_internal.h index 460df5c98..826c46896 100644 --- a/src/bsp/pc-linux/src/pclinux_bsp_internal.h +++ b/src/bsp/generic-linux/src/generic_linux_bsp_internal.h @@ -1,5 +1,5 @@ /****************************************************************************** -** File: pclinux_bsp_internal.h +** File: generic_linux_bsp_internal.h ** ** ** This is governed by the NASA Open Source Agreement and may be used, @@ -11,12 +11,12 @@ ** ** ** Purpose: -** Header file for internal data to the PC-LINUX BSP +** Header file for internal data to the LINUX BSP ** ******************************************************************************/ -#ifndef _PCLINUX_BSP_INTERNAL_H_ -#define _PCLINUX_BSP_INTERNAL_H_ +#ifndef GENERIC_LINUX_BSP_INTERNAL_H_ +#define GENERIC_LINUX_BSP_INTERNAL_H_ #include "osapi.h" #include "bsp-impl.h" @@ -27,11 +27,11 @@ typedef struct { bool EnableTermControl; /**< Will be set "true" when invoked from a TTY device, false otherwise */ -} OS_BSP_PcLinuxGlobalData_t; +} OS_BSP_GenericLinuxGlobalData_t; /* * Global Data object */ -extern OS_BSP_PcLinuxGlobalData_t OS_BSP_PcLinuxGlobal; +extern OS_BSP_GenericLinuxGlobalData_t OS_BSP_GenericLinuxGlobal; -#endif /* _PCLINUX_BSP_INTERNAL_H_ */ +#endif /* GENERIC_LINUX_BSP_INTERNAL_H_ */ diff --git a/src/bsp/generic-vxworks/CMakeLists.txt b/src/bsp/generic-vxworks/CMakeLists.txt new file mode 100644 index 000000000..8e638b930 --- /dev/null +++ b/src/bsp/generic-vxworks/CMakeLists.txt @@ -0,0 +1,14 @@ +###################################################################### +# +# CMAKE build recipe for Generic VxWorks Board Support Package (BSP) +# +###################################################################### + +add_library(osal_generic-vxworks_impl OBJECT + src/bsp_start.c + src/bsp_console.c +) + +# This BSP only works with "vxworks" OS layer. +# Confirming this reduces risk of accidental misconfiguration +set(OSAL_EXPECTED_OSTYPE "vxworks" PARENT_SCOPE) diff --git a/src/bsp/mcp750-vxworks/build_options.cmake b/src/bsp/generic-vxworks/build_options.cmake similarity index 59% rename from src/bsp/mcp750-vxworks/build_options.cmake rename to src/bsp/generic-vxworks/build_options.cmake index 3e3c71751..5ba936aba 100644 --- a/src/bsp/mcp750-vxworks/build_options.cmake +++ b/src/bsp/generic-vxworks/build_options.cmake @@ -1,8 +1,8 @@ ########################################################################## # -# Build options for "mcp750-vxworks" BSP +# Build options for "generic-vxworks" BSP # ########################################################################## -# The "-u" switch is required to ensure that "ldppc" pulls in the OS_BSPMain entry point +# The "-u" switch is required to ensure that the linker pulls in the OS_BSPMain entry point target_link_libraries(osal_bsp -uOS_BSPMain) diff --git a/src/bsp/mcp750-vxworks/src/bsp_console.c b/src/bsp/generic-vxworks/src/bsp_console.c similarity index 97% rename from src/bsp/mcp750-vxworks/src/bsp_console.c rename to src/bsp/generic-vxworks/src/bsp_console.c index 710b1a007..504bedc4c 100644 --- a/src/bsp/mcp750-vxworks/src/bsp_console.c +++ b/src/bsp/generic-vxworks/src/bsp_console.c @@ -19,7 +19,7 @@ #include #include -#include "mcp750_bsp_internal.h" +#include "generic_vxworks_bsp_internal.h" #include "bsp-impl.h" /**************************************************************************************** diff --git a/src/bsp/mcp750-vxworks/src/bsp_start.c b/src/bsp/generic-vxworks/src/bsp_start.c similarity index 97% rename from src/bsp/mcp750-vxworks/src/bsp_start.c rename to src/bsp/generic-vxworks/src/bsp_start.c index 4669e7a8b..68e342a5f 100644 --- a/src/bsp/mcp750-vxworks/src/bsp_start.c +++ b/src/bsp/generic-vxworks/src/bsp_start.c @@ -22,7 +22,7 @@ #include #include -#include "mcp750_bsp_internal.h" +#include "generic_vxworks_bsp_internal.h" /* --------------------------------------------------------- OS_BSP_Shutdown_Impl() diff --git a/src/bsp/mcp750-vxworks/src/mcp750_bsp_internal.h b/src/bsp/generic-vxworks/src/generic_vxworks_bsp_internal.h similarity index 72% rename from src/bsp/mcp750-vxworks/src/mcp750_bsp_internal.h rename to src/bsp/generic-vxworks/src/generic_vxworks_bsp_internal.h index 7b6d84363..461b725c6 100644 --- a/src/bsp/mcp750-vxworks/src/mcp750_bsp_internal.h +++ b/src/bsp/generic-vxworks/src/generic_vxworks_bsp_internal.h @@ -1,5 +1,5 @@ /****************************************************************************** -** File: mcp750_bsp_internal.h +** File: generic_vxworks_bsp_internal.h ** ** ** This is governed by the NASA Open Source Agreement and may be used, @@ -11,12 +11,12 @@ ** ** ** Purpose: -** Header file for internal data to the MCP750 BSP +** Header file for internal data to the VxWorks BSP ** ******************************************************************************/ -#ifndef _MCP750_BSP_INTERNAL_H_ -#define _MCP750_BSP_INTERNAL_H_ +#ifndef GENERIC_VXWORKS_BSP_INTERNAL_H_ +#define GENERIC_VXWORKS_BSP_INTERNAL_H_ /* ** OSAL includes @@ -24,4 +24,4 @@ #include "osapi.h" #include "bsp-impl.h" -#endif /* _MCP750_BSP_INTERNAL_H_ */ +#endif /* GENERIC_VXWORKS_BSP_INTERNAL_H_ */ diff --git a/src/bsp/mcp750-vxworks/CMakeLists.txt b/src/bsp/mcp750-vxworks/CMakeLists.txt deleted file mode 100644 index a73a2d25d..000000000 --- a/src/bsp/mcp750-vxworks/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -###################################################################### -# -# CMAKE build recipe for MCP750 Board Support Package (BSP) -# -###################################################################### - -add_library(osal_mcp750-vxworks_impl OBJECT - src/bsp_start.c - src/bsp_console.c -) - -target_include_directories(osal_mcp750-vxworks_impl PUBLIC - $ENV{WIND_BASE}/target/h - $ENV{WIND_BASE}/target/h/wrn/coreip - $ENV{WIND_BASE}/target/config/mcp750 -) - -# NOTE: the __PPC__ and MCP750 macros are referenced in some system headers. -# therefore all code compiled for this platform should always define these symbols. -target_compile_definitions(osal_mcp750-vxworks_impl PUBLIC - "__PPC__" - "MCP750" -) - -# This BSP only works with "vxworks" OS layer. -# Confirming this reduces risk of accidental misconfiguration -set(OSAL_EXPECTED_OSTYPE "vxworks" PARENT_SCOPE) diff --git a/src/bsp/mcp750-vxworks/src/bsp.mak b/src/bsp/mcp750-vxworks/src/bsp.mak deleted file mode 100644 index f1ebaf8cd..000000000 --- a/src/bsp/mcp750-vxworks/src/bsp.mak +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################### -# File: bsp.mak -# -# Purpose: -# Compile Board Support Package routines -# -# History: -# -############################################################################### - -# Subsystem produced by this makefile. -TARGET = bsp.o - -#============================================================================== -# Object files required to build subsystem. -OBJS = bsp_start.o bsp_voltab.o - -#============================================================================== -# Source files required to build subsystem; used to generate dependencies. -SOURCES = bsp_start.c bsp_voltab.c - From f3f8b8a7f1d2572a8b37062f1983fe5cab40e2f1 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Mon, 1 Jun 2020 16:54:52 -0400 Subject: [PATCH 6/8] fix #380, Updated test to implement changes requested --- .../time-base-api-test/time-base-api-test.c | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/tests/time-base-api-test/time-base-api-test.c b/src/tests/time-base-api-test/time-base-api-test.c index 2f30782c7..cf8aee607 100644 --- a/src/tests/time-base-api-test/time-base-api-test.c +++ b/src/tests/time-base-api-test/time-base-api-test.c @@ -25,13 +25,10 @@ #include "uttest.h" #include "utbsp.h" -static uint32 TimerSyncCount = 0; -static uint32 TimerSyncRetVal = 0; - static uint32 UT_TimerSync(uint32 timer_id) { - ++TimerSyncCount; - return TimerSyncRetVal; + OS_TaskDelay(1); + return 1; } @@ -42,12 +39,14 @@ void TestTimeBaseApi(void) int32 expected; int32 actual; int32 TimeBaseNum; + int32 tbc_results[OS_MAX_TIMEBASES]; uint32 freerun; uint32 objid; uint32 time_base_id; uint32 time_base_id2; - char maxTimeBase[12]; + uint32 tb_id[OS_MAX_TIMEBASES]; char overMaxTimeBase[12]; + char TimeBaseIter[OS_MAX_TIMEBASES][12]; OS_timebase_prop_t timebase_prop; /* @@ -58,29 +57,30 @@ void TestTimeBaseApi(void) /* Test for nominal inputs */ expected = OS_SUCCESS; - actual= OS_TimeBaseCreate(&time_base_id, "TimeBase", 0); + actual= OS_TimeBaseCreate(&time_base_id, "TimeBaseA", 0); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - actual = OS_TimeBaseCreate(&time_base_id2, "TimeBase2", NULL); + actual = OS_TimeBaseCreate(&time_base_id2, "TimeBaseB", NULL); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - actual = OS_TimeBaseCreate(&time_base_id, "TimeBase3", UT_TimerSync); + actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseC", UT_TimerSync); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); /* Test for nominal, max/min cases */ objid = 0xFFFFFFFF; - actual = OS_TimeBaseCreate(&objid, "TimeBase4", 0); + actual = OS_TimeBaseCreate(&objid, "TimeBaseD", 0); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - /* - * Note: OS_MAX_TIMEBASES = 5, so no more than 5 TimeBase IDs are allowed - * Checking for OS_MAX_TIMEBASES: - */ - TimeBaseNum = OS_MAX_TIMEBASES; - snprintf(maxTimeBase, 12, "TimeBase%d", TimeBaseNum); - objid = 0x00000000; - actual = OS_TimeBaseCreate(&objid, "maxTimeBase", 0); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + /* Checking for OS_MAX_TIMEBASES */ + for ( int i = 0; i < OS_MAX_TIMEBASES; i++ ) + { + snprintf(TimeBaseIter[i], 12, "TimeBase%d", i); + tbc_results[i] = OS_TimeBaseCreate(&tb_id[i], TimeBaseIter[i], 0); + UtAssert_True(tbc_results[i] == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + OS_TimeBaseDelete(tb_id[i]); + } /* Test for invalid inputs */ @@ -97,10 +97,15 @@ void TestTimeBaseApi(void) UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_INVALID_POINTER", (long)actual); expected = OS_ERR_NAME_TAKEN; - actual= OS_TimeBaseCreate(&time_base_id, "TimeBase", 0); + actual= OS_TimeBaseCreate(&time_base_id, "TimeBaseA", 0); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); - /* OS_MAX_TIMEBASES + 1 */ + /* Checking OS_MAX_TIMEBASES + 1 */ + for ( int i = 0; i < OS_MAX_TIMEBASES; i++ ) + { + snprintf(TimeBaseIter[i], 12, "TimeBase%d", i); + tbc_results[i] = OS_TimeBaseCreate(&tb_id[i], TimeBaseIter[i], 0); + } TimeBaseNum = OS_MAX_TIMEBASES+1; snprintf(overMaxTimeBase, 12, "TimeBase%d", TimeBaseNum); expected = OS_ERR_NO_FREE_IDS; @@ -108,6 +113,7 @@ void TestTimeBaseApi(void) UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NO_FREE_IDS", (long)actual); + /* * Test Case For: * int32 OS_TimeBaseSet(uint32 timer_id, uint32 start_time, uint32 interval_time) @@ -173,7 +179,7 @@ void TestTimeBaseApi(void) /* Note: TimeBase2 was created above using TimeBaseCreate and id was set to time_base_id2 */ expected = OS_SUCCESS; objid = 0; - actual = OS_TimeBaseGetIdByName(&objid, "TimeBase2"); + actual = OS_TimeBaseGetIdByName(&objid, "TimeBaseB"); UtAssert_True(actual == expected, "OS_TimeBaseGetIdByName() (%ld) == OS_SUCCESS", (long)actual); UtAssert_True(objid == time_base_id2, "OS_TimeBaseGetIdByName() objid (%lu) Matches!", (unsigned long)objid); @@ -213,7 +219,7 @@ timebase_prop.name)); UtAssert_True(timebase_prop.creator == 0, "timebase_prop.creator (%lu) == 0", (unsigned long)timebase_prop.creator); - UtAssert_True(strcmp(timebase_prop.name, "TimeBase2") == 0, "timebase_prop.name (%s) == TimeBase2", + UtAssert_True(strcmp(timebase_prop.name, "TimeBaseB") == 0, "timebase_prop.name (%s) == TimeBase2", timebase_prop.name); UtAssert_True(timebase_prop.nominal_interval_time == 0, "timebase_prop.nominal_interval_time (%lu) == 0", From a64a43520f923e67d7c50611a66d4f519663b813 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 9 Jun 2020 09:47:10 -0400 Subject: [PATCH 7/8] Fix #493, race condition in idmap api test Use a proper "setup" function to create the resources for the test. Add a delay loop to ensure that the child task has executed before continuing with the rest of the test. --- src/tests/idmap-api-test/idmap-api-test.c | 69 +++++++++++++++-------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/src/tests/idmap-api-test/idmap-api-test.c b/src/tests/idmap-api-test/idmap-api-test.c index a66699a9e..ad13f5163 100644 --- a/src/tests/idmap-api-test/idmap-api-test.c +++ b/src/tests/idmap-api-test/idmap-api-test.c @@ -26,6 +26,17 @@ #include "utbsp.h" +uint32 task_id; +uint32 queue_id; +uint32 count_sem_id; +uint32 bin_sem_id; +uint32 mutex_id1; +uint32 mutex_id2; +uint32 mutex_id3; +uint32 time_base_id; + +#define UT_EXIT_LOOP_MAX 100 + /* *************************************** MAIN ************************************** */ typedef struct @@ -80,38 +91,52 @@ void Test_Void_Fn(void) } /* end Test_Void_Fn */ +void TestIdMapApi_Setup(void) +{ + uint32 loopcnt; + int32 status; + OS_task_prop_t taskprop; + /* + * Create all allowed objects + */ + status = OS_TaskCreate( &task_id, "Task", Test_Void_Fn, 0, 0, 0, 0); + UtAssert_True(status == OS_SUCCESS, "OS_TaskCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_QueueCreate( &queue_id, "Queue", 5, 5, 0); + UtAssert_True(status == OS_SUCCESS, "OS_QueueCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_CountSemCreate( &count_sem_id, "CountSem", 1, 0); + UtAssert_True(status == OS_SUCCESS, "OS_CountSemCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_BinSemCreate( &bin_sem_id, "BinSem", 1, 0); + UtAssert_True(status == OS_SUCCESS, "OS_BinSemCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_MutSemCreate( &mutex_id1, "Mutex1", 0); + UtAssert_True(status == OS_SUCCESS, "OS_MutSemCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_MutSemCreate( &mutex_id2, "Mutex2", 0); + UtAssert_True(status == OS_SUCCESS, "OS_MutSemCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_MutSemCreate( &mutex_id3, "Mutex3", 0); + UtAssert_True(status == OS_SUCCESS, "OS_MutSemCreate() (%ld) == OS_SUCCESS", (long)status); + status = OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); + UtAssert_True(status == OS_SUCCESS, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)status); + + /* Looping delay in parent task to wait for child task to exit */ + loopcnt = 0; + while ((OS_TaskGetInfo(task_id, &taskprop) == OS_SUCCESS) && (loopcnt < UT_EXIT_LOOP_MAX)) + { + OS_TaskDelay(10); + loopcnt++; + } + UtAssert_True(loopcnt < UT_EXIT_LOOP_MAX, "Task exited after %ld iterations", (long)loopcnt); +} /* *************************************** MAIN ************************************** */ void TestIdMapApi(void) { int32 expected; int32 actual; - uint32 task_id; - uint32 queue_id; - uint32 count_sem_id; - uint32 bin_sem_id; - uint32 mutex_id1; - uint32 mutex_id2; - uint32 mutex_id3; - uint32 time_base_id; uint32 TestArrayIndex; uint32 TestMutex1Index; uint32 TestMutex2Index; Test_OS_ObjTypeCount_t Count; - /* - * Create all allowed objects - */ - OS_TaskCreate( &task_id, "Task", Test_Void_Fn, 0, 0, 0, 0); - OS_QueueCreate( &queue_id, "Queue", 5, 5, 0); - OS_CountSemCreate( &count_sem_id, "CountSem", 1, 0); - OS_BinSemCreate( &bin_sem_id, "BinSem", 1, 0); - OS_MutSemCreate( &mutex_id1, "Mutex1", 0); - OS_MutSemCreate( &mutex_id2, "Mutex2", 0); - OS_MutSemCreate( &mutex_id3, "Mutex3", 0); - OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); - /* * NOTE: The following objects were not created and tested: * OS_OBJECT_TYPE_OS_STREAM @@ -229,7 +254,7 @@ void TestIdMapApi(void) OS_ForEachObject (0, &ObjTypeCounter, &Count); /* Verify Outputs */ - UtAssert_True(Count.TaskCount == 1, "OS_ForEachObject() TaskCount (%lu) == 1", (unsigned long)Count.TaskCount); + UtAssert_True(Count.TaskCount == 0, "OS_ForEachObject() TaskCount (%lu) == 0", (unsigned long)Count.TaskCount); UtAssert_True(Count.QueueCount == 1, "OS_ForEachObject() QueueCount (%lu) == 1", (unsigned long)Count.QueueCount); UtAssert_True(Count.CountSemCount == 1, "OS_ForEachObject() CountSemCount (%lu) == 1", (unsigned long)Count.CountSemCount); UtAssert_True(Count.BinSemCount == 2, "OS_ForEachObject() BinSemCount (%lu) == 2", (unsigned long)Count.BinSemCount); @@ -289,6 +314,6 @@ void UtTest_Setup(void) /* * Register the test setup and check routines in UT assert */ - UtTest_Add(TestIdMapApi, NULL, NULL, "TestIdMapApi"); + UtTest_Add(TestIdMapApi, TestIdMapApi_Setup, NULL, "TestIdMapApi"); } From 28d6865b3bf0a14a47d947e4f820d7f36a796276 Mon Sep 17 00:00:00 2001 From: "Gerardo E. Cruz-Ortiz" Date: Tue, 9 Jun 2020 23:11:47 -0400 Subject: [PATCH 8/8] Increase version to 5.0.19 and update ReadMe --- README.md | 12 ++++++++++++ src/os/inc/osapi-version.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 77024e144..60e25cb7c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,18 @@ This distribution contains: ## Version History +### Development Build: 5.0.19 + +- Rename BSPs that can be used on multiple platforms. +`mcp750-vxworks` becomes `generic-vxworks` +`pc-linux` becomes `generic-linux` +- New features only, does not change existing behavior. +UT Hook functions now have the capability to get argument values by name, which is more future proof than assuming a numeric index. +- Add functional test for `OS_TimerAdd` +- Added functional tests for `OS_TimeBase Api` on `OS_TimeBaseCreate`, `OS_TimeBaseSet`, `OS_TimeBaseDelete`, `OS_TimeBaseGetIdByName`, `OS_TimeBaseGetInfo`, `OS_TimeBaseGetFreeRun` +- See for details + + ### Development Build: 5.0.18 - Add functional tests for `OS_IdentifyObject`, `OS_ConvertToArrayIndex` and `OS_ForEachObject` functions. diff --git a/src/os/inc/osapi-version.h b/src/os/inc/osapi-version.h index 2212e80f9..2f4b53374 100644 --- a/src/os/inc/osapi-version.h +++ b/src/os/inc/osapi-version.h @@ -20,7 +20,7 @@ #define OS_MAJOR_VERSION 5 /**< @brief Major version number */ #define OS_MINOR_VERSION 0 /**< @brief Minor version number */ -#define OS_REVISION 18 /**< @brief Revision number */ +#define OS_REVISION 19 /**< @brief Revision number */ #define OS_MISSION_REV 0 /**< @brief Mission revision */ /**