|
PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
|
RT_CLASS_1 cyclic data exchange controller. More...
#include <cyclic.h>
Inheritance diagram for profinet::cyclic::CyclicController:
Collaboration diagram for profinet::cyclic::CyclicController:Public Member Functions | |
| CyclicController (std::string interface, MacAddress srcMac, MacAddress dstMac, rt::IOCRConfig inputIocr, rt::IOCRConfig outputIocr, int maxConsecutiveTimeouts=DEFAULT_MAX_CONSECUTIVE_TIMEOUTS, std::uint16_t etherType=rt::ETHERTYPE_PROFINET) | |
| Construct a controller for the given interface and IOCR configuration. | |
| ~CyclicController () override | |
| Stop (if running) and release resources. | |
| CyclicController (const CyclicController &)=delete | |
| Not copyable (owns sockets and background threads). | |
| CyclicController & | operator= (const CyclicController &)=delete |
| Not copyable (owns sockets and background threads). | |
| void | SetOutputData (int slot, int subslot, const Bytes &data) |
| Set output data for the next cycle. | |
| std::optional< Bytes > | GetInputData (int slot, int subslot, bool allowBad=false) const |
| Get the latest input data received from the device, if any or IOPS is BAD. | |
| void | OnInputStatus (std::function< void(std::uint16_t slot, std::uint16_t subslot, std::uint8_t iops)> callback) |
| Register a callback for PROFINET provider status (IOPS) changes. | |
| void | OnInput (std::function< void(int slot, int subslot, const Bytes &data)> callback) |
| Register a callback invoked whenever new input data is received. | |
| void | OnTimeout (std::function< void()> callback) |
| Register a callback invoked on each watchdog timeout. | |
| void | OnError (std::function< void(const std::string &)> callback) |
| Register a callback invoked on TX/RX socket errors. | |
| void | OnStateChange (std::function< void(CyclicState oldState, CyclicState newState)> callback) |
| Register a callback invoked on every state transition. | |
| void | Start () override |
| Create TX/RX sockets and spawn the TX/RX threads. | |
| void | Stop () override |
| Stop gracefully. | |
| bool | IsRunning () const |
| Whether the controller is actively exchanging cyclic data. | |
| CyclicState | State () const |
| The controller's current lifecycle state. | |
| const CyclicStats & | Stats () const |
| Communication statistics for this controller. | |
| CyclicStatsSnapshot | StatsSnapshot () const |
| std::optional< std::uint8_t > | GetInputStatus (std::uint16_t slot, std::uint16_t subslot) const |
| Get the last provider status (IOPS) received for a submodule. | |
| bool | IsInputGood (std::uint16_t slot, std::uint16_t subslot) const |
| Check whether the device currently reports GOOD provider status. | |
Public Member Functions inherited from profinet::cyclic::ICyclicController | |
| virtual | ~ICyclicController ()=default |
| Virtual destructor. | |
Private Member Functions | |
| void | Transition (CyclicState newState) |
| Change state and invoke the OnStateChange callback if registered. | |
| void | CheckCycleTime () |
| Validate the configured cycle time, throwing if it's below 1ms. | |
| void | TxCycle () |
| Swap the output buffer and transmit one cyclic output frame. | |
| void | TxLoop () |
| TX thread body: sends output frames at the configured cycle rate. | |
| void | SendOutputFrame (std::optional< std::uint8_t > dataStatusOverride=std::nullopt) |
| Build and send one output frame. | |
| void | SendStopFrames () |
| Send STOP_FRAME_COUNT output frames with ProviderRun cleared. | |
| void | RxLoop () |
| RX thread body: receives and processes input frames, checking the watchdog. | |
| void | HandleWatchdogTimeout () |
| Handle a watchdog timeout: update stats and possibly transition to Fault. | |
| void | ProcessInputFrame (const Bytes &data) |
| Parse and process one received input frame. | |
| bool | LocalIsInputGood (std::uint16_t slot, std::uint16_t subslot) const |
| Check whether a submodule has GOOD provider status without locking. | |
| void | TrackCycleCounter (std::uint16_t rxCounter) |
| Update cycle-counter tracking stats (gaps/duplicates/reordering) for a received frame. | |
Private Attributes | |
| std::map< std::pair< std::uint16_t, std::uint16_t >, std::uint8_t > | inputStatus |
| Last provider status (IOPS) the device sent per submodule. Payload bytes are only meaningful while the matching IOPS reports GOOD. | |
| std::string | interface |
| Network interface name. | |
| MacAddress | srcMac |
| This host's MAC address. | |
| MacAddress | dstMac |
| The device's MAC address. | |
| rt::IOCRConfig | inputIocr |
| Configuration for the input (device -> controller) IOCR. | |
| rt::IOCRConfig | outputIocr |
| Configuration for the output (controller -> device) IOCR. | |
| int | maxConsecutiveTimeouts |
| Consecutive watchdog timeouts before transitioning to Fault. | |
| std::atomic< CyclicState > | state {CyclicState::Idle} |
| Current lifecycle state. | |
| std::uint16_t | etherType {rt::ETHERTYPE_PROFINET} |
| Current lifecycle state. | |
| std::atomic< bool > | running {false} |
| Whether the TX/RX threads should keep running. | |
| std::thread | txThread |
| Thread sending output frames. | |
| std::thread | rxThread |
| Thread receiving input frames. | |
| std::optional< EthernetSocket > | txSock |
| Raw socket used for sending output frames. | |
| std::optional< EthernetSocket > | rxSock |
| Raw socket used for receiving input frames. | |
| std::uint16_t | cycleCounter = 0 |
| Current TX cycle counter value. | |
| rt::CyclicDataBuilder | outputBuilder |
| Double-buffered builder for output cyclic data. | |
| std::mutex | inputLock |
| Guards inputData against concurrent access. | |
| std::map< std::pair< int, int >, Bytes > | inputData |
| Latest received data per (slot, subslot). | |
| std::optional< std::uint16_t > | lastRxCycleCounter |
| Last received cycle counter, for gap/duplicate/reorder detection. | |
| std::uint32_t | rxCounterStep |
| Expected cycle-counter increment per received input frame. | |
| std::uint32_t | txCounterStep |
| Cycle-counter increment applied per sent output frame. | |
| std::function< void(int, int, const std::uint8_t)> | onInputStatus |
| Registered OnInputStatus callback, if any. | |
| std::function< void(int, int, const Bytes &)> | onInputData |
| Registered OnInput callback, if any. | |
| std::function< void()> | onTimeout |
| Registered OnTimeout callback, if any. | |
| std::function< void(const std::string &)> | onError |
| Registered OnError callback, if any. | |
| std::function< void(CyclicState, CyclicState)> | onStateChange |
| Registered OnStateChange callback, if any. | |
| CyclicStats | stats |
| Communication statistics. | |
| bool | iocsGood |
| Tracks the watchdog-driven IOCS state so the RX/timeout paths only rewrite the buffer on transitions (both run on the RX thread). | |
Friends | |
| class | CyclicControllerConformanceTest |
| class | ReceivedIopsTest |
RT_CLASS_1 cyclic data exchange controller.
Example:
Cycle-time guidance carried over from the Python original (Python's GIL made sub-8ms cycles unreliable there): this C++ port has no such language-level ceiling, but the constructor still throws below 1ms and still surfaces a warning below 8ms, since the underlying two-thread sleep-based scheduling here is the same design, just compiled – actual achievable jitter depends on the OS scheduler, not the language.
| profinet::cyclic::CyclicController::CyclicController | ( | std::string | interface, |
| MacAddress | srcMac, | ||
| MacAddress | dstMac, | ||
| rt::IOCRConfig | inputIocr, | ||
| rt::IOCRConfig | outputIocr, | ||
| int | maxConsecutiveTimeouts = DEFAULT_MAX_CONSECUTIVE_TIMEOUTS, |
||
| std::uint16_t | etherType = rt::ETHERTYPE_PROFINET |
||
| ) |
Construct a controller for the given interface and IOCR configuration.
| interface | Network interface name to bind to, e.g. "eth0". |
| srcMac | This host's MAC address. |
| dstMac | The device's MAC address. |
| inputIocr | Configuration for the input (device -> controller) IOCR. |
| outputIocr | Configuration for the output (controller -> device) IOCR. |
| maxConsecutiveTimeouts | Consecutive watchdog timeouts before transitioning to Fault. |
| etherType | Bind protocol. 0 binds ETH_P_ALL so VLAN-tagged frames are delivered too. |
Definition at line 60 of file cyclic.cpp.
References CheckCycleTime(), profinet::rt::IOXS_GOOD, outputBuilder, profinet::rt::IOCRConfig::reductionRatio, rxCounterStep, profinet::rt::IOCRConfig::sendClockFactor, profinet::rt::CyclicDataBuilder::SetAllIocs(), profinet::rt::CyclicDataBuilder::SetAllIops(), and txCounterStep.
Here is the call graph for this function:
|
override |
Stop (if running) and release resources.
Definition at line 92 of file cyclic.cpp.
References running, and Stop().
Here is the call graph for this function:
|
delete |
Not copyable (owns sockets and background threads).
|
private |
Validate the configured cycle time, throwing if it's below 1ms.
Definition at line 100 of file cyclic.cpp.
References profinet::rt::IOCRConfig::CycleTimeMs(), and outputIocr.
Referenced by CyclicController().
Here is the call graph for this function:
Here is the caller graph for this function:| std::optional< Bytes > profinet::cyclic::CyclicController::GetInputData | ( | int | slot, |
| int | subslot, | ||
| bool | allowBad = false |
||
| ) | const |
Get the latest input data received from the device, if any or IOPS is BAD.
Data whose IOPS is BAD must not be used by the application: the device is telling us the payload is not valid (module pulled, sensor faulted), and the bytes it keeps sending are stale. Such data is withheld unless allowBad is set. Use GetInputStatus() to inspect the raw IOPS.
| slot | Slot number of the object to read. |
| subslot | Subslot number of the object to read. |
| allowBad | Return the payload even when the device marked IOPS BAD. |
Thread-safe.
Definition at line 148 of file cyclic.cpp.
References inputData, inputLock, and LocalIsInputGood().
Here is the call graph for this function:| std::optional< std::uint8_t > profinet::cyclic::CyclicController::GetInputStatus | ( | std::uint16_t | slot, |
| std::uint16_t | subslot | ||
| ) | const |
Get the last provider status (IOPS) received for a submodule.
Returns the raw IOPS byte reported by the PROFINET device for the specified slot and subslot. The access is protected by the input status mutex.
A value of 0x80 indicates GOOD provider status.
| slot | Slot number. |
| subslot | Subslot number. |
Definition at line 159 of file cyclic.cpp.
References inputLock, and inputStatus.
|
private |
Handle a watchdog timeout: update stats and possibly transition to Fault.
Definition at line 505 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::consecutiveTimeouts, profinet::cyclic::Fault, profinet::cyclic::CyclicStats::framesMissed, iocsGood, profinet::rt::IOXS_BAD, maxConsecutiveTimeouts, onError, onTimeout, outputBuilder, profinet::cyclic::Running, profinet::rt::CyclicDataBuilder::SetAllIocs(), state, stats, and Transition().
Referenced by RxLoop().
Here is the call graph for this function:
Here is the caller graph for this function:| bool profinet::cyclic::CyclicController::IsInputGood | ( | std::uint16_t | slot, |
| std::uint16_t | subslot | ||
| ) | const |
Check whether the device currently reports GOOD provider status.
Checks the last IOPS value received for the specified submodule. The access is protected by the input status mutex.
| slot | Slot number. |
| subslot | Subslot number. |
Definition at line 173 of file cyclic.cpp.
References inputLock, and LocalIsInputGood().
Here is the call graph for this function:
|
inline |
Whether the controller is actively exchanging cyclic data.
Definition at line 314 of file cyclic.h.
References profinet::cyclic::Running, and state.
|
private |
Check whether a submodule has GOOD provider status without locking.
This is the internal implementation of IsInputGood(). The caller must already hold m_inputStatusMutex.
| slot | Slot number. |
| subslot | Subslot number. |
Definition at line 180 of file cyclic.cpp.
References inputStatus, and profinet::rt::IOXS_DATA_STATE_GOOD.
Referenced by GetInputData(), IsInputGood(), and ProcessInputFrame().
Here is the caller graph for this function:| void profinet::cyclic::CyclicController::OnError | ( | std::function< void(const std::string &)> | callback | ) |
Register a callback invoked on TX/RX socket errors.
| callback | Function called with a human-readable error message. |
Definition at line 205 of file cyclic.cpp.
References onError.
| void profinet::cyclic::CyclicController::OnInput | ( | std::function< void(int slot, int subslot, const Bytes &data)> | callback | ) |
Register a callback invoked whenever new input data is received.
| callback | Function called with (slot, subslot, data) for each updated object. |
Definition at line 197 of file cyclic.cpp.
References onInputData.
| void profinet::cyclic::CyclicController::OnInputStatus | ( | std::function< void(std::uint16_t slot, std::uint16_t subslot, std::uint8_t iops)> | callback | ) |
Register a callback for PROFINET provider status (IOPS) changes.
The callback is invoked by the RX thread whenever the provider status (IOPS) of a submodule transitions between GOOD and BAD.
A device can use an IOPS transition to indicate that its input data has become invalid, for example when a module is removed or a sensor fault occurs, without terminating the Application Relationship (AR). In this situation cyclic frames may continue to arrive with stale payload data, making the IOPS transition the relevant notification available to the application.
The callback receives the slot number, subslot number, and raw IOPS byte reported by the device.
| callback | Function invoked as callback(slot, subslot, iops). Passing an empty std::function disables the callback. |
Definition at line 192 of file cyclic.cpp.
References onInputStatus.
| void profinet::cyclic::CyclicController::OnStateChange | ( | std::function< void(CyclicState oldState, CyclicState newState)> | callback | ) |
Register a callback invoked on every state transition.
| callback | Function called with (old_state, new_state). |
Definition at line 209 of file cyclic.cpp.
References onStateChange.
| void profinet::cyclic::CyclicController::OnTimeout | ( | std::function< void()> | callback | ) |
Register a callback invoked on each watchdog timeout.
| callback | Function called with no arguments. |
Definition at line 201 of file cyclic.cpp.
References onTimeout.
|
delete |
Not copyable (owns sockets and background threads).
|
private |
Parse and process one received input frame.
| data | Raw Ethernet frame bytes. |
Definition at line 543 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::consecutiveTimeouts, profinet::rt::RTFrame::cycleCounter, dstMac, profinet::rt::ETHERTYPE_PROFINET, profinet::cyclic::Fault, profinet::rt::IOCRConfig::frameId, profinet::rt::RTFrame::frameId, profinet::cyclic::CyclicStats::framesInvalid, profinet::cyclic::CyclicStats::framesReceived, profinet::rt::RTFrame::FromBytes(), inputData, inputIocr, inputLock, inputStatus, iocsGood, profinet::rt::IOXS_DATA_STATE_GOOD, profinet::rt::IOXS_GOOD, profinet::rt::RTFrame::IsValid(), profinet::cyclic::CyclicStats::lastReceiveTime, LocalIsInputGood(), obj, profinet::rt::IOCRConfig::objects, profinet::OneOctetShift, onInputData, onInputStatus, outputBuilder, profinet::rt::RTFrame::payload, profinet::cyclic::Running, profinet::rt::CyclicDataBuilder::SetAllIocs(), profinet::SkipVlanTags(), state, stats, TrackCycleCounter(), profinet::rt::RTFrame::transferStatus, and Transition().
Referenced by RxLoop().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
RX thread body: receives and processes input frames, checking the watchdog.
Definition at line 464 of file cyclic.cpp.
References HandleWatchdogTimeout(), inputIocr, profinet::cyclic::CyclicStats::lastReceiveTime, onError, ProcessInputFrame(), running, rxSock, stats, and profinet::rt::IOCRConfig::WatchdogTimeUs().
Referenced by Start().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
Build and send one output frame.
| dataStatusOverride | If set, overrides the computed DataStatus (used for STOP frames). |
Definition at line 396 of file cyclic.cpp.
References profinet::rt::CyclicDataBuilder::Build(), profinet::rt::BuildEthernetFrame(), cycleCounter, profinet::rt::RTFrame::cycleCounter, profinet::rt::DATA_STATUS_PROVIDER_RUN, profinet::rt::DATA_STATUS_STATE, profinet::rt::DATA_STATUS_STATION_OK, profinet::rt::DATA_STATUS_VALID, profinet::rt::RTFrame::dataStatus, dstMac, profinet::rt::IOCRConfig::frameId, profinet::rt::RTFrame::frameId, onError, outputBuilder, outputIocr, profinet::rt::RTFrame::payload, payload, srcMac, profinet::rt::RTFrame::transferStatus, txCounterStep, and txSock.
Referenced by SendStopFrames(), and TxCycle().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
Send STOP_FRAME_COUNT output frames with ProviderRun cleared.
Definition at line 434 of file cyclic.cpp.
References profinet::rt::IOCRConfig::CycleTimeUs(), profinet::rt::DATA_STATUS_STATE, profinet::rt::DATA_STATUS_STATION_OK, profinet::rt::DATA_STATUS_VALID, profinet::cyclic::CyclicStats::framesSent, outputBuilder, outputIocr, SendOutputFrame(), stats, profinet::cyclic::STOP_FRAME_COUNT, profinet::rt::CyclicDataBuilder::Swap(), and txSock.
Referenced by Stop().
Here is the call graph for this function:
Here is the caller graph for this function:| void profinet::cyclic::CyclicController::SetOutputData | ( | int | slot, |
| int | subslot, | ||
| const Bytes & | data | ||
| ) |
Set output data for the next cycle.
| slot | Slot number of the object to update. |
| subslot | Subslot number of the object to update. |
| data | New data for the object. |
Thread-safe. Throws std::runtime_error if in Fault or Stopped state.
Definition at line 137 of file cyclic.cpp.
References profinet::cyclic::Fault, profinet::rt::IOXS_GOOD, outputBuilder, profinet::rt::CyclicDataBuilder::SetData(), profinet::rt::CyclicDataBuilder::SetIops(), state, profinet::cyclic::Stopped, and profinet::cyclic::ToString().
Here is the call graph for this function:
|
overridevirtual |
Create TX/RX sockets and spawn the TX/RX threads.
Throws std::runtime_error if not in Idle/Stopped/Fault state, or if CycleTimeMs() < 1ms (not achievable). Throws PermissionDeniedError if raw sockets need elevated privilege.
Implements profinet::cyclic::ICyclicController.
Definition at line 214 of file cyclic.cpp.
References etherType, profinet::cyclic::Fault, profinet::cyclic::Idle, interface, lastRxCycleCounter, outputBuilder, profinet::cyclic::CyclicStats::Reset(), profinet::cyclic::Running, running, RxLoop(), rxSock, rxThread, profinet::cyclic::Starting, state, stats, profinet::cyclic::Stopped, profinet::rt::CyclicDataBuilder::Swap(), profinet::cyclic::ToString(), Transition(), TxLoop(), txSock, and txThread.
Here is the call graph for this function:
|
inline |
|
inline |
| CyclicStatsSnapshot profinet::cyclic::CyclicController::StatsSnapshot | ( | ) | const |
Definition at line 278 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::consecutiveTimeouts, profinet::cyclic::CyclicStatsSnapshot::consecutiveTimeouts, profinet::cyclic::CyclicStats::cycleCount, profinet::cyclic::CyclicStatsSnapshot::cycleCount, profinet::cyclic::CyclicStats::cycleTimeSumUs, profinet::cyclic::CyclicStatsSnapshot::cycleTimeSumUs, profinet::cyclic::CyclicStats::framesDuplicate, profinet::cyclic::CyclicStatsSnapshot::framesDuplicate, profinet::cyclic::CyclicStats::framesInvalid, profinet::cyclic::CyclicStatsSnapshot::framesInvalid, profinet::cyclic::CyclicStats::framesMissed, profinet::cyclic::CyclicStatsSnapshot::framesMissed, profinet::cyclic::CyclicStats::framesOutOfOrder, profinet::cyclic::CyclicStatsSnapshot::framesOutOfOrder, profinet::cyclic::CyclicStats::framesReceived, profinet::cyclic::CyclicStatsSnapshot::framesReceived, profinet::cyclic::CyclicStats::framesSent, profinet::cyclic::CyclicStatsSnapshot::framesSent, profinet::cyclic::CyclicStats::lastCycleTimeUs, profinet::cyclic::CyclicStatsSnapshot::lastCycleTimeUs, profinet::cyclic::CyclicStats::lastReceiveTime, profinet::cyclic::CyclicStatsSnapshot::lastReceiveTime, profinet::cyclic::CyclicStats::maxCycleTimeUs, profinet::cyclic::CyclicStatsSnapshot::maxCycleTimeUs, profinet::cyclic::CyclicStats::maxJitterUs, profinet::cyclic::CyclicStatsSnapshot::maxJitterUs, profinet::cyclic::CyclicStats::minCycleTimeUs, profinet::cyclic::CyclicStatsSnapshot::minCycleTimeUs, and stats.
|
overridevirtual |
Stop gracefully.
Signals threads to exit, joins the TX thread, sends STOP frames (ProviderRun cleared), closes the RX socket, joins the RX thread, then closes the TX socket.
Implements profinet::cyclic::ICyclicController.
Definition at line 244 of file cyclic.cpp.
References running, rxSock, rxThread, SendStopFrames(), profinet::cyclic::Stopped, profinet::cyclic::Stopping, Transition(), txSock, and txThread.
Referenced by ~CyclicController().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
Update cycle-counter tracking stats (gaps/duplicates/reordering) for a received frame.
| rxCounter | Cycle counter from the received frame. |
Definition at line 732 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::framesDuplicate, profinet::cyclic::CyclicStats::framesMissed, profinet::cyclic::CyclicStats::framesOutOfOrder, lastRxCycleCounter, rxCounterStep, and stats.
Referenced by ProcessInputFrame().
Here is the caller graph for this function:
|
private |
Change state and invoke the OnStateChange callback if registered.
| newState | State to transition to. |
Definition at line 118 of file cyclic.cpp.
References onStateChange, and state.
Referenced by HandleWatchdogTimeout(), ProcessInputFrame(), Start(), and Stop().
Here is the caller graph for this function:
|
private |
Swap the output buffer and transmit one cyclic output frame.
Executes one PROFINET cyclic output transmission cycle.
The output buffer is swapped before transmission so that the frame contains the latest prepared output data. A frame must continue to be transmitted even while the controller is in FAULT state. Stopping cyclic transmission would cause the device's Data Hold Timer to expire, which would terminate the Application Relationship (AR) and prevent the input stream from resuming during FAULT recovery.
IOCS is already reported as BAD while the controller is in FAULT, so cyclic transmission can safely continue while the controller is in that state.
Definition at line 313 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::framesSent, outputBuilder, SendOutputFrame(), stats, and profinet::rt::CyclicDataBuilder::Swap().
Referenced by TxLoop().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
TX thread body: sends output frames at the configured cycle rate.
Definition at line 322 of file cyclic.cpp.
References profinet::cyclic::CyclicStats::cycleCount, profinet::cyclic::CyclicStats::cycleTimeSumUs, profinet::rt::IOCRConfig::CycleTimeUs(), profinet::cyclic::CyclicStats::lastCycleTimeUs, profinet::cyclic::CyclicStats::maxCycleTimeUs, profinet::cyclic::CyclicStats::maxJitterUs, profinet::cyclic::CyclicStats::minCycleTimeUs, outputIocr, running, stats, and TxCycle().
Referenced by Start().
Here is the call graph for this function:
Here is the caller graph for this function:
|
private |
Current TX cycle counter value.
Definition at line 464 of file cyclic.h.
Referenced by SendOutputFrame().
|
private |
The device's MAC address.
Definition at line 431 of file cyclic.h.
Referenced by ProcessInputFrame(), and SendOutputFrame().
|
private |
|
private |
Latest received data per (slot, subslot).
Definition at line 473 of file cyclic.h.
Referenced by GetInputData(), and ProcessInputFrame().
|
private |
Configuration for the input (device -> controller) IOCR.
Definition at line 434 of file cyclic.h.
Referenced by ProcessInputFrame(), and RxLoop().
|
mutableprivate |
Guards inputData against concurrent access.
Definition at line 470 of file cyclic.h.
Referenced by GetInputData(), GetInputStatus(), IsInputGood(), and ProcessInputFrame().
|
private |
Last provider status (IOPS) the device sent per submodule. Payload bytes are only meaningful while the matching IOPS reports GOOD.
Definition at line 418 of file cyclic.h.
Referenced by GetInputStatus(), LocalIsInputGood(), and ProcessInputFrame().
|
private |
|
private |
Tracks the watchdog-driven IOCS state so the RX/timeout paths only rewrite the buffer on transitions (both run on the RX thread).
Definition at line 504 of file cyclic.h.
Referenced by HandleWatchdogTimeout(), and ProcessInputFrame().
|
private |
Last received cycle counter, for gap/duplicate/reorder detection.
Definition at line 476 of file cyclic.h.
Referenced by Start(), and TrackCycleCounter().
|
private |
Consecutive watchdog timeouts before transitioning to Fault.
Definition at line 440 of file cyclic.h.
Referenced by HandleWatchdogTimeout().
|
private |
Registered OnError callback, if any.
Definition at line 494 of file cyclic.h.
Referenced by HandleWatchdogTimeout(), OnError(), RxLoop(), and SendOutputFrame().
|
private |
Registered OnInput callback, if any.
Definition at line 488 of file cyclic.h.
Referenced by OnInput(), and ProcessInputFrame().
|
private |
Registered OnInputStatus callback, if any.
Definition at line 485 of file cyclic.h.
Referenced by OnInputStatus(), and ProcessInputFrame().
|
private |
Registered OnStateChange callback, if any.
Definition at line 497 of file cyclic.h.
Referenced by OnStateChange(), and Transition().
|
private |
Registered OnTimeout callback, if any.
Definition at line 491 of file cyclic.h.
Referenced by HandleWatchdogTimeout(), and OnTimeout().
|
private |
Double-buffered builder for output cyclic data.
Definition at line 467 of file cyclic.h.
Referenced by CyclicController(), HandleWatchdogTimeout(), ProcessInputFrame(), SendOutputFrame(), SendStopFrames(), SetOutputData(), Start(), and TxCycle().
|
private |
Configuration for the output (controller -> device) IOCR.
Definition at line 437 of file cyclic.h.
Referenced by CheckCycleTime(), SendOutputFrame(), SendStopFrames(), and TxLoop().
|
private |
|
private |
Expected cycle-counter increment per received input frame.
Definition at line 479 of file cyclic.h.
Referenced by CyclicController(), and TrackCycleCounter().
|
private |
|
private |
|
private |
|
private |
Current lifecycle state.
Definition at line 443 of file cyclic.h.
Referenced by HandleWatchdogTimeout(), IsRunning(), ProcessInputFrame(), SetOutputData(), Start(), State(), and Transition().
|
private |
Communication statistics.
Definition at line 500 of file cyclic.h.
Referenced by HandleWatchdogTimeout(), ProcessInputFrame(), RxLoop(), SendStopFrames(), Start(), Stats(), StatsSnapshot(), TrackCycleCounter(), TxCycle(), and TxLoop().
|
private |
Cycle-counter increment applied per sent output frame.
Definition at line 482 of file cyclic.h.
Referenced by CyclicController(), and SendOutputFrame().
|
private |
Raw socket used for sending output frames.
Definition at line 458 of file cyclic.h.
Referenced by SendOutputFrame(), SendStopFrames(), Start(), and Stop().
|
private |