[PATCH 3/3] score: Install timecounter according to quality

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Oct 1 11:50:09 UTC 2019


This makes it possible to install higher quality timecounter in
plug-and-play systems and helps to override the clock driver provided
timecounter in some test scenarios.
---
 cpukit/score/src/kern_tc.c                |   2 +
 testsuites/sptests/sptimecounter01/init.c | 101 +++++++++++++++++++++++-------
 2 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index e550b22580..1b65cf41ee 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -1394,11 +1394,13 @@ tc_init(struct timecounter *tc)
 		return;
 	if (tc->tc_quality < 0)
 		return;
+#endif /* __rtems__ */
 	if (tc->tc_quality < timecounter->tc_quality)
 		return;
 	if (tc->tc_quality == timecounter->tc_quality &&
 	    tc->tc_frequency < timecounter->tc_frequency)
 		return;
+#ifndef __rtems__
 	(void)tc->tc_get_timecount(tc);
 	(void)tc->tc_get_timecount(tc);
 #endif /* __rtems__ */
diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c
index 8928c5e051..c949244dc4 100644
--- a/testsuites/sptests/sptimecounter01/init.c
+++ b/testsuites/sptests/sptimecounter01/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2015, 2019 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -29,32 +29,87 @@
 
 const char rtems_test_name[] = "SPTIMECOUNTER 1";
 
+#define TEST_QUAL 1234
+
+#define TEST_FREQ 1000000
+
 typedef struct {
-  struct timecounter tc_soft;
-  u_int tc_soft_counter;
+  struct timecounter tc;
+  uint32_t counter;
+  struct timecounter tc_2;
+  uint32_t counter_2;
 } test_context;
 
 static test_context test_instance;
 
-static uint32_t test_get_timecount_soft(struct timecounter *tc)
+static uint32_t test_get_timecount(struct timecounter *tc)
+{
+  test_context *ctx;
+
+  ctx = RTEMS_CONTAINER_OF(tc, test_context, tc);
+  ++ctx->counter;
+
+  return ctx->counter;
+}
+
+static uint32_t test_get_timecount_2(struct timecounter *tc)
 {
   test_context *ctx;
 
-  ctx = RTEMS_CONTAINER_OF(tc, test_context, tc_soft);
-  ++ctx->tc_soft_counter;
+  ctx = RTEMS_CONTAINER_OF(tc, test_context, tc_2);
+  ++ctx->counter_2;
+
+  return ctx->counter_2;
+}
 
-  return ctx->tc_soft_counter;
+static void test_install(test_context *ctx)
+{
+  struct timecounter *tc;
+  struct timecounter *tc_2;
+  uint32_t c;
+  uint32_t c_2;
+
+  tc = &ctx->tc;
+  tc_2 = &ctx->tc_2;
+  c = ctx->counter;
+  c_2 = ctx->counter_2;
+
+  tc_2->tc_get_timecount = test_get_timecount_2;
+  tc_2->tc_counter_mask = 0x0fffffff;
+  tc_2->tc_frequency = TEST_FREQ - 1;
+  tc_2->tc_quality = TEST_QUAL;
+  _Timecounter_Install(tc_2);
+  assert(ctx->counter == c);
+  assert(ctx->counter_2 == c_2);
+
+  tc_2->tc_get_timecount = test_get_timecount_2;
+  tc_2->tc_counter_mask = 0x0fffffff;
+  tc_2->tc_frequency = TEST_FREQ - 1;
+  tc_2->tc_quality = TEST_QUAL + 1;
+  _Timecounter_Install(tc_2);
+  assert(ctx->counter == c + 1);
+  assert(ctx->counter_2 == c_2 + 1);
+
+  tc->tc_get_timecount = test_get_timecount;
+  tc->tc_counter_mask = 0x0fffffff;
+  tc->tc_frequency = TEST_FREQ;
+  tc->tc_quality = TEST_QUAL + 1;
+  _Timecounter_Install(tc);
+  assert(ctx->counter == c + 2);
+  assert(ctx->counter_2 == c_2 + 2);
 }
 
 void boot_card(const char *cmdline)
 {
-  test_context *ctx = &test_instance;
-  struct timecounter *tc_soft = &ctx->tc_soft;
-  uint64_t soft_freq = 1000000;
+  test_context *ctx;
+  struct timecounter *tc;
   struct bintime bt;
   struct timeval tv;
   struct timespec ts;
 
+  ctx = &test_instance;
+  tc = &ctx->tc;
+
   TEST_BEGIN();
 
   assert(time(NULL) == TOD_SECONDS_1970_THROUGH_1988);
@@ -120,34 +175,36 @@ void boot_card(const char *cmdline)
   assert(bt.sec == 1);
   assert(bt.frac == 0);
 
-  ctx->tc_soft_counter = 0;
-  tc_soft->tc_get_timecount = test_get_timecount_soft;
-  tc_soft->tc_counter_mask = 0x0fffffff;
-  tc_soft->tc_frequency = soft_freq;
-  tc_soft->tc_quality = 1234;
-  _Timecounter_Install(tc_soft);
-  assert(ctx->tc_soft_counter == 1);
+  ctx->counter = 0;
+  tc->tc_get_timecount = test_get_timecount;
+  tc->tc_counter_mask = 0x0fffffff;
+  tc->tc_frequency = TEST_FREQ;
+  tc->tc_quality = TEST_QUAL;
+  _Timecounter_Install(tc);
+  assert(ctx->counter == 1);
 
   rtems_bsd_binuptime(&bt);
-  assert(ctx->tc_soft_counter == 2);
+  assert(ctx->counter == 2);
 
   assert(bt.sec == 1);
   assert(bt.frac == 18446744073708);
 
-  ctx->tc_soft_counter = 0xf0000000 | 1;
+  ctx->counter = 0xf0000000 | 1;
   rtems_bsd_binuptime(&bt);
-  assert(ctx->tc_soft_counter == (0xf0000000 | 2));
+  assert(ctx->counter == (0xf0000000 | 2));
 
   assert(bt.sec == 1);
   assert(bt.frac == 18446744073708);
 
   /* Ensure that the fraction overflows and the second remains constant */
-  ctx->tc_soft_counter = (0xf0000000 | 1) + soft_freq;
+  ctx->counter = (0xf0000000 | 1) + TEST_FREQ;
   rtems_bsd_binuptime(&bt);
-  assert(ctx->tc_soft_counter == (0xf0000000 | 2) + soft_freq);
+  assert(ctx->counter == (0xf0000000 | 2) + TEST_FREQ);
   assert(bt.sec == 1);
   assert(bt.frac == 18446742522092);
 
+  test_install(ctx);
+
   TEST_END();
 
   _Terminate(RTEMS_FATAL_SOURCE_EXIT, 0);
-- 
2.16.4



More information about the devel mailing list