24#include <gtest/gtest.h>
41 std::uint16_t sendClockFactor,
42 std::uint16_t reductionRatio,
79 const auto output =
MakeConfig(32, 32, 0x8001);
82 auto ioContext = std::make_unique<asio::io_context>();
83 return std::make_unique<CyclicController>(*
ioContext,
"lo", src, dst, input, output);
88 auto rxSocket = std::make_unique<test::BlockingRawEthernetSocket>();
90 auto* rxSocketForTest =
rxSocket.get();
93 const auto output =
MakeConfig(32, 32, 0x8001);
97 auto ioContext = std::make_unique<asio::io_context>();
99 controller = std::make_unique<CyclicController>(
111 rxSocketForTest->WaitUntilReceiveEntered();
121 auto placeholder =
controller->rxThread.joinable();
149 EXPECT_EQ(stats.
framesSent.load(),
static_cast<std::uint64_t
>(0));
150 EXPECT_EQ(stats.
framesMissed.load(),
static_cast<std::uint64_t
>(0));
157 auto input = MakeConfig(32, 32, 0xC001);
158 auto output = MakeConfig(32, 32, 0x8001);
163 auto ioContext = std::make_unique<asio::io_context>();
173 std::invalid_argument);
181 auto input = MakeConfig(1, 1, 0xC001);
182 auto output = MakeConfig(1, 1, 0x8001);
187 auto ioContext = std::make_unique<asio::io_context>();
201 auto input = MakeConfig(32, 32, 0xC001);
202 auto output = MakeConfig(32, 32, 0x8001);
207 auto ioContext = std::make_unique<asio::io_context>();
RT_CLASS_1 cyclic data exchange controller.
bool IsRunning() const override
Whether the controller is actively exchanging cyclic data.
CyclicState State() const override
The controller's current lifecycle state.
std::unique_ptr< CyclicController > controller
static std::unique_ptr< CyclicController > MakeController()
static rt::IOCRConfig MakeConfig(std::uint16_t sendClockFactor, std::uint16_t reductionRatio, std::uint16_t frameId)
bool RxThreadJoinableForTest()
Return whether the RX worker thread is still joinable.
void StartControllerWithBlockedReceive()
Start the controller with an injected RX socket that blocks in Receive().
Declares the PROFINET RTC1 cyclic IO controller and process-data exchange API.
Deterministic raw Ethernet socket stub for cyclic-controller unit tests.
GoogleMock implementation of IRawEthernetSocket.
TEST_F(CyclicTest, CyclicStateToStringCoversAllStates)
constexpr int DEFAULT_MAX_CONSECUTIVE_TIMEOUTS
Default number of consecutive watchdog timeouts before transitioning to Fault.
std::string ToString(CyclicState state)
Human-readable name for a CyclicState value.
@ Fault
Communication failure (e.g. consecutive watchdog timeouts).
@ Running
Active cyclic data exchange.
@ Stopping
Graceful shutdown in progress (sending STOP frames).
@ Stopped
Fully stopped, threads joined.
@ Starting
Sockets created, threads launching.
@ Idle
Initial state, not yet started.
constexpr std::uint16_t ETHERTYPE_PROFINET
EtherType used by PROFINET RT frames (0x8892).
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
MacAddress String2Mac(const std::string &macStr)
Parse a colon-separated MAC address string.
Statistics for cyclic communication.
void Reset()
Reset all counters to their initial values.
std::uint64_t AvgCycleTimeUs() const
Compute the average TX cycle duration.
std::atomic< std::uint64_t > cycleTimeSumUs
Running sum of observed TX cycle durations, in microseconds.
std::atomic< std::uint64_t > framesMissed
Total number of watchdog timeouts (missed input frames).
std::atomic< std::uint64_t > framesSent
Total number of output frames sent.
std::atomic< std::uint64_t > cycleCount
Number of TX cycles included in CycleTimeSumUs.
IOCR configuration derived from AR setup: timing parameters and IO object mappings needed for cyclic ...
std::uint16_t dataLength
Total cyclic data length in bytes.
std::uint16_t sendClockFactor
Send clock base factor (31.25us units).
std::uint16_t frameId
Frame ID assigned to this IOCR.
std::uint16_t reductionRatio
Reduction ratio relative to the send clock.
std::uint16_t frameId
Ethernet FrameID.
std::unique_ptr< asio::io_context > ioContext
Shared ASIO context.
MockRawEthernetSocket * rxSocket