Skip to main content

Crate pnio

Crate pnio 

Source
Expand description

pnio — pure-Rust PROFINET RT IO-Device stack.

Community project, NOT affiliated with or endorsed by PROFIBUS & PROFINET International. “PROFINET” is a registered trademark of PNO.

§Example: answer a DCP Identify on the device side

use pnio::dcp::{handle_dcp_frame, DcpConfig, DeviceProperties};
use pnio::eth::MacAddr;

let cfg = DcpConfig {
    mac: MacAddr([0x02, 0xc0, 0xa8, 0x01, 0x0f, 0x02]),
    properties: DeviceProperties {
        name_of_station: "i-device".to_string(),
        type_of_station: "demo".to_string(),
        vendor_id: 0x002a,
        device_id: 0x010e,
        device_role: 0,
        device_instance: 0x1064,
        device_options: vec![0x02, 0x07],
        ip: [192, 168, 1, 61],
        subnet: [255, 255, 255, 0],
        gateway: [192, 168, 1, 61],
        ip_block_info: 1,
    },
};

// A DCP Identify request for "i-device" produces an Identify response.
let req = [
    0x01, 0x0e, 0xcf, 0x00, 0x00, 0x00, 0xec, 0x1c, 0x5d, 0x61, 0xe7, 0x3f, 0x88, 0x92,
    0xfe, 0xfe, 0x05, 0x00, 0x03, 0x00, 0x01, 0x52, 0x00, 0x01, 0x00, 0x0c, 0x02, 0x02,
    0x00, 0x08, 0x69, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
];
let resp = handle_dcp_frame(&req, &cfg).unwrap();
assert!(resp.is_some());

Modules§

alarm
PROFINET alarm channel (RTA over 0x8892, FrameIDs 0xFC01 High / 0xFE01 Low): the codec (rta) and the one-alarm-in-flight sender/receiver state machine (channel). Pure: no sockets, no clock — the device loop drives both.
api
Typed facade over device::Device + rt::IoImage (spec §6): start the device from a DeviceConfig in one call, read the controller’s outputs and write our inputs by (slot, index) with the config’s field table. The RT path is untouched.
capture
Offline replay of captured traffic: an iterator over raw Ethernet frames read from a pcap or pcapng file (auto-detected by magic bytes), for feeding recorded captures back through the codecs without a live socket.
cm
PROFINET Context Manager (CM): PNIO status, PNIO block header, and the Connect-request block parsers (ARBlockReq, IOCRBlockReq, ExpectedSubmoduleBlockReq, AlarmCRBlockReq) needed to establish an Application Relationship (AR).
config
Typed device configuration: the single source from which the device model, the per-field byte/bit table, the DCP identity and the GSDML are derived (spec §4).
data
Encoding/decoding of PROFINET process data types.
dcp
PROFINET DCP (Discovery & Configuration Protocol) — device side.
device
The acyclic loop: services the DCP (Ethernet) and RPC (UDP) sockets, drives Cm with what they produce, and executes its outputs. Log-and-drop for parse errors (spec §8); only transport I/O failures abort the loop.
diag
Channel-diagnosis store: tracks the active ChannelDiagnosis state per submodule and turns raise/clear events into AlarmNotifications (Diagnosis / DiagnosisDisappears) plus the aggregate problem indicator. Pure: no I/O, no clock — the device loop drives it.
eth
Raw Ethernet layer: the L2 header codec, the EthTransport send/receive abstraction, a BPF filter builder, and the Linux AF_PACKET transport (AfPacketTransport, the only production backend).
gsdml
GSDML V2.4 rendering from a DeviceConfig: same object, same idents, same field order as the code, so the file cannot drift from what the device answers (spec §5). Text template; no XML library in the crate.
im
I&M0-3 (Identification & Maintenance) record codec and store.
rpc
DCE-RPC v4 connectionless (CL) codec used by PROFINET IO (UDP port 34964).
rt
Cyclic RTC1 exchange: frame codec, I/O layout, and the real-time provider/consumer thread.

Functions§

version
Crate version (foundations smoke test).