RCP 驱动功能设计
RCP 原生库 PLC 远程通信 · 变量追踪采集 · 组态一致性检测
RCP 驱动用于接入支持 RCP 协议的 PLC(可编程逻辑控制器)。RCP 是一种厂商 PLC 远程通信协议,通过它平台可以读取/写入 PLC 的追踪变量(Trace Variables)——即 PLC 程序中定义的内部变量。
与 Modbus 直接读写「寄存器地址」不同,RCP 读写的是按变量名/索引组织的逻辑变量,更贴近 PLC 工程师的工作方式。
RCP 驱动通过 JNA(Java Native Access)调用原生动态库(Windows Rcp.dll / Linux Rcp.so)。部署时必须保证对应平台的原生库存在于运行环境,否则驱动无法初始化。
| 属性 | 值 | 说明 |
|---|---|---|
| 驱动名称 | rcp | SPI 注册名 |
| 版本 | V 1.2.0 | getDriverVersion() |
| 接入模式 | EMBEDDED | 内嵌于平台主应用 |
| 协议库 | 原生 Rcp.dll / Rcp.so(JNA) | 平台自动加载对应 OS 的库 |
| 通信模型 | 轮询(后台线程批读) | 变更检测后推送 |
| Web 接口 | 1 个 | ZIP 导入 PLC 工程 |
| 定时任务 | 1 个 | 每 4 秒心跳 + 读触发 |
驱动通过 JNA 定义 RcpLibrary 接口,映射原生库的一组 C 函数,由 RcpConnector 调用。整个生命周期由原生库管理:
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。
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,定义每种类型的合法取值范围,用于写操作的值校验。
实例管理 · 校验 · 写分发"] 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
每个在线实例有一个独立的后台读线程(readRcpPointsValueTask),循环调用 GetTraceVariables 批量读取所有变量。读取采用变更检测——只有值真正变化时才推送到平台,避免重复上报。
批量读取以 MapConstants.BATCH_SIZE 为单位分批,避免单次请求过大。
平台下发(writeAllPointValue → WriteTraceVariables)时,按 writeRetry 次重试,每次间隔 1 秒。返回码判定:
| 返回码 | 含义 |
|---|---|
0 / 4 | 成功 |
16 | 组态不一致(见下) |
| 其他 | 失败,触发重试 |
当 PLC 程序变更导致变量结构(组态)与平台记录不一致时,GetTraceVariables/GetPlcStatus 会返回码 16 或非零。此时该实例被加入 INCONSISTENT_CONFIGURATION 集合,停止正常读写,提示用户重新导入工程。
PLC 工程师重新下载程序后,变量地址/类型可能变化。若平台仍按旧配置读写,会读到错误数据或写入危险值。组态检测是一道安全防线。
GetPlcStatus 返回的值用于判断 PLC 健康:0x4 或 0xaa 视为健康;0x55 表示无强制,0xaa 表示有强制存在。
| 属性名 | 类型 | 默认 | 说明 |
|---|---|---|---|
host | string | 必填 | PLC IP 地址;项目内唯一 |
port | string | 必填 | PLC 端口 |
modelId | string | "24609" | 目标设备型号 ID |
readTime | int | 150 | 组包间隔 |
instanceReadSleepTime | int | 500 | 读循环休眠(毫秒) |
token | string | 写必填 | 密签(写操作安全凭证) |
writeRetry | int | 0 | 写重试次数 |
产品/设备/物模型名称有正则约束(ValidPattern),通常 1-32 / 1-128 字符。
RCP 点位定位一个 PLC 追踪变量,由以下属性组成(RcpPointAttribute):
| 属性名 | 含义 |
|---|---|
source | 源类型(byte) |
addrOrIdx | 地址或索引 |
area | 存储区(byte) |
size | 数据大小 |
cType | C/PLC 数据类型(映射 SourceType) |
index | 位/数组索引 |
点位唯一码(复合键):source&&addrOrIdx&&area&&size。
| 映射路径 | 用途 | 参数 / 上传 |
|---|---|---|
importDriverInstance | 从 ZIP 导入 PLC 工程(JSON 配置),创建实例+点位+设备 | ZIP 文件上传 + driverId,可选 subsystemId、mergeProduct(默认 true) |
调用路径前缀:POST /driver/api/rcp/{mapping}。导入有并发互斥保护。
| 任务名 | Cron | 频率 | 职责 |
|---|---|---|---|
aliveTask | 0/4 * * * * ? | 每 4 秒 | 心跳检测 PLC 状态,设置 RUNNING/OFFLINE;在线时拉起读线程 |
resources/dll/ 下存在与当前 OS/架构匹配的库(Windows 用 Rcp.dll,Linux 用 Rcp.so)。JNA 会按平台自动选择,库缺失或位数不匹配(32/64 位)都会加载失败。INCONSISTENT_CONFIGURATION 集合中。若是,说明 PLC 工程已变更,需重新用 ZIP 导入最新工程配置后再恢复读写。token(密签)作为安全凭证,且写必填。确认实例属性 token 与 PLC 侧配置一致。若 writeRetry 为 0 则不重试,可适当调大。