From 04085a839d4e56eade1951f77e0066d375be85ff Mon Sep 17 00:00:00 2001 From: Ryan Steel Date: Wed, 15 Jul 2026 12:44:00 +0000 Subject: [PATCH 1/7] docs: add examples user documentation --- docs/index.rst | 1 + docs/manuals/.gitkeep | 0 docs/manuals/examples/basic_clocks.rst | 349 ++++++++++++++++++++++++ docs/manuals/examples/index.rst | 64 +++++ docs/manuals/examples/vehicle_time.rst | 350 +++++++++++++++++++++++++ docs/manuals/index.rst | 22 ++ 6 files changed, 786 insertions(+) delete mode 100644 docs/manuals/.gitkeep create mode 100644 docs/manuals/examples/basic_clocks.rst create mode 100644 docs/manuals/examples/index.rst create mode 100644 docs/manuals/examples/vehicle_time.rst create mode 100644 docs/manuals/index.rst diff --git a/docs/index.rst b/docs/index.rst index e35c841d..6007e6f8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,6 +43,7 @@ For a detailed concept and architectural design, please refer to the :doc:`time_ :caption: Contents: features/index + manuals/index Project Layout -------------- diff --git a/docs/manuals/.gitkeep b/docs/manuals/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/manuals/examples/basic_clocks.rst b/docs/manuals/examples/basic_clocks.rst new file mode 100644 index 00000000..a1c7a387 --- /dev/null +++ b/docs/manuals/examples/basic_clocks.rst @@ -0,0 +1,349 @@ +.. ******************************************************************************* + Copyright (c) 2026 Contributors to the Eclipse Foundation + + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 + ******************************************************************************* + +Basic Clock Examples +==================== + +Overview +-------- + +Three examples demonstrate the basic SCORE clock types: ``system_time``, ``steady_time``, +and ``high_res_steady_time``. All follow an identical pattern - a periodic time printer +that outputs time values once per second until interrupted. + +These examples show the fundamental pattern for using SCORE time APIs and can serve as +starting points for applications requiring simple time reading. + +Common Implementation Pattern +----------------------------- + +All three examples share the same structure: + +**Handler Class** + Wrapper around ``Clock::GetInstance()`` that provides a clean ``GetCurrentTime()`` + method returning a ``TimeReport`` struct. + +**Main Program** + - Signal handling for graceful shutdown (SIGINT/SIGTERM) + - Loop reading time every second + - Simple text output with sequence numbers + - Consistent error handling + +**Unit Tests** + Demonstrate mocking with ``ScopedClockOverride`` for dependency injection. + +Building and Running +-------------------- + +.. code-block:: bash + + # Build any of the basic examples + bazel build //examples/time/system_time + bazel build //examples/time/steady_time + bazel build //examples/time/high_res_steady_time + + # Run examples + bazel run //examples/time/system_time + bazel run //examples/time/steady_time + bazel run //examples/time/high_res_steady_time + + # Run tests + bazel test //examples/time/system_time/src:system_time_handler_test + bazel test //examples/time/steady_time/src:steady_time_handler_test + bazel test //examples/time/high_res_steady_time/src:high_res_steady_time_handler_test + +Example Output +-------------- + +Each example prints time in a similar format: + +**System Time:** + +.. code-block:: text + + SystemTime printer started. Press Ctrl+C to stop. + [0] unix=1720184400.123456789 s + [1] unix=1720184401.234567890 s + [2] unix=1720184402.345678901 s + ... + +**Steady Time:** + +.. code-block:: text + + SteadyTime printer started. Press Ctrl+C to stop. + [0] monotonic=12345.123456789 s + [1] monotonic=12346.234567890 s + [2] monotonic=12347.345678901 s + ... + +**High-Resolution Steady Time:** + +.. code-block:: text + + HighResSteadyTime printer started. Press Ctrl+C to stop. + [0] time=12345.123456789 s + [1] time=12346.234567890 s + [2] time=12347.345678901 s + ... + +Clock Type Differences +---------------------- + +While the implementation pattern is identical, each clock type serves different use cases: + +System Time (``system_time``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- **Purpose**: Wall-clock time for timestamps and user-visible time displays +- **Characteristics**: + - Unix epoch time (seconds since 1970-01-01 00:00:00 UTC) + - Can jump forward/backward when system clock is adjusted + - Affected by NTP corrections, manual time changes +- **Use when**: Logging timestamps, displaying current time, scheduling events +- **Don't use for**: Duration measurement, timeouts, performance timing + +Steady Time (``steady_time``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- **Purpose**: Monotonic time for duration measurements and timeouts +- **Characteristics**: + - Always moves forward, never jumps backward + - Unaffected by system clock adjustments + - Arbitrary epoch (typically boot time) +- **Use when**: Measuring elapsed time, implementing timeouts, rate limiting +- **Best for**: General-purpose timing where precision beyond milliseconds is not critical + +High-Resolution Steady Time (``high_res_steady_time``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- **Purpose**: High-precision monotonic time for precise timing applications +- **Characteristics**: + - Highest available timing resolution (nanosecond on modern systems) + - May have higher overhead than standard steady clock + - Platform-dependent actual resolution +- **Use when**: Precise performance measurements, sub-millisecond timing, real-time control +- **Trade-off**: Higher precision may cost more CPU cycles per call + +Code Structure +-------------- + +Each example follows this pattern: + +**Handler Header** (``*_time_handler.h``): + +.. code-block:: cpp + + struct TimeReport { + std::int64_t time_field_ns{0}; // Field name varies by clock type + }; + + class TimeHandler { + public: + TimeReport GetCurrentTime() const noexcept { + const auto snapshot = ClockType::GetInstance().Now(); + return TimeReport{snapshot.TimePointNs().count()}; + } + }; + +**Main Program** (``main.cpp``): + +.. code-block:: cpp + + volatile std::sig_atomic_t gShutdownRequested{0}; + extern "C" void HandleSignal(int) noexcept { gShutdownRequested = 1; } + + int main() { + signal(SIGINT, HandleSignal); + signal(SIGTERM, HandleSignal); + + HandlerType handler; + std::uint64_t seq{0}; + + while (gShutdownRequested == 0) { + const auto report = handler.GetCurrentTime(); + PrintReport(report, seq++); + std::this_thread::sleep_for(std::chrono::seconds{1}); + } + return 0; + } + +Testing Pattern +--------------- + +All examples use the same mocking approach: + +.. code-block:: cpp + + TEST(HandlerTest, GetCurrentTime) { + auto mock = std::make_shared(); + score::time::test_utils::ScopedClockOverride guard{mock}; + + EXPECT_CALL(*mock, Now()).WillOnce(Return(test_snapshot)); + + HandlerType handler; + const auto report = handler.GetCurrentTime(); + + EXPECT_EQ(expected_value, report.time_field_ns); + } + +.. note:: + + Tests using ``ScopedClockOverride`` must declare ``tags = ["exclusive", "unit"]`` + in their Bazel BUILD file to prevent parallel execution conflicts. + +When to Use Each Example +------------------------ + +Choose the appropriate clock type based on your application needs: + +.. list-table:: + :header-rows: 1 + :widths: 25 35 40 + + * - Use Case + - Recommended Clock + - Example + * - User-visible timestamps + - System Time + - Log file entries, UI clock displays + * - Duration measurement + - Steady Time + - Function execution time, timeout implementation + * - High-precision timing + - High-Res Steady Time + - Performance profiling, real-time control loops + * - Rate limiting + - Steady Time + - Request throttling, periodic tasks + * - Scheduling + - System Time + - Calendar-based events, cron-like scheduling + +The examples provide a solid foundation that can be extended with additional features +like configuration, multiple output formats, or integration with larger applications. + +Bazel Build Setup +----------------- + +Understanding the dependency structure helps when adapting these examples for your application. + +Target Structure +~~~~~~~~~~~~~~~~ + +Each example has three Bazel targets in ``examples/time//src/BUILD``: + +.. code-block:: python + + cc_library( + name = "time_handler", + hdrs = ["system_time_handler.h"], + deps = ["//score/time/system_time:interface"], # Header-only dep + ) + + cc_binary( + name = "system_time", + srcs = ["main.cpp"], + deps = [ + ":time_handler", + "//score/time/system_time", # Production backend + ], + ) + + cc_test( + name = "system_time_handler_test", + srcs = ["system_time_handler_test.cpp"], + tags = ["exclusive", "unit"], # Required for ScopedClockOverride + deps = [ + ":time_handler", + "//score/time/system_time:system_time_mock", # Mock backend + "@googletest//:gtest", + "@googletest//:gtest_main", + ], + ) + +Dependency Layers +~~~~~~~~~~~~~~~~~ + +**Handler Library** (``time_handler``): + - Header-only wrapper around SCORE clock API + - Depends on ``:interface`` target (types only, no implementation) + - Can be tested without linking production backend + +**Binary** (``system_time``, ``steady_time``, ``high_res_steady_time``): + - Links production backend (``//score/time/``) + - Depends on handler library + - Minimal dependencies for deployment + +**Test** (``*_handler_test``): + - Links mock backend (``//score/time/:*_mock``) + - Uses ``ScopedClockOverride`` for dependency injection + - **Must** have ``tags = ["exclusive", "unit"]`` to prevent parallel test conflicts + +Key Dependency Targets +~~~~~~~~~~~~~~~~~~~~~~ + +For each clock type (``system_time``, ``steady_time``, ``high_res_steady_time``): + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Target + - Purpose + * - ``//score/time/:interface`` + - Header-only, types and tag definitions + * - ``//score/time/`` + - Production backend implementation + * - ``//score/time/:_mock`` + - GMock test double for unit testing + +Adapting for Your Application +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use these patterns in your code: + +1. **Production code** depends on ``:interface`` for headers, production target for binary: + + .. code-block:: python + + cc_library( + name = "my_component", + hdrs = ["my_component.h"], + deps = ["//score/time/steady_time:interface"], + ) + + cc_binary( + name = "my_app", + deps = [ + ":my_component", + "//score/time/steady_time", # Link production backend + ], + ) + +2. **Tests** depend on ``:interface`` and ``*_mock``: + + .. code-block:: python + + cc_test( + name = "my_component_test", + tags = ["exclusive", "unit"], # Required! + deps = [ + ":my_component", + "//score/time/steady_time:steady_time_mock", + "@googletest//:gtest_main", + ], + ) + +This layering keeps compile times fast (interface-only deps) and enables testing without +runtime dependencies. \ No newline at end of file diff --git a/docs/manuals/examples/index.rst b/docs/manuals/examples/index.rst new file mode 100644 index 00000000..2c05373b --- /dev/null +++ b/docs/manuals/examples/index.rst @@ -0,0 +1,64 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Examples User Manual +==================== + +This manual explains the examples included in the ``examples/time/`` subdirectory and how they +can be used as patterns for building applications with the SCORE time library. + +Overview +-------- + +The ``examples/time/`` directory contains four working examples that demonstrate how to use +different SCORE time sources: + +- **Basic Clock Examples** (system_time, steady_time, high_res_steady_time): Simple periodic time printers showing the common pattern for reading time from SCORE clocks +- **Vehicle Time Example** (vehicle_time): More complex example showing PTP-synchronized time with initialization, status monitoring, and dual time sources + +All examples follow consistent patterns and can be used as starting points for real applications. + +Building and Running Examples +------------------------------ + +All examples use Bazel: + +.. code-block:: bash + + # Build all examples + bazel build //examples/... + + # Run specific example + bazel run //examples/time/system_time + + # Run tests + bazel test //examples/time/system_time/src:system_time_handler_test + +Common Patterns +--------------- + +All examples share these implementation patterns: + +- **Handler wrapper classes** providing clean APIs over SCORE Clock types +- **TimeReport structs** containing time data with consistent field naming +- **Signal handling** for graceful shutdown on SIGINT/SIGTERM +- **Unit test patterns** using ScopedClockOverride for dependency injection +- **Nanosecond precision** throughout all time calculations + +.. toctree:: + :maxdepth: 2 + :caption: Examples: + + basic_clocks + vehicle_time diff --git a/docs/manuals/examples/vehicle_time.rst b/docs/manuals/examples/vehicle_time.rst new file mode 100644 index 00000000..7aaf0bd2 --- /dev/null +++ b/docs/manuals/examples/vehicle_time.rst @@ -0,0 +1,350 @@ +.. ******************************************************************************* + Copyright (c) 2026 Contributors to the Eclipse Foundation + + See the NOTICE file(s) distributed with this work for additional + information regarding copyright ownership. + + This program and the accompanying materials are made available under the + terms of the Apache License Version 2.0 which is available at + https://www.apache.org/licenses/LICENSE-2.0 + + SPDX-License-Identifier: Apache-2.0 + ******************************************************************************* + +Vehicle Time Example +==================== + +Overview +-------- + +The ``vehicle_time`` example demonstrates how to use the SCORE library's VehicleClock +in combination with HighResSteadyClock. This example shows how to work with +PTP-synchronized vehicle time alongside local monotonic time, which is essential +for automotive applications requiring distributed time synchronization. + +What it does +------------ + +This example creates a ``VehicleTimeHandler`` wrapper class that: + +- Provides access to both SCORE ``VehicleClock`` and ``HighResSteadyClock`` +- Returns combined time reports with status information +- Demonstrates initialization patterns for vehicle time backends +- Shows how to monitor time synchronization quality +- Can be unit tested with independent clock mocks + +The main program: + +- Initializes the vehicle time backend +- Runs a loop reading both time sources simultaneously +- Displays time values, reliability, and synchronization status +- Handles SIGINT/SIGTERM for clean shutdown + +Building and Running +-------------------- + +To build and run the example: + +.. code-block:: bash + + # Build the example + bazel build //examples/time/vehicle_time + + # Run the example + bazel run //examples/time/vehicle_time + + # Or run the built binary directly + ./bazel-bin/examples/time/vehicle_time/src/vehicle_time + +**Note**: The vehicle time backend requires proper initialization. The example will +exit with error code 1 if initialization fails (e.g., no PTP service available). + +Output Format +------------- + +The program outputs lines in this format: + +.. code-block:: text + + VehicleTime + HighResSteadyTime printer started. Press Ctrl+C to stop. + [0] vehicle=1720184400.123456789 s hirs=12345.234567890 s is_reliable=yes is_consistent=yes rate_deviation=1.23e-09 + [1] vehicle=1720184401.234567890 s hirs=12346.345678901 s is_reliable=yes is_consistent=yes rate_deviation=1.24e-09 + ... + Shutdown requested. Exiting. + +Where: +- ``vehicle=`` shows the PTP-synchronized time in seconds.nanoseconds +- ``hirs=`` shows the local high-resolution steady time +- ``is_reliable=`` indicates if the vehicle time is synchronized and fault-free +- ``is_consistent=`` indicates if status flags are internally consistent +- ``rate_deviation=`` shows local clock deviation relative to PTP Grand Master + +Code Structure +-------------- + +VehicleTimeHandler Class +~~~~~~~~~~~~~~~~~~~~~~~~ + +Located in ``examples/time/vehicle_time/src/vehicle_time_handler.h``: + +.. code-block:: cpp + + class VehicleTimeHandler { + public: + bool Init() noexcept; + TimeReport GetCurrentTime() const noexcept; + void RegisterStatusCallback(VehicleTime::StatusChangedCallback callback) noexcept; + }; + + struct TimeReport { + std::int64_t vehicle_time_ns{0}; // PTP-synchronized time + std::int64_t high_res_steady_time_ns{0}; // Local monotonic time + bool is_reliable{false}; // Time sync quality + bool is_consistent{false}; // Status flag consistency + double rate_deviation{0.0}; // Clock drift rate + }; + +Key features: +- **Dual time sources**: Both vehicle and local time in single call +- **Status monitoring**: Reliability and consistency flags +- **Rate tracking**: Clock deviation measurement +- **Callback support**: Status change notifications (future feature) + +Main Program +~~~~~~~~~~~~ + +Located in ``examples/time/vehicle_time/src/main.cpp``: + +Key features: +- Initialization error handling with early exit +- Combined time display showing both sources +- Status information formatting for monitoring +- Same signal handling pattern as other examples + +Testing +------- + +Run the unit tests: + +.. code-block:: bash + + bazel test //examples/time/vehicle_time/src:vehicle_time_handler_test + +The test shows how to mock both time sources independently: + +.. code-block:: cpp + + auto vehicle_mock = std::make_shared(); + auto hirs_mock = std::make_shared(); + + score::time::test_utils::ScopedClockOverride vg{vehicle_mock}; + score::time::test_utils::ScopedClockOverride hg{hirs_mock}; + + EXPECT_CALL(*vehicle_mock, Init()).WillOnce(Return(true)); + EXPECT_CALL(*vehicle_mock, Now()).WillOnce(Return(...)); + EXPECT_CALL(*hirs_mock, Now()).WillOnce(Return(...)); + +Vehicle Time Concepts +--------------------- + +**PTP Synchronization (Precision Time Protocol):** + +- Provides network-wide time synchronization across vehicle systems +- Typically accurate to microseconds or better across the network +- Requires a Grand Master clock and PTP-capable network infrastructure +- Subject to network latency variations and synchronization loss + +**Status Flags:** + +- **is_reliable**: Time is synchronized and no faults detected +- **is_consistent**: Status flags don't contain contradictory information +- **rate_deviation**: Local clock frequency difference from Grand Master (parts per billion) + +**Combined Time Sources:** + +Using both vehicle time and local steady time provides: +- **Vehicle time**: For coordination with other vehicle systems +- **Local steady time**: For local timing that's unaffected by network issues +- **Comparison**: Ability to detect synchronization problems + +Vehicle Time vs Other Time Sources +----------------------------------- + +**Vehicle Time characteristics:** + +- **Network synchronized**: Coordinated across vehicle ECUs +- **Can become unreliable**: Network issues, Grand Master failures +- **May have gaps**: Synchronization loss periods +- **Best for**: Cross-ECU coordination, distributed logging + +**When to use Vehicle Time:** + +- Coordinating events across multiple ECUs +- Distributed system logging with consistent timestamps +- Safety-critical applications requiring time correlation +- AUTOSAR Classic/Adaptive compliance + +**When to fallback to Local Time:** + +- Vehicle time becomes unreliable (is_reliable=false) +- Network synchronization is lost +- Local-only timing requirements +- Backup timing for safety applications + +Use Cases +--------- + +This example demonstrates patterns for: + +- **Automotive ECU applications** requiring time synchronization +- **Distributed logging systems** with consistent timestamps +- **Safety-critical systems** with redundant time sources +- **Performance monitoring** of network time synchronization +- **AUTOSAR applications** using synchronized time services + +The dual time source approach provides robustness: use vehicle time when reliable, +fall back to local time when network synchronization is lost. + +Bazel Build Setup +----------------- + +The vehicle_time example has more complex dependencies due to dual time sources and initialization. + +Target Structure +~~~~~~~~~~~~~~~~ + +From ``examples/time/vehicle_time/src/BUILD``: + +.. code-block:: python + + cc_library( + name = "time_handler", + hdrs = ["vehicle_time_handler.h"], + deps = [ + "//score/time/vehicle_time:interface", + "//score/time/high_res_steady_time:interface", + ], + ) + + cc_binary( + name = "vehicle_time", + srcs = ["main.cpp"], + deps = [ + ":time_handler", + "//score/time/vehicle_time", # VehicleTime production backend + "//score/time/high_res_steady_time", # HIRS production backend + "@score_baselibs//score/mw/log:console_only_backend", + ], + ) + + cc_test( + name = "vehicle_time_handler_test", + srcs = ["vehicle_time_handler_test.cpp"], + tags = ["exclusive", "unit"], # Required for ScopedClockOverride + deps = [ + ":time_handler", + "//score/time/vehicle_time:vehicle_time_mock", + "//score/time/high_res_steady_time:high_res_steady_time_mock", + "@googletest//:gtest_main", + ], + ) + +Dual Clock Dependencies +~~~~~~~~~~~~~~~~~~~~~~~ + +The handler depends on **two** clock interfaces: + +- ``//score/time/vehicle_time:interface`` - VehicleTime tag and status types +- ``//score/time/high_res_steady_time:interface`` - HighResSteadyTime tag + +The binary links **both** production backends, while tests link **both** mocks. + +Key Targets +~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Target + - Purpose + * - ``//score/time/vehicle_time:interface`` + - VehicleTime types, status flags, callback signatures + * - ``//score/time/vehicle_time`` + - Production backend with TimeDaemon IPC + * - ``//score/time/vehicle_time:vehicle_time_mock`` + - Mock for Init/Now/Subscribe testing + * - ``//score/time/high_res_steady_time:interface`` + - HighResSteadyTime tag + * - ``//score/time/high_res_steady_time`` + - Production HIRS clock backend + * - ``//score/time/high_res_steady_time:high_res_steady_time_mock`` + - Mock for HIRS in tests + +Testing with Dual Mocks +~~~~~~~~~~~~~~~~~~~~~~~ + +The test demonstrates independent mock control: + +.. code-block:: cpp + + auto vehicle_mock = std::make_shared(); + auto hirs_mock = std::make_shared(); + + ScopedClockOverride vg{vehicle_mock}; + ScopedClockOverride hg{hirs_mock}; + + EXPECT_CALL(*vehicle_mock, Init()).WillOnce(Return(true)); + EXPECT_CALL(*vehicle_mock, Now()).WillOnce(Return(vehicle_snapshot)); + EXPECT_CALL(*hirs_mock, Now()).WillOnce(Return(hirs_snapshot)); + +Each clock can be mocked separately with different return values and expectations. + +Adapting for Your Application +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When building components that use VehicleTime: + +1. **Header-only dependencies** use ``:interface``: + + .. code-block:: python + + cc_library( + name = "my_sync_component", + hdrs = ["my_sync_component.h"], + deps = [ + "//score/time/vehicle_time:interface", + "//score/time/high_res_steady_time:interface", + ], + ) + +2. **Binaries** link production backends: + + .. code-block:: python + + cc_binary( + name = "my_app", + deps = [ + ":my_sync_component", + "//score/time/vehicle_time", + "//score/time/high_res_steady_time", + ], + ) + +3. **Tests** link mocks and require exclusive tag: + + .. code-block:: python + + cc_test( + name = "my_sync_component_test", + tags = ["exclusive", "unit"], + deps = [ + ":my_sync_component", + "//score/time/vehicle_time:vehicle_time_mock", + "//score/time/high_res_steady_time:high_res_steady_time_mock", + "@googletest//:gtest_main", + ], + ) + +The layered dependency structure keeps compile times minimal while enabling comprehensive +testing with independent clock control. diff --git a/docs/manuals/index.rst b/docs/manuals/index.rst new file mode 100644 index 00000000..24c29564 --- /dev/null +++ b/docs/manuals/index.rst @@ -0,0 +1,22 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Manuals +======= + +.. toctree:: + :maxdepth: 2 + :caption: Manuals: + + examples/index From 00f95df8e605cedcce4e730eed6188d219913d3f Mon Sep 17 00:00:00 2001 From: Ryan Steel Date: Wed, 15 Jul 2026 13:23:53 +0000 Subject: [PATCH 2/7] docs: remove API specifics from the examples docs --- docs/manuals/examples/basic_clocks.rst | 71 +------------------------- docs/manuals/examples/vehicle_time.rst | 61 ---------------------- 2 files changed, 1 insertion(+), 131 deletions(-) diff --git a/docs/manuals/examples/basic_clocks.rst b/docs/manuals/examples/basic_clocks.rst index a1c7a387..47d900e0 100644 --- a/docs/manuals/examples/basic_clocks.rst +++ b/docs/manuals/examples/basic_clocks.rst @@ -97,44 +97,6 @@ Each example prints time in a similar format: [2] time=12347.345678901 s ... -Clock Type Differences ----------------------- - -While the implementation pattern is identical, each clock type serves different use cases: - -System Time (``system_time``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- **Purpose**: Wall-clock time for timestamps and user-visible time displays -- **Characteristics**: - - Unix epoch time (seconds since 1970-01-01 00:00:00 UTC) - - Can jump forward/backward when system clock is adjusted - - Affected by NTP corrections, manual time changes -- **Use when**: Logging timestamps, displaying current time, scheduling events -- **Don't use for**: Duration measurement, timeouts, performance timing - -Steady Time (``steady_time``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- **Purpose**: Monotonic time for duration measurements and timeouts -- **Characteristics**: - - Always moves forward, never jumps backward - - Unaffected by system clock adjustments - - Arbitrary epoch (typically boot time) -- **Use when**: Measuring elapsed time, implementing timeouts, rate limiting -- **Best for**: General-purpose timing where precision beyond milliseconds is not critical - -High-Resolution Steady Time (``high_res_steady_time``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- **Purpose**: High-precision monotonic time for precise timing applications -- **Characteristics**: - - Highest available timing resolution (nanosecond on modern systems) - - May have higher overhead than standard steady clock - - Platform-dependent actual resolution -- **Use when**: Precise performance measurements, sub-millisecond timing, real-time control -- **Trade-off**: Higher precision may cost more CPU cycles per call - Code Structure -------------- @@ -202,37 +164,6 @@ All examples use the same mocking approach: Tests using ``ScopedClockOverride`` must declare ``tags = ["exclusive", "unit"]`` in their Bazel BUILD file to prevent parallel execution conflicts. -When to Use Each Example ------------------------- - -Choose the appropriate clock type based on your application needs: - -.. list-table:: - :header-rows: 1 - :widths: 25 35 40 - - * - Use Case - - Recommended Clock - - Example - * - User-visible timestamps - - System Time - - Log file entries, UI clock displays - * - Duration measurement - - Steady Time - - Function execution time, timeout implementation - * - High-precision timing - - High-Res Steady Time - - Performance profiling, real-time control loops - * - Rate limiting - - Steady Time - - Request throttling, periodic tasks - * - Scheduling - - System Time - - Calendar-based events, cron-like scheduling - -The examples provide a solid foundation that can be extended with additional features -like configuration, multiple output formats, or integration with larger applications. - Bazel Build Setup ----------------- @@ -346,4 +277,4 @@ To use these patterns in your code: ) This layering keeps compile times fast (interface-only deps) and enables testing without -runtime dependencies. \ No newline at end of file +runtime dependencies. diff --git a/docs/manuals/examples/vehicle_time.rst b/docs/manuals/examples/vehicle_time.rst index 7aaf0bd2..ec2b1d71 100644 --- a/docs/manuals/examples/vehicle_time.rst +++ b/docs/manuals/examples/vehicle_time.rst @@ -144,67 +144,6 @@ The test shows how to mock both time sources independently: EXPECT_CALL(*vehicle_mock, Now()).WillOnce(Return(...)); EXPECT_CALL(*hirs_mock, Now()).WillOnce(Return(...)); -Vehicle Time Concepts ---------------------- - -**PTP Synchronization (Precision Time Protocol):** - -- Provides network-wide time synchronization across vehicle systems -- Typically accurate to microseconds or better across the network -- Requires a Grand Master clock and PTP-capable network infrastructure -- Subject to network latency variations and synchronization loss - -**Status Flags:** - -- **is_reliable**: Time is synchronized and no faults detected -- **is_consistent**: Status flags don't contain contradictory information -- **rate_deviation**: Local clock frequency difference from Grand Master (parts per billion) - -**Combined Time Sources:** - -Using both vehicle time and local steady time provides: -- **Vehicle time**: For coordination with other vehicle systems -- **Local steady time**: For local timing that's unaffected by network issues -- **Comparison**: Ability to detect synchronization problems - -Vehicle Time vs Other Time Sources ------------------------------------ - -**Vehicle Time characteristics:** - -- **Network synchronized**: Coordinated across vehicle ECUs -- **Can become unreliable**: Network issues, Grand Master failures -- **May have gaps**: Synchronization loss periods -- **Best for**: Cross-ECU coordination, distributed logging - -**When to use Vehicle Time:** - -- Coordinating events across multiple ECUs -- Distributed system logging with consistent timestamps -- Safety-critical applications requiring time correlation -- AUTOSAR Classic/Adaptive compliance - -**When to fallback to Local Time:** - -- Vehicle time becomes unreliable (is_reliable=false) -- Network synchronization is lost -- Local-only timing requirements -- Backup timing for safety applications - -Use Cases ---------- - -This example demonstrates patterns for: - -- **Automotive ECU applications** requiring time synchronization -- **Distributed logging systems** with consistent timestamps -- **Safety-critical systems** with redundant time sources -- **Performance monitoring** of network time synchronization -- **AUTOSAR applications** using synchronized time services - -The dual time source approach provides robustness: use vehicle time when reliable, -fall back to local time when network synchronization is lost. - Bazel Build Setup ----------------- From 261d68a9964a31ede92fbee1a760bf5626135082 Mon Sep 17 00:00:00 2001 From: "Ludwig Weise (ETAS-E2E/XPC-Hi3)" Date: Wed, 15 Jul 2026 15:42:16 +0200 Subject: [PATCH 3/7] feat(docs): Create public user manual for time module It includes - An overall architecture introduction and a guide for choosing the right clock. - A detailed API description covering basic usage, lifecycle management, advanced subscriptions, and unit-testing patterns. - A dedicated integration guide for system integrators. - A troubleshooting guide for diagnosing common runtime issues. --- docs/manuals/.gitkeep | 0 docs/manuals/api_description/advanced_api.rst | 122 ++++++++++++++ docs/manuals/api_description/api_usage.rst | 88 ++++++++++ docs/manuals/api_description/lifecycle.rst | 116 +++++++++++++ .../manuals/api_description/testing_guide.rst | 153 ++++++++++++++++++ docs/manuals/config/configuration_guide.rst | 94 +++++++++++ docs/manuals/index_user_manual.rst | 32 ++++ docs/manuals/integration_guide.rst | 57 +++++++ docs/manuals/introduction.rst | 92 +++++++++++ docs/manuals/troubleshooting_guide.rst | 73 +++++++++ 10 files changed, 827 insertions(+) delete mode 100644 docs/manuals/.gitkeep create mode 100644 docs/manuals/api_description/advanced_api.rst create mode 100644 docs/manuals/api_description/api_usage.rst create mode 100644 docs/manuals/api_description/lifecycle.rst create mode 100644 docs/manuals/api_description/testing_guide.rst create mode 100644 docs/manuals/config/configuration_guide.rst create mode 100644 docs/manuals/index_user_manual.rst create mode 100644 docs/manuals/integration_guide.rst create mode 100644 docs/manuals/introduction.rst create mode 100644 docs/manuals/troubleshooting_guide.rst diff --git a/docs/manuals/.gitkeep b/docs/manuals/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/manuals/api_description/advanced_api.rst b/docs/manuals/api_description/advanced_api.rst new file mode 100644 index 00000000..dd1270dd --- /dev/null +++ b/docs/manuals/api_description/advanced_api.rst @@ -0,0 +1,122 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_advanced_api + +Advanced API Usage: Subscribing to PTP Protocol Events +====================================================== + +For advanced use cases, such as diagnostics, network monitoring, or detailed performance analysis, the ``score::time`` framework allows applications to subscribe directly to low-level PTP protocol data events. Instead of polling for the final, processed time, an application can register a callback function that is invoked asynchronously whenever new data arrives from the ``TimeSlave``. + +.. warning:: + + This is an advanced feature. Most applications should use the simpler polling mechanism described in the previous chapter, as it provides the fully quality-assured time. Subscribing to raw PTP data bypasses some of the quality checks performed by the ``TimeDaemon``. + +Available Data Subscriptions +---------------------------- + +Two types of data events can be subscribed to: + +1. **`TimeSlaveSyncData`**: + This event is triggered whenever the ``TimeSlave`` successfully processes a PTP Sync/Follow-Up message pair from the Time Master. The data contains raw offset and rate correction information, as well as the underlying hardware and software timestamps. + +2. **`PDelayMeasurementData`**: + This event is triggered after the ``TimeSlave`` completes a peer-delay measurement cycle (PDelay_Req/Resp/FUp exchange). The data contains the calculated path delay to the communication partner. + +Subscribing to Events +--------------------- + +The following code example demonstrates how to register, handle, and unregister callbacks for these events. + +.. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + #include + #include + #include + + // A thread-safe data handler for our application + class PtpDataLogger + { + public: + void HandleSyncData(const score::time::TimeSlaveSyncData& data) + { + std::lock_guard lock(mutex_); + std::cout << "PTP Sync Event: Offset = " << data.offset_ns + << " ns, Rate Ratio = " << data.rate_ratio << std::endl; + // Further processing of the data... + } + + void HandlePDelayData(const score::time::PDelayMeasurementData& data) + { + std::lock_guard lock(mutex_); + std::cout << "PTP PDelay Event: Path Delay = " << data.path_delay_ns << " ns" << std::endl; + // Further processing of the data... + } + + private: + std::mutex mutex_; + }; + + /** + * @brief Demonstrates how to subscribe to and unsubscribe from PTP protocol events. + */ + void subscribe_to_ptp_events() + { + auto& clock = score::time::Clock::GetInstance(); + PtpDataLogger logger; + + // 1. Subscribe to Sync data events using a lambda that calls our thread-safe handler. + // The returned handle is used later to unsubscribe. + auto sync_subscription = clock.Subscribe>( + [&logger](const auto& data) { logger.HandleSyncData(data); }); + + std::cout << "Subscribed to TimeSlaveSyncData events." << std::endl; + + + // 2. Subscribe to Peer-Delay data events. + auto pdelay_subscription = clock.Subscribe>( + [&logger](const auto& data) { logger.HandlePDelayData(data); }); + + std::cout << "Subscribed to PDelayMeasurementData events." << std::endl; + + // ... application runs and receives callbacks asynchronously ... + std::this_thread::sleep_for(std::chrono::seconds(10)); + + + // 3. Unsubscribe when the data is no longer needed. + // The subscription handle is moved into the Unsubscribe call. + clock.Unsubscribe(std::move(sync_subscription)); + std::cout << "Unsubscribed from TimeSlaveSyncData events." << std::endl; + + clock.Unsubscribe(std::move(pdelay_subscription)); + std::cout << "Unsubscribed from PDelayMeasurementData events." << std::endl; + } + + +Threading and Safety Considerations +----------------------------------- + +.. attention:: + + Callback functions are executed on a **backend thread** owned by the ``score::time`` framework, not on the application's main thread. Therefore, all callback handlers **must be thread-safe**. + +* **Data Protection**: Use mutexes, atomics, or other synchronization primitives to protect any shared data that is accessed or modified within the callback. +* **Keep it Short**: Callbacks should be lightweight and non-blocking. Offload any time-consuming processing to a separate application-owned thread to avoid delaying the ``score::time`` backend. + +Unsubscribing +------------- + +It is crucial to unsubscribe from events when they are no longer needed to prevent resource leaks and dangling callbacks. The ``Subscribe`` method returns a handle object which must be passed to the ``Unsubscribe`` method. The handle is invalidated upon unsubscription. diff --git a/docs/manuals/api_description/api_usage.rst b/docs/manuals/api_description/api_usage.rst new file mode 100644 index 00000000..91456cba --- /dev/null +++ b/docs/manuals/api_description/api_usage.rst @@ -0,0 +1,88 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_api_usage + +API Usage: Accessing Vehicle Time +================================= + +The primary interface for applications to access synchronized time is the ``score::time`` client library. It provides a simple, robust, and testable way to get the current time without dealing with the underlying complexities of PTP and IPC. + +This section describes the most common use case: polling the current Vehicle Time. + +Polling the Current Time +------------------------ + +This method involves actively requesting the current time from the ``score::time`` framework. It is the simplest way to get a timepoint when needed. + +.. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + #include + #include + + /** + * @brief Demonstrates how to poll the current Vehicle Time and check its status. + */ + void poll_vehicle_time() + { + // 1. Get a handle to the VehicleClock singleton instance. + auto& clock = score::time::Clock::GetInstance(); + + // 2. Request the current time snapshot. + // This call retrieves the latest time information from the TimeDaemon via IPC. + const auto snapshot = clock.Now(); + + // 3. Check the status of the snapshot. + // The IsReliable() flag indicates if the time is currently synchronized + // to a master and has passed all quality checks in the TimeDaemon. + if (snapshot.Status().IsReliable()) + { + // 4. Use the timepoint. + // The timepoint is a std::chrono::time_point. + const auto current_time = snapshot.TimePoint(); + const auto ns_since_epoch = std::chrono::duration_cast( + current_time.time_since_epoch()).count(); + + std::cout << "Successfully retrieved reliable Vehicle Time: " + << ns_since_epoch << " ns since epoch." << std::endl; + } + else + { + // 5. Handle the "not synchronized" case. + // If the time is not reliable, applications must not use the timepoint value. + // This can happen during startup or if the connection to the Time Master is lost. + // The application should implement a retry-logic or fallback. + std::cerr << "Warning: Vehicle Time is not synchronized or not reliable. " + << "Retrying later..." << std::endl; + } + } + +Workflow Explanation +-------------------- + +The sequence diagram "VT1 — VehicleTime: Time Polling with Status Check" illustrates the following steps: + +1. **Get Instance**: The application first obtains a singleton instance of the ``VehicleClock``. This is a lightweight operation and the clock handle can be stored and reused. +2. **Now()**: The application calls the ``Now()`` method on the clock instance. This triggers an IPC call to the ``TimeDaemon`` to fetch the latest synchronized time data. +3. **Return Snapshot**: The framework returns a ``ClockSnapshot`` object. This object contains not just the timepoint, but also a crucial ``VehicleTimeStatus`` payload. +4. **Status Check**: The application **must** call the ``Status().IsReliable()`` method on the snapshot. This boolean flag consolidates all underlying quality metrics (e.g., is PTP master available? is shared memory data fresh? has the time passed plausibility checks?). +5. **Conditional Logic**: + * If ``IsReliable()`` returns ``true``, the timepoint is valid and can be safely used by the application logic. + * If ``IsReliable()`` returns ``false``, the application must discard the timepoint value and handle the failure case (e.g., by logging a warning and retrying the operation after a short delay). + +.. attention:: + + Never use the ``TimePoint`` from a ``ClockSnapshot`` without first verifying that ``Status().IsReliable()`` is true. Using an unreliable timepoint can lead to incorrect or inconsistent behavior in safety-critical applications. diff --git a/docs/manuals/api_description/lifecycle.rst b/docs/manuals/api_description/lifecycle.rst new file mode 100644 index 00000000..a5eec71c --- /dev/null +++ b/docs/manuals/api_description/lifecycle.rst @@ -0,0 +1,116 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_lifecycle + +Clock Lifecycle Management +========================== + +Before an application can read reliable time from clocks like ``VehicleClock``, the underlying backend service must be initialized and ready. The ``Clock`` API provides several functions to manage this lifecycle gracefully. + +.. attention:: + These lifecycle functions are primarily relevant for clocks that depend on external services, like ``VehicleClock``. Simpler clocks such as ``SystemClock`` or ``SteadyClock`` are always available and do not require these steps. + +Initializing the Clock +---------------------- + +The ``Init()`` method must be called once to establish the connection to the backend service (e.g., the ``TimeDaemon``). Until ``Init()`` succeeds, any call to ``Now()`` will return a snapshot with a "not ready" or "unknown" status. + +.. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + #include + + void initialize_clock() + { + auto& clock = score::time::Clock::GetInstance(); + + // Attempt to initialize the connection to the backend. + // This can be retried if it fails (e.g., if the TimeDaemon is not yet running). + if (clock.Init()) + { + std::cout << "Clock backend initialized successfully." << std::endl; + } + else + { + std::cerr << "Clock backend initialization failed. Please retry." << std::endl; + } + } + +Waiting for Availability +------------------------ + +After initialization, the clock might still not be "reliable" because the ``TimeDaemon`` itself is waiting for synchronization with the PTP master. Instead of polling in a loop, applications can use ``WaitUntilAvailable()`` to block efficiently until the clock is ready. + +This is the recommended approach for applications that cannot proceed without a valid time source at startup. + +.. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + #include + #include + #include + + void wait_for_reliable_time(const score::cpp::stop_token& stop_token) + { + auto& clock = score::time::Clock::GetInstance(); + + if (!clock.Init()) { + std::cerr << "Initialization failed. Cannot wait for time." << std::endl; + return; + } + + // Wait for a maximum of 30 seconds for the clock to become available. + // The wait will be interrupted if the application's stop_token is triggered. + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(30); + + std::cout << "Waiting for VehicleTime to become available..." << std::endl; + + if (clock.WaitUntilAvailable(stop_token, deadline)) + { + std::cout << "VehicleTime is now available and synchronized!" << std::endl; + + // Now it is safe to start polling or using the time. + const auto snapshot = clock.Now(); + if (snapshot.Status().IsReliable()) { + // ... proceed with application logic ... + } + } + else + { + std::cerr << "Timed out waiting for VehicleTime. Is the TimeSlave running and synchronized?" << std::endl; + } + } + + +Checking Availability (Non-Blocking) +------------------------------------ + +For applications that need to perform other tasks while waiting for time, the non-blocking ``IsAvailable()`` method can be used to periodically check the status. + +.. code-block:: cpp + + // Inside an application's main loop + auto& clock = score::time::Clock::GetInstance(); + + if (clock.IsAvailable()) + { + // Time is ready, perform time-sensitive tasks. + } + else + { + // Time is not yet ready, perform other tasks. + } diff --git a/docs/manuals/api_description/testing_guide.rst b/docs/manuals/api_description/testing_guide.rst new file mode 100644 index 00000000..dbd0b81c --- /dev/null +++ b/docs/manuals/api_description/testing_guide.rst @@ -0,0 +1,153 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_testing: + +Unit-Testing Time-Dependent Code +================================ + +Testing application logic that depends on time can be challenging. To solve this, the ``score::time`` framework provides a powerful mechanism to replace the real-time clock with a controllable "fake" clock during unit tests. This is achieved using the ``ScopedClockOverride`` helper. + +A Helper for Controllable Time: The `ClockTestFactory` +====================================================== + +To make tests cleaner and more readable, it is a recommended practice to create a small test factory helper class. This class encapsulates the creation of the fake clock and provides a simple API to control the time within a test. + +Here is a minimal implementation of such a factory. You can add this helper to your own test utilities. + +**`clock_test_factory.h` (Example Implementation):** + +.. code-block:: cpp + + #include "score/time/clock/src/clock_backend_mock.h" + #include "score/time/vehicle_time.h" + #include + #include + + // A helper class to manage a fake clock backend in tests. + class ClockTestFactory { + public: + // Creates the backend and returns a shared_ptr to it. + // This backend is then passed to the ScopedClockOverride. + std::shared_ptr> + CreateFakeClock() { + fake_clock_backend_ = std::make_shared>(); + return fake_clock_backend_; + } + + // Advances the time on the created fake clock. + void AdvanceTime(std::chrono::nanoseconds duration) { + // We simulate a monotonic clock by shifting the offset of the mock + // to return a progressively advanced timestamp on every subsequent call. + current_time_ += duration; + ON_CALL(*fake_clock_backend_, Now()) + .WillByDefault(testing::Return(score::time::TimeSnapshot( + score::time::VehicleTime::time_point(current_time_)))); + } + + private: + std::shared_ptr> fake_clock_backend_; + std::chrono::nanoseconds current_time_{0}; + }; + + +Example: Testing a Timeout Handler +================================== + +This example demonstrates how to use the custom `ClockTestFactory` helper to test a component that performs an action once a specific timeout duration has elapsed. + +**Component to be tested (`my_component.h`):** + +.. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + #include + + class MyTimeoutHandler { + public: + MyTimeoutHandler() + : clock_{score::time::Clock::GetInstance()} + , start_time_{clock_.Now().TimePoint()} {} + + bool HasTimedOut(std::chrono::seconds timeout_duration) { + const auto now = clock_.Now().TimePoint(); + return (now - start_time_) > timeout_duration; + } + + private: + score::time::Clock clock_; + score::time::VehicleTime::time_point start_time_; + }; + +**Unit Test (`my_component_test.cpp`):** + +.. code-block:: cpp + + #include "my_component.h" + #include "clock_test_factory.h" // Our custom helper + #include "score/time/clock/src/scoped_clock_override.h" + #include + + TEST(MyTimeoutHandlerTest, DetectsTimeoutCorrectly) + { + // 1. Create our test factory helper. + ClockTestFactory test_factory; + auto fake_clock_backend = test_factory.CreateFakeClock(); + + // 2. Activate the override with the backend from our factory. + auto clock_override = score::time::test_utils::ScopedClockOverride( + fake_clock_backend); + + // 3. Instantiate the component-under-test. It will now automatically use the fake clock. + MyTimeoutHandler handler; + const auto timeout = std::chrono::seconds{10}; + + // 4. Initially, no timeout should be detected. + EXPECT_FALSE(handler.HasTimedOut(timeout)); + + // 5. Advance the fake clock's time via our factory helper by 9 seconds. + test_factory.AdvanceTime(std::chrono::seconds{9}); + EXPECT_FALSE(handler.HasTimedOut(timeout)); + + // 6. Advance the time past the 10 seconds timeout threshold (Total: 11 seconds). + test_factory.AdvanceTime(std::chrono::seconds{2}); + EXPECT_TRUE(handler.HasTimedOut(timeout)); + + } // <-- 7. Here, `clock_override` is destroyed, and the real clock backend is automatically restored. + + +Bazel BUILD Setup +================= + +Because ``ScopedClockOverride`` modifies global state (the active backend for a given clock tag), tests utilizing it must be configured carefully in Bazel. + +To prevent parallel tests from overriding the clock simultaneously and interfering with each other, you **must** mark your test targets with the ``exclusive`` tag. + +.. code-block:: python + + cc_test( + name = "my_component_test", + srcs = [ + "my_component_test.cpp", + "clock_test_factory.h" + ], + tags = ["exclusive", "unit"], # "exclusive" prevents parallel execution conflicts + deps = [ + ":my_component", + "//score/time/vehicle_time:vehicle_time_mock", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], + ) diff --git a/docs/manuals/config/configuration_guide.rst b/docs/manuals/config/configuration_guide.rst new file mode 100644 index 00000000..fe9dab7a --- /dev/null +++ b/docs/manuals/config/configuration_guide.rst @@ -0,0 +1,94 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_configuration: + +Configuration Guide +=================== + +This guide describes the configuration of the sCore ``time`` module components. + +TimeSlave Daemon (`time_slave`) +=============================== + +The behavior of the ``TimeSlave`` is controlled by the ``GptpEngineOptions`` structure. Currently, only a subset of these options can be overridden at runtime via command-line arguments. For all other options, the hard-coded default values are used. + +Command-Line Arguments +---------------------- + +The following argument is available to configure the ``TimeSlave`` at runtime: + +.. list-table:: + :widths: 25 15 60 + :header-rows: 1 + + * - Argument + - Overrides + - Description + * - ``-i, --interface `` + - ``iface_name`` + - **Mandatory Runtime Parameter.** Specifies the Ethernet network interface. Although the internal default is "emac0", this **must** be set correctly at runtime to match the target hardware. + + +Default Configuration (`GptpEngineOptions`) +------------------------------------------- + +The following table lists all available options and their default values as defined in the source code. Currently, only ``iface_name`` can be changed without recompiling the application. + +.. list-table:: GptpEngineOptions Default Values + :widths: 25 15 60 + :header-rows: 1 + + * - Option + - Default Value + - Description + * - ``iface_name`` + - ``"emac0"`` + - The network interface to use for gPTP traffic. + * - ``pdelay_interval_ms`` + - ``1000`` + - The interval in milliseconds for sending Peer-Delay measurement requests. + * - ``pdelay_warmup_ms`` + - ``2000`` + - The initial delay in milliseconds before the first Peer-Delay request is sent. + * - ``sync_timeout_ms`` + - ``3300`` + - The time in milliseconds without receiving a PTP Sync message before a timeout is declared and the clock is considered unreliable. + * - ``jump_future_threshold_ns`` + - ``500'000'000`` + - The threshold in nanoseconds (500 ms) for detecting a significant forward time jump. + * - ``domain_number`` + - ``0`` + - The gPTP domain number. The TimeSlave will only interact with a PTP master in the same domain. + * - ``phc_config`` + - ``disabled`` + - Configuration for hardware clock (PHC) adjustments. Disabled by default. + + +Example Invocation +------------------ + +.. code-block:: bash + + # Start the TimeSlave, overriding the default interface name "emac0" + ./time_slave --interface eth1 + +.. attention:: + The command-line parsing is currently incomplete. To change parameters other than the interface name, you must modify the default values in the ``GptpEngineOptions`` structure and recompile the application. A comprehensive configuration mechanism (e.g., via a JSON file) is planned for future versions. + + +TimeDaemon (`time_daemon`) & Client Applications +================================================ + +The ``TimeDaemon`` process and all client applications using the ``score::time`` library currently operate **without any external configuration**. They rely on the default, built-in settings for IPC communication. diff --git a/docs/manuals/index_user_manual.rst b/docs/manuals/index_user_manual.rst new file mode 100644 index 00000000..2c0b2251 --- /dev/null +++ b/docs/manuals/index_user_manual.rst @@ -0,0 +1,32 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +sCore::time User Manual +======================= + +This manual describes the architecture, usage, and configuration of the sCore ``time`` module. + +.. toctree:: + :maxdepth: 2 + :caption: Chapters: + + introduction + api_description/choosing_a_clock + api_description/api_usage + api_description/lifecycle + api_description/testing_guide + api_description/advanced_api + config/configuration_guide + integration_guide + troubleshooting_guide diff --git a/docs/manuals/integration_guide.rst b/docs/manuals/integration_guide.rst new file mode 100644 index 00000000..c4b03e3f --- /dev/null +++ b/docs/manuals/integration_guide.rst @@ -0,0 +1,57 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_integration: + +***************** +Integration Guide +***************** + +This guide is intended for system integrators who are responsible for deploying and configuring the ``time`` module services on an ECU. + +System Services +=============== + +The sCore ``time`` module consists of two essential system services that must be running for the client library to function: + +1. ``time_slave``: The PTP slave process that communicates with the network master clock. +2. ``time_daemon``: The daemon that processes the data from the ``time_slave`` and provides it to client applications. + +These two processes must be managed by the system's service manager (e.g., `systemd` on Linux, or a launch script on QNX). + +Runtime Requirements +==================== + +Operating System Privileges +--------------------------- +The ``time_slave`` process requires elevated privileges to access raw network sockets and control the hardware clock. It is strongly recommended **not** to run this process as the `root` user. Instead, grant the required Linux Capabilities to the executable: + +.. code-block:: bash + + sudo setcap cap_net_admin,cap_net_raw,cap_sys_time+eip /path/to/your/time_slave + +* ``cap_net_admin``: For network interface configuration. +* ``cap_net_raw``: For the use of raw sockets to listen to PTP traffic. +* ``cap_sys_time``: For adjusting the system's hardware clock. + +Network Configuration +--------------------- +* The network interface used for PTP communication **must** be provided to the ``time_slave`` via the ``-i, --interface `` command-line argument. +* The ECU must have network connectivity to the PTP Grandmaster clock on this interface. + +Build-Time Dependencies (Bazel) +------------------------------- +For an application to successfully link against the ``score::time`` client library, its ``cc_binary`` or ``cc_library`` target in the `BUILD` file must include the `vehicle_time` dependencies. + +Please refer to the **Bazel Build Setup** section in the examples documentation for a detailed explanation of the required ``deps``. diff --git a/docs/manuals/introduction.rst b/docs/manuals/introduction.rst new file mode 100644 index 00000000..3fe485f6 --- /dev/null +++ b/docs/manuals/introduction.rst @@ -0,0 +1,92 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_introduction + +Architecture and Components +=========================== + +The sCore ``time`` module provides a robust, high-precision time base for applications on an ECU, synchronized to a network-wide PTP (Precision Time Protocol) Grandmaster Clock. The architecture is split into two main processes, the **TimeSlave** and the **TimeDaemon**, which communicate via a highly efficient shared memory channel. + +.. figure:: /docs/features/time_slave/_assets/timeslave_deployment.png + :align: center + :alt: TimeSlave Deployment View + + The deployment view shows the key components and their interactions. + +Component Overview +------------------ + +**1. Time Master (External)** + +* The **PTP Grandmaster Clock** is the authoritative time source for the entire vehicle network. It periodically sends PTP synchronization messages (EtherType ``0x88F7``) over the Ethernet network. + +**2. TimeSlave Process** + +* The ``TimeSlave`` is a standalone process responsible for all network-related PTP activities. It is the direct counterpart to the Time Master. +* **GptpEngine**: The core of the TimeSlave. It runs two main threads: + * **RxThread**: Listens for incoming PTP messages from the Time Master. + * **PdelayThread**: Actively measures the network latency (path delay) to the communication partner, as specified by the gPTP standard. +* **PhcAdjuster**: Receives the calculated time offset and frequency deviation from the ``GptpEngine``. It then directly adjusts the hardware clock of the network card (PHC Device) using kernel system calls like ``clock_adjtime``. This ensures the hardware clock is precisely synchronized. +* **GptpIpcPublisher**: Publishes the raw synchronization data, including timestamps and quality metrics, into a POSIX shared memory segment (``/gptp_ptp_info``). +* **ProbeManager + Recorder**: An instrumentation component for diagnostics and performance monitoring. + +**3. TimeDaemon Process** + +* The ``TimeDaemon`` is responsible for quality assurance and providing the synchronized time to all local applications on the ECU. It acts as the server for the sCore time service. +* **GptpIpcReceiver**: Reads the raw data from the shared memory segment published by the ``TimeSlave``. +* **ShmPTPEngine**: The core of the TimeDaemon. It wraps the ``GptpIpcReceiver``, processes the raw ``GptpIpcData``, performs quality checks and plausibility assessments, and converts it into the final, high-level ``PtpTimeInfo`` format that client applications will consume. + +**4. Shared Memory (IPC Channel)** + +* A POSIX shared memory segment, typically ``/gptp_ptp_info``, serves as a high-performance, lock-free communication channel between the ``TimeSlave`` and the ``TimeDaemon``. +* **seqlock**: The communication is protected by a seqlock (sequence lock) mechanism. This allows the ``GptpIpcReceiver`` to read the data without ever being blocked, ensuring real-time safety, while also guaranteeing that it never receives partially updated (torn) data. + +Data Flow Summary +----------------- + +1. The **Time Master** sends PTP messages over the Ethernet network. +2. The **GptpEngine** in the ``TimeSlave`` process receives these messages. +3. The ``GptpEngine`` calculates the time offset and adjusts the **PHC Device** (hardware clock) via the ``PhcAdjuster``. +4. Simultaneously, the ``GptpEngine`` passes the raw synchronization data to the **GptpIpcPublisher**. +5. The publisher writes the data into **Shared Memory** using a seqlock. +6. The **GptpIpcReceiver** in the ``TimeDaemon`` process reads the data from shared memory, also using the seqlock mechanism. +7. The **ShmPTPEngine** processes this data, turning it into the final, quality-assured time base for the system. + +Choosing the Right Clock +======================== + +The sCore ``time`` module provides several clock types, each designed for a specific use case. Understanding their differences is crucial for writing robust and correct applications. + +In general, you should **always prefer ``VehicleTime``** unless you have a specific reason to measure a local time interval or need a simple wall-clock timestamp for purely informational purposes. + +.. list-table:: Clock Types Overview + :widths: 20 40 40 + :header-rows: 1 + + * - Clock Type + - Key Characteristic + - Typical Use Case + * - ``VehicleTime`` + - High-precision, PTP-synchronized, quality-assured network time. **This is the recommended clock for almost all applications.** + - Synchronized logging across ECUs, event timestamping, any logic that depends on a common time base in the vehicle. + * - ``SystemTime`` + - The system's "wall clock" time (Unix time). Can jump forwards or backwards (e.g., due to NTP correction or manual changes). + - Displaying human-readable timestamps. Creating log entries where absolute time is more important than monotonic progression. + * - ``SteadyTime`` + - A clock that is guaranteed to only ever move forward (monotonic). Its starting point is arbitrary (e.g., system boot time). + - Measuring time intervals, implementing timeouts, scheduling tasks where guaranteed monotonic progression is essential. + * - ``HighResSteadyTime`` + - A monotonic clock that provides the highest possible resolution the underlying hardware can offer. + - High-precision performance measurements and profiling, or very short-interval timing. diff --git a/docs/manuals/troubleshooting_guide.rst b/docs/manuals/troubleshooting_guide.rst new file mode 100644 index 00000000..b1044092 --- /dev/null +++ b/docs/manuals/troubleshooting_guide.rst @@ -0,0 +1,73 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _manual_time_troubleshooting + +********************* +Troubleshooting Guide +********************* + +This guide provides solutions to common problems encountered when using or integrating the sCore ``time`` module. + +Clock is Not Reliable or Not Available +====================================== + +**Symptom:** +Your application calls ``clock.Now()``, but ``snapshot.Status().IsReliable()`` always returns `false`. Or, ``clock.WaitUntilAvailable()`` runs into a timeout. + +**Potential Causes and Solutions:** + +1. **TimeSlave Not Running or Not Synchronized:** + * **Check:** Is the `time_slave` process running on the ECU? + * **Check:** Is there a PTP Grandmaster Clock active on the network, in the same PTP domain as the `time_slave` (default domain: 0)? + * **Solution:** Ensure the `time_slave` is started correctly and that a PTP master is present and reachable on the specified network interface. Check the logs of the `time_slave` for messages related to master detection. + +2. **TimeDaemon Not Running:** + * **Check:** Is the `time_daemon` process running on the ECU? The `time_slave` can run, but if the `time_daemon` isn't there to process the data, client applications will not receive reliable time. + * **Solution:** Ensure the `time_daemon` process is started. + +3. **IPC Channel Mismatch:** + * **Check:** The `time_slave` and `time_daemon` communicate via a POSIX shared memory file. By default, this is ``/gptp_ptp_info``. + * **Solution:** Verify that this file exists in the shared memory file system (e.g., under `/dev/shm/` on Linux). Check for permission issues that might prevent one of the processes from accessing the file. + +4. **Sync Timeout:** + * **Check:** The `time_slave` has a built-in timeout (`sync_timeout_ms`, default: 3300 ms). If it doesn't receive PTP Sync messages within this period, it declares a timeout. + * **Solution:** Check the network for packet loss. If you are in a simulated environment (QEMU, Docker), ensure the virtual network bridge is configured correctly. + +"Permission Denied" on TimeSlave Startup +======================================== + +**Symptom:** +The `time_slave` process fails to start with an error message similar to "Permission denied", "Operation not permitted", or a socket creation error. + +**Cause & Solution:** +This typically indicates that the ``time_slave`` executable is missing the required Linux Capabilities to run. Please refer to the section on **Operating System Privileges** in the :ref:`Integration Guide ` for detailed setup instructions. + +Understanding Log Messages +========================== + +The `time` module components use specific logging contexts to identify the source of a message. This can help you pinpoint where a problem is occurring. + +.. list-table:: Logging Contexts + :widths: 20 80 + :header-rows: 1 + + * - Context ID + - Description + * - ``[TSAP]`` + - **Time Slave Application.** Relates to the main lifecycle (Initialize/Run) of the ``time_slave`` process. + * - ``[GTPS]`` + - **GPTP Slave.** Relates to the core gPTP protocol engine within the ``time_slave`` (e.g., parsing PTP messages, state machines). + * - ``[GPTP]`` + - **GPTP Machine Adapter.** Relates to the component within the ``time_daemon`` that receives and processes the data from shared memory. From c3fd62aa4fcda41e1ed8880aaebaa8d44e1a7223 Mon Sep 17 00:00:00 2001 From: "Ludwig Weise (ETAS-E2E/XPC-Hi3)" Date: Thu, 16 Jul 2026 12:30:05 +0200 Subject: [PATCH 4/7] fix(docs): Correct RST structure and apply review feedback --- docs/manuals/api_description/advanced_api.rst | 2 +- docs/manuals/api_description/api_usage.rst | 2 +- docs/manuals/api_description/lifecycle.rst | 2 +- docs/manuals/config/configuration_guide.rst | 2 +- .../{index_user_manual.rst => index.rst} | 21 ++++++++++++++----- docs/manuals/integration_guide.rst | 2 +- docs/manuals/introduction.rst | 13 ++++++------ docs/manuals/troubleshooting_guide.rst | 4 ++-- 8 files changed, 29 insertions(+), 19 deletions(-) rename docs/manuals/{index_user_manual.rst => index.rst} (66%) diff --git a/docs/manuals/api_description/advanced_api.rst b/docs/manuals/api_description/advanced_api.rst index dd1270dd..679e53d7 100644 --- a/docs/manuals/api_description/advanced_api.rst +++ b/docs/manuals/api_description/advanced_api.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_advanced_api +.. _manual_time_advanced_api: Advanced API Usage: Subscribing to PTP Protocol Events ====================================================== diff --git a/docs/manuals/api_description/api_usage.rst b/docs/manuals/api_description/api_usage.rst index 91456cba..d81b9400 100644 --- a/docs/manuals/api_description/api_usage.rst +++ b/docs/manuals/api_description/api_usage.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_api_usage +.. _manual_time_api_usage: API Usage: Accessing Vehicle Time ================================= diff --git a/docs/manuals/api_description/lifecycle.rst b/docs/manuals/api_description/lifecycle.rst index a5eec71c..cddf8987 100644 --- a/docs/manuals/api_description/lifecycle.rst +++ b/docs/manuals/api_description/lifecycle.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_lifecycle +.. _manual_time_lifecycle: Clock Lifecycle Management ========================== diff --git a/docs/manuals/config/configuration_guide.rst b/docs/manuals/config/configuration_guide.rst index fe9dab7a..6c5ad308 100644 --- a/docs/manuals/config/configuration_guide.rst +++ b/docs/manuals/config/configuration_guide.rst @@ -17,7 +17,7 @@ Configuration Guide =================== -This guide describes the configuration of the sCore ``time`` module components. +This guide describes the configuration of the S-CORE ``time`` module components. TimeSlave Daemon (`time_slave`) =============================== diff --git a/docs/manuals/index_user_manual.rst b/docs/manuals/index.rst similarity index 66% rename from docs/manuals/index_user_manual.rst rename to docs/manuals/index.rst index 2c0b2251..1fd4ae07 100644 --- a/docs/manuals/index_user_manual.rst +++ b/docs/manuals/index.rst @@ -12,17 +12,18 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -sCore::time User Manual -======================= +.. _manuals_main: -This manual describes the architecture, usage, and configuration of the sCore ``time`` module. +Manuals +======= + +This section contains all user-facing manuals for the sCore ``time`` module, combining the main User Manual with all relevant examples. .. toctree:: :maxdepth: 2 - :caption: Chapters: + :caption: User Manual: introduction - api_description/choosing_a_clock api_description/api_usage api_description/lifecycle api_description/testing_guide @@ -30,3 +31,13 @@ This manual describes the architecture, usage, and configuration of the sCore `` config/configuration_guide integration_guide troubleshooting_guide + +.. +.. The following toctree is for the examples manual. It is commented out +.. temporarily until the corresponding files are checked in. +.. +.. .. toctree:: +.. :maxdepth: 2 +.. :caption: Examples: +.. +.. examples/index diff --git a/docs/manuals/integration_guide.rst b/docs/manuals/integration_guide.rst index c4b03e3f..d9032e0f 100644 --- a/docs/manuals/integration_guide.rst +++ b/docs/manuals/integration_guide.rst @@ -23,7 +23,7 @@ This guide is intended for system integrators who are responsible for deploying System Services =============== -The sCore ``time`` module consists of two essential system services that must be running for the client library to function: +The S-CORE ``time`` module consists of two essential system services that must be running for the client library to function: 1. ``time_slave``: The PTP slave process that communicates with the network master clock. 2. ``time_daemon``: The daemon that processes the data from the ``time_slave`` and provides it to client applications. diff --git a/docs/manuals/introduction.rst b/docs/manuals/introduction.rst index 3fe485f6..9dc9e5a1 100644 --- a/docs/manuals/introduction.rst +++ b/docs/manuals/introduction.rst @@ -12,16 +12,15 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_introduction +.. _manual_time_introduction: Architecture and Components =========================== -The sCore ``time`` module provides a robust, high-precision time base for applications on an ECU, synchronized to a network-wide PTP (Precision Time Protocol) Grandmaster Clock. The architecture is split into two main processes, the **TimeSlave** and the **TimeDaemon**, which communicate via a highly efficient shared memory channel. +The S-CORE ``time`` module provides a robust, high-precision time base for applications on an ECU, synchronized to a network-wide PTP (Precision Time Protocol) Grandmaster Clock. The architecture is split into two main processes, the **TimeSlave** and the **TimeDaemon**, which communicate via a highly efficient shared memory channel. -.. figure:: /docs/features/time_slave/_assets/timeslave_deployment.png - :align: center - :alt: TimeSlave Deployment View +.. uml:: ../features/time_slave/_assets/timeslave_deployment.puml + :alt: Deployment Diagram The deployment view shows the key components and their interactions. @@ -44,7 +43,7 @@ Component Overview **3. TimeDaemon Process** -* The ``TimeDaemon`` is responsible for quality assurance and providing the synchronized time to all local applications on the ECU. It acts as the server for the sCore time service. +* The ``TimeDaemon`` is responsible for quality assurance and providing the synchronized time to all local applications on the ECU. It acts as the server for the S-CORE time service. * **GptpIpcReceiver**: Reads the raw data from the shared memory segment published by the ``TimeSlave``. * **ShmPTPEngine**: The core of the TimeDaemon. It wraps the ``GptpIpcReceiver``, processes the raw ``GptpIpcData``, performs quality checks and plausibility assessments, and converts it into the final, high-level ``PtpTimeInfo`` format that client applications will consume. @@ -67,7 +66,7 @@ Data Flow Summary Choosing the Right Clock ======================== -The sCore ``time`` module provides several clock types, each designed for a specific use case. Understanding their differences is crucial for writing robust and correct applications. +The S-CORE ``time`` module provides several clock types, each designed for a specific use case. Understanding their differences is crucial for writing robust and correct applications. In general, you should **always prefer ``VehicleTime``** unless you have a specific reason to measure a local time interval or need a simple wall-clock timestamp for purely informational purposes. diff --git a/docs/manuals/troubleshooting_guide.rst b/docs/manuals/troubleshooting_guide.rst index b1044092..c3c6e6c5 100644 --- a/docs/manuals/troubleshooting_guide.rst +++ b/docs/manuals/troubleshooting_guide.rst @@ -12,13 +12,13 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_troubleshooting +.. _manual_time_troubleshooting: ********************* Troubleshooting Guide ********************* -This guide provides solutions to common problems encountered when using or integrating the sCore ``time`` module. +This guide provides solutions to common problems encountered when using or integrating the S-CORE ``time`` module. Clock is Not Reliable or Not Available ====================================== From 094c15e902161ddfb8f9b4ff796e9d6fffe88aed Mon Sep 17 00:00:00 2001 From: "Ludwig Weise (ETAS-E2E/XPC-Hi3)" Date: Thu, 16 Jul 2026 12:51:06 +0200 Subject: [PATCH 5/7] fix(docs): Integrate user manual into main documentation toctree --- docs/index.rst | 1 + docs/manuals/introduction.rst | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index e35c841d..6007e6f8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,6 +43,7 @@ For a detailed concept and architectural design, please refer to the :doc:`time_ :caption: Contents: features/index + manuals/index Project Layout -------------- diff --git a/docs/manuals/introduction.rst b/docs/manuals/introduction.rst index 9dc9e5a1..5ee50ff6 100644 --- a/docs/manuals/introduction.rst +++ b/docs/manuals/introduction.rst @@ -22,8 +22,6 @@ The S-CORE ``time`` module provides a robust, high-precision time base for appli .. uml:: ../features/time_slave/_assets/timeslave_deployment.puml :alt: Deployment Diagram - The deployment view shows the key components and their interactions. - Component Overview ------------------ From 1cb0e9615de6c3992d8494ea1df4ce02f0629eb8 Mon Sep 17 00:00:00 2001 From: Ryan Steel Date: Fri, 17 Jul 2026 10:05:33 +0000 Subject: [PATCH 6/7] add user manuals --- BUILD | 2 +- docs/conf.py => conf.py | 10 +- docs/manuals/index.rst | 24 +-- docs/manuals/integration_guide.rst | 57 ------- docs/manuals/introduction.rst | 89 ---------- docs/manuals/troubleshooting_guide.rst | 1 - docs/manuals/user_manual.rst | 161 ++++++++++++++++++ docs/index.rst => index.rst | 12 +- .../manuals/api_description/advanced_api.rst | 0 .../manuals/api_description/api_usage.rst | 13 -- .../manuals/api_description/lifecycle.rst | 0 .../manuals/api_description/testing_guide.rst | 0 .../docs}/manuals/examples/basic_clocks.rst | 0 .../time/docs}/manuals/examples/index.rst | 0 .../docs}/manuals/examples/vehicle_time.rst | 0 score/time/docs/manuals/user_manual.rst | 150 ++++++++++++++++ .../manuals/config/configuration_guide.rst | 30 ++++ .../time_daemon/docs/manuals/user_manual.rst | 50 ++++++ score/time_slave/docs/index.rst | 6 - score/time_slave/docs/manuals/.gitkeep | 0 .../manuals/config/configuration_guide.rst | 21 +-- score/time_slave/docs/manuals/user_manual.rst | 64 +++++++ 22 files changed, 482 insertions(+), 208 deletions(-) rename docs/conf.py => conf.py (91%) delete mode 100644 docs/manuals/integration_guide.rst delete mode 100644 docs/manuals/introduction.rst create mode 100644 docs/manuals/user_manual.rst rename docs/index.rst => index.rst (94%) rename {docs => score/time/docs}/manuals/api_description/advanced_api.rst (100%) rename {docs => score/time/docs}/manuals/api_description/api_usage.rst (71%) rename {docs => score/time/docs}/manuals/api_description/lifecycle.rst (100%) rename {docs => score/time/docs}/manuals/api_description/testing_guide.rst (100%) rename {docs => score/time/docs}/manuals/examples/basic_clocks.rst (100%) rename {docs => score/time/docs}/manuals/examples/index.rst (100%) rename {docs => score/time/docs}/manuals/examples/vehicle_time.rst (100%) create mode 100644 score/time/docs/manuals/user_manual.rst create mode 100644 score/time_daemon/docs/manuals/config/configuration_guide.rst create mode 100644 score/time_daemon/docs/manuals/user_manual.rst delete mode 100644 score/time_slave/docs/manuals/.gitkeep rename {docs => score/time_slave/docs}/manuals/config/configuration_guide.rst (83%) create mode 100644 score/time_slave/docs/manuals/user_manual.rst diff --git a/BUILD b/BUILD index cfb90305..937a17b2 100644 --- a/BUILD +++ b/BUILD @@ -24,7 +24,7 @@ docs( data = [ "@score_process//:needs_json", ], - source_dir = "docs", + source_dir = ".", ) copyright_checker( diff --git a/docs/conf.py b/conf.py similarity index 91% rename from docs/conf.py rename to conf.py index a834ad1f..1f15db24 100644 --- a/docs/conf.py +++ b/conf.py @@ -42,6 +42,14 @@ "score_metrics", ] +include_patterns = [ + "index.rst", + "docs/**", + "score/time/docs/**", + "score/time_slave/docs/**", + "score/time_daemon/docs/**", +] + exclude_patterns = [ # The following entries are not required when building the documentation via 'bazel # build //docs:docs', as that command runs in a sandboxed environment. However, when @@ -51,7 +59,7 @@ ".venv_docs", ] -templates_path = ["templates"] +templates_path = ["docs/templates"] # Enable numref numfig = True diff --git a/docs/manuals/index.rst b/docs/manuals/index.rst index e99a7c08..d31147d5 100644 --- a/docs/manuals/index.rst +++ b/docs/manuals/index.rst @@ -12,28 +12,10 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manuals_main: - Manuals -======= - -This section contains all user-facing manuals for the sCore ``time`` module, combining the main User Manual with all relevant examples. - -.. toctree:: - :maxdepth: 2 - :caption: User Manual: - - introduction - api_description/api_usage - api_description/lifecycle - api_description/testing_guide - api_description/advanced_api - config/configuration_guide - integration_guide - troubleshooting_guide +####### .. toctree:: - :maxdepth: 2 - :caption: Examples: + :titlesonly: - examples/index + user_manual diff --git a/docs/manuals/integration_guide.rst b/docs/manuals/integration_guide.rst deleted file mode 100644 index d9032e0f..00000000 --- a/docs/manuals/integration_guide.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. - # ******************************************************************************* - # Copyright (c) 2026 Contributors to the Eclipse Foundation - # - # See the NOTICE file(s) distributed with this work for additional - # information regarding copyright ownership. - # - # This program and the accompanying materials are made available under the - # terms of the Apache License Version 2.0 which is available at - # https://www.apache.org/licenses/LICENSE-2.0 - # - # SPDX-License-Identifier: Apache-2.0 - # ******************************************************************************* - -.. _manual_time_integration: - -***************** -Integration Guide -***************** - -This guide is intended for system integrators who are responsible for deploying and configuring the ``time`` module services on an ECU. - -System Services -=============== - -The S-CORE ``time`` module consists of two essential system services that must be running for the client library to function: - -1. ``time_slave``: The PTP slave process that communicates with the network master clock. -2. ``time_daemon``: The daemon that processes the data from the ``time_slave`` and provides it to client applications. - -These two processes must be managed by the system's service manager (e.g., `systemd` on Linux, or a launch script on QNX). - -Runtime Requirements -==================== - -Operating System Privileges ---------------------------- -The ``time_slave`` process requires elevated privileges to access raw network sockets and control the hardware clock. It is strongly recommended **not** to run this process as the `root` user. Instead, grant the required Linux Capabilities to the executable: - -.. code-block:: bash - - sudo setcap cap_net_admin,cap_net_raw,cap_sys_time+eip /path/to/your/time_slave - -* ``cap_net_admin``: For network interface configuration. -* ``cap_net_raw``: For the use of raw sockets to listen to PTP traffic. -* ``cap_sys_time``: For adjusting the system's hardware clock. - -Network Configuration ---------------------- -* The network interface used for PTP communication **must** be provided to the ``time_slave`` via the ``-i, --interface `` command-line argument. -* The ECU must have network connectivity to the PTP Grandmaster clock on this interface. - -Build-Time Dependencies (Bazel) -------------------------------- -For an application to successfully link against the ``score::time`` client library, its ``cc_binary`` or ``cc_library`` target in the `BUILD` file must include the `vehicle_time` dependencies. - -Please refer to the **Bazel Build Setup** section in the examples documentation for a detailed explanation of the required ``deps``. diff --git a/docs/manuals/introduction.rst b/docs/manuals/introduction.rst deleted file mode 100644 index 5ee50ff6..00000000 --- a/docs/manuals/introduction.rst +++ /dev/null @@ -1,89 +0,0 @@ -.. - # ******************************************************************************* - # Copyright (c) 2026 Contributors to the Eclipse Foundation - # - # See the NOTICE file(s) distributed with this work for additional - # information regarding copyright ownership. - # - # This program and the accompanying materials are made available under the - # terms of the Apache License Version 2.0 which is available at - # https://www.apache.org/licenses/LICENSE-2.0 - # - # SPDX-License-Identifier: Apache-2.0 - # ******************************************************************************* - -.. _manual_time_introduction: - -Architecture and Components -=========================== - -The S-CORE ``time`` module provides a robust, high-precision time base for applications on an ECU, synchronized to a network-wide PTP (Precision Time Protocol) Grandmaster Clock. The architecture is split into two main processes, the **TimeSlave** and the **TimeDaemon**, which communicate via a highly efficient shared memory channel. - -.. uml:: ../features/time_slave/_assets/timeslave_deployment.puml - :alt: Deployment Diagram - -Component Overview ------------------- - -**1. Time Master (External)** - -* The **PTP Grandmaster Clock** is the authoritative time source for the entire vehicle network. It periodically sends PTP synchronization messages (EtherType ``0x88F7``) over the Ethernet network. - -**2. TimeSlave Process** - -* The ``TimeSlave`` is a standalone process responsible for all network-related PTP activities. It is the direct counterpart to the Time Master. -* **GptpEngine**: The core of the TimeSlave. It runs two main threads: - * **RxThread**: Listens for incoming PTP messages from the Time Master. - * **PdelayThread**: Actively measures the network latency (path delay) to the communication partner, as specified by the gPTP standard. -* **PhcAdjuster**: Receives the calculated time offset and frequency deviation from the ``GptpEngine``. It then directly adjusts the hardware clock of the network card (PHC Device) using kernel system calls like ``clock_adjtime``. This ensures the hardware clock is precisely synchronized. -* **GptpIpcPublisher**: Publishes the raw synchronization data, including timestamps and quality metrics, into a POSIX shared memory segment (``/gptp_ptp_info``). -* **ProbeManager + Recorder**: An instrumentation component for diagnostics and performance monitoring. - -**3. TimeDaemon Process** - -* The ``TimeDaemon`` is responsible for quality assurance and providing the synchronized time to all local applications on the ECU. It acts as the server for the S-CORE time service. -* **GptpIpcReceiver**: Reads the raw data from the shared memory segment published by the ``TimeSlave``. -* **ShmPTPEngine**: The core of the TimeDaemon. It wraps the ``GptpIpcReceiver``, processes the raw ``GptpIpcData``, performs quality checks and plausibility assessments, and converts it into the final, high-level ``PtpTimeInfo`` format that client applications will consume. - -**4. Shared Memory (IPC Channel)** - -* A POSIX shared memory segment, typically ``/gptp_ptp_info``, serves as a high-performance, lock-free communication channel between the ``TimeSlave`` and the ``TimeDaemon``. -* **seqlock**: The communication is protected by a seqlock (sequence lock) mechanism. This allows the ``GptpIpcReceiver`` to read the data without ever being blocked, ensuring real-time safety, while also guaranteeing that it never receives partially updated (torn) data. - -Data Flow Summary ------------------ - -1. The **Time Master** sends PTP messages over the Ethernet network. -2. The **GptpEngine** in the ``TimeSlave`` process receives these messages. -3. The ``GptpEngine`` calculates the time offset and adjusts the **PHC Device** (hardware clock) via the ``PhcAdjuster``. -4. Simultaneously, the ``GptpEngine`` passes the raw synchronization data to the **GptpIpcPublisher**. -5. The publisher writes the data into **Shared Memory** using a seqlock. -6. The **GptpIpcReceiver** in the ``TimeDaemon`` process reads the data from shared memory, also using the seqlock mechanism. -7. The **ShmPTPEngine** processes this data, turning it into the final, quality-assured time base for the system. - -Choosing the Right Clock -======================== - -The S-CORE ``time`` module provides several clock types, each designed for a specific use case. Understanding their differences is crucial for writing robust and correct applications. - -In general, you should **always prefer ``VehicleTime``** unless you have a specific reason to measure a local time interval or need a simple wall-clock timestamp for purely informational purposes. - -.. list-table:: Clock Types Overview - :widths: 20 40 40 - :header-rows: 1 - - * - Clock Type - - Key Characteristic - - Typical Use Case - * - ``VehicleTime`` - - High-precision, PTP-synchronized, quality-assured network time. **This is the recommended clock for almost all applications.** - - Synchronized logging across ECUs, event timestamping, any logic that depends on a common time base in the vehicle. - * - ``SystemTime`` - - The system's "wall clock" time (Unix time). Can jump forwards or backwards (e.g., due to NTP correction or manual changes). - - Displaying human-readable timestamps. Creating log entries where absolute time is more important than monotonic progression. - * - ``SteadyTime`` - - A clock that is guaranteed to only ever move forward (monotonic). Its starting point is arbitrary (e.g., system boot time). - - Measuring time intervals, implementing timeouts, scheduling tasks where guaranteed monotonic progression is essential. - * - ``HighResSteadyTime`` - - A monotonic clock that provides the highest possible resolution the underlying hardware can offer. - - High-precision performance measurements and profiling, or very short-interval timing. diff --git a/docs/manuals/troubleshooting_guide.rst b/docs/manuals/troubleshooting_guide.rst index c3c6e6c5..cfe224d0 100644 --- a/docs/manuals/troubleshooting_guide.rst +++ b/docs/manuals/troubleshooting_guide.rst @@ -52,7 +52,6 @@ Your application calls ``clock.Now()``, but ``snapshot.Status().IsReliable()`` a The `time_slave` process fails to start with an error message similar to "Permission denied", "Operation not permitted", or a socket creation error. **Cause & Solution:** -This typically indicates that the ``time_slave`` executable is missing the required Linux Capabilities to run. Please refer to the section on **Operating System Privileges** in the :ref:`Integration Guide ` for detailed setup instructions. Understanding Log Messages ========================== diff --git a/docs/manuals/user_manual.rst b/docs/manuals/user_manual.rst new file mode 100644 index 00000000..1ee2719a --- /dev/null +++ b/docs/manuals/user_manual.rst @@ -0,0 +1,161 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _user_manual: + +User Manual +########### + +.. document:: User Manual Time Module + :id: doc__user_manual_time + :status: draft + :version: 1 + :safety: QM + :security: NO + :realizes: wp__training_path[version==1] + +Overview +======== + +This user manual provides comprehensive guidance for integrating and deploying the S-CORE ``time`` module from a system integrator perspective. + +The S-CORE ``time`` module provides a robust, high-precision time base for applications on an ECU, +synchronized to a network-wide PTP (Precision Time Protocol) Grandmaster Clock. The module consists of three components: + +* **Client Library** (``score::time``): C++ API for accessing synchronized time +* **TimeSlave**: System daemon that synchronizes with the PTP Grandmaster over the network +* **TimeDaemon**: System daemon that provides quality-assured time to client applications + +This module manual covers module-level integration, deployment, and troubleshooting. For component-specific usage and configuration, refer to the component manuals below. + +For build and test of the module itself, please refer to the main documentation. + +Component Manuals +----------------- + +For detailed component-specific user manuals: + +.. toctree:: + :maxdepth: 1 + + /score/time/docs/manuals/user_manual + /score/time_slave/docs/manuals/user_manual + /score/time_daemon/docs/manuals/user_manual + +Environment Needs +================= + +Basic needed software environment for the module: + +* **C++**: C++17 or later +* **Build System**: Bazel 6.0 or later +* **Operating Systems**: Linux, QNX + +Dependencies +------------ + +* Standard library (STL/Core) +* PTP Grandmaster Clock (external network time source) +* POSIX shared memory support +* Network hardware with PHC (PTP Hardware Clock) support + +See also MODULE.bazel files for more details on dependencies. + +Performance Considerations +========================== + +The ``time`` module is designed for high-performance, low-latency time access in automotive ECUs: + +* **VehicleTime access**: Sub-microsecond latency via POSIX shared memory with seqlock +* **Lock-free IPC**: TimeDaemon reads from TimeSlave without blocking +* **Hardware clock sync**: Direct PHC adjustment for nanosecond-precision synchronization +* **Minimal overhead**: Singleton pattern, zero allocations in time-critical paths + +For detailed performance analysis and benchmarks, this information will be added in future releases. + +Integration Guidelines +====================== + +Integrating with Your Project +------------------------------ + +1. Add the module to your Bazel workspace: + + .. code-block:: python + + # In your MODULE.bazel + bazel_dep(name = "score_time", version = "1.0") + +2. Reference in your build files: + + .. code-block:: python + + cc_library( + name = "my_target", + deps = ["@score_time//score/time/vehicle_time:vehicle_time"], + ) + +3. Include headers and compile your code + +.. For detailed API usage and examples, refer to the :doc:`/score/time/docs/manuals/user_manual`. + +System Services Deployment +--------------------------- + +The ``time`` module requires two system daemons to be running. These processes must be managed by the system's service manager (e.g., `systemd` on Linux, or a launch script on QNX). + +.. For detailed configuration of each daemon (OS privileges, network configuration, command-line arguments), refer to the :ref:`component_manuals` linked above. + +Version History, Compatibility, and Troubleshooting +=================================================== + +For comprehensive information on the following topics: + +* Version history and changes +* Compatibility notes and upgrade instructions +* Known issues and limitations +* Troubleshooting tips and solutions +* Security vulnerabilities (CVEs) + +.. toctree:: + :maxdepth: 1 + + troubleshooting_guide + +Safety and Security +=================== + +**Safety Classification**: QM (Quality Managed) + +This module is designed for Quality Managed (QM) applications. For safety-critical usage requirements and guidelines, refer to the safety manual (to be added in future releases). + +**Security Considerations**: + +* The ``time`` module assumes a trusted network for PTP communication +* No authentication or encryption is provided for PTP messages (per IEEE 1588 standard) +* OS-level security (Linux Capabilities) limits attack surface for TimeSlave daemon + +For detailed security aspects and requirements, refer to the security manual (to be added in future releases). + +License +======= + +This module is licensed under the Apache License Version 2.0. +See the LICENSE file in the repository for full license text. + +Feedback and Contributions +========================== + +Your feedback and contributions are welcome! Please report issues or suggestions through the +project's issue tracker or contribute directly to the repository. diff --git a/docs/index.rst b/index.rst similarity index 94% rename from docs/index.rst rename to index.rst index 6007e6f8..3afba0ed 100644 --- a/docs/index.rst +++ b/index.rst @@ -36,14 +36,20 @@ The main responsibilities of time_daemon include: - **Providing diagnostic information** for system monitoring - **Supporting additional verification mechanisms** such as QualifiedVehicleTime (QVT) for safety-critical applications -For a detailed concept and architectural design, please refer to the :doc:`time_daemon Concept Documentation `. +For a detailed concept and architectural design, please refer to the :doc:`time_daemon Concept Documentation `. .. toctree:: :maxdepth: 2 :caption: Contents: - features/index - manuals/index + docs/features/index + docs/manuals/index + +.. toctree:: + :maxdepth: 1 + :caption: Component Documentation: + + score/time_slave/docs/index Project Layout -------------- diff --git a/docs/manuals/api_description/advanced_api.rst b/score/time/docs/manuals/api_description/advanced_api.rst similarity index 100% rename from docs/manuals/api_description/advanced_api.rst rename to score/time/docs/manuals/api_description/advanced_api.rst diff --git a/docs/manuals/api_description/api_usage.rst b/score/time/docs/manuals/api_description/api_usage.rst similarity index 71% rename from docs/manuals/api_description/api_usage.rst rename to score/time/docs/manuals/api_description/api_usage.rst index d81b9400..bcca5b8f 100644 --- a/docs/manuals/api_description/api_usage.rst +++ b/score/time/docs/manuals/api_description/api_usage.rst @@ -70,19 +70,6 @@ This method involves actively requesting the current time from the ``score::time } } -Workflow Explanation --------------------- - -The sequence diagram "VT1 — VehicleTime: Time Polling with Status Check" illustrates the following steps: - -1. **Get Instance**: The application first obtains a singleton instance of the ``VehicleClock``. This is a lightweight operation and the clock handle can be stored and reused. -2. **Now()**: The application calls the ``Now()`` method on the clock instance. This triggers an IPC call to the ``TimeDaemon`` to fetch the latest synchronized time data. -3. **Return Snapshot**: The framework returns a ``ClockSnapshot`` object. This object contains not just the timepoint, but also a crucial ``VehicleTimeStatus`` payload. -4. **Status Check**: The application **must** call the ``Status().IsReliable()`` method on the snapshot. This boolean flag consolidates all underlying quality metrics (e.g., is PTP master available? is shared memory data fresh? has the time passed plausibility checks?). -5. **Conditional Logic**: - * If ``IsReliable()`` returns ``true``, the timepoint is valid and can be safely used by the application logic. - * If ``IsReliable()`` returns ``false``, the application must discard the timepoint value and handle the failure case (e.g., by logging a warning and retrying the operation after a short delay). - .. attention:: Never use the ``TimePoint`` from a ``ClockSnapshot`` without first verifying that ``Status().IsReliable()`` is true. Using an unreliable timepoint can lead to incorrect or inconsistent behavior in safety-critical applications. diff --git a/docs/manuals/api_description/lifecycle.rst b/score/time/docs/manuals/api_description/lifecycle.rst similarity index 100% rename from docs/manuals/api_description/lifecycle.rst rename to score/time/docs/manuals/api_description/lifecycle.rst diff --git a/docs/manuals/api_description/testing_guide.rst b/score/time/docs/manuals/api_description/testing_guide.rst similarity index 100% rename from docs/manuals/api_description/testing_guide.rst rename to score/time/docs/manuals/api_description/testing_guide.rst diff --git a/docs/manuals/examples/basic_clocks.rst b/score/time/docs/manuals/examples/basic_clocks.rst similarity index 100% rename from docs/manuals/examples/basic_clocks.rst rename to score/time/docs/manuals/examples/basic_clocks.rst diff --git a/docs/manuals/examples/index.rst b/score/time/docs/manuals/examples/index.rst similarity index 100% rename from docs/manuals/examples/index.rst rename to score/time/docs/manuals/examples/index.rst diff --git a/docs/manuals/examples/vehicle_time.rst b/score/time/docs/manuals/examples/vehicle_time.rst similarity index 100% rename from docs/manuals/examples/vehicle_time.rst rename to score/time/docs/manuals/examples/vehicle_time.rst diff --git a/score/time/docs/manuals/user_manual.rst b/score/time/docs/manuals/user_manual.rst new file mode 100644 index 00000000..e3b366e4 --- /dev/null +++ b/score/time/docs/manuals/user_manual.rst @@ -0,0 +1,150 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _time_component_user_manual: + +Time Library User Manual +######################## + +.. document:: User Manual Time Library Component + :id: doc__user_manual_time_lib + :status: draft + :version: 1 + :safety: QM + :security: NO + :realizes: wp__training_path[version==1] + +Overview +======== + +This user manual covers the ``score::time`` client library - the C++ API for accessing synchronized time in your applications. + +The library provides multiple clock types (``VehicleTime``, ``SystemTime``, ``SteadyTime``, ``HighResSteadyTime``) with a unified interface for time access, lifecycle management, and testing. + +For module-level integration and deployment information, see the main module manual. + +Choosing the Right Clock +========================= + +The S-CORE ``time`` module provides several clock types, each designed for a specific use case. Understanding their differences is crucial for writing robust and correct applications. + +In general, you should **always prefer ``VehicleTime``** unless you have a specific reason to measure a local time interval or need a simple wall-clock timestamp for purely informational purposes. + +.. list-table:: Clock Types Overview + :widths: 20 40 40 + :header-rows: 1 + + * - Clock Type + - Key Characteristic + - Typical Use Case + * - ``VehicleTime`` + - High-precision, PTP-synchronized, quality-assured network time. **This is the recommended clock for almost all applications.** + - Synchronized logging across ECUs, event timestamping, any logic that depends on a common time base in the vehicle. + * - ``SystemTime`` + - The system's "wall clock" time (Unix time). Can jump forwards or backwards (e.g., due to NTP correction or manual changes). + - Displaying human-readable timestamps. Creating log entries where absolute time is more important than monotonic progression. + * - ``SteadyTime`` + - A clock that is guaranteed to only ever move forward (monotonic). Its starting point is arbitrary (e.g., system boot time). + - Measuring time intervals, implementing timeouts, scheduling tasks where guaranteed monotonic progression is essential. + * - ``HighResSteadyTime`` + - A monotonic clock that provides the highest possible resolution the underlying hardware can offer. + - High-precision performance measurements and profiling, or very short-interval timing. + +API Usage +========= + +This section covers how to use the ``score::time`` client library in your applications: + +.. toctree:: + :maxdepth: 2 + + api_description/api_usage + api_description/lifecycle + api_description/testing_guide + api_description/advanced_api + +.. note:: + For a complete C++ API reference with full class and function documentation, + please refer to the generated Doxygen documentation (to be added in future releases). + +Examples +======== + +Practical examples and tutorials for using the time library: + +.. toctree:: + :maxdepth: 2 + + examples/index + +Build Integration +================= + +To use the ``score::time`` library in your application: + +1. Add the module to your Bazel workspace: + + .. code-block:: python + + # In your MODULE.bazel + bazel_dep(name = "score_time", version = "1.0") + +2. Reference the clock type you need in your build files: + + .. code-block:: python + + cc_library( + name = "my_target", + deps = [ + "@score_time//score/time/vehicle_time:vehicle_time", # For VehicleTime + # OR + "@score_time//score/time/system_time:system_time", # For SystemTime + # OR + "@score_time//score/time/steady_time:steady_time", # For SteadyTime + # OR + "@score_time//score/time/high_res_steady_time:high_res_steady_time", # For HighResSteadyTime + ], + ) + + For testing, use the mock variants: + + .. code-block:: python + + cc_test( + name = "my_test", + deps = [ + "@score_time//score/time/vehicle_time:vehicle_time_mock", + ], + ) + +3. Include headers in your code: + + .. code-block:: cpp + + #include "score/time/clock.h" + #include "score/time/vehicle_time.h" + + // Example usage + auto& clock = score::time::Clock::GetInstance(); + auto snapshot = clock.Now(); + if (snapshot.Status().IsReliable()) { + // Use snapshot.TimePoint() + } + +Runtime Requirements +==================== + +The ``score::time`` library requires the ``TimeSlave`` and ``TimeDaemon`` system services to be running. +For deployment and configuration of these services, refer to the module manual and component manuals for +:doc:`/score/time_slave/docs/manuals/user_manual` and :doc:`/score/time_daemon/docs/manuals/user_manual`. diff --git a/score/time_daemon/docs/manuals/config/configuration_guide.rst b/score/time_daemon/docs/manuals/config/configuration_guide.rst new file mode 100644 index 00000000..ecc450da --- /dev/null +++ b/score/time_daemon/docs/manuals/config/configuration_guide.rst @@ -0,0 +1,30 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _time_daemon_configuration: + +TimeDaemon Configuration +========================= + +The ``TimeDaemon`` process currently operates **without any external configuration**. It relies on default, built-in settings for IPC communication. + +Shared Memory Configuration +---------------------------- + +The daemon reads from the shared memory segment published by ``TimeSlave``: + +* **Shared memory path**: ``/gptp_ptp_info`` +* **IPC mechanism**: POSIX shared memory with seqlock protection + +No runtime configuration options are exposed at this time. All settings are compiled into the binary. diff --git a/score/time_daemon/docs/manuals/user_manual.rst b/score/time_daemon/docs/manuals/user_manual.rst new file mode 100644 index 00000000..81d38097 --- /dev/null +++ b/score/time_daemon/docs/manuals/user_manual.rst @@ -0,0 +1,50 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _time_daemon_user_manual: + +Time Daemon User Manual +####################### + +.. document:: User Manual Time Daemon Component + :id: doc__user_manual_time_daemon + :status: draft + :version: 1 + :safety: QM + :security: NO + :realizes: wp__training_path[version==1] + +Overview +======== + +The ``TimeDaemon`` component is a system daemon responsible for quality assurance and providing synchronized time to local applications on the ECU. It reads raw synchronization data from shared memory (published by ``TimeSlave``), performs quality checks and plausibility assessments, and provides the final ``score::time`` API to client applications. + +For module-level integration and deployment information, see the main module manual. + +Configuration +============= + +.. toctree:: + :maxdepth: 2 + + config/configuration_guide + +Runtime Requirements +==================== + +The ``TimeDaemon`` requires: + +* ``TimeSlave`` must be running and publishing data to shared memory +* Access to POSIX shared memory segment (``/gptp_ptp_info``) +* Managed by system service manager (e.g., `systemd` on Linux, launch script on QNX) diff --git a/score/time_slave/docs/index.rst b/score/time_slave/docs/index.rst index 6e07edcd..27df135f 100644 --- a/score/time_slave/docs/index.rst +++ b/score/time_slave/docs/index.rst @@ -19,9 +19,3 @@ time_slave Component :maxdepth: 1 component_classification - architecture/index - detailed_design/index - requirements/index - manuals/index - safety_analysis/index - security_analysis/index diff --git a/score/time_slave/docs/manuals/.gitkeep b/score/time_slave/docs/manuals/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/manuals/config/configuration_guide.rst b/score/time_slave/docs/manuals/config/configuration_guide.rst similarity index 83% rename from docs/manuals/config/configuration_guide.rst rename to score/time_slave/docs/manuals/config/configuration_guide.rst index 6c5ad308..8ea3c983 100644 --- a/docs/manuals/config/configuration_guide.rst +++ b/score/time_slave/docs/manuals/config/configuration_guide.rst @@ -12,20 +12,15 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _manual_time_configuration: +.. _time_slave_configuration: -Configuration Guide -=================== - -This guide describes the configuration of the S-CORE ``time`` module components. - -TimeSlave Daemon (`time_slave`) -=============================== +TimeSlave Configuration +======================= The behavior of the ``TimeSlave`` is controlled by the ``GptpEngineOptions`` structure. Currently, only a subset of these options can be overridden at runtime via command-line arguments. For all other options, the hard-coded default values are used. Command-Line Arguments ----------------------- +----------------------- The following argument is available to configure the ``TimeSlave`` at runtime: @@ -42,7 +37,7 @@ The following argument is available to configure the ``TimeSlave`` at runtime: Default Configuration (`GptpEngineOptions`) -------------------------------------------- +-------------------------------------------- The following table lists all available options and their default values as defined in the source code. Currently, only ``iface_name`` can be changed without recompiling the application. @@ -86,9 +81,3 @@ Example Invocation .. attention:: The command-line parsing is currently incomplete. To change parameters other than the interface name, you must modify the default values in the ``GptpEngineOptions`` structure and recompile the application. A comprehensive configuration mechanism (e.g., via a JSON file) is planned for future versions. - - -TimeDaemon (`time_daemon`) & Client Applications -================================================ - -The ``TimeDaemon`` process and all client applications using the ``score::time`` library currently operate **without any external configuration**. They rely on the default, built-in settings for IPC communication. diff --git a/score/time_slave/docs/manuals/user_manual.rst b/score/time_slave/docs/manuals/user_manual.rst new file mode 100644 index 00000000..6fcf6462 --- /dev/null +++ b/score/time_slave/docs/manuals/user_manual.rst @@ -0,0 +1,64 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _time_slave_user_manual: + +Time Slave User Manual +###################### + +.. document:: User Manual Time Slave Component + :id: doc__user_manual_time_slave + :status: draft + :version: 1 + :safety: QM + :security: NO + :realizes: wp__training_path[version==1] + +Overview +======== + +The ``TimeSlave`` component is a system daemon responsible for synchronizing with the PTP Grandmaster Clock over the network. It adjusts the hardware clock (PHC) and publishes synchronization data to shared memory for consumption by the ``TimeDaemon``. + +For module-level integration and deployment information, see the main module manual. + +Configuration +============= + +.. toctree:: + :maxdepth: 2 + + config/configuration_guide + +Runtime Requirements +==================== + +Operating System Privileges +--------------------------- + +The ``TimeSlave`` executable (``time_slave``) requires elevated privileges to access raw network sockets and control the hardware clock. It is strongly recommended **not** to run this process as the `root` user. Instead, grant the required Linux Capabilities to the executable: + +.. code-block:: bash + + sudo setcap cap_net_admin,cap_net_raw,cap_sys_time+eip /path/to/time_slave + +* ``cap_net_admin``: For network interface configuration. +* ``cap_net_raw``: For the use of raw sockets to listen to PTP traffic. +* ``cap_sys_time``: For adjusting the system's hardware clock. + +Network Requirements +-------------------- + +* The network interface used for PTP communication **must** be provided via the ``-i, --interface `` command-line argument. +* The ECU must have network connectivity to the PTP Grandmaster clock on this interface. +* Network hardware must support PHC (PTP Hardware Clock). From 1ca194b4cf6702dd526c5f21267a14da955b39d4 Mon Sep 17 00:00:00 2001 From: Ryan Steel Date: Mon, 20 Jul 2026 09:06:33 +0000 Subject: [PATCH 7/7] chore: address comments --- docs/manuals/troubleshooting_guide.rst | 11 +++++++++++ docs/manuals/user_manual.rst | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/manuals/troubleshooting_guide.rst b/docs/manuals/troubleshooting_guide.rst index cfe224d0..cf236eb1 100644 --- a/docs/manuals/troubleshooting_guide.rst +++ b/docs/manuals/troubleshooting_guide.rst @@ -53,6 +53,17 @@ The `time_slave` process fails to start with an error message similar to "Permis **Cause & Solution:** +The `time_slave` requires elevated network privileges to open a raw PTP socket on the specified network interface. + +* **On Linux:** Grant the ``CAP_NET_RAW`` capability to the ``time_slave`` binary instead of running it as root: + + .. code-block:: bash + + sudo setcap cap_net_raw+ep /path/to/time_slave + +* **On QNX:** The ``time_slave`` opens ``/dev/bpf`` (Berkeley Packet Filter device) to capture raw PTP frames. Ensure the process user has read/write permission on ``/dev/bpf``. If a PHC device is configured (``phc_device`` option), the process also needs read/write access to that device node. +* **Shared memory access:** If the error refers to ``/gptp_ptp_info``, verify that the user running ``time_slave`` has read/write permission on the shared memory path (``/dev/shm/`` on Linux). Adjust the file permissions or run both ``time_slave`` and ``time_daemon`` under the same user/group. + Understanding Log Messages ========================== diff --git a/docs/manuals/user_manual.rst b/docs/manuals/user_manual.rst index 1ee2719a..2a425c96 100644 --- a/docs/manuals/user_manual.rst +++ b/docs/manuals/user_manual.rst @@ -41,6 +41,8 @@ This module manual covers module-level integration, deployment, and troubleshoot For build and test of the module itself, please refer to the main documentation. +.. _component_manuals: + Component Manuals ----------------- @@ -108,8 +110,6 @@ Integrating with Your Project 3. Include headers and compile your code -.. For detailed API usage and examples, refer to the :doc:`/score/time/docs/manuals/user_manual`. - System Services Deployment ---------------------------