Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1051, use OSAL time conversion/access methods #1058

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions fsw/cfe-core/src/es/cfe_es_backgroundtask.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,25 +136,12 @@ void CFE_ES_BackgroundTask(void)
{
/*
* compute the elapsed time (difference) between last
* execution and now, in microseconds.
*
* Note this calculation is done as a uint32 which will overflow
* after about 35 minutes, but the max delays ensure that this
* executes at least every few seconds, so that should never happen.
* execution and now, in milliseconds.
*/
CFE_PSP_GetTime(&CurrTime);
ElapsedTime = 1000000 * (CurrTime.seconds - LastTime.seconds);
ElapsedTime += CurrTime.microsecs;
ElapsedTime -= LastTime.microsecs;
ElapsedTime = OS_TimeGetTotalMilliseconds(OS_TimeSubtract(CurrTime, LastTime));
LastTime = CurrTime;

/*
* convert to milliseconds.
* we do not really need high precision
* for background task timings
*/
ElapsedTime /= 1000;

NextDelay = CFE_ES_BACKGROUND_MAX_IDLE_DELAY; /* default; will be adjusted based on active jobs */
JobPtr = CFE_ES_BACKGROUND_JOB_TABLE;
JobTotal = CFE_ES_BACKGROUND_NUM_JOBS;
Expand Down
100 changes: 16 additions & 84 deletions fsw/cfe-core/src/time/cfe_time_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,57 +489,16 @@ CFE_TIME_Compare_t CFE_TIME_Compare(CFE_TIME_SysTime_t TimeA, CFE_TIME_SysTime_
*/
uint32 CFE_TIME_Sub2MicroSecs(uint32 SubSeconds)
{
uint32 MicroSeconds;

/* 0xffffdf00 subseconds = 999999 microseconds, so anything greater
* than that we set to 999999 microseconds, so it doesn't get to
* a million microseconds */

if (SubSeconds > 0xffffdf00)
{
MicroSeconds = 999999;
}
else
{
/*
** Convert a 1/2^32 clock tick count to a microseconds count
**
** Conversion factor is ( ( 2 ** -32 ) / ( 10 ** -6 ) ).
**
** Logic is as follows:
** x * ( ( 2 ** -32 ) / ( 10 ** -6 ) )
** = x * ( ( 10 ** 6 ) / ( 2 ** 32 ) )
** = x * ( ( 5 ** 6 ) ( 2 ** 6 ) / ( 2 ** 26 ) ( 2 ** 6) )
** = x * ( ( 5 ** 6 ) / ( 2 ** 26 ) )
** = x * ( ( 5 ** 3 ) ( 5 ** 3 ) / ( 2 ** 7 ) ( 2 ** 7 ) (2 ** 12) )
**
** C code equivalent:
** = ( ( ( ( ( x >> 7) * 125) >> 7) * 125) >> 12 )
*/

MicroSeconds = (((((SubSeconds >> 7) * 125) >> 7) * 125) >> 12);

OS_time_t tm;

/* if the Subseconds % 0x4000000 != 0 then we will need to
* add 1 to the result. the & is a faster way of doing the % */
if ((SubSeconds & 0x3ffffff) != 0)
{
MicroSeconds++;
}

/* In the Micro2SubSecs conversion, we added an extra anomaly
* to get the subseconds to bump up against the end point,
* 0xFFFFF000. This must be accounted for here. Since we bumped
* at the half way mark, we must "unbump" at the same mark
*/
if (MicroSeconds > 500000)
{
MicroSeconds --;
}

} /* end else */

return(MicroSeconds);
/*
** Convert using the OSAL method. Note that there
** is no range check here because any uint32 value is valid,
** and OSAL will handle and properly convert any input.
*/
tm = OS_TimeAssembleFromSubseconds(0, SubSeconds);

return OS_TimeGetMicrosecondsPart(tm);

} /* End of CFE_TIME_Sub2MicroSecs() */

Expand All @@ -549,51 +508,24 @@ uint32 CFE_TIME_Sub2MicroSecs(uint32 SubSeconds)
*/
uint32 CFE_TIME_Micro2SubSecs(uint32 MicroSeconds)
{
OS_time_t tm;
uint32 SubSeconds;

/*
** Conversion amount must be less than one second
** (preserves existing behavior where output saturates at max value)
*/
if (MicroSeconds > 999999)
{
SubSeconds = 0xFFFFFFFF;
}
else
{
/*
** Convert micro-seconds count to sub-seconds (1/2^32) count
**
** Conversion factor is ( ( 10 ** -6 ) / ( 2 ** -20 ).
**
** Logic is as follows:
** x * ( ( 10 ** -6 ) / ( 2 ** -32 ) )
** = x * ( ( 2 ** 32 ) / ( 10 ** 6 ) )
** = x * ( ( ( 2 ** 26 ) ( 2 ** 6) ) / ( ( 5 ** 6 ) ( 2 ** 6 ) ) )
** = x * ( ( 2 ** 26 ) / ( 5 ** 6 ) )
** = x * ( ( ( 2 ** 11) ( 2 ** 3) (2 ** 12) ) / ( 5( 5 ** 5 ) ) )
** = x * ( ( ( ( ( 2 ** 11 ) / 5 ) * ( 2 ** 3 ) ) / ( 5 ** 5 ) ) * (2 ** 12) )
**
** C code equivalent:
** = ( ( ( ( ( x << 11 ) / 5 ) << 3 ) / 3125 ) << 12 )
**
** Conversion factor was reduced and factored accordingly
** to minimize precision loss and register overflow.
*/
SubSeconds = ( ( ( ( MicroSeconds << 11 ) / 5 ) << 3 ) / 3125 ) << 12;

/* To get the SubSeconds to "bump up" against 0xFFFFF000 when
* MicroSeconds = 9999999, we add in another anomaly to the
* conversion at the half-way point (500000 us). This will bump
* all of the subseconds up by 0x1000, so 999999 us == 0xFFFFF00,
* 999998 == 0xFFFFE000, etc. This extra anomaly is accounted for
* in the Sub2MicroSecs conversion as well.
*/

if (SubSeconds > 0x80001000)
{
SubSeconds += 0x1000;
}

/*
** Convert micro-seconds count to sub-seconds (1/2^32) count using OSAL
*/
tm = OS_TimeAssembleFromNanoseconds(0, MicroSeconds * 1000);
SubSeconds = OS_TimeGetSubsecondsPart(tm);
}

return(SubSeconds);
Expand Down
4 changes: 2 additions & 2 deletions fsw/cfe-core/src/time/cfe_time_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ CFE_TIME_SysTime_t CFE_TIME_LatchClock(void)
/*
** Convert time to cFE format (seconds : 1/2^32 subseconds)...
*/
LatchTime.Seconds = LocalTime.seconds;
LatchTime.Subseconds = CFE_TIME_Micro2SubSecs(LocalTime.microsecs);
LatchTime.Seconds = OS_TimeGetTotalSeconds(LocalTime);
LatchTime.Subseconds = OS_TimeGetSubsecondsPart(LocalTime);

return(LatchTime);

Expand Down
53 changes: 9 additions & 44 deletions fsw/cfe-core/unit-test/time_UT.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,38 +1056,28 @@ void Test_ConvertTime(void)
"CFE_TIME_MET2SCTime",
testDesc);

/* NOTE: Microseconds <-> Subseconds conversion routines are implemented
* as part of OS_time_t in OSAL, and are coverage tested there. CFE time
* conversions are now just wrappers of these OSAL routines.

* This should only sanity-check basic values to get coverage of the CFE
* wrappers. Testing of value corner cases / rounding should be limited to
* OSAL coverage test. */

/* Test subseconds to microseconds conversion; zero subsecond value */
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Sub2MicroSecs(0) == 0,
"CFE_TIME_Sub2MicroSecs",
"Convert 0 subsecond value");

/* Test subseconds to microseconds conversion; positive microsecond
* adjust
*/
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Sub2MicroSecs(0xffff) == 16,
"CFE_TIME_Sub2MicroSecs",
"+1 microsecond adjustment");

/* Test subseconds to microseconds conversion; no microsecond adjust */
/* Test subseconds to microseconds conversion; half second */
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Sub2MicroSecs(0x80000000) == 500000,
"CFE_TIME_Sub2MicroSecs",
"No microsecond adjustment");

/* Test subseconds to microseconds conversion; negative microsecond
* adjust
*/
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Sub2MicroSecs(0x80002000) == 500001,
"CFE_TIME_Sub2MicroSecs",
"-1 microsecond adjustment");

/* Test subseconds to microseconds conversion; subseconds exceeds
* microseconds limit
*/
Expand All @@ -1104,31 +1094,6 @@ void Test_ConvertTime(void)
"CFE_TIME_Micro2SubSecs",
"Convert 0 microseconds to 0 subseconds");

/* Test microseconds to subseconds conversion; no subsecond adjust */
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Micro2SubSecs(0xffff) == 281468928,
"CFE_TIME_Micro2SubSecs",
"Microseconds below maximum value (no subsecond adjustment)");

/* Test microseconds to subseconds conversion; microseconds below
* maximum limit
*/
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Micro2SubSecs(999998) == 0xffffe000,
"CFE_TIME_Micro2SubSecs",
"Microseconds below maximum value (subsecond adjustment)");

/* Test microseconds to subseconds conversion; microseconds equals
* maximum limit
*/
UT_InitData();
UT_Report(__FILE__, __LINE__,
CFE_TIME_Micro2SubSecs(999999) == 0xfffff000,
"CFE_TIME_Micro2SubSecs",
"Microseconds equals maximum value (subsecond adjustment)");

/* Test microseconds to subseconds conversion; microseconds exceeds
* maximum limit
*/
Expand Down
3 changes: 1 addition & 2 deletions fsw/cfe-core/unit-test/ut_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ void UT_SetBSP_Time(uint32 seconds, uint32 microsecs)
{
OS_time_t BSP_Time;

BSP_Time.seconds = seconds;
BSP_Time.microsecs = microsecs;
BSP_Time = OS_TimeAssembleFromNanoseconds(seconds, microsecs * 1000);

UT_SetDataBuffer(UT_KEY(CFE_PSP_GetTime), &BSP_Time, sizeof(BSP_Time), true);
}
Expand Down