mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-26 06:08:20 +00:00
1134 lines
33 KiB
C
1134 lines
33 KiB
C
/* SPDX-License-Identifier: BSD-2-Clause */
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* @ingroup ScoreTimecounterValInstall
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2021 embedded brains GmbH & Co. KG
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/*
|
|
* This file is part of the RTEMS quality process and was automatically
|
|
* generated. If you find something that needs to be fixed or
|
|
* worded better please post a report or patch to an RTEMS mailing list
|
|
* or raise a bug report:
|
|
*
|
|
* https://www.rtems.org/bugs.html
|
|
*
|
|
* For information on updating and regenerating please refer to the How-To
|
|
* section in the Software Requirements Engineering chapter of the
|
|
* RTEMS Software Engineering manual. The manual is provided as a part of
|
|
* a release. For development sources please refer to the online
|
|
* documentation at:
|
|
*
|
|
* https://docs.rtems.org
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <rtems.h>
|
|
#include <rtems/timecounter.h>
|
|
#include <rtems/score/atomic.h>
|
|
#include <rtems/score/threaddispatch.h>
|
|
|
|
#include "tx-support.h"
|
|
|
|
#include <rtems/test.h>
|
|
|
|
/**
|
|
* @defgroup ScoreTimecounterValInstall spec:/score/timecounter/val/install
|
|
*
|
|
* @ingroup TestsuitesValidationTimecounter0
|
|
*
|
|
* @brief Tests timecounter installation related functions and directives of
|
|
* the Clock Manager.
|
|
*
|
|
* This test case performs the following actions:
|
|
*
|
|
* - Call the simple timecounter tick service with a zero delta and offset.
|
|
* This will lead to an overflow to zero of the timehand generation. It
|
|
* shall not change the initial clock values.
|
|
*
|
|
* - Call the directives to get the initial value of CLOCK_REALTIME and the
|
|
* initial boot time.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in seconds and nanoseconds format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in seconds and nanoseconds format.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in binary time format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in binary time format.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in coarse resolution in binary time
|
|
* format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in coarse resolution in binary time
|
|
* format.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in seconds and microseconds format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in seconds and microseconds format.
|
|
*
|
|
* - Check the initial CLOCK_REALTIME in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*
|
|
* - Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*
|
|
* - Check the initial boot time in seconds and nanoseconds format.
|
|
*
|
|
* - Check the initial boot time in binary time format.
|
|
*
|
|
* - Check the initial boot time in seconds and microseconds format.
|
|
*
|
|
* - Call the directives to get the initial value of CLOCK_MONOTONIC and the
|
|
* initial boot time.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in seconds and nanoseconds format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in seconds and nanoseconds format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in binary time format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in binary time format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in coarse resolution in binary time
|
|
* format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in coarse resolution in binary time
|
|
* format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in signed binary time format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in signed binary time format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in seconds and microseconds format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in seconds and microseconds format.
|
|
*
|
|
* - Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*
|
|
* - Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*
|
|
* - Install timecounter of different quality levels and frequencies.
|
|
*
|
|
* - Install a timecounter with a high quality level and normal frequency.
|
|
* Check that it was installed.
|
|
*
|
|
* - Install a timecounter with a high quality level and low frequency. Check
|
|
* that it was not installed.
|
|
*
|
|
* - Install a timecounter with a high quality level and high frequency.
|
|
* Check that it was installed.
|
|
*
|
|
* - Install a timecounter with a low quality level. Check that it was not
|
|
* installed.
|
|
*
|
|
* - Call the directives to get the time in the highest resolution available to
|
|
* the system.
|
|
*
|
|
* - Check that the timecounter was used by rtems_clock_get_realtime().
|
|
*
|
|
* - Check that the timecounter was used by
|
|
* rtems_clock_get_realtime_bintime().
|
|
*
|
|
* - Check that the timecounter was used by
|
|
* rtems_clock_get_realtime_timeval().
|
|
*
|
|
* - Check that the timecounter was used by rtems_clock_get_monotonic().
|
|
*
|
|
* - Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_bintime().
|
|
*
|
|
* - Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_sbintime().
|
|
*
|
|
* - Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_timeval().
|
|
*
|
|
* - Call the directives to get the time in a coarse resolution.
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse_bintime().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse_timeval().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse_bintime().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse_timeval().
|
|
*
|
|
* - Check that the timecounter was not used by rtems_clock_get_boot_time().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_boot_time_bintime().
|
|
*
|
|
* - Check that the timecounter was not used by
|
|
* rtems_clock_get_boot_time_timeval().
|
|
*
|
|
* - Call the directives to get the time in the highest resolution available to
|
|
* the system.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime_bintime() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime_timeval() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_bintime() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_sbintime() returns the correct time.
|
|
*
|
|
* - Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_timeval() returns the correct time.
|
|
*
|
|
* - Update the oldest timehand after a large time interval.
|
|
*
|
|
* - Call the simple timecounter tick service with non-zero delta and offset
|
|
* parameter values so that exactly one second passed.
|
|
*
|
|
* - Check that exactly one second passed due to the simple clock tick
|
|
* service.
|
|
*
|
|
* - Install a very high quality timecounter with a low frequency to test the
|
|
* NTP support.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME not change. Check that the NTP
|
|
* update second handler is not called.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by one. Check that the
|
|
* NTP update second handler is called exactly once.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by 200. Check that the
|
|
* NTP update second handler is called exactly 200 times.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by 201. Check that the
|
|
* NTP update second handler is called exactly twice.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by one. Check that the
|
|
* NTP update second handler is incremented the CLOCK_REALTIME by one
|
|
* second.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by one. Check that the
|
|
* NTP update second handler is decremented the CLOCK_REALTIME by one
|
|
* second.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by one. Check that the
|
|
* NTP update second handler increased the timecounter frequency.
|
|
*
|
|
* - Let the seconds value of CLOCK_REALTIME change by one. Check that the
|
|
* NTP update second handler decreased the timecounter frequency.
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
typedef struct {
|
|
struct timecounter base;
|
|
Atomic_Ulong counter;
|
|
} Timecounter;
|
|
|
|
static Timecounter high_quality_low_frequency;
|
|
|
|
static Timecounter high_quality_normal_frequency;
|
|
|
|
static Timecounter high_quality_high_frequency;
|
|
|
|
static Timecounter low_quality;
|
|
|
|
static Timecounter very_high_quality;
|
|
|
|
static uint32_t ntp_counter;
|
|
|
|
static uint32_t GetTimecount( struct timecounter *base )
|
|
{
|
|
Timecounter *tc;
|
|
|
|
tc = (Timecounter *) base;
|
|
|
|
return (uint32_t) _Atomic_Fetch_add_ulong(
|
|
&tc->counter,
|
|
1,
|
|
ATOMIC_ORDER_RELAXED
|
|
);
|
|
}
|
|
|
|
static uint32_t GetCounter( const Timecounter *tc )
|
|
{
|
|
return (uint32_t) _Atomic_Load_ulong(
|
|
&tc->counter,
|
|
ATOMIC_ORDER_RELAXED
|
|
);
|
|
}
|
|
|
|
static void SetCounter( Timecounter *tc, uint32_t counter )
|
|
{
|
|
_Atomic_Store_ulong(
|
|
&tc->counter,
|
|
counter,
|
|
ATOMIC_ORDER_RELAXED
|
|
);
|
|
}
|
|
|
|
static void NtpUpdateCounter( int64_t *adjustment, time_t *newsec )
|
|
{
|
|
(void) newsec;
|
|
T_eq_i64( *adjustment, 0 );
|
|
++ntp_counter;
|
|
}
|
|
|
|
static void NtpUpdateSecondIncrement( int64_t *adjustment, time_t *newsec )
|
|
{
|
|
(void) adjustment;
|
|
++(*newsec);
|
|
}
|
|
|
|
static void NtpUpdateSecondDecrement( int64_t *adjustment, time_t *newsec )
|
|
{
|
|
(void) adjustment;
|
|
--(*newsec);
|
|
}
|
|
|
|
static void NtpUpdateAdjustmentFaster( int64_t *adjustment, time_t *newsec )
|
|
{
|
|
*adjustment = ( (int64_t) 5000 ) << 32;
|
|
(void) newsec;
|
|
}
|
|
|
|
static void NtpUpdateAdjustmentSlower( int64_t *adjustment, time_t *newsec )
|
|
{
|
|
*adjustment = -( (int64_t) 5000 ) << 32;
|
|
(void) newsec;
|
|
}
|
|
|
|
static void CallTimecounterTick( void )
|
|
{
|
|
Per_CPU_Control *cpu_self;
|
|
|
|
cpu_self = _Thread_Dispatch_disable();
|
|
rtems_timecounter_tick();
|
|
_Thread_Dispatch_enable( cpu_self );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the simple timecounter tick service with a zero delta and
|
|
* offset. This will lead to an overflow to zero of the timehand generation.
|
|
* It shall not change the initial clock values.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_0( void )
|
|
{
|
|
ISR_lock_Context lock_context;
|
|
|
|
_Timecounter_Acquire( &lock_context );
|
|
_Timecounter_Tick_simple( 0, 0, &lock_context );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the directives to get the initial value of CLOCK_REALTIME and
|
|
* the initial boot time.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_1( void )
|
|
{
|
|
struct bintime bt;
|
|
struct timespec ts;
|
|
struct timeval tv;
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in seconds and nanoseconds format.
|
|
*/
|
|
rtems_clock_get_realtime( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993600 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in seconds and nanoseconds format.
|
|
*/
|
|
rtems_clock_get_realtime( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993600 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993600 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993600 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in binary time format.
|
|
*/
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993600 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in binary time format.
|
|
*/
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993600 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in coarse resolution in binary time
|
|
* format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993600 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in coarse resolution in binary time
|
|
* format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993600 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in seconds and microseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993600 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in seconds and microseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993600 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_REALTIME in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993600 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*/
|
|
rtems_clock_get_realtime_coarse_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993600 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check the initial boot time in seconds and nanoseconds format.
|
|
*/
|
|
rtems_clock_get_boot_time( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993599 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check the initial boot time in binary time format.
|
|
*/
|
|
rtems_clock_get_boot_time_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993599 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check the initial boot time in seconds and microseconds format.
|
|
*/
|
|
rtems_clock_get_boot_time_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993599 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the directives to get the initial value of CLOCK_MONOTONIC and
|
|
* the initial boot time.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_2( void )
|
|
{
|
|
struct bintime bt;
|
|
sbintime_t sb;
|
|
struct timespec ts;
|
|
struct timeval tv;
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in seconds and nanoseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic( &ts );
|
|
T_eq_i64( ts.tv_sec, 1 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in seconds and nanoseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic( &ts );
|
|
T_eq_i64( ts.tv_sec, 1 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse( &ts );
|
|
T_eq_i64( ts.tv_sec, 1 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
|
|
* nanoseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse( &ts );
|
|
T_eq_i64( ts.tv_sec, 1 );
|
|
T_eq_u64( ts.tv_nsec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in binary time format.
|
|
*/
|
|
rtems_clock_get_monotonic_bintime( &bt );
|
|
T_eq_i64( bt.sec, 1 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in binary time format.
|
|
*/
|
|
rtems_clock_get_monotonic_bintime( &bt );
|
|
T_eq_i64( bt.sec, 1 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in coarse resolution in binary time
|
|
* format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_bintime( &bt );
|
|
T_eq_i64( bt.sec, 1 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in coarse resolution in binary time
|
|
* format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_bintime( &bt );
|
|
T_eq_i64( bt.sec, 1 );
|
|
T_eq_u64( bt.frac, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in signed binary time format.
|
|
*/
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_i64( sb, SBT_1S );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in signed binary time format.
|
|
*/
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_i64( sb, SBT_1S );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in seconds and microseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 1 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in seconds and microseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 1 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 1 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
|
|
/*
|
|
* Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
|
|
* microseconds format.
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 1 );
|
|
T_eq_long( tv.tv_usec, 0 );
|
|
}
|
|
|
|
/**
|
|
* @brief Install timecounter of different quality levels and frequencies.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_3( void )
|
|
{
|
|
Timecounter *hqlf;
|
|
Timecounter *hqnf;
|
|
Timecounter *hqhf;
|
|
Timecounter *lq;
|
|
sbintime_t sb;
|
|
|
|
hqlf = &high_quality_low_frequency;
|
|
hqnf = &high_quality_normal_frequency;
|
|
hqhf = &high_quality_high_frequency;
|
|
lq = &low_quality;
|
|
|
|
/*
|
|
* Install a timecounter with a high quality level and normal frequency.
|
|
* Check that it was installed.
|
|
*/
|
|
hqnf->base.tc_get_timecount = GetTimecount;
|
|
hqnf->base.tc_counter_mask = 0xffffffff;
|
|
hqnf->base.tc_frequency = 0x20000000;
|
|
hqnf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
|
|
rtems_timecounter_install( &hqnf->base );
|
|
|
|
T_eq_u32( GetCounter( hqnf ), 1 );
|
|
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_u32( GetCounter( hqnf ), 2 );
|
|
T_eq_i64( sb, SBT_1S + 8 );
|
|
|
|
/*
|
|
* Install a timecounter with a high quality level and low frequency. Check
|
|
* that it was not installed.
|
|
*/
|
|
hqlf->base.tc_get_timecount = GetTimecount;
|
|
hqlf->base.tc_counter_mask = 0xffffffff;
|
|
hqlf->base.tc_frequency = 0x10000000;
|
|
hqlf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
|
|
rtems_timecounter_install( &hqlf->base );
|
|
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 2 );
|
|
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 3 );
|
|
T_eq_i64( sb, SBT_1S + 16 );
|
|
|
|
/*
|
|
* Install a timecounter with a high quality level and high frequency. Check
|
|
* that it was installed.
|
|
*/
|
|
hqhf->base.tc_get_timecount = GetTimecount;
|
|
hqhf->base.tc_counter_mask = 0xffffffff;
|
|
hqhf->base.tc_frequency = 0x40000000;
|
|
hqhf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
|
|
rtems_timecounter_install( &hqhf->base );
|
|
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 4 );
|
|
T_eq_u32( GetCounter( hqhf ), 1 );
|
|
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 4 );
|
|
T_eq_u32( GetCounter( hqhf ), 2 );
|
|
T_eq_i64( sb, SBT_1S + 28 );
|
|
|
|
/*
|
|
* Install a timecounter with a low quality level. Check that it was not
|
|
* installed.
|
|
*/
|
|
lq->base.tc_get_timecount = GetTimecount;
|
|
lq->base.tc_counter_mask = 0xffffffff;
|
|
lq->base.tc_frequency = 0x80000000;
|
|
lq->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
|
|
rtems_timecounter_install( &lq->base );
|
|
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 4 );
|
|
T_eq_u32( GetCounter( hqhf ), 2 );
|
|
T_eq_u32( GetCounter( lq ), 0 );
|
|
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_u32( GetCounter( hqlf ), 0 );
|
|
T_eq_u32( GetCounter( hqnf ), 4 );
|
|
T_eq_u32( GetCounter( hqhf ), 3 );
|
|
T_eq_u32( GetCounter( lq ), 0 );
|
|
T_eq_i64( sb, SBT_1S + 32 );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the directives to get the time in the highest resolution
|
|
* available to the system.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_4( void )
|
|
{
|
|
Timecounter *tc;
|
|
uint32_t counter;
|
|
struct bintime bt;
|
|
struct timespec ts;
|
|
struct timeval tv;
|
|
|
|
tc = &high_quality_high_frequency;
|
|
counter = GetCounter( tc );
|
|
|
|
/*
|
|
* Check that the timecounter was used by rtems_clock_get_realtime().
|
|
*/
|
|
rtems_clock_get_realtime( &ts );
|
|
T_eq_u32( GetCounter( tc ), counter + 1 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by rtems_clock_get_realtime_bintime().
|
|
*/
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_u32( GetCounter( tc ), counter + 2 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by rtems_clock_get_realtime_timeval().
|
|
*/
|
|
rtems_clock_get_realtime_timeval( &tv );
|
|
T_eq_u32( GetCounter( tc ), counter + 3 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by rtems_clock_get_monotonic().
|
|
*/
|
|
rtems_clock_get_monotonic( &ts );
|
|
T_eq_u32( GetCounter( tc ), counter + 4 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_bintime().
|
|
*/
|
|
rtems_clock_get_monotonic_bintime( &bt );
|
|
T_eq_u32( GetCounter( tc ), counter + 5 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_sbintime().
|
|
*/
|
|
(void) rtems_clock_get_monotonic_sbintime();
|
|
T_eq_u32( GetCounter( tc ), counter + 6 );
|
|
|
|
/*
|
|
* Check that the timecounter was used by
|
|
* rtems_clock_get_monotonic_timeval().
|
|
*/
|
|
rtems_clock_get_monotonic_timeval( &tv );
|
|
T_eq_u32( GetCounter( tc ), counter + 7 );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the directives to get the time in a coarse resolution.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_5( void )
|
|
{
|
|
Timecounter *tc;
|
|
uint32_t counter;
|
|
struct bintime bt;
|
|
struct timespec ts;
|
|
struct timeval tv;
|
|
|
|
tc = &high_quality_high_frequency;
|
|
counter = GetCounter( tc );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse().
|
|
*/
|
|
rtems_clock_get_realtime_coarse( &ts );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse_bintime().
|
|
*/
|
|
rtems_clock_get_realtime_coarse_bintime( &bt );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_realtime_coarse_timeval().
|
|
*/
|
|
rtems_clock_get_realtime_coarse_timeval( &tv );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse().
|
|
*/
|
|
rtems_clock_get_monotonic_coarse( &ts );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse_bintime().
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_bintime( &bt );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_monotonic_coarse_timeval().
|
|
*/
|
|
rtems_clock_get_monotonic_coarse_timeval( &tv );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by rtems_clock_get_boot_time().
|
|
*/
|
|
rtems_clock_get_boot_time( &ts );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_boot_time_bintime().
|
|
*/
|
|
rtems_clock_get_boot_time_bintime( &bt );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
|
|
/*
|
|
* Check that the timecounter was not used by
|
|
* rtems_clock_get_boot_time_timeval().
|
|
*/
|
|
rtems_clock_get_boot_time_timeval( &tv );
|
|
T_eq_u32( GetCounter( tc ), counter );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the directives to get the time in the highest resolution
|
|
* available to the system.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_6( void )
|
|
{
|
|
Timecounter *tc;
|
|
uint32_t counter;
|
|
struct bintime bt;
|
|
sbintime_t sb;
|
|
struct timespec ts;
|
|
struct timeval tv;
|
|
|
|
tc = &high_quality_high_frequency;
|
|
counter = 3 * tc->base.tc_frequency + 123456789;
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_realtime( &ts );
|
|
T_eq_i64( ts.tv_sec, 567993603 );
|
|
T_eq_u64( ts.tv_nsec, 114978100 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime_bintime() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993603 );
|
|
T_eq_u64( bt.frac, 2120971587975905280 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_realtime_timeval() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_realtime_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 567993603 );
|
|
T_eq_long( tv.tv_usec, 114978 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_monotonic( &ts );
|
|
T_eq_i64( ts.tv_sec, 4 );
|
|
T_eq_u64( ts.tv_nsec, 114978100 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_bintime() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_monotonic_bintime( &bt );
|
|
T_eq_i64( bt.sec, 4 );
|
|
T_eq_u64( bt.frac, 2120971587975905280 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_sbintime() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
sb = rtems_clock_get_monotonic_sbintime();
|
|
T_eq_i64( sb, 17673696364 );
|
|
|
|
/*
|
|
* Prepare the timecounter to get a large time difference. Check that
|
|
* rtems_clock_get_monotonic_timeval() returns the correct time.
|
|
*/
|
|
SetCounter( tc, counter );
|
|
rtems_clock_get_monotonic_timeval( &tv );
|
|
T_eq_i64( tv.tv_sec, 4 );
|
|
T_eq_long( tv.tv_usec, 114978 );
|
|
}
|
|
|
|
/**
|
|
* @brief Update the oldest timehand after a large time interval.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_7( void )
|
|
{
|
|
Timecounter *tc;
|
|
struct bintime bt;
|
|
|
|
tc = &high_quality_high_frequency;
|
|
|
|
SetCounter( tc, 0 );
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993600 );
|
|
T_eq_u64( bt.frac, 103079215104 );
|
|
|
|
SetCounter( tc, 2 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
|
|
SetCounter( tc, 2 * tc->base.tc_frequency );
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993602 );
|
|
T_eq_u64( bt.frac, 103079215104 );
|
|
}
|
|
|
|
/**
|
|
* @brief Call the simple timecounter tick service with non-zero delta and
|
|
* offset parameter values so that exactly one second passed.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_8( void )
|
|
{
|
|
ISR_lock_Context lock_context;
|
|
Timecounter *tc;
|
|
struct bintime bt;
|
|
|
|
tc = &high_quality_high_frequency;
|
|
|
|
_Timecounter_Acquire( &lock_context );
|
|
_Timecounter_Tick_simple(
|
|
tc->base.tc_frequency / 2,
|
|
GetCounter( tc ) - tc->base.tc_frequency / 2,
|
|
&lock_context
|
|
);
|
|
|
|
/*
|
|
* Check that exactly one second passed due to the simple clock tick service.
|
|
*/
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993603 );
|
|
T_eq_u64( bt.frac, 103079215104 );
|
|
}
|
|
|
|
/**
|
|
* @brief Install a very high quality timecounter with a low frequency to test
|
|
* the NTP support.
|
|
*/
|
|
static void ScoreTimecounterValInstall_Action_9( void )
|
|
{
|
|
Timecounter *tc;
|
|
struct bintime bt;
|
|
|
|
tc = &very_high_quality;
|
|
tc->base.tc_get_timecount = GetTimecount;
|
|
tc->base.tc_counter_mask = 0xffffffff;
|
|
tc->base.tc_frequency = 0x01000000;
|
|
tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 2;
|
|
rtems_timecounter_install( &tc->base );
|
|
|
|
T_eq_u32( GetCounter( tc ), 1 );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993603 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME not change. Check that the NTP
|
|
* update second handler is not called.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateCounter );
|
|
SetCounter( tc, tc->base.tc_frequency / 2 );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
T_eq_u32( ntp_counter, 0 );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993603 );
|
|
T_eq_u64( bt.frac, UINT64_C( 9223373256625487872 ) );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
|
|
* update second handler is called exactly once.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateCounter );
|
|
SetCounter( tc, tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
T_eq_u32( ntp_counter, 1 );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993604 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by 200. Check that the NTP
|
|
* update second handler is called exactly 200 times.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateCounter );
|
|
SetCounter( tc, 201 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
T_eq_u32( ntp_counter, 201 );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567993804 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by 201. Check that the NTP
|
|
* update second handler is called exactly twice.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateCounter );
|
|
SetCounter( tc, 402 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
T_eq_u32( ntp_counter, 203 );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567994005 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
|
|
* update second handler is incremented the CLOCK_REALTIME by one second.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateSecondIncrement );
|
|
SetCounter( tc, 403 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567994007 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
|
|
* update second handler is decremented the CLOCK_REALTIME by one second.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateSecondDecrement );
|
|
SetCounter( tc, 404 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567994007 );
|
|
T_eq_u64( bt.frac, 1219770712064 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
|
|
* update second handler increased the timecounter frequency.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateAdjustmentFaster );
|
|
SetCounter( tc, 405 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
SetCounter( tc, 406 * tc->base.tc_frequency );
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567994009 );
|
|
T_eq_u64( bt.frac, 92353004044288 );
|
|
|
|
/*
|
|
* Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
|
|
* update second handler decreased the timecounter frequency.
|
|
*/
|
|
_Timecounter_Set_NTP_update_second( NtpUpdateAdjustmentSlower );
|
|
SetCounter( tc, 407 * tc->base.tc_frequency );
|
|
CallTimecounterTick();
|
|
_Timecounter_Set_NTP_update_second( NULL );
|
|
|
|
SetCounter( tc, 408 * tc->base.tc_frequency );
|
|
rtems_clock_get_realtime_bintime( &bt );
|
|
T_eq_i64( bt.sec, 567994011 );
|
|
T_eq_u64( bt.frac, 92353004044288 );
|
|
}
|
|
|
|
/**
|
|
* @fn void T_case_body_ScoreTimecounterValInstall( void )
|
|
*/
|
|
T_TEST_CASE( ScoreTimecounterValInstall )
|
|
{
|
|
ScoreTimecounterValInstall_Action_0();
|
|
ScoreTimecounterValInstall_Action_1();
|
|
ScoreTimecounterValInstall_Action_2();
|
|
ScoreTimecounterValInstall_Action_3();
|
|
ScoreTimecounterValInstall_Action_4();
|
|
ScoreTimecounterValInstall_Action_5();
|
|
ScoreTimecounterValInstall_Action_6();
|
|
ScoreTimecounterValInstall_Action_7();
|
|
ScoreTimecounterValInstall_Action_8();
|
|
ScoreTimecounterValInstall_Action_9();
|
|
}
|
|
|
|
/** @} */
|