Darra_Profinet_Slave 设计文档
本文件是 20 个并行执行 agent 的唯一契约。所有实现必须严格遵循本节定义的文件路径、命名、接口与数据格式。冲突时以本文为准。
- 产品:西门子 PROFINET IO Device (从站),基于 P-Net (rt-labs) 开源协议栈
- 实时等级:RT Class 1(常规周期报文,周期下限 1ms 起以实测为准),不支持 IRT / RTC3;不做顶级硬实时循环(无核隔离 / TSC 校准 / 24h soak 承诺)
- 简化对照:参考
Darra_EtherCAT_Master(SDK/驱动/安装包)与Darra_Software_PLC/System/Darra_PLC_Kernel/Profinet(DarraRT_Pnet.sys 驱动数据面参照)- 交付物:① 驱动(NDIS 协议,DarraRT_Pnet.sys) ② 服务(Windows Service,控制面:PNIO-CM / DCP / LLDP / Alarm / P-Net 状态机) ③ GUI(配置,输出 GSDML+XML) ④ SDK(C/C++/C#/Java/Python/Rust 6 语言) ⑤ 测试(基础模块,参照 ETH 测试项目) ⑥ 安装包(WinForms + 嵌入式 Payload.zip) ⑦ 前端 API 文档官网(VitePress)
- 约定:源码英文 PascalCase(产品代码);非产品/依赖/无代码目录中文(工具/脚本/安装/样例);所有注释中文;版本号单源
version/目录。
1. 顶层目录树(唯一权威)
Darra_Profinet_Slave/ (新仓根,当前为空)
├── README.md # 产品简介 + 快速开始
├── CMakeLists.txt # 版本单源: project(DarraProfinet VERSION 1.0.0)
├── version/
│ ├── core.txt # 1.0.0(与 CMake 同步)
│ ├── driver.txt # 1.0.0
│ ├── sdk.txt # 1.0.0
│ └── sync-versions.ps1 # 从 CMake 同步到各组件
├── Darra_Pnet_Kernel/ # ① 驱动 (WDK C, 仿 Darra_EtherCAT_Kernel/Windows/Eth)
│ ├── Windows/
│ │ ├── Pnet/
│ │ │ ├── DarraRT_Pnet.vcxproj
│ │ │ ├── DarraRT_Pnet.inf
│ │ │ ├── DarraRT_Pnet_Entry.c # DriverEntry + 设备/IOCTL
│ │ │ ├── DarraRT_Pnet_Instance.h
│ │ │ ├── DarraRT_Pnet_Internal.h
│ │ │ ├── DarraRT_Pnet_Nic.c # NDIS 协议绑定 + 收发包
│ │ │ ├── DarraRT_Pnet_Nic.h
│ │ │ ├── DarraRT_Pnet_Frame.c # 0x8892 周期帧编解码 (RT Class 1)
│ │ │ ├── DarraRT_Pnet_Frame.h
│ │ │ ├── DarraRT_Pnet_Iocr.c # IOCR 管理 (PPM/CPM, 已建 IOCR)
│ │ │ ├── DarraRT_Pnet_Iocr.h
│ │ │ ├── DarraRT_Pnet_Shared.c/.h # 用户态共享内存 (GlobalIO 风格)
│ │ │ ├── DarraRT_Pnet_Timer.c/.h # 周期定时器 (无顶级隔离, 常规 DPC)
│ │ │ ├── DarraRT_Pnet_Diagnostics.c/.h # ETW/计数/环形日志
│ │ │ ├── DarraRT_Pnet_Log.h
│ │ │ └── README.md # 仿 PLC Profinet/WDK/README.md 口径
│ │ └── scripts/
│ │ ├── build-driver.ps1 # Release x64 Clean/Build + sha256
│ │ └── install-pnet.ps1 # netcfg -l inf -c p -i DarraRT_Pnet (仅测试机)
│ └── Linux/ # P5 占位, 仅 README
│ └── README.md
├── Darra_Pnet_Core/ # ② P-Net 栈集成 + 服务核心 (C, 仿 Darra_EtherCAT_Drive)
│ ├── CMakeLists.txt
│ ├── ThirdParty/
│ │ └── p-net/ # ★ vendored 上游 rt-labs p-net (从 PLC 侧复制, 88 文件, GPLv3/商业双许可, 只读不改)
│ ├── main/
│ │ ├── core/
│ │ │ ├── pnet_wrapper.h # P-Net C API 统一封装
│ │ │ ├── pnet_stack.c/.h # pnet_init + 事件循环 (数据面/控制面分线)
│ │ │ ├── pnet_slot.c/.h # 槽位/子模块模型
│ │ │ ├── pnet_pdi.c/.h # PDI (过程数据接口) 读/写
│ │ │ ├── pnet_iocr.c/.h # IOCR 生命周期
│ │ │ ├── pnet_alarm.c/.h # 报警 API
│ │ │ ├── pnet_dcp.c/.h # DCP 以太网配置 (含 Set IP)
│ │ │ ├── pnet_snmp.c/.h # SNMP 通道 (最小)
│ │ │ ├── pnet_llmnr.c/.h # LLMNR (最小)
│ │ │ ├── pnet_config.c/.h # 加载 GUI 输出的 XML 配置
│ │ │ ├── pnet_gsdml.c/.h # GSDML 校验与解析 (只读)
│ │ │ ├── pnet_log.c/.h # 日志
│ │ │ ├── pnet_version.c/.h # 版本
│ │ │ └── platform/
│ │ │ ├── pnal_port.c # pnal_socket/eth/thread/timer/osal 移植 (win32)
│ │ │ └── pnal_port.h
│ │ └── win64/
│ │ ├── main.c # DllMain + P/Invoke 入口
│ │ ├── DarraPnet.def # 序数导出 (仿 Darra.Core.def)
│ │ ├── version.rc.in
│ │ └── scripts/gen-ordinals.ps1
│ └── tests/ # P-Net 核心纯 C 测试
│ ├── CMakeLists.txt
│ ├── test_pnet_core.c
│ ├── test_pnet_iocr.c
│ ├── test_pnet_slot.c
│ ├── test_pnet_config.c
│ ├── test_pnet_dcp.c
│ ├── test_pnet_cycle.c
│ └── test-build.ps1
├── Darra_Pnet_Service/ # ② 服务 (C#, .NET 8, Windows Service)
│ ├── Darra.Pnet.Service.csproj
│ ├── Program.cs # SCM 安装/启动 + 服务主循环
│ ├── PnetService.cs # ServiceBase 主实现
│ ├── Core/
│ │ ├── PnetNative.cs # P/Invoke -> DarraPnet.dll
│ │ ├── PnetRuntime.cs # 加载栈/启动/停止
│ │ ├── PnetStateService.cs # 运行态单一权威 (StateChanged 事件)
│ │ └── PnetConfigService.cs # 读取/应用 XML 配置
│ ├── Io/
│ │ ├── PnetProcessImage.cs # 过程映像 (输入/输出数据区)
│ │ └── PnetIoProvider.cs # 数据源抽象 (模块接口)
│ ├── Diagnostics/
│ │ ├── PnetAlarmService.cs # 报警汇聚 (Critical bypass)
│ │ ├── PnetTelemetry.cs # 周期/丢帧/状态上报
│ │ └── PnetLogger.cs
│ ├── Api/
│ │ ├── PnetApiServer.cs # Web API (端口 18840 固定, 由服务运行, 与 SDK 同层)
│ │ └── PnetApiModels.cs
│ ├── Install/
│ │ └── ServiceInstaller.cs
│ └── appsettings.json # 配置: 网卡/站点名/周期/XML 路径
├── Darra_Pnet_GUI/ # ③ GUI (WinForms .NET 8 + DevExpress)
│ ├── Darra.Pnet.GUI.csproj
│ ├── Program.cs
│ ├── MainForm.cs / MainForm.Designer.cs
│ ├── Views/
│ │ ├── DeviceView.cs # 设备/站点配置
│ │ ├── SlotView.cs # 槽位/子模块配置
│ │ ├── IoView.cs # 过程数据映射
│ │ ├── AlarmView.cs # 报警配置
│ │ └── XmlPreviewView.cs # 生成的 XML 预览
│ ├── Services/
│ │ ├── GsdmlWriter.cs # 输出 GSDML XML
│ │ ├── ConfigWriter.cs # 输出运行配置 XML
│ │ ├── ProjectStore.cs # 保存/加载配置工程
│ │ └── ValidationService.cs # 校验
│ └── Resources/
├── Darra_Pnet_SDK/ # ④ SDK 6 语言 (仿 Darra_EtherCAT_ClassLibrary)
│ ├── README.md
│ ├── CSharp/ # netstandard2.0, DarraPnet.dll (SDK), P/Invoke -> DarraPnet.dll (native)
│ │ ├── Darra.Pnet.SDK.csproj
│ │ ├── Pnet/
│ │ │ ├── PnetDevice.cs # 设备枚举/连接
│ │ │ ├── PnetSlave.cs # 从站控制
│ │ │ ├── PnetIo.cs # IO 数据读写
│ │ │ ├── PnetAlarm.cs
│ │ │ ├── PnetConfig.cs
│ │ │ ├── PnetDiag.cs
│ │ │ ├── Native/ # P/Invoke 声明 (DLL.cs 风格)
│ │ │ │ ├── PnetDll.cs
│ │ │ │ └── PnetEnums.cs
│ │ │ └── Utils/
│ │ └── version/
│ ├── C/ # C SDK: include/pnet.h + src + examples
│ │ ├── Darra_C_SDK.vcxproj
│ │ ├── include/pnet.h
│ │ ├── src/
│ │ └── examples/basic.c
│ ├── CPP/ # header-only include/pnet.hpp + examples
│ │ ├── Darra_CPP_SDK.vcxproj
│ │ ├── include/pnet.hpp
│ │ └── examples/basic.cpp
│ ├── Java/ # Maven src/com/darra/pnet/ + resources
│ │ ├── pom.xml
│ │ └── src/
│ ├── Python/ # darra_pnet 包 (ctypes 直连, 不做 Cython)
│ │ ├── pyproject.toml
│ │ └── darra_pnet/
│ └── Rust/ # Cargo src/
│ ├── Cargo.toml
│ └── src/
├── 测试项目/ # ⑤ 测试模块 (仿 Darra_EtherCAT_Master/测试项目)
│ ├── TEST_Driver/ # 驱动冒烟 (netcfg 绑定 + 设备打开 + 帧收发)
│ │ └── README.md
│ ├── TEST_SDK_CSharp/
│ ├── TEST_SDK_C/
│ ├── TEST_SDK_CPP/
│ ├── TEST_SDK_Java/
│ ├── TEST_SDK_Python/
│ ├── TEST_SDK_Rust/
│ ├── TEST_Config/ # GSDML/XML 配置生成与回读
│ ├── TEST_GUI/
│ └── TEST_Pnet_Sim/ # 西门子 PLC 模拟器对测 (基础)
├── 安装包/ # ⑥ 安装包 (WinForms .NET 8 + DevExpress, 仿 ETH 安装包)
│ ├── 安装包.csproj
│ ├── Form1.cs / Form1.Designer.cs
│ ├── Views/ # ucWelcome/ucAction/ucOptions/ucConfirm/ucInstall/ucFinish
│ ├── Services/
│ │ ├── InstallEngine.cs # 解压 Payload.zip -> C:\DARRA\Profinet_Slave
│ │ ├── DriverManager.cs # netcfg -l inf -c p -i DarraRT_Pnet
│ │ ├── UninstallService.cs
│ │ └── InstallerLogger.cs
│ └── Resources/
│ └── Payload.zip # 构建时生成
├── docs/ # ⑦ 前端 API 文档官网 (Docusaurus, 仿 Darra_CAD/云端/cad-doc 先例)
│ ├── package.json
│ ├── docusaurus.config.js
│ ├── sidebars.js
│ ├── docs/
│ │ ├── index.md
│ │ ├── guide/ # 快速开始/概念
│ │ ├── api/ # 6 语言 API 参考 (属性表: 类别/读写)
│ │ └── protocol/ # PROFINET 协议说明
│ └── deploy-docs.ps1 # 构建 + 部署到服务器
├── 工具/ # 构建/辅助脚本
│ ├── build-all.ps1 # 一键: core + driver + service + gui + sdk
│ └── gen-ordinals.ps1
├── 样例/ # 样例工程
│ └── basic-slave/ # 最简从站样例 (C#)
└── 发布链/ # symlink -> A:\c\Darra\Darra_发布专用仓库\Darra_Pnet_Publish
2. 协议分层与周期循环(用户 2026-08-07 确认)
2A. 授权系统(用户 2026-08-07 裁定: GUI 激活 + 证书与服务绑定)
授权链路: GUI 进行激活 → 激活成功后证书落盘 → Service 启动时加载证书并绑定校验(证书与服务绑定,未激活/证书失效 → Service 拒绝启动或降级)。仿 ETH 三层授权(Darra_EtherCAT_Master 授权/ + SDK Static/Authorization.cs + Darra_EtherCAT_SQL 后台),但 PROFINET 版验签走 HTTP 直连后台(核心验签留待后续 wave)。
- ① 授权后台(
授权后台/):Cloudflare Worker + D1 三表(pnet_personal_codes/pnet_enterprise_codes/pnet_enterprise_devices),API:POST /api/v1/license/activate(激活码 + 设备指纹 → 签发证书)、GET /api/v1/license/status、POST /api/v1/license/deactivate、管理 API(企业码签发/吊销)。证书 Signature = HMAC-SHA256(secret 占位待换)。 - ② SDK 授权类(
Darra_Pnet_SDK/CSharp/Pnet/Static/):PnetAuthorization(LicenseStatus 8 态 + Activate + Deactivate)+PnetDeviceInfoHelper(设备指纹:机器名/MAC/磁盘/产品密钥)+PnetLicenseCertificate(证书模型)。 - ③ GUI 激活(
Darra_Pnet_GUI/授权/):授权管理器(已激活判断)+激活窗体(激活码输入 + 激活按钮 + 状态显示)。激活成功后证书写入注册表(HKLM\SOFTWARE\Darra\Profinet\License,用户 2026-08-07 修订:不落文件,防篡改)。 - ④ Service 证书绑定(
Darra_Pnet_Service/License/):PnetLicenseService启动时单独从注册表加载证书 → 校验(签名 HMAC + 机器码绑定 + 状态)→ 绑定 Service 运行(未激活/证书失效 → 日志 Error + 拒绝启动从站)。授权不对外开放(用户 2026-08-07 修订:Web API 不提供授权端点,授权仅 GUI 注册 + Service 内部验证)。``` L4 应用层 过程数据消费方 (IO 映射 / 用户逻辑) L3 服务层 PnetStateService / PnetProcessImage (单一权威 + epoch 快照) L2 协议栈 p-net: PNIO-CM 状态机 + DCP + LLDP + Alarm + IOCR + 周期循环 L1 数据链路 DarraRT_Pnet.sys (NDIS 收 0x8892 帧 → 共享内存, 预分配发帧) L0 物理 以太网 100M 全双工 (DAP 双口)
- **实时/非实时分线**:非实时 = DCP / LLDP / PNIO-CM / Alarm(服务控制面);实时(RT Class 1)= 仅周期数据帧(EtherType 0x8892,周期下限以实测为准)。
- **★ 周期循环是数据面心脏(必须)**:IO Device 数据面是双向周期协议——
- **CPM**(控制器→设备):控制器每周期发输出帧 → 驱动收 → 共享内存 → 应用读。
- **PPM**(设备→控制器):设备**必须主动每周期发输入帧** → 驱动组帧发送;不发 = 控制器报 IO 故障断连。
- `pnet_handle_periodic` + 周期循环驱动这两个方向。
### 实时性增强(简化级内拉满,不承诺 µs 级)
1. **周期线程高优先级**:Realtime 优先级类 + TimeCritical 线程优先级(服务 LocalSystem 有 SeIncreaseBasePriorityPrivilege)。
2. **驱动层零拷贝**:RX 帧直接进共享内存,用户态只读 epoch 快照;TX 预分配 NBL/MDL,周期路径零分配。
3. **周期线程零分配 + 零锁**:用户态池化缓冲;过程映像 epoch 快照无锁读;周期路径无锁竞争。
4. **QPC 高精度定时**:QueryPerformanceCounter 节拍,Stopwatch 节奏不追赶。
5. **抖动预算**:1ms 周期(常规 KTIMER 相对到期,默认系统 tick ~15.6ms 下不可达,下限以实测为准),软件循环目标 < 500µs 抖动,如实标注不承诺硬实时。
### 2.1 驱动(Agent A1-A2)— `Darra_Pnet_Kernel/Windows/Pnet/`
- NDIS 协议驱动 `DarraRT_Pnet`,设备 `\\.\DarraRT_Pnet`,INF 的 `RequireExclusiveBinding=1`。
- **数据面(驱动,生产唯一路径)**:已建立 IOCR 的周期 PPM/CPM 帧收发、过程映像读写、看门狗;0x8892/0x88CC 帧环。
- **控制面(服务)**:PNIO-CM、DCP、LLDP、Alarm、SNMP、P-Net 状态机(与 PLC Profinet 参照一致的分工)。
- 热路径:TX NBL/MDL/帧缓冲预分配,周期路径不分配内存;**不做**核隔离/TSC 校准/72h soak。
- 签名:`signing/` 目录(测试证书 + sha256 校验,不碰 MS 副签链)。
### 2.1A 数据面驱动化(用户 2026-08-08 裁定: 删 Npcap, 数据面全走驱动, 对齐 ETH)
> **背景**:原 `pnal_port.c` 的 `pnal_eth_*` 用 Npcap(用户态 pcap)收发 0x8892/0x88CC。用户裁定 **Npcap 全部删除, 不使用软件层**, p-net 数据面改为经 **`\\.\DarraRT_Pnet` 驱动**收发 —— 对齐 ETH 的 wdk_bridge(IOCTL)+ GlobalIO(命名 Section)模式。控制面(UDP/DCP 等)仍走 Winsock(pnal_udp_* 保留)。
**数据面链路(唯一)**:
物理网卡 → DarraRT_Pnet.sys (NDIS RX) → 0x8892/0x88CC 分类 → CPM 写共享内存输入区 / 控制帧入环 → pnal_eth_recv(驱动路径): 服务从驱动收帧喂 p-net p-net 发帧 → pnal_eth_send(驱动路径): IOCTL_PNET_SEND_CONTROL / 共享内存输出区 → 驱动组帧 PPM/控制帧发送
**共享内存契约(对齐 ETH GlobalIO, 替换旧"内核 VA 直给用户态")**:
1. **命名 Section**:驱动创建 `\Device\DarraRT_Pnet_GlobalIO`(内核命名空间, M3 防低权用户抢占;`ZwCreateSection` + `SEC_COMMIT`),服务经 `NtOpenSection` + `NtMapViewOfSection` 映射(**PAGE_READWRITE 可写**:输入区只读、输出区可写, SDDL + 长度 clamp 兜底)。SDDL 限 SYSTEM/Administrators。
2. **服务映射方式**:`pnal_eth_handle` 内持有映射视图;驱动**不再**经 `IOCTL_PNET_MAP_SHARED_MEMORY` 返回内核 VA(该裸地址 = P0 安全漏洞, 必须移除)。
3. **长度安全**:所有从共享内存读取"长度类"字段用作 `RtlCopyMemory` 长度前, 必须 clamp 到固定契约上限(对齐 ETH `DARRT_GIO_CLAMP_*` 教训, 防用户态写坏长度 → 内核 OOB 读)。
**驱动改造点(对齐 ETH, P1 内做)**:
| # | 改造 | 说明 |
|---|---|---|
| D1 | RX 锁粒度 | 全局 `RxLock` 单锁 → 每 IOCR 槽位锁 + 只锁不变量(帧 ID 匹配), 避免多核收包串行 |
| D2 | MDL 长度恢复顺序 | `DarraPnetNicSend`: 先 `InFlight` 判定成功, 再 `NdisAdjustMdlLength`, 避免中途失败留 0 长度 |
| D3 | 控制环入队 Ready 判断 | `DarraPnetEnqueueControl`: 写前判 `slot->Ready==0`(与 dequeue 对称), 防对端撕裂帧 |
| D4 | 共享内存 Section 化 | 移除内核 VA 直给, 命名 Section + 只读映射(见上) |
| D5 | 看门狗配置落地 | `DeviceConfig.WatchdogUs` 校验并用于超时判定(现仅校验未使用) |
**Npcap 删除范围(全仓)**:
- `pnal_port.c`: `pcap_*`/`Npcap`/`npcap`/`pnal_pcap_*` 全部删除(函数指针表 / try_load / pkthdr / rx_thread / handle 字段),`pnal_eth_*` 重写为驱动路径。
- 依赖 `pnal_eth_*` 的 vendored p-net(`pf_eth.c` 等)不改(上游契约),由 `pnal_eth_*` 实现提供。
- 安装包 / GUI / 服务 / 文档: 删除 Npcap 安装提示与依赖。
- 判据: 全仓 grep `pcap|Npcap|npcap|wpcap` = 0 命中(除历史注释/文档说明)。
### 2.2 P-Net 核心 + 服务(Agent B1-B4 + C1-C3)
- **`Darra_Pnet_Core`**:C 静态库/动态库,封装 **vendored 上游 p-net**(`ThirdParty/p-net/`,Profinet v2.43,Conformance Class A/B,RT Class 1,88 文件只读)。`main/core/platform/pnal_port.c` 提供 **win32 pnal 移植**(socket/eth/thread/timer/osal);**eth 层 = 驱动路径(删 Npcap, 见 §2.1A)**,udp 层 = Winsock。核心对外序数导出(仿 Darra.Core.def)。
- **`Darra_Pnet_Service`**:.NET 8 Windows Service。加载 `DarraPnet.dll`,运行控制面(PNIO-CM / DCP / LLDP / Alarm / SNMP / P-Net 状态机)+ 数据面分发;`PnetStateService` 是运行态单一权威;`PnetProcessImage` 是过程映像唯一数据源。**Web API(HTTP 18840)由服务运行,与 SDK 同层**(用户 2026-08-07 裁定)——SDK 与 Web API 都是访问从站运行时状态的同一层接口,服务是唯一的运行宿主。
- **简化**:周期下限 1ms 起以实测为准(可配),普通线程,DCP 支持 IP 配置;无核隔离/TSC 校准/72h soak。GUI 只负责配置参数 + 导出 XML。
### 2.3 GUI(Agent D1-D3)— 输出 GSDML + XML
- WinForms .NET 8 + DevExpress(版本与 ETH GUI 对齐 25.2 或 26.1,以 NuGet 可用为准)。
- 功能:设备/站点名/IP/槽位子模块/过程数据映射/报警配置;输出 **GSDML XML**(给西门子 TIA 导入)+ **运行配置 XML**(给 Service 加载)。
- R78 工程师文案铁律:禁 "请输入" 等教程式废话;DevExpress 控件优先。
### 2.4 SDK 6 语言(Agent E1-E6)— 仿 Darra_EtherCAT_ClassLibrary
| 语言 | 布局 | 绑定方式 |
|---|---|---|
| C# | `CSharp/Pnet/*.cs` + `Native/PnetDll.cs` | P/Invoke 序数导出(仿 DLL.cs 526 序数风格,集中声明) |
| C | `include/pnet.h` + `src/` | 直接链接 `DarraPnet.dll`(或静态库) |
| C++ | header-only `include/pnet.hpp` | 包装 C API |
| Java | Maven `src/com/darra/pnet/` + resources | JNA 或 JNI(以 ETH Java SDK 方式对齐) |
| Python | `darra_pnet/` 包 | ctypes 直连(简化,不做 Cython) |
| Rust | Cargo `src/` | FFI 包装 C API |
- 统一 API 面:Device / Slave / IO / Alarm / Config / Diag。
- SDK 文档(官网 api/)属性表必须含 **类别/读写** 列(ETH SDK 规范继承)。
### 2.5 测试模块(Agent F1-F3)— 基础测试
- `TEST_Driver`:驱动冒烟(设备打开/IOCTL/帧收发)—— 测试机。
- `TEST_SDK_*` 6 语言:连接 Service 冒烟 + IO 读写。
- `TEST_Config`:配置生成 → GSDML/XML 输出 → 回读校验。
- `TEST_GUI`:界面冒烟。
- `TEST_Pnet_Sim`:西门子 PLC 模拟器对测(基础)。
- **不做**:72h soak / 核隔离 / 硬实时判定。
### 2.6 安装包(Agent G1-G2)— 仿 ETH `安装包/`
- WinForms .NET 8 + DevExpress,嵌入式 `Payload.zip` → 解压到 `C:\DARRA\Profinet_Slave`。
- `DriverManager.cs`:netcfg 装 `DarraRT_Pnet`;服务安装 `Darra.Pnet.Service`。
- 发布链 symlink 目标 `Darra_发布专用仓库/Darra_Pnet_Publish`(若不存在,安装包独立可构建)。
### 2.7 官网(Agent H1)— VitePress API 文档
- `docs/` 目录,VitePress 构建,含 6 语言 API 参考 + 快速开始 + 协议说明。
- 部署脚本 `deploy-docs.ps1`(可选部署到服务器)。
### 2.8 服务接口分类契约(用户 2026-08-08 裁定: 服务/驱动紧密绑定 + GUI 柔性绑定)
> **背景裁定**: ① **服务与驱动必须紧密绑定** —— 服务是驱动的唯一运行宿主, 服务启动时探测驱动, 驱动不在 → 服务拒绝启动从站(数据面驱动化 §2.1A 已落地)。② **加密/认证授权暂缓** —— 当前不做接口鉴权/加密(仅本机回环 + 授权证书门保留), 后续 wave 再加。③ **GUI 必须柔性绑定** —— GUI 不直接连驱动, 只经**服务对外接口**操作从站。
**服务接口分 2 类**(HTTP 18840, 均为服务运行):
| 类 | 端点 | 本质 | 消费者 |
|---|---|---|---|
| **配置接口**(Config API) | `POST /api/config/reload` | 重载运行配置 XML(ConfigWriter 输出), 走 PnetConfigService 口径, 结果如实返回 | GUI(柔性绑定: 导出 XML → 调 reload → 服务应用) |
| **使用接口**(Use API, **服务的本质 = ETH 式 DLL**) | `GET /api/status` / `GET /api/io` / `POST /api/io` / `GET /api/alarms` / `POST /api/start` / `POST /api/stop` | 与 SDK 完全同层同契约: 启停从站 + 读写输入输出区 + 状态/报警 —— 即"远程化的 ETH DarraEtherCAT DLL" | SDK 6 语言(服务模式主路径)、GUI(状态/IO 观测)、Web 工具 |
**绑定语义**:
- **服务 ↔ 驱动**: 紧密绑定(硬依赖)。服务启动 `Probe()` 驱动 → 不在 → 拒绝启动从站(如实日志)。驱动共享内存/IOCTL 是服务数据面唯一路径, 无回退。
- **GUI ↔ 服务**: 柔性绑定。GUI 不依赖驱动/服务运行即可工作(纯配置 + 导出 XML); 导出后经配置接口通知服务; 状态/IO 观测经使用接口(服务不在 → GUI 状态栏"服务离线", 配置功能不受影响)。
- **SDK ↔ 服务**: 使用接口主路径(服务模式 HTTP 18840), native 直连(DarraPnet.dll)保留为备选(进程内从站, 不经服务)。
**暂缓项(如实, 后续 wave)**: 接口加密(TLS)/认证授权(令牌/签名)暂不做; 当前仅本机回环默认放行(`Api:ApiKey` 未配置时), 授权证书门(GUI 激活 → 注册表 → Service 校验)保留。对外暴露时须先补鉴权。
## 3. 接口契约(跨 agent 硬依赖)
| 契约 | 定义文件 | 生产方 | 消费方 |
|---|---|---|---|
| 驱动 IOCTL 集 | `DarraRT_Pnet_Entry.c` + `DarraRT_Pnet_Internal.h` | A1/A2 | C1-C4 (Service) |
| 共享内存布局 | `DarraRT_Pnet_Shared.h` | A2 | C1-C4 (Service) |
| P-Net C API 封装 | `pnet_wrapper.h` + `ThirdParty/p-net/include/pnet_api.h` | B1/B2 | C1-C3 (Service) |
| pnal win32 移植 | `main/core/platform/pnal_port.c`(eth=驱动路径, udp=Winsock) | B4 | B1 (编译进核心) |
| 配置 XML schema | `pnet_config.c/.h` + `ConfigWriter.cs` | B3 + D2 | C1-C4 (Service 加载) |
| GSDML 输出格式 | `GsdmlWriter.cs` | D2 | 外部 TIA |
| native DLL 导出表 | `DarraPnet.def` | B4 | E1-E6 (SDK) |
| SDK 统一 API 面 | `PnetDevice/PnetSlave/PnetIo/PnetAlarm/PnetConfig/PnetDiag` | E1 | E2-E6 |
| 服务安装契约 | `ServiceInstaller.cs` (sc create DarraPnetService) | C3 | 安装包 G1 |
| 安装包 Payload 布局 | `InstallEngine.cs` 常量 | G1/G2 | 发布链 |
> 契约冲突解决:**主线程(curator)是唯一裁决者**。任何 agent 发现契约与设计不符 → 报告主线程,不自行改契约。
## 4. 文件域分配表(20 agent)
> 每个 agent 严格限定于自己文件域;**写操作(Edit/Write)禁止越域**;查询(Read/Grep)可跨域。各域两两不相交。
| # | Agent | 域 | 允许写路径 | 验证门 |
|---|---|---|---|---|
| A1 | 驱动全域 | 驱动 | `Darra_Pnet_Kernel/Windows/Pnet/**` + `Darra_Pnet_Kernel/Windows/scripts/**` | 编译 0E + README 口径 |
| B1 | 核心 栈集成 | 核心 | `Darra_Pnet_Core/main/core/pnet_{wrapper,stack}.c/.h` + `Darra_Pnet_Core/CMakeLists.txt` + `Darra_Pnet_Core/tests/CMakeLists.txt` | C 测试 PASS |
| B2 | 核心 槽/PDI/IOCR/Alarm | 核心 | `Darra_Pnet_Core/main/core/pnet_{slot,pdi,iocr,alarm}.*` + `Darra_Pnet_Core/tests/test_pnet_{iocr,slot,cycle}.c` | C 测试 PASS |
| B3 | 核心 配置/GSDML/DCP | 核心 | `Darra_Pnet_Core/main/core/pnet_{config,gsdml,dcp,snmp,llmnr}.*` + `Darra_Pnet_Core/tests/test_pnet_{config,dcp}.c` | C 测试 PASS |
| B4 | 核心 win64 导出+平台(eth 驱动化) | 核心 | `Darra_Pnet_Core/main/win64/**` + `Darra_Pnet_Core/main/core/pnet_{log,version}.*` + `Darra_Pnet_Core/main/core/platform/pnal_port.*` + `Darra_Pnet_Core/tests/test_pnet_core.c` | 导出表验证 + 驱动路径编译 |
| C1 | 服务 宿主+核心 | 服务 | `Darra_Pnet_Service/{Program.cs,PnetService.cs,appsettings.json,Darra.Pnet.Service.csproj}` + `Darra_Pnet_Service/Core/**` | dotnet build 0E |
| C2 | 服务 IO+诊断 | 服务 | `Darra_Pnet_Service/{Io,Diagnostics}/**` | dotnet build 0E |
| C3 | 服务 API+安装 | 服务 | `Darra_Pnet_Service/{Api,Install}/**` | dotnet build 0E |
| D1 | GUI 工程+主窗体 | GUI | `Darra_Pnet_GUI/{*.csproj,Program.cs,MainForm.*}` | dotnet build 0E |
| D2 | GUI 配置+输出 | GUI | `Darra_Pnet_GUI/Views/**` + `Darra_Pnet_GUI/Services/{GsdmlWriter,ConfigWriter,ProjectStore}.cs` | dotnet build 0E + 生成 XML 校验 |
| D3 | GUI 校验+资源 | GUI | `Darra_Pnet_GUI/Services/ValidationService.cs` + `Darra_Pnet_GUI/Resources/**` | dotnet build 0E |
| E1 | SDK C# | SDK | `Darra_Pnet_SDK/CSharp/**` | dotnet build 0E |
| E2 | SDK C | SDK | `Darra_Pnet_SDK/C/**` | C 编译 0E |
| E3 | SDK C++ | SDK | `Darra_Pnet_SDK/CPP/**` | C++ 编译 0E |
| E4 | SDK Java | SDK | `Darra_Pnet_SDK/Java/**` | javac/mvn 0E |
| E5 | SDK Python | SDK | `Darra_Pnet_SDK/Python/**` | py_compile + 冒烟 |
| E6 | SDK Rust | SDK | `Darra_Pnet_SDK/Rust/**` | cargo check 0E |
| F1 | 测试全域 | 测试 | `测试项目/**` | 冒烟脚本可跑 |
| G1 | 安装包全域 | 安装包 | `安装包/**` | dotnet build 0E |
| H1 | 官网 Docusaurus | 官网 | `docs/**` | docusaurus build 0E |
> 共享文件(契约头文件 `pnet_wrapper.h` 等)由**主线程指定单一 agent 生产**(B1),其他 agent 只读消费;冲突时主线程裁决。
> **20 个 agent 并行 = 大 wave → 必须先打 backup tag(见 §6)。**
## 5. 实现铁律(所有 agent 必须遵守)
1. **R295U 防回档**:禁止 `git reset --hard` / `git checkout HEAD~` / `git push --force` / `--no-verify`。
2. **文件域隔离**:只写自己的域;越界 = 一票否决。每 agent 完成后报告"改了哪些文件 + 做了什么",主线程统一 commit。
3. **不整文件重写**:只用局部编辑;新文件可 Write。
4. **注释中文**:所有注释用中文,UTF-8 编码。
5. **编码风格**:C# PascalCase;C snake_case;常量全大写。
6. **禁止 facade**:不做"退场 / stub / TODO 占位 / 假实现";能力缺口如实报告主线程。
7. **编译验证**:写代码的 agent 必须能自证编译通过(C# 用 dotnet build;native 用对应工具链);不能编译的环境 → 如实报告,主线程安排验证。
8. **不动既有仓**:`Darra_EtherCAT_Master` / `Darra_Software_PLC` / `Darra_发布专用仓库` 一律只读引用,不 Edit/Write。
9. **版本**:统一 1.0.0,只写 `version/` 目录;不自行加版本文件。
10. **dev 机只编译**:不安装驱动 / 不启 Service / 不跑运行时(测试机才跑)。
11. **PPT0-PLAN-FORMAT-GUARD**:不新建 `*_PLAN.md` / `*_VERIFICATION.md` / `*_EXECUTION_STATUS.md` / `CONSOLIDATED_*.md`。
12. **GSDML 正确性**:输出必须通过 XML 格式校验(最小:well-formed + 关键节点存在)。
## 6. 执行编排(curator 主线程)
1. **设计文档落档**(本文件)→ 主线程 commit。
2. **backup tag**:`git tag backup-<timestamp> HEAD`(R295U #6 大 wave 铁律)。
3. **派 20 agent 并行**(上表),每个 prompt 含:文件域清单 + 验证门 + 本设计文档路径。
4. **完成一个收一个**:agent 报告 → 主线程验证(grep 判据 + 编译 0E)→ `git add <该 agent 文件域>` + commit(中文,含文件列表)。
5. **全完成后汇总**:交付物清单 + 编译状态 + 未决项报告用户。
6. **push 说明**:当前仓库无 remote,只本地 commit;用户后续配置 remote 后由用户推送。