The live process-data runtime: the published image, the cross-thread exchange buffers, and per-object PDO access over them.
More...
|
| PauseResult | pauseCycle () |
| |
| void | resumeCycle (const ProcessImage *previous) |
| | Control plane: republishes previous, letting RT work resume.
|
| |
| bool | healthy () const |
| | True when an image is published and the last working counter meets the expectation.
|
| |
| std::optional< std::vector< uint8_t > > | readPdo (uint16_t slavePosition, uint16_t index, uint8_t subindex) const |
| | Reads a PDO-mapped object's current bytes from the live image. Lock-free.
|
| |
| bool | isOutputMapped (uint16_t slavePosition, uint16_t index, uint8_t subindex) const |
| | Whether an object is output-mapped in the published image, and so driven cyclically.
|
| |
The live process-data runtime: the published image, the cross-thread exchange buffers, and per-object PDO access over them.
Carries the output (master→slave) and input (slave→master) images across the RT / non-RT boundary, the pointer to the currently published ProcessImage layout, and the working-counter health. DeviceManager owns one of these and drives the whole-buffer exchange each cycle; it also hands a pointer to it to every Device so a device can read and write its own PDO-mapped objects (readPdo / writePdo) without knowing how the image is stored. That single seam is what lets Device::readParameter / Device::writeParameter serve the live IO-map value while exchanging — identically from an HTTP handler or an RT task — and fall back to SDO otherwise.
Both accessors are lock-free (so an RT task can read a value or set a setpoint without ever blocking on a non-RT writer). The output path is single-composer by construction: each output object's value lives in its own DeviceParameter cell, which any number of writers store into independently, and the RT loop is the sole thread that composes those cells into the packed wire image each cycle (DeviceManager::exchangeProcessData). Composing on one thread is what makes bit-packed objects that share a byte safe without a lock — see NEXTGEN.md (Design B).
Defined in a header (rather than pimpl'd) so both device.cc and device_manager.cc can use it; the recorder ring and fixed buffers are heavy, but only those two translation units pull them in (the public device.h / device_manager.h only forward-declare it).
| bool mm::node::ProcessData::isOutputMapped |
( |
uint16_t |
slavePosition, |
|
|
uint16_t |
index, |
|
|
uint8_t |
subindex |
|
) |
| const |
Whether an object is output-mapped in the published image, and so driven cyclically.
Asks a question rather than staging a value, because there is nowhere left to stage one: the parameter's own cell is what the RT loop composes the wire image from, and a writer has already stored there by the time it asks. So a true answer means "your value will go out on
the next cycle"; false means the caller must reach the object over SDO instead.
Lock-free. No health gate — an output is our own setpoint, always valid to send.
| std::optional< std::vector< uint8_t > > mm::node::ProcessData::readPdo |
( |
uint16_t |
slavePosition, |
|
|
uint16_t |
index, |
|
|
uint8_t |
subindex |
|
) |
| const |
Reads a PDO-mapped object's current bytes from the live image. Lock-free.
Outputs come from the parameter's own cell (our current setpoint — always valid); inputs from the newest recorded cycle (ring head()-1), gated on healthy(). Returns nullopt when no image is published, nothing is recorded yet, the object is not PDO-mapped, its owning parameter is unknown, or (inputs only) the bus is unhealthy — in each case the caller reads it over SDO instead. Bytes are little-endian and LSB-aligned.