phase 2 tcp

This commit is contained in:
flower_linux
2026-06-12 21:23:21 +08:00
parent 628ccf1409
commit ebff25e0d5
75 changed files with 3014 additions and 289 deletions

View File

@@ -8,7 +8,7 @@
`softbus_edge` 是边缘代理进程,运行在靠近现场设备的一侧,负责:
- **物理域采集ingress**:按 `physical_*.json` 轮询 Modbus RTU/TCP 等设备,产出 `RawPacket`
- **物理域采集ingress**:按 `physical_*.json` 轮询 Modbus / CANopen / 裸以太网设备,产出 `RawPacket`
- **上行egress/uplink**:经 TCP 将 `RawPacket`、心跳、注册信息发送给 `softbus_daemon`
- **下行egress**:接收 daemon 下发的 `ExecuteCommand`写回物理设备Modbus 写寄存器等)
@@ -16,7 +16,7 @@ edge **不**加载逻辑点表、**不**操作 OPC UA、**不**运行 `protocol_
| 模式 | 说明 |
|------|------|
| **正常模式** | libmodbus + `ModbusIngress`,读真实硬件 |
| **正常模式** | `CompositeIngress`Modbus + CANopen + Eth,读真实硬件 |
| **Mock 模式** | `--mock`,无硬件,模拟 Modbus 帧上行 |
| **独立模式** | daemon 未启动时 edge 仍可运行,后台重连 uplink |
@@ -93,8 +93,8 @@ edge 上行时**不做** binding 初筛:所有已配置物理点都会采集
→ 物理点 ID 自动加前缀edge01/phy_modbus_s1_r40001
4. [可选] BindingRegistry.loadLocal(bindings_local.json)
5. UplinkClient + CommandExecutor 初始化
6. DeviceFactory.createIngress → ModbusIngress 或 MockModbusIngress
7. ModbusChannelManager.openChannel逐通道 libmodbus 连接
6. DeviceFactory.createIngress → CompositeIngress按 protocol 创建子 ingress
7. ChannelManager.openChannellibmodbus / SocketCAN / asio
8. uplink.connect();成功则 sendEdgeRegister(edgeId)
→ 失败仅 WARNedge 独立运行并后台重连
```
@@ -122,7 +122,11 @@ edge 上行时**不做** binding 初筛:所有已配置物理点都会采集
| 字段 | 说明 |
|------|------|
| `transport` | `rtu`(串口)或 `tcp`Modbus TCP`host` + `tcpPort` |
| `pollIntervalMs` | 通道下所有点的轮询周期(当前整通道统一 |
| `pollIntervalMs` | 通道默认轮询周期(点可覆盖 |
| `interface` / `bitrate` | CANopen 通道:`can0``500000` |
| `host` / `tcpPort` | Modbus TCP 或裸以太网 |
CANopen 通道示例见 `config/edge/physical_channels_can.json`
### 3.4 物理设备与点(`physical_devices.json`
@@ -141,7 +145,10 @@ edge 上行时**不做** binding 初筛:所有已配置物理点都会采集
"function": 3,
"scale": 0.1,
"signalType": "AI",
"writable": false
"writable": false,
"pollIntervalMs": 1000,
"reportOnChange": true,
"deadband": 0.5
}
]
}
@@ -149,8 +156,22 @@ edge 上行时**不做** binding 初筛:所有已配置物理点都会采集
}
```
**点级可选字段:**
| 字段 | 说明 |
|------|------|
| `pollIntervalMs` | 覆盖通道默认周期 |
| `reportOnChange` | `true` 时启用变化上报 |
| `deadband` | 工程值死区(配合 `reportOnChange` |
| `objectIndex` / `subIndex` | CANopen 对象字典索引 |
| `pdoType` | `tpdo` / `sdo` / `rpdo` |
| `cobId` | PDO COB-ID 覆盖 |
| `nodeId` / `edsPath` | 设备级 CANopen 字段 |
运行时 `physicalPointId` 会变为 `{edgeId}/{physicalPointId}`,作为 `RawPacket.sourceId` 上报。
CANopen 示例见 `config/edge/physical_devices_can.json``config/edge/samples/minimal.eds`
### 3.5 热加载
| 信号 | 行为 |
@@ -163,18 +184,38 @@ edge 上行时**不做** binding 初筛:所有已配置物理点都会采集
## 4. 组件架构
### 4.0 目录结构
```
include/softbus_edge/
ingress/ IIngressPort, CompositeIngress
modbus/ ModbusIngress, MockModbusIngress
can/ CanIngress
eth/ EthIngress
driver/
modbus/ ModbusChannelManager (libmodbus)
can/ CanChannelManager (SocketCAN)
eth/ EthChannelManager (asio)
egress/
modbus/ ModbusEgress
can/ CanEgress (SDO 写)
eth/ EthEgress
scheduler/ ModbusPollScheduler, PollPlanner, ChangeFilter
canopen/ NmtManager, SdoClient, PdoMapper
config/ runtime/ factory/ discovery/
```
```
main.cpp
└── EdgeRuntime
├── PhysicalRegistry ← physical_*.json
├── BindingRegistry (local) ← bindings_local.json可选
├── ModbusChannelManager ← libmodbus RTU/TCP I/O
├── IIngressPort
── ModbusIngress ← 正常模式
│ └── MockModbusIngress ← --mock
├── ModbusEgress ← 下行写寄存器
── CommandExecutor ← ExecuteCommand → Modbus 写 / mock
└── UplinkClient ← TcpUplinkClient 封装
├── PhysicalRegistry
├── CompositeIngress
├── ModbusIngress + ModbusPollScheduler / PollPlanner / ChangeFilter
├── CanIngress + NmtManager / PdoMapper / SdoClient
── EthIngress
── ModbusEgress / CanEgress / EthEgress
├── CommandExecutor ← 按 protocol 分发写
── UplinkClient
```
### 4.1 IIngressPort — 入站抽象
@@ -185,9 +226,13 @@ main.cpp
| `close()` | 关闭采集通道 |
| `poll()` | 轮询,返回 `vector<RawPacket>` |
**ModbusIngress**`pollIntervalMs` 遍历 `pollPoints()`,经 `ModbusChannelManager` 读寄存器,组装 Modbus 0x03 响应帧作为 `payload`
**ModbusIngress**`PollPlanner` 调度到期点 → `ModbusPollScheduler` 合并相邻寄存器批量读 → `ChangeFilter` 变化过滤 → `RawPacket`
**MockModbusIngress**无硬件,生成递增值模拟帧
**CanIngress**启动时 NMT Start + 加载 EDSTPDO 监听 + SDO 慢点轮询;`protocolTag: "canopen"`
**EthIngress**:裸 TCP/UDP 收字节;`protocolTag: "raw_eth"`
**MockModbusIngress**`--mock` 模式,无硬件模拟帧。
### 4.2 ModbusChannelManager — 硬件 I/O
@@ -214,10 +259,12 @@ main.cpp
### 4.4 CommandExecutor — 下行写
daemon 经 `bindings_global` 在命令中注入 `physicalPointId` + `edgeId`edge 直接写 Modbus
daemon 经 `bindings_global` 在命令中注入 `physicalPointId` + `edgeId`edge 按协议写
```
ExecuteCommand.params.physicalPointId → PhysicalRegistry → ModbusEgress.write
modbus → ModbusEgress
canopen → CanEgress (SDO download)
raw → EthEgress
```
仅当命令**缺少** `physicalPointId` 时,才用 `bindings_local.json``logicalPointId → physicalPointId` 备用解析。
@@ -310,8 +357,10 @@ while (!shouldStop) {
| `softbus_registry` | BindingRegistry仅 local 可选) |
| `softbus_transport` | TcpUplinkClient、UplinkWire |
| `softbus_api` | ExecuteCommand、SoftbusAck |
| **libmodbus** | Modbus RTU/TCP 硬件 I/Ovendor 或系统包) |
| asio | TcpUplinkClient 底层 |
| **libmodbus** | Modbus RTU/TCP 硬件 I/O |
| **SocketCAN** | Linux `linux/can.h``SOFTBUS_HAS_SOCKETCAN` |
| **softbus_canopen_common** | EDS 解析、对象字典 |
| asio | Uplink + EthChannel |
---
@@ -351,68 +400,46 @@ kill -HUP $(pidof softbus_edge)
---
## 9. 未来扩展CANopen 与以太网设备
## 9. 多协议与物理层优化(已实现)
当前仅 **Modbus RTU/TCP** 在 edge 侧有完整 ingress/egress。CANopen 与更多以太网协议按同一双域模型扩展。
### 9.1 多 Ingress 并存
### 9.1 目标架构
`physical_channels.json` 中可混合 `protocol: modbus | canopen | raw``DeviceFactory` 为每种协议创建子 ingress`CompositeIngress` 统一 `poll()`
```
physical_channels.json ──→ ChannelDriver按 protocol 选择)
physical_devices.json ──→ PhysicalRegistry
┌───────────┼───────────┐
▼ ▼ ▼
ModbusIngress CanIngress EthIngress规划
│ │ │
└───────────┴───────────┘
RawPacket → UplinkClient
```
### 9.2 Modbus 采集优化
daemon 侧已有对应解析插件(`protocol_modbus``protocol_canopen`edge 只需换 ingress/driver**上行仍是 RawPacket + protocolTag**。
### 9.2 CANopen规划
| 层级 | 计划 |
| 组件 | 行为 |
|------|------|
| **edge** | `CanIngress` + SocketCAN/`can0` 通道SDO/PDO 读对象字典 → `RawPacket``protocolTag: "canopen"` |
| **配置** | `physical_channels` 增加 `transport: can``interface: can0``bitrate: 500000``physical_devices` 增加 `nodeId`、对象索引 |
| **daemon** | 已有 `protocol_canopen.so`Framer/Parser 占位),绑定仍走 `bindings_global` |
| **EDS/DCF** | edge 侧加载 EDS 映射物理点 ↔ COB-ID/索引daemon 不接收 EDS 全量 |
| **ModbusPollScheduler** | 同 (channel, slave, function) 下合并相邻寄存器,单次最多 125 寄存器 |
| **PollPlanner** | 每点独立 `pollIntervalMs`(缺省继承通道) |
| **ChangeFilter** | `reportOnChange` + `deadband` 物理层过滤 |
### 9.3 以太网设备(规划
### 9.3 CANopenedge 已实现
| 类型 | edge 侧 | 说明 |
|------|---------|------|
| **Modbus TCP** | 已支持 | `physical_channels``transport: tcp``host` + `tcpPort` |
| **裸 TCP / 自定义帧** | `EthIngress`(规划) | 按 channel 配置帧格式或插件化 driver |
| **UDP 组播** | 待定 | 适用于部分工业相机/传感器 |
| 组件 | 说明 |
|------|------|
| **CanChannelManager** | SocketCAN 收发(无头文件时模拟降级) |
| **NmtManager** | 启动时 NMT Start Remote Node |
| **EdsDcfLoader** | `softbus_canopen_common` 解析 EDS |
| **PdoMapper** | TPDO 订阅表 + 帧解包 |
| **SdoClient** | SDO upload慢点/ download下行写 |
| **daemon** | `protocol_canopen.so` 解析仍占位 |
以太网通道示例Modbus TCP已可用
CAN 前置:`sudo ip link set can0 up type can bitrate 500000`
```json
{
"channelId": "eth_modbus_0",
"protocol": "modbus",
"transport": "tcp",
"host": "192.168.1.10",
"tcpPort": 502,
"pollIntervalMs": 200
}
```
### 9.4 裸以太网(骨架)
### 9.4 edge 侧待增强Modbus 及通用)
`protocol: "raw"` + `transport: tcp|udp``EthIngress` 原样上行;`EthEgress` 支持原始字节写。
Modbus TCP 仍走 `protocol: modbus` + `transport: tcp`
### 9.5 待增强
| 项 | 说明 |
|----|------|
| **ModbusPollScheduler** | 合并相邻寄存器读,减少串口占用 |
| **按点 pollInterval** | 不同信号类型不同采集周期 |
| **变化上报 / deadband** | 物理层过滤,减少 uplink 流量 |
| **DeviceDiscovery** | 总线扫描、动态写入 `physical_devices` |
| **多 ingress 并存** | 同一 edge 上 Modbus + CANopen 并行 |
上述优化均在**物理域**完成,不改变 daemon 双域模型。
| **daemon CANopen 解析** | `CanopenParser` 完整实现 |
| **Eth 帧解析** | 自定义帧格式插件化 |
---
@@ -430,6 +457,7 @@ daemon 侧已有对应解析插件(`protocol_modbus`、`protocol_canopen`
| 文档 | 内容 |
|------|------|
| [edge/tcp_rtu_callstack.md](edge/tcp_rtu_callstack.md) | Modbus TCP 点完整调用栈(含 RTU-over-TCP |
| [edge_device_setup.md](edge_device_setup.md) | 配置目录、双域、libmodbus、Mock |
| [UPLINK_WIRE_PROTOCOL.md](UPLINK_WIRE_PROTOCOL.md) | TCP JSON 线协议 |
| [softbus_daemon.md](softbus_daemon.md) | daemon 侧 Pipeline 与 OPC |