跳到主要内容

Rust API 参考

Rust SDK(Cargo 包 darra-pnet)。命名采用 Rust 惯例(snake_case),语义与 C# 页一致。含两种形态:

  • 服务模式(推荐)PnetService 单一入口,经 Pnet Service 内置 HTTP API(端口 18840 固定)连接,由服务承载从站运行(纯 std TcpStream HTTP/1.1,不依赖 native DLL / libloading);
  • native 直连(备选)Deviceffi 模块 + libloading 运行时加载 DarraPnet.dll)。

单一 PROFINET 网口契约(audit-2026-08-11,用户裁定 2026-08-10):设备对外只开放一个 PROFINET 网口(工业现场常态)。网卡选择在 GUI / Service 配置层完成,服务侧单一权威 = NetworkInterfaceName(读取链:环境变量 DARRA_PNET_NIC > 运行配置 XML <Network/InterfaceName> > appsettings 出厂默认;驱动绑定 / pnal 绑定目标 / MAC 解析同源一致,无双配置歧义)。native 直连模式下配置的网卡名为栈绑定的唯一网口名;EnumerateInterfaces() 仅作诊断/枚举用途。

use darra_pnet::{PnetService, Device};

概览

类型职责
PnetService服务模式单一入口:连接服务 18840 / 启停 / 地址化 IO 读写
Devicenative 直连:打开 / load_config / 启停 / 槽位 IO
Slave / PnetIo / Alarm / PnetConfig / Diagnative 直连子对象
ServiceAddress / ServiceArea服务模式地址解析
PnetError / ServiceError错误类型

PnetService — 服务模式单一入口(推荐)

经服务 HTTP API(端口 18840 固定)连接服务,由服务承载从站运行;SDK 与 Web API 同层。启停(POST /api/start|stop)/ IO(GET|POST /api/io)全部经服务转发。

use darra_pnet::{PnetService, DEFAULT_PORT};

let service = PnetService::new("127.0.0.1", DEFAULT_PORT, None);
service.start()?; // POST /api/start

// 地址化读写(ETH 式地址,对齐 C# 基准)
service.write_bool("I0.0", true)?; // 写输入位(设备 → 控制器)
service.write_int16("IW2", counter)?; // 写输入字(大端)
let cmd = service.read_int16("QW0")?; // 读输出字(控制器 → 设备)
let start = service.read_bool("Q0.0")?; // 读输出位
let (io_i, io_q) = service.get_io()?; // 服务端过程映像快照

service.stop()?; // POST /api/stop(幂等)
service.close();
成员类型类别读写说明
PnetService::new(host, port, api_key)PnetService设备构造连接服务(仅本地回环 127.0.0.1 可达,audit-2026-08-10:服务未开放局域网监听;端口固定 18840)
DEFAULT_PORTu16设备只读服务 HTTP API 固定端口 18840(编译期常量)
start()ServiceResult<()>设备启动从站(POST /api/start,由服务承载)
stop()ServiceResult<()>设备停止从站(POST /api/stop,幂等)
status()ServiceResult<ServiceState>设备只读服务端运行态(GET /api/status 映射)
status_ex()ServiceResult<ServiceStatus>设备只读服务端运行态快照(GET /api/status 一次取回 state / connected / errorCode;用户裁定 2026-08-10:错误码是调用契约的一部分,SDK 必须透出服务端 connected / errorCode)
read_bool(address)ServiceResult<bool>IO只读读位(I0.0 / Q0.0 / M1.6 / DB1.DBX0.0)
write_bool(address, value)ServiceResult<()>IO写位(I / M / DB;Q 区只读返回 ServiceError::OutputReadOnly
read_int16(address)ServiceResult<i16>IO只读读字(IW2 / QW2 / MW0 / DB1.DBW0,大端)
write_int16(address, value)ServiceResult<()>IO写字(I / M / DB;Q 区只读)
read_int32(address)ServiceResult<i32>IO只读读双字(ID4 / QD4 / MD0 / DB1.DBD0,大端)
write_int32(address, value)ServiceResult<()>IO写双字(I / M / DB;Q 区只读)
get_io()ServiceResult<(Vec<u8>, Vec<u8>)>IO只读服务端过程映像快照(I 区 / Q 区)
parse_address(text)ServiceResult<ServiceAddress>IO静态解析 HSL 式地址(对齐 C# PnetAddress.Parse
is_connected() / is_started()bool设备只读会话 / 本地启动状态

地址格式(与 C# 基准一致):I0.0 / IB0 / IW2 / ID4(I 区输入面)、Q0.0 / QB0 / QW2 / QD4(Q 区输出面,只读)、M0.0 / MB0 / MW100 / MD0(内部存储)、DB1.DBX0.0 / DB1.DBB2 / DB1.DBW0 / DB1.DBD4(DB 区槽位 1 数据块)。字 / 双字大端序,偏移即字节偏移、不强制 2 / 4 对齐(与 C# 基准一致,IW3 合法);连接服务模式为单一线性过程区,DB 仅槽位 1 有效(槽位 > 1 返回 ServiceError::DbSlotNotSupported)。

status_ex() 返回 ServiceStatusstate / connected / error_code / error_code_enum()):connected = 是否已与 IO 控制器建立周期数据交换(GET /api/status 的 connected 原值),error_code = 最近一次错误码原值(0 = 无错误;非零 = pnet 栈错误码),error_code_enum() = 枚举化映射(PnetRuntimeErrorCodeOk=0 / ErrInit=-1 / ErrCfg=-2 / ErrThread=-3 / ErrRunning=-4 / ErrPdi=-5 / Unknown=-10000,#[repr(i32)] + From<i32>;未识别值如实返回 Unknown,原始值仍经 error_code 透传)。

Device — native 直连(备选)

use darra_pnet::Device;

let mut device = Device::open()?; // 运行时加载 DarraPnet.dll
device.load_config(r"C:\DARRA\Profinet_Slave\config.xml")?; // 加载运行配置 XML
device.start()?; // 启动协议栈,等待控制器连接

let mut output = vec![0u8; 16];
device.io().read_inputs(&mut output)?; // 控制器 → 设备
device.io().write_outputs(&[1u8, 2, 3, 4])?; // 设备 → 控制器

device.stop()?;
成员类型类别读写说明
Device::open()Result<Device>设备静态打开设备(当前目录 / PATH 搜索 DarraPnet.dll
Device::builder()DeviceBuilder设备静态构建器入口(可指定 DLL 路径)
load_config(path)Result<()>配置加载运行配置 XML(GUI 输出)
start() / stop()Result<()>设备启动 / 停止协议栈
application_ready()Result<()>从站应用就绪
state()DeviceState设备只读设备状态
slave()Slave<'_>从站只读从站控制(站名 / 网络配置 / 状态)
io()PnetIo<'_>IO只读过程数据(read_inputs / write_outputs / 帧)
alarm() / config() / diag()Alarm<'_> / PnetConfig<'_> / Diag<'_>各域只读报警 / 配置 / 诊断
dll_version()Option<(u16, u16, u16, u16)>设备静态DLL 版本(未部署返回 None)

完整示例(服务模式)

use darra_pnet::{PnetService, DEFAULT_PORT};
use std::{thread, time::Duration};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let service = PnetService::new("127.0.0.1", DEFAULT_PORT, None);
service.start()?;

// 地址化周期 IO(大端序)
let mut counter: i16 = 0;
for _ in 0..100 {
service.write_bool("I0.0", counter % 2 == 0)?;
service.write_int16("IW2", counter)?;
let _cmd = service.read_int16("QW0")?;
counter = counter.wrapping_add(1);
thread::sleep(Duration::from_millis(10));
}

service.stop()?;
service.close();
Ok(())
}

Cargo.toml

[package]
name = "darra-pnet"
version = "1.0.0"
edition = "2021"

[dependencies]

相关