C++ API
Darra Profinet Slave C++ SDK:header-only pns.hpp,命名空间 darra::pns。产品入口是 PnSService。
#include "pns.hpp"
using namespace darra::pns;
周期自由配置,最低 1 ms。失败抛 PnSException。
生命周期
Connect() → Start → Write / Read / PDO().In · PDO().Out → Stop → Close
快速开始
#include "pns.hpp"
#include <cstdio>
using namespace darra::pns;
int main()
{
PnSService service;
try {
service.Connect();
service.Start();
auto q = service.Read(); // Q:控制器 → 设备
service.Write({0x01, 0x02, 0x03, 0x04}); // I:设备 → 控制器
printf("PDO In[0]=0x%02X\n",
(unsigned)service.PDO().In[0].Content());
service.PDO().Out[0].Content(0x11);
service.Stop();
service.Close();
} catch (const PnSException& e) {
printf("错误: %s\n", e.what());
return 1;
}
return 0;
}
连接
| 类别 | 成员 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 生命周期 | Connect() | void | 写 | 本机会话 |
| 生命周期 | Connect("127.0.0.1") | void | 写 | 指定本机服务 |
| 生命周期 | Connect(host, port, api_key) | void | 写 | 完整签名。服务端配置密钥后必传 api_key |
| 生命周期 | Close() | void | 写 | 释放会话。析构自动调用 |
| 设备 | kDefaultPort | uint16_t | 只读 | 本机服务默认端口 |
| 设备 | IsConnected() | bool | 只读 | 会话是否已连接 |
| 设备 | Host() / Port() | string / uint16_t | 只读 | 服务主机 / 端口 |
- 本机:
service.Connect(); - 指定服务:
service.Connect("127.0.0.1");—— 服务不可达抛PnSException。
方向契约
过程映像方向固定,写 Q 必须失败。
| 区 | 方向 | 允许 | 禁止 |
|---|---|---|---|
| I | 设备 → 控制器 | Write / PDO().Out / Write* | — |
| Q | 控制器 → 设备 | Read / PDO().In / Read* | 任何写 Q |
WriteArea(PnSServiceArea::Output, …) / WriteBool("Q0.0", …) 抛 PnSException(文案:Q 区 (输出面, 控制器 -> 设备) 只读)。字 / 双字一律大端。
启停与运行态
| 类别 | 成员 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 生命周期 | Start() | void | 写 | 启动会话。已启动则成功返回 |
| 生命周期 | Stop() | void | 写 | 停止本会话。主站在连时不要拆应用关系 |
| 生命周期 | IsStarted() | bool | 只读 | 本地会话是否已启动 |
| 生命周期 | ResetDevice(mode) | void | 写 | 复位。mode = "communication" / "factory" |
| 运行态 | State() / Status() | PnSState | 只读 | 运行态枚举 |
| 运行态 | StatusEx() | PnSServiceStatus | 只读 | state / connected / error_code 一次取回 |
| 运行态 | ErrorCode() | PnSRuntimeErrorCode | 只读 | 运行错误码枚举。未识别 = Unknown |
| 运行态 | ErrorMessage() | string | 只读 | 错误码中文消息 |
| 诊断 | LastError() | const string& | 只读 | 最近一次调用错误(成功后清空) |
| IO | IoStatus() | PnSIoStatus | 只读 | IOPS / IOCS 快照 |
PnSServiceStatus::connected = 是否已与 IO 控制器建立周期数据交换。error_code 为原值(0 = 无错误);未识别值仍经该字段透传。
整区 IO
| 类别 | 成员 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| IO | Read() | vector<uint8_t> | 只读 | 读整区 Q |
| IO | Write(data) | void | 只写 | 写 I,从偏移 0 起,允许短写 |
| IO | ReadArea(area, offset, length) | vector<uint8_t> | 只读 | 按区截取 |
| IO | WriteArea(area, offset, data) | void | 只写 | 按区写入。写 Q 抛异常 |
| IO | GetIo() | pair<vector<uint8_t>, vector<uint8_t>> | 只读 | 快照:first = I,second = Q |
| IO | operator[] / at(offset) | IoByte | 读写 | 绝对字节。get = Q,set = I |
std::vector<uint8_t> q = service.Read();
service.Write({0x01, 0x02, 0x03, 0x04});
PDO
对齐 PDO().In / PDO().Out。In 只读 Q,Out 可写 I。无 live 指针。
| 类别 | 成员 | 类型 | 方向 | 说明 |
|---|---|---|---|---|
| PDO | PDO() | Pdo | — | 取访问器 |
| PDO | PDO().In[offset] | PdoDataItem | 只读 | Q 区字节偏移 |
| PDO | PDO().Out[offset] | PdoDataItem | 只写 | I 区字节偏移 |
| PDO | Content() / Content(v) | uint8_t / void | 只读 / 只写 | 1 字节。In 只读;Out 可写 |
| PDO | AsInt16 / AsUInt16 / AsInt32 / AsUInt32 | 对应宽度 | 读写 | 大端。In 读 Q,Out 写 I |
| PDO | CopyInputsTo(dest, dest_size) | int | 只读 | 整区 Q → 缓冲。失败返 0 |
| PDO | CopyToOutputs(src, src_size) | int | 只写 | 短写 I。失败返 0 |
| PDO | InputsMapping<T>() | T | 只读 | Q 打包字节拷到平凡结构体(无 live 指针) |
uint8_t q0 = service.PDO().In[0].Content();
service.PDO().Out[0].Content(0x11);
service.PDO().Out[2].AsInt16(-2);
#pragma pack(push, 1)
struct QFrame { uint8_t b0; uint8_t b1; int16_t w; };
#pragma pack(pop)
QFrame frame = service.InputsMapping<QFrame>();
地址化读写
HSL 式地址,与 C# PnSAddress.Parse 对齐。字 / 双字偏移即字节偏移,不强制 2 / 4 对齐(IW3 合法)。
| 区域 | 地址 | 方向 |
|---|---|---|
| I | I0.0 / IB0 / IW2 / ID4 | 设备 → 控制器 |
| Q | Q0.0 / QB0 / QW2 / QD4 | 控制器 → 设备;只读 |
| M | M0.0 / MB0 / MW100 / MD0 | 内部存储,映射输入面 |
| DB | DB1.DBX0.0 / DB1.DBB2 / DB1.DBW0 / DB1.DBD4 | 槽位 1。编号 > 1 抛 PnSException |
| 类别 | 成员 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 地址 | ParseAddress(text) | PnSServiceAddress | 只读 | 静态解析 |
| IO | ReadBool / ReadInt16 / ReadInt32 | bool / int16_t / int32_t | 只读 | 位 / 字 / 双字。字双字大端 |
| IO | WriteBool / WriteInt16 / WriteInt32 | void | 只写 | 写 I / M / DB。写 Q 抛 PnSException |
service.WriteBool("I0.0", true);
service.WriteInt16("IW2", 0x1234);
bool start = service.ReadBool("Q0.0");
int16_t cmd = service.ReadInt16("QW0");
报警 / 标识 / 记录
报警 / 标识 / 记录走服务接口。过程数据不必走这些接口。
| 类别 | 成员 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 报警 | GetAlarms() | vector<PnSServiceAlarmItem> | 只读 | 活动报警。空列表不是失败 |
| 报警 | AcknowledgeAlarm(id) | void | 写 | 确认单条 |
| 报警 | AcknowledgeAllAlarms() | int | 写 | 确认全部,返回条数 |
| 报警 | SendProcessAlarm(slot, subslot, usi, data, len) | void | 写 | 发送过程报警 |
| 标识 | GetIm() | PnSServiceImInfo | 只读 | I&M 观测 |
| 记录 | GetRecords() | PnSServiceRecords | 只读 | 应用参数记录 |
异常与枚举
| 类别 | 类型 | 读写 | 说明 |
|---|---|---|---|
| 诊断 | PnSException | — | 失败抛出。code() 为错误码,what() 为消息 |
| 运行态 | PnSState | 只读 | Disconnected / Connecting / Connected / Running / Idle / ConfigError / Unknown |
| 运行态 | PnSRuntimeErrorCode | 只读 | Ok=0 / ErrInit=-1 / ErrCfg=-2 / ErrThread=-3 / ErrRunning=-4 / ErrPdi=-5 / Unknown=-10000 |
C++17,仅 Windows。运行前提:驱动已就绪(通常需管理员)。示例见 Darra_PnS_SDK/CPP/examples/basic_service.cpp。