Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6003e06

Browse files
committedOct 27, 2024·
CLOCK_MONOTONIC_RAW
1 parent c3c36be commit 6003e06

File tree

8 files changed

+125
-105
lines changed

8 files changed

+125
-105
lines changed
 

‎tests/xcp_test_executor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ pub const OPTION_XCP_LOG_LEVEL: xcp::XcpLogLevel = xcp::XcpLogLevel::Info;
2424

2525
// Test parameters
2626
pub const MULTI_THREAD_TASK_COUNT: usize = 16; // Number of threads
27-
pub const DAQ_TEST_TASK_SLEEP_TIME_US: u64 = 100; // Measurement thread task cycle time in us
27+
pub const DAQ_TEST_TASK_SLEEP_TIME_US: u64 = 500; // Measurement thread task cycle time in us
2828
const DAQ_TEST_DURATION_MS: u64 = 6000; // DAQ test duration, 6s to get a nano second 32 bit overflow while checking timestamp monotony
2929
const CAL_TEST_MAX_ITER: u32 = 4000; // Number of calibrations
30-
const CAL_TEST_TASK_SLEEP_TIME_US: u64 = 50; // Checking task cycle time in us
30+
const CAL_TEST_TASK_SLEEP_TIME_US: u64 = 100; // Checking task cycle time in us
3131

3232
//------------------------------------------------------------------------
3333
// Handle incomming SERV_TEXT data

‎xcplib/main_cfg.h

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
11
#pragma once
22
#define __MAIN_CFG_H__
33

4-
// main_cfg.h
5-
// XCPlite
6-
7-
/* Copyright(c) Vector Informatik GmbH.All rights reserved.
8-
Licensed under the MIT license.See LICENSE file in the project root for details. */
4+
/* main.h */
5+
/*
6+
| Code released into public domain, no attribution required
7+
*/
98

109

11-
// When static library xcplib is used for Rust xcp-lite, consider the following options which are compiled into it
1210
/*
11+
Build options:
12+
13+
OPTION_ENABLE_DBG_PRINTS // Enable debug prints
14+
OPTION_DEFAULT_DEBUG_LEVEL // Default debug level 1-5
15+
16+
OPTION_MTU // UDP MTU
17+
18+
Clock default is 1ns since 1970 epoch, free running timescale
19+
OPTION_ARB_CLOCK // 1 us free running timescale and arbitrary epoch
20+
OPTION_TAI_CLOCK // 1ns since 1970 clock, TAI syncronized by platform specific real time clock NTP, PTP4L, ...
21+
22+
23+
PLATFORM_ENABLE_GET_LOCAL_ADDR
24+
PLATFORM_ENABLE_KEYBOARD
1325
14-
main_cfg.h:
15-
XCP_ENABLE_DBG_PRINTS // Enable debug prints
16-
XCP_DEFAULT_DEBUG_LEVEL // Default debug level 1-5
17-
OPTION_MTU // UDP MTU
1826
XCPTL_ENABLE_TCP
1927
XCPTL_ENABLE_UDP
20-
CLOCK_USE_APP_TIME_US or CLOCK_USE_UTC_TIME_NS // Clock resolution, TAI or ARB epoch
2128
2229
xcptl_cfg.h:
2330
XCPTL_QUEUE_SIZE // Allocate static memory for transmit queue, an entry has XCPTL_MAX_SEGMENT_SIZE bytes
2431
XCPTL_MAX_SEGMENT_SIZE // Set to (OPTION_MTU-20-8) optimzed for the maximum possible UDP payload
2532
2633
xcp_cfg.h:
27-
XCP_DAQ_MEM_SIZE // Allocate static meory for DAQ tables
34+
XCP_DAQ_MEM_SIZE // Amount of memory used for DAQ setup
2835
CLOCK_TICKS_PER_S // Resolution of the DAQ clock
2936
3037
*/
3138

3239
// Application configuration:
3340
// XCP configuration is in xcp_cfg.h (Protocol Layer) and xcptl_cfg.h (Transport Layer)
3441

35-
#define ON 1
36-
#define OFF 0
37-
38-
// Set clock resolution (for clock function in platform.c)
39-
//#define CLOCK_USE_APP_TIME_US
40-
#define CLOCK_USE_UTC_TIME_NS
41-
42-
// #define PLATFORM_ENABLE_GET_LOCAL_ADDR
43-
// #define PLATFORM_ENABLE_KEYBOARD
42+
// Debug prints
43+
#define OPTION_ENABLE_DBG_PRINTS
44+
#define OPTION_DEFAULT_DBG_LEVEL 4 /* Default log level: 1 - Error, 2 - Warn, 3 - Info, 4 - Trace, 5 - Debug */
4445

4546

4647
// Ethernet Server
@@ -52,11 +53,3 @@
5253
// Ethernet Transport Layer
5354
#define OPTION_MTU 8000 // Ethernet MTU
5455

55-
// Debug prints
56-
#define OPTION_ENABLE_DBG_PRINTS ON
57-
#define OPTION_DEBUG_LEVEL 2 /*1 - Error, 2 - Warn, 3 - Info, 4 - Trace, 5 - Debug */
58-
#if OPTION_ENABLE_DBG_PRINTS
59-
#define XCP_ENABLE_DBG_PRINTS
60-
#define XCP_DEFAULT_DEBUG_LEVEL OPTION_DEBUG_LEVEL
61-
#endif
62-

‎xcplib/src/dbg_print.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
//-------------------------------------------------------------------------------
1212
// Debug print
1313

14-
#if !defined(OPTION_ENABLE_DBG_PRINTS) || !defined(OPTION_DEBUG_LEVEL)
15-
#error "Please define OPTION_ENABLE_DBG_PRINTS and OPTION_DEBUG_LEVEL in main_cfg.h to ON or OFF"
14+
#if defined(OPTION_ENABLE_DBG_PRINTS) && !defined(OPTION_DEFAULT_DBG_LEVEL)
15+
#error "Please define OPTION_DEFAULT_DBG_LEVEL"
1616
#endif
1717

1818

19-
#if OPTION_ENABLE_DBG_PRINTS
19+
#ifdef OPTION_ENABLE_DBG_PRINTS
2020

2121
/*
2222
1 - Error

‎xcplib/src/main.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22
#define __MAIN_CFG_H__
33

4-
54
/* main.h */
65
/*
76
| Code released into public domain, no attribution required

‎xcplib/src/platform.c

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -674,25 +674,61 @@ uint64_t clockGetLast() {
674674
return sClock;
675675
}
676676

677+
678+
/*
679+
#include <mach/mach_time.h>
680+
#include <iostream>
681+
682+
int main() {
683+
uint64_t start = mach_absolute_time();
684+
685+
// Perform some actions here
686+
687+
uint64_t end = mach_absolute_time();
688+
689+
// Get the conversion factor to convert ticks to nanoseconds
690+
mach_timebase_info_data_t timebase;
691+
mach_timebase_info(&timebase);
692+
uint64_t duration = (end - start) * timebase.numer / timebase.denom;
693+
694+
std::cout << "Duration in nanoseconds: " << duration << std::endl;
695+
return 0;
696+
}
697+
698+
*/
699+
700+
701+
677702
#if defined(_LINUX) // Linux
678703

679704
/*
705+
Option OPTION_ARB_CLOCK provides a clock with 1us resolution since program start
706+
707+
680708
Linux clock type
681-
CLOCK_REALTIME This clock is affected by incremental adjustments performed by NTP
682-
CLOCK_TAI This clock does not experience discontinuities and backwards jumps caused by NTP inserting leap seconds as CLOCK_REALTIME does.
683-
Not available on WSL
709+
CLOCK_REALTIME This clock is affected by incremental adjustments performed by NTP
710+
1ns resolution on MacOS
711+
CLOCK_TAI This clock does not experience discontinuities and backwards jumps caused by NTP or inserting leap seconds as CLOCK_REALTIME does.
712+
Not available on Linux and MacOS
713+
CLOCK_MONOTONIC_RAW Provides a monotonic clock without time drift adjustments by NTP, giving higher stability and resolution
714+
1ns resolution also on MACOS
684715
*/
685-
#define CLOCK_TYPE CLOCK_REALTIME
686-
// #define CLOCK_TYPE CLOCK_TAI
716+
717+
718+
#define CLOCK_TYPE CLOCK_MONOTONIC_RAW
719+
//#define CLOCK_TYPE CLOCK_REALTIME
720+
//#define CLOCK_TYPE CLOCK_TAI
721+
687722

688723
static struct timespec gtr;
689-
#ifndef CLOCK_USE_UTC_TIME_NS
724+
#ifdef OPTION_ARB_CLOCK
690725
static struct timespec gts0;
691726
#endif
692727

728+
693729
char* clockGetString(char* s, uint32_t l, uint64_t c) {
694730

695-
#ifndef CLOCK_USE_UTC_TIME_NS
731+
#ifdef OPTION_ARB_CLOCK
696732
SNPRINTF(s,l, "%gs", (double)c / CLOCK_TICKS_PER_S);
697733
#else
698734
time_t t = (time_t)(c / CLOCK_TICKS_PER_S); // s since 1.1.1970
@@ -711,43 +747,41 @@ char* clockGetString(char* s, uint32_t l, uint64_t c) {
711747
BOOL clockInit()
712748
{
713749
DBG_PRINT3("\nInit clock\n (");
714-
#ifdef CLOCK_USE_UTC_TIME_NS
715-
DBG_PRINT3("CLOCK_USE_UTC_TIME_NS,");
716-
#endif
717-
#ifdef CLOCK_USE_APP_TIME_US
718-
DBG_PRINT3("CLOCK_USE_APP_TIME_US,");
719-
#endif
720-
#if CLOCK_TYPE == CLOCK_TAI
721-
DBG_PRINT3("CLOCK_TYPE_TAI,");
750+
#ifdef OPTION_TAI_CLOCK
751+
DBG_PRINT3("OPTION_TAI_CLOCK\n");
722752
#endif
723-
#if CLOCK_TYPE == CLOCK_REALTIME
724-
DBG_PRINT3("CLOCK_TYPE_REALTIME,");
753+
#ifdef OPTION_ARB_CLOCK
754+
DBG_PRINT3("OPTION_TAI_CLOCK\n");
725755
#endif
726-
DBG_PRINT3(")\n");
727-
756+
728757
sClock = 0;
729758

730759
clock_getres(CLOCK_TYPE, &gtr);
731-
DBG_PRINTF4("Clock resolution is %lds,%ldns!\n", gtr.tv_sec, gtr.tv_nsec);
760+
DBG_PRINTF3("Clock resolution is %lds,%ldns!\n", gtr.tv_sec, gtr.tv_nsec);
732761

733-
#ifndef CLOCK_USE_UTC_TIME_NS
762+
#ifdef OPTION_ARB_CLOCK
734763
clock_gettime(CLOCK_TYPE, &gts0);
735764
#endif
736765
clockGet();
737766

738767
#ifdef DBG_LEVEL
739-
if (DBG_LEVEL >= 4) {
768+
if (DBG_LEVEL >= 4) { // Test
740769
uint64_t t1, t2;
741770
char s[128];
771+
/*
742772
struct timespec gts;
743773
struct timeval ptm;
744774
time_t now = time(NULL);
745775
gettimeofday(&ptm, NULL);
746776
clock_gettime(CLOCK_TYPE, &gts);
747-
DBG_PRINTF4(" CLOCK_REALTIME=%lus time=%lu timeofday=%lu\n", gts.tv_sec, now, ptm.tv_sec);
748-
t1 = clockGet(); sleepNs(100000); t2 = clockGet();
777+
DBG_PRINTF5(" CLOCK_REALTIME=%lus time=%lu timeofday=%lu\n", gts.tv_sec, now, ptm.tv_sec);
778+
*/
779+
t1 = clockGet(); sleepMs(1); t2 = clockGet();
780+
DBG_PRINTF4(" +0us: %llu %s\n", t1, clockGetString(s, sizeof(s), t1));
781+
DBG_PRINTF4(" +1ms: %llu %s (dt=%u)\n", t2, clockGetString(s, sizeof(s), t2), (uint32_t)(t2 - t1));
782+
t1 = clockGet(); sleepMs(100); t2 = clockGet();
749783
DBG_PRINTF4(" +0us: %llu %s\n", t1, clockGetString(s, sizeof(s), t1));
750-
DBG_PRINTF4(" +100us: %llu %s (dt=%u)\n", t2, clockGetString(s, sizeof(s), t2), (uint32_t)(t2 - t1));
784+
DBG_PRINTF4(" +100ms: %llu %s (dt=%u)\n", t2, clockGetString(s, sizeof(s), t2), (uint32_t)(t2 - t1));
751785
DBG_PRINT4("\n");
752786
}
753787
#endif
@@ -761,7 +795,7 @@ uint64_t clockGet() {
761795

762796
struct timespec ts;
763797
clock_gettime(CLOCK_TYPE, &ts);
764-
#ifdef CLOCK_USE_UTC_TIME_NS // ns since 1.1.1970
798+
#ifndef OPTION_ARB_CLOCK // ns since 1.1.1970
765799
return sClock = (((uint64_t)(ts.tv_sec) * 1000000000ULL) + (uint64_t)(ts.tv_nsec)); // ns
766800
#else // us since init
767801
return sClock = (((uint64_t)(ts.tv_sec - gts0.tv_sec) * 1000000ULL) + (uint64_t)(ts.tv_nsec / 1000)); // us
@@ -772,14 +806,14 @@ uint64_t clockGet() {
772806

773807
// Performance counter to clock conversion
774808
static uint64_t sFactor = 0; // ticks per us
775-
#ifdef CLOCK_USE_UTC_TIME_NS
809+
#ifndef OPTION_ARB_CLOCK
776810
static uint8_t sDivide = 0; // divide or multiply
777811
#endif
778812
static uint64_t sOffset = 0; // offset
779813

780814
char* clockGetString(char* str, uint32_t l, uint64_t c) {
781815

782-
#ifndef CLOCK_USE_UTC_TIME_NS
816+
#ifdef OPTION_ARB_CLOCK
783817
SNPRINTF(str, l, "%gs", (double)c / CLOCK_TICKS_PER_S);
784818
#else
785819
uint64_t s = c / CLOCK_TICKS_PER_S;
@@ -799,7 +833,7 @@ char* clockGetString(char* str, uint32_t l, uint64_t c) {
799833

800834
char* clockGetTimeString(char* str, uint32_t l, int64_t t) {
801835

802-
#ifndef CLOCK_USE_UTC_TIME_NS
836+
#ifdef OPTION_ARB_CLOCK
803837
SNPRINTF(str, l, "%gs", (double)t/CLOCK_TICKS_PER_S);
804838
#else
805839
char sign = '+'; if (t < 0) { sign = '-'; t = -t; }
@@ -815,10 +849,8 @@ char* clockGetTimeString(char* str, uint32_t l, int64_t t) {
815849
BOOL clockInit() {
816850

817851
DBG_PRINT3("\nInit clock\n");
818-
#ifdef CLOCK_USE_UTC_TIME_NS
819-
DBG_PRINT3(" CLOCK_USE_UTC_TIME_NS\n");
820-
#else
821-
DBG_PRINT3(" CLOCK_USE_APP_TIME_US\n");
852+
#ifndef OPTION_ARB_CLOCK
853+
DBG_PRINT3(" OPTION_TAI_CLOCK\n");
822854
#endif
823855

824856
sClock = 0;
@@ -835,7 +867,7 @@ BOOL clockInit() {
835867
DBG_PRINT_ERROR("ERROR: Unexpected performance counter frequency!\n");
836868
return FALSE;
837869
}
838-
#ifdef CLOCK_USE_UTC_TIME_NS
870+
#ifndef OPTION_ARB_CLOCK
839871
if (CLOCK_TICKS_PER_S > tF.u.LowPart) {
840872
sFactor = CLOCK_TICKS_PER_S / tF.u.LowPart;
841873
sDivide = 0;
@@ -849,7 +881,7 @@ BOOL clockInit() {
849881
#endif
850882

851883
// Get current performance counter to absolute time relation
852-
#ifdef CLOCK_USE_UTC_TIME_NS
884+
#ifndef OPTION_ARB_CLOCK
853885

854886
// Set time zone from TZ environment variable. If TZ is not set, the operating system is queried
855887
_tzset();
@@ -867,7 +899,7 @@ BOOL clockInit() {
867899
// Calculate factor and offset
868900
QueryPerformanceCounter(&tC);
869901
tp = (((int64_t)tC.u.HighPart) << 32) | (int64_t)tC.u.LowPart;
870-
#ifdef CLOCK_USE_UTC_TIME_NS
902+
#ifndef OPTION_ARB_CLOCK
871903
// set offset from local clock UTC value t
872904
// this is inaccurate up to 1 s, but irrelevant because system clock UTC offset is also not accurate
873905
sOffset = time_s * CLOCK_TICKS_PER_S + (uint64_t)time_ms * CLOCK_TICKS_PER_MS - tp * sFactor;
@@ -880,7 +912,7 @@ BOOL clockInit() {
880912

881913
#ifdef DBG_LEVEL
882914
if (DBG_LEVEL >= 5) {
883-
#ifdef CLOCK_USE_UTC_TIME_NS
915+
#ifndef OPTION_ARB_CLOCK
884916
if (DBG_LEVEL >= 6) {
885917
struct tm tm;
886918
_gmtime64_s(&tm, (const __time64_t*)&time_s);
@@ -915,7 +947,7 @@ uint64_t clockGet() {
915947

916948
QueryPerformanceCounter(&tp);
917949
t = (((uint64_t)tp.u.HighPart) << 32) | (uint64_t)tp.u.LowPart;
918-
#ifdef CLOCK_USE_UTC_TIME_NS
950+
#ifndef OPTION_ARB_CLOCK
919951
if (sDivide) {
920952
t = t / sFactor + sOffset;
921953
}

‎xcplib/src/platform.h

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
#ifndef __MAIN_CFG_H__
8-
#error "Include dependency error!"
8+
#error "Include dependency error! options not set"
99
#endif
1010

1111
//-------------------------------------------------------------------------------
@@ -159,28 +159,21 @@ extern BOOL socketGetLocalAddr(uint8_t* mac, uint8_t* addr);
159159
#endif
160160

161161
//-------------------------------------------------------------------------------
162-
// Clock
163-
164-
// Clock resolution and epoch
165-
#if !defined(CLOCK_USE_UTC_TIME_NS) && !defined(CLOCK_USE_APP_TIME_US)
166-
// Default
167-
#define CLOCK_USE_UTC_TIME_NS // Use ns timestamps relative to 1.1.1970 (TAI monotonic - no backward jumps)
168-
//#define CLOCK_USE_APP_TIME_US // Use arbitrary us timestamps relative to application start
169-
#endif
162+
// High resolution clock
170163

171-
#ifdef CLOCK_USE_UTC_TIME_NS
164+
#ifndef OPTION_ARB_CLOCK
172165

173-
#define CLOCK_TICKS_PER_M (1000000000ULL*60)
174-
#define CLOCK_TICKS_PER_S 1000000000
175-
#define CLOCK_TICKS_PER_MS 1000000
176-
#define CLOCK_TICKS_PER_US 1000
177-
#define CLOCK_TICKS_PER_NS 1
166+
#define CLOCK_TICKS_PER_M (1000000000ULL*60)
167+
#define CLOCK_TICKS_PER_S 1000000000
168+
#define CLOCK_TICKS_PER_MS 1000000
169+
#define CLOCK_TICKS_PER_US 1000
170+
#define CLOCK_TICKS_PER_NS 1
178171

179172
#else
180173

181-
#define CLOCK_TICKS_PER_S 1000000
182-
#define CLOCK_TICKS_PER_MS 1000
183-
#define CLOCK_TICKS_PER_US 1
174+
#define CLOCK_TICKS_PER_S 1000000
175+
#define CLOCK_TICKS_PER_MS 1000
176+
#define CLOCK_TICKS_PER_US 1
184177

185178
#endif
186179

0 commit comments

Comments
 (0)
Please sign in to comment.