1
驱动概览
这是什么

RCP 驱动用于接入支持 RCP 协议的 PLC(可编程逻辑控制器)。RCP 是一种厂商 PLC 远程通信协议,通过它平台可以读取/写入 PLC 的追踪变量(Trace Variables)——即 PLC 程序中定义的内部变量。

与 Modbus 直接读写「寄存器地址」不同,RCP 读写的是按变量名/索引组织的逻辑变量,更贴近 PLC 工程师的工作方式。

依赖原生库

RCP 驱动通过 JNA(Java Native Access)调用原生动态库(Windows Rcp.dll / Linux Rcp.so)。部署时必须保证对应平台的原生库存在于运行环境,否则驱动无法初始化。

关键事实
属性值说明
驱动名称rcpSPI 注册名
版本V 1.2.0getDriverVersion()
接入模式EMBEDDED内嵌于平台主应用
协议库原生 Rcp.dll / Rcp.so(JNA)平台自动加载对应 OS 的库
通信模型轮询(后台线程批读)变更检测后推送
Web 接口1 个ZIP 导入 PLC 工程
定时任务1 个每 4 秒心跳 + 读触发
2
RCP 与 PLC 变量追踪
JNA 调用链

驱动通过 JNA 定义 RcpLibrary 接口,映射原生库的一组 C 函数,由 RcpConnector 调用。整个生命周期由原生库管理:

flowchart TB P[" 平台
RcpConnector"] J["JNA 接口
RcpLibrary"] LIB[" 原生库
Rcp.dll / Rcp.so"] PLC[" PLC 设备"] P -->|"Java 调用"| J J -->|"JNI 桥接"| LIB LIB <-->|"RCP 协议 TCP"| PLC style P fill:#e8f0fe,stroke:#007aff,stroke-width:2px,color:#1c1c1e style LIB fill:#fff4e8,stroke:#ff9500,stroke-width:2px,color:#1c1c1e style PLC fill:#f0f0f5,stroke:#5856d6,color:#1c1c1e
原生库函数
JNA 函数职责
Create创建连接句柄
Open打开与 PLC 的连接通道
Connect建立 TCP 连接(Target 结构)
GetPlcStatus查询 PLC 运行状态
GetTraceVariables批量读取追踪变量
WriteTraceVariables批量写入追踪变量
Free释放连接句柄

连接目标由 Target 结构定义:FromPort.DeviceId=0x6000,ToPort.Ip/Port/DeviceId 指向 PLC。

3
PLC 数据类型
20 种 SourceType

RCP 支持完整的 PLC(IEC 61131-3)数据类型集合,由 SourceType 枚举定义,采用小端序:

类别类型
整数(有符号)SINT, INT, DINT, LINT
整数(无符号)USINT, UINT, UDINT, ULINT
布尔/字节/字BOOL, BYTE, WORD, DWORD, LWORD
浮点REAL, LREAL
字符串STRING(128)
时间相关TIME, DATE, TOD, DT
其他LOGLEVEL
值域校验

RCP 与 SECP 各有独立的 SourceTypeLimit,定义每种类型的合法取值范围,用于写操作的值校验。

4
整体架构
组件协作
flowchart TB subgraph 接入 A["RcpDriverAccess"] end subgraph 管理 M["RcpConnectorManager
实例管理 · 校验 · 写分发"] C["RcpConnector
每实例一个 · JNA 调用"] end subgraph 接口/任务 API["ImportDriverInstanceApi
ZIP 导入"] T["AliveTask
cron 0/4 * * * * ?"] end A --> M M --> C C -->|"GetTraceVariables"| PLC["PLC"] API --> M T -->|"心跳+读触发"| M style A fill:#e8f0fe,stroke:#007aff,stroke-width:2px,color:#1c1c1e style M fill:#f0f0f5,stroke:#5856d6,stroke-width:2px,color:#1c1c1e style C fill:#fff4e8,stroke:#ff9500,color:#1c1c1e
5
数据采集流程
批读 + 变更检测

每个在线实例有一个独立的后台读线程(readRcpPointsValueTask),循环调用 GetTraceVariables 批量读取所有变量。读取采用变更检测——只有值真正变化时才推送到平台,避免重复上报。

sequenceDiagram participant T as AliveTask (每4秒) participant M as ConnectorManager participant C as RcpConnector participant PLC as PLC T->>M: checkDriverInstanceAlive() M->>C: startReadPointsValue() (若在线) loop 每个读周期 C->>PLC: GetTraceVariables (批量) PLC-->>C: 原始字节 C->>C: 按 SourceType 解析 C->>C: needPush 变更检测 alt 值变化 C->>M: pushValue end C->>C: sleep(instanceReadSleepTime) end

批量读取以 MapConstants.BATCH_SIZE 为单位分批,避免单次请求过大。

6
下行写与组态检测
带重试的写入

平台下发(writeAllPointValue → WriteTraceVariables)时,按 writeRetry 次重试,每次间隔 1 秒。返回码判定:

返回码含义
0 / 4成功
16组态不一致(见下)
其他失败,触发重试
组态一致性检测(特色)

当 PLC 程序变更导致变量结构(组态)与平台记录不一致时,GetTraceVariables/GetPlcStatus 会返回码 16 或非零。此时该实例被加入 INCONSISTENT_CONFIGURATION 集合,停止正常读写,提示用户重新导入工程。

为什么需要

PLC 工程师重新下载程序后,变量地址/类型可能变化。若平台仍按旧配置读写,会读到错误数据或写入危险值。组态检测是一道安全防线。

PLC 状态判定

GetPlcStatus 返回的值用于判断 PLC 健康:0x4 或 0xaa 视为健康;0x55 表示无强制,0xaa 表示有强制存在。

7
实例与点位属性
实例属性
属性名类型默认说明
hoststring必填PLC IP 地址;项目内唯一
portstring必填PLC 端口
modelIdstring"24609"目标设备型号 ID
readTimeint150组包间隔
instanceReadSleepTimeint500读循环休眠(毫秒)
tokenstring写必填密签(写操作安全凭证)
writeRetryint0写重试次数
名称校验

产品/设备/物模型名称有正则约束(ValidPattern),通常 1-32 / 1-128 字符。

点位属性(变量定位)

RCP 点位定位一个 PLC 追踪变量,由以下属性组成(RcpPointAttribute):

属性名含义
source源类型(byte)
addrOrIdx地址或索引
area存储区(byte)
size数据大小
cTypeC/PLC 数据类型(映射 SourceType)
index位/数组索引

点位唯一码(复合键):source&&addrOrIdx&&area&&size。

8
Web 接口与定时任务
1 个 HTTP API
映射路径用途参数 / 上传
importDriverInstance从 ZIP 导入 PLC 工程(JSON 配置),创建实例+点位+设备ZIP 文件上传 + driverId,可选 subsystemId、mergeProduct(默认 true)

调用路径前缀:POST /driver/api/rcp/{mapping}。导入有并发互斥保护。

定时任务
任务名Cron频率职责
aliveTask0/4 * * * * ?每 4 秒心跳检测 PLC 状态,设置 RUNNING/OFFLINE;在线时拉起读线程
9
常见问题
Q1
驱动启动报错"找不到 Rcp.dll/Rcp.so"?
RCP 驱动依赖原生库。确认部署环境的 resources/dll/ 下存在与当前 OS/架构匹配的库(Windows 用 Rcp.dll,Linux 用 Rcp.so)。JNA 会按平台自动选择,库缺失或位数不匹配(32/64 位)都会加载失败。
Q2
读到的值一直不变,但 PLC 程序里确实在变化?
可能进入了组态不一致状态(返回码 16)。检查实例是否在 INCONSISTENT_CONFIGURATION 集合中。若是,说明 PLC 工程已变更,需重新用 ZIP 导入最新工程配置后再恢复读写。
Q3
下行写值失败,提示 token 错误?
RCP 写操作需要 token(密签)作为安全凭证,且写必填。确认实例属性 token 与 PLC 侧配置一致。若 writeRetry 为 0 则不重试,可适当调大。
Q4
RCP 和 Modbus 都是接 PLC,怎么选?
看 PLC 支持的协议与采集粒度:Modbus 按寄存器地址读写,通用性强、跨厂商;RCP 按变量名/索引读写(追踪变量),更贴近工程,但依赖厂商原生库、部署受限。若 PLC 支持 RCP 且需要按变量采集,优先 RCP;否则用 Modbus。