[rtems-central commit] spec: Specify NTP support

Sebastian Huber sebh at rtems.org
Thu Oct 28 18:14:04 UTC 2021


Module:    rtems-central
Branch:    master
Commit:    bcb0753fd32cb74c0fbb5c7e65829241053dd2af
Changeset: http://git.rtems.org/rtems-central/commit/?id=bcb0753fd32cb74c0fbb5c7e65829241053dd2af

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Oct 28 14:28:51 2021 +0200

spec: Specify NTP support

---

 spec/score/timecounter/req/ntp-adjustment.yml |  16 +++
 spec/score/timecounter/req/ntp-seconds.yml    |  17 +++
 spec/score/timecounter/req/ntp-step-large.yml |  20 +++
 spec/score/timecounter/req/ntp-step.yml       |  20 +++
 spec/score/timecounter/req/ntp.yml            |  15 ++
 spec/score/timecounter/val/install.yml        | 191 +++++++++++++++++++++++++-
 6 files changed, 273 insertions(+), 6 deletions(-)

diff --git a/spec/score/timecounter/req/ntp-adjustment.yml b/spec/score/timecounter/req/ntp-adjustment.yml
new file mode 100644
index 0000000..86edb63
--- /dev/null
+++ b/spec/score/timecounter/req/ntp-adjustment.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: ntp
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  While the timehand is updated, when the ${/glossary/ntp:/term} handler is
+  called, the value returned by the ``adjustment`` parameter shall be used to
+  adjust the timecounter frequency of the timehand.
+type: requirement
diff --git a/spec/score/timecounter/req/ntp-seconds.yml b/spec/score/timecounter/req/ntp-seconds.yml
new file mode 100644
index 0000000..e8542fe
--- /dev/null
+++ b/spec/score/timecounter/req/ntp-seconds.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: ntp
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  While the timehand is updated, when the ${/glossary/ntp:/term} handler is
+  called, the value returned by the ``newsec`` parameter shall define the
+  seconds value of the ${/glossary/clock-realtime:/term} time point of the
+  timehand.
+type: requirement
diff --git a/spec/score/timecounter/req/ntp-step-large.yml b/spec/score/timecounter/req/ntp-step-large.yml
new file mode 100644
index 0000000..76c3a6d
--- /dev/null
+++ b/spec/score/timecounter/req/ntp-step-large.yml
@@ -0,0 +1,20 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: ntp
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  Let ``T`` be the seconds value of the ${/glossary/clock-realtime:/term} time
+  point of the timehand which is currently updated, let ``S`` be the seconds
+  value of the ${/glossary/clock-realtime:/term} time point of the previous
+  timehand, let ``D`` be ``T`` minus ``S``, while the ${/glossary/ntp:/term}
+  handler is not ${/c/if/null:/name}, while ``D`` is greater than 200, while
+  the timehand is updated, the ${/glossary/ntp:/term} handler shall be called
+  exactly two times.
+type: requirement
diff --git a/spec/score/timecounter/req/ntp-step.yml b/spec/score/timecounter/req/ntp-step.yml
new file mode 100644
index 0000000..a0ed01f
--- /dev/null
+++ b/spec/score/timecounter/req/ntp-step.yml
@@ -0,0 +1,20 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: ntp
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  Let ``T`` be the seconds value of the ${/glossary/clock-realtime:/term} time
+  point of the timehand which is currently updated, let ``S`` be the seconds
+  value of the ${/glossary/clock-realtime:/term} time point of the previous
+  timehand, let ``D`` be ``T`` minus ``S``, while the ${/glossary/ntp:/term}
+  handler is not ${/c/if/null:/name}, while ``D`` is greater than or equal to
+  one, while ``D`` is less than or equal to 200, while the timehand is updated,
+  the ${/glossary/ntp:/term} handler shall be called exactly ``D`` times.
+type: requirement
diff --git a/spec/score/timecounter/req/ntp.yml b/spec/score/timecounter/req/ntp.yml
new file mode 100644
index 0000000..6a2342d
--- /dev/null
+++ b/spec/score/timecounter/req/ntp.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: group
+non-functional-type: design
+rationale: null
+references: []
+requirement-type: non-functional
+text: |
+  The clock implementation shall optionally use a handler to do time
+  adjustments and second updates through a ${/glossary/ntp:/term} service.
+type: requirement
diff --git a/spec/score/timecounter/val/install.yml b/spec/score/timecounter/val/install.yml
index 543dc00..de656ff 100644
--- a/spec/score/timecounter/val/install.yml
+++ b/spec/score/timecounter/val/install.yml
@@ -771,9 +771,8 @@ test-actions:
 - action-brief: |
     Update the oldest timehand after a large time interval.
   action-code: |
-    Timecounter     *tc;
-    Per_CPU_Control *cpu_self;
-    struct bintime   bt;
+    Timecounter    *tc;
+    struct bintime  bt;
 
     tc = &high_quality_high_frequency;
 
@@ -783,9 +782,7 @@ test-actions:
     T_eq_u64( bt.frac, 103079215104 );
 
     SetCounter( tc, 2 * tc->base.tc_frequency );
-    cpu_self = _Thread_Dispatch_disable();
-    rtems_timecounter_tick();
-    _Thread_Dispatch_enable( cpu_self );
+    CallTimecounterTick();
 
     SetCounter( tc, 2 * tc->base.tc_frequency );
     rtems_clock_get_realtime_bintime( &bt );
@@ -825,6 +822,144 @@ test-actions:
     - role: validation
       uid: ../req/tick-simple-offset
   links: []
+- action-brief: |
+    Install a very high quality timecounter with a low frequency to test the
+    NTP support.
+  action-code: |
+    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 );
+  checks:
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by one.
+      Check that the NTP update second handler is called exactly once.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-step
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by 200.
+      Check that the NTP update second handler is called exactly 200 times.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-step
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by 201.
+      Check that the NTP update second handler is called exactly twice.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-step-large
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by one.
+      Check that the NTP update second handler is incremented the
+      ${/glossary/clock-realtime:/term} by one second.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-second
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by one.
+      Check that the NTP update second handler is decremented the
+      ${/glossary/clock-realtime:/term} by one second.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-second
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by one.
+      Check that the NTP update second handler increased the timecounter
+      frequency.
+    code: |
+      _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 );
+    links:
+    - role: validation
+      uid: ../req/ntp-adjustment
+  - brief: |
+      Let the seconds value of ${/glossary/clock-realtime:/term} change by one.
+      Check that the NTP update second handler decreased the timecounter
+      frequency.
+    code: |
+      _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, 120259084288 );
+    links:
+    - role: validation
+      uid: ../req/ntp-adjustment
+  links: []
 test-brief: |
   Tests timecounter installation related functions and directives of the Clock
   Manager.
@@ -855,6 +990,10 @@ test-support: |
 
   static Timecounter low_quality;
 
+  static Timecounter very_high_quality;
+
+  static uint32_t ntp_counter;
+
   static uint32_t GetTimecount( struct timecounter *base )
   {
     Timecounter *tc;
@@ -884,6 +1023,46 @@ test-support: |
       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 );
+  }
 test-target: testsuites/validation/tc-timecounter-install.c
 test-teardown: null
 type: test-case



More information about the vc mailing list