C++ SDK 概述
DarraEtherCAT C++ SDK 是 Header-Only 的现代 C++17 封装库, 命名空间 darra::ethercat。提供 RAII 生命周期管理、移动语义、std::function 回调、std::optional 返回、异常处理, 支持主站与从站之间的高速实时通信。
本文档对应 SDK 2.7.x。该版本新增 SDK 异步隔离层与 RT 进程隔离 API。早前 2.5.x 引入的 MDP 模块化设备进 OP 自动编排、per-group WKC 访问器、从站邮箱健康度可观测等能力仍然保留, 详见各章节标注的"2.5.x 新增 / 接口变更"。
与 C API 的对比
| 特性 | C API | C++ SDK |
|---|---|---|
| 资源管理 | 手动 Dispose / Close | RAII 析构自动释放 |
| 类型安全 | void* 句柄 | 强类型类 |
| 回调机制 | 函数指针 | std::function + Lambda |
| 错误处理 | 返回值检查 | 异常 (DarraException) |
| 字符串 | char* + 手动释放 | std::string 自动管理 |
| 数据容器 | 原始指针 + 长度 | std::vector / std::optional |
| 从站访问 | API(handle, index, ...) | master.GetSlave(1).GetCoE().SDORead(...) |
| 拷贝语义 | 无限制 | 禁止拷贝, 仅支持移动 |
#include "ethercat.hpp"
using namespace darra::ethercat;
int main() {
EtherCATMaster master(dll);
master.SetNetwork("\\Device\\NPF_{...}");
master.Build();
master.SetState(EcState::OP);
master.Start();
master.Events().SetPDOCallbackSync([&](uint16_t mi) {
auto& s = master.GetSlave(1);
auto* input = s.InputDataPointer();
auto* output = s.OutputDataPointer();
});
// 离开作用域, 析构自动 Stop + Dispose
}
安装
从 下载页面 获取 SDK 包, 包含 C++ 头文件与运行时库。
包含头文件:
#include "ethercat.hpp"
CMake 配置:
add_executable(my_app main.cpp)
target_compile_features(my_app PRIVATE cxx_std_17)
target_include_directories(my_app PRIVATE ${SDK_PATH}/include)
系统要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 7+ (推荐 Windows 10/11) / Linux |
| 编译器 | MSVC 2019+, GCC 7+, Clang 10+ |
| C++ 标准 | C++17 或更高 |
| 网络适配器 | 常规以太网网卡 |
| 权限 | 管理员 / root 权限 |
安装 DarraRT 驱动
DarraRT 驱动提供微秒级实时性能, 完全免费。详见 下载页面。
快速开始
- 打开 Darra 配置工具, 扫描 EtherCAT 网络
- 配置从站参数 (PDO 映射、DC 设置等)
- 导出 DENI 配置文件
- 在代码中加载 DENI 文件初始化主站
#include <iostream>
#include <darra/ethercat.hpp>
int main() {
// ★ 推荐方式: 使用 DENI 文件 (Darra 配置工具一键导出)
darra::dll_t dll;
darra::EtherCATMaster master(dll); // 构造需传 dll_t&
master.SetENI("C:\\EtherCAT\\MyProject.deni")
.Build(); // SetENI 后必须 Build()
master.SetState(darra::EcState::OP);
auto& slave = master.GetSlave(1);
auto data = slave.GetCoE().SDORead(0x6041, 0x00); // GetCoE(), 不是 coe()
if (data.size() >= 2) {
uint16_t status = data[0] | (data[1] << 8);
std::cout << "Statusword=0x" << std::hex << status << "\n";
}
return 0; // RAII 自动析构
}
备选方式: 自动搜索网卡 (无 DENI 时)
不使用 DENI 时, 用 GetNetworkInfo() 自动扫描所有网卡, 取有从站的那张:
#include <iostream>
#include <algorithm>
#include <darra/ethercat.hpp>
int main() {
dll_t dll;
// 扫所有 NIC 并探测从站数 (耗时 ~500ms-1.5s)
auto nets = darra::ethercat::GetAvailableNetworks(dll, /*isRedundant=*/false,
/*needSlaveCount=*/true);
// 选有从站的 NIC (AvailableNetworkInfo.slaveCount)
auto it = std::find_if(nets.begin(), nets.end(),
[](const auto& n){ return n.slaveCount > 0; });
if (it == nets.end()) {
std::cerr << "未发现 EtherCAT 网络\n";
return -1;
}
std::cout << "找到: " << it->desc << " (从站 " << it->slaveCount << " 台)\n";
darra::EtherCATMaster master(dll);
master.SetNetwork(it->name);
master.Build();
master.SetState(darra::EcState::OP);
return 0;
}
- DENI — 生产环境, 一行加载 ESI/PDO/DC 全套参数, 推荐.
- 自动搜索 — 演示 / 工具类应用 / 不需要预配置启动参数的场景.
功能概览
| 功能 | C++ 类 | 说明 |
|---|---|---|
| 主站管理 | EtherCATMaster | Builder 模式初始化、状态机、配置、RAII 生命周期 |
| 从站访问 | Slave | 80+ PascalCase 属性方法、状态、看门狗 |
| PDO 读写 | SlavePDO | 零拷贝 PDO 数据指针访问 |
| CoE | CoE | SDORead / SDOWrite 及类型化版本 |
| CiA 401 | CiA401 | 通用 I/O 协议 |
| CiA 402 | CiA402 | 伺服驱动器协议, Enable / Disable / FaultReset |
| SoE | SoE | SERCOS 参数读写及类型化版本 |
| FoE | FoE | 文件传输 (Download / Upload) |
| EoE | EoE | 以太网隧道 (IP / MAC 配置、帧收发) |
| AoE | AoE | ADS 协议 (ReadWrite / SendCommand) |
| VoE | VoE | 厂商协议 (Send / Receive / SendAndReceive) |
| FSoE | FSoE | 功能安全 (Initialize / ReadSafeInput / WriteSafeOutput) |
| MDP | MDP | 模块化设备配置, 进 OP 自动编排 (ETG.5001) |
| 诊断 | Diagnostics | 通信统计、PDO 丢帧、冗余状态、per-group WKC |
| 配置 | MasterConfig | 周期时间、看门狗、VLAN、帧优先级等 |
核心设计理念
RAII 自动资源管理 — EtherCATMaster 在析构时自动调用 Stop() + Dispose(), 无需手动管理生命周期。
延迟初始化 — 从站协议子对象 (CoE / SoE / FoE 等) 采用延迟创建模式, 首次访问时才分配:
auto& s = master.GetSlave(1);
s.GetCoE(); // 首次调用, 创建 CoE 对象
s.GetCoE(); // 后续调用, 返回已缓存的对象
移动语义 — EtherCATMaster 支持移动但禁止拷贝, 确保资源唯一所有权:
EtherCATMaster master1(dll);
EtherCATMaster master2 = std::move(master1);
// master1 现在无效, master2 拥有资源
多实例支持 — 每个 EtherCATMaster 管理独立的 EtherCAT 总线, 使用不同网卡:
EtherCATMaster master1(dll);
master1.SetNetwork("adapter1");
master1.Build();
EtherCATMaster master2(dll);
master2.SetNetwork("adapter2");
master2.Build();
- 每个实例必须使用不同的网卡 — 同一网卡不能被多个实例同时使用
- CPU 核心自动分配 — 每个实例自动占用不同的 CPU 核心
C++ 特有语法糖
除标准 API 外, C++ SDK 在 darra::sugar 命名空间提供一组利用 C++ 语言特性的可选扩展. 包含 <sugar/sugar.hpp> 一行引入全部. 详见 C++ 特有语法糖 — 包含 ScopedStart/State/LockIO RAII 守护 / SlavesView STL 友好迭代 / sugar::slave_opt(master, i) 返回 std::optional<std::reference_wrapper<Slave>> / master[1] operator overload / auto [vendor, product, rev] = darra::sugar::identity_tuple(slave) structured binding / std::string_view 零拷贝字符串参数 / StartAsync/StopAsync std::future 异步 / C++20 concepts (条件编译). 这些是可选的, 不影响标准 API 使用.
自动健康检查 · Auto health checks
master.Build() 时自动跑, 不匹配 → SDK 日志 Warning:
- 驱动版本比对 — SDK 运行时查询已安装的实时驱动内核版本, 跟 SDK MAJOR.MINOR 比, 不匹配给出提示
- RT 核隔离 — 后台检查 RT 核隔离配置是否就绪, 缺失提示重装 SDK
错误码本地化 · Error localization
AL Status 描述双语. SDK 默认英文, 中文专用接口给 UI:
using namespace darra::ethercat::statics;
std::string en = al_status_description(code); // English
auto drv = DriverVersionHelper::get(dll); // 内核驱动版本 (需传 dll_t&)
版本兼容
- 同 MAJOR.MINOR 内 PATCH 互相兼容 (例 2.1.0 ↔ 2.1.5), 包管理器升级即可, 不需重装驱动
- MAJOR / MINOR 变化 → 必须重装配套的驱动安装包, 否则会报版本兼容错误