欧姆龙通讯协议-Enthip/IP_ CIP报文(未测试)
Enthip/IP_ CIP报文格式
Ethernet Frame
└── IP Header
└── TCP Header
└── EtherNet/IP Encapsulation Header (24 bytes)
├─ Command (2 bytes)
├─ Length (2 bytes)
├─ Session Handle (4 bytes)
├─ Status (4 bytes)
├─ Sender Context (8 bytes)
└─ Options (4 bytes)
└── Encapsulation Data (Common Packet Format)
├─ Item Count (2 bytes)
├─ Address Item (Type/Length/Data)
├─ Data Item (Type/Length/CIP Message)
└── CIP Message (Message Router Request)
├─ Service (1 byte)
├─ Request Path Size (1 byte)
├─ Request Path (n bytes)
└─ Service Data (n bytes)
功能字分布在 3 层
-
EtherNet/IP Encapsulation(命令级)
-
CPF(承载方式级)
-
CIP(真正的“读 / 写 / 功能”)
Encapsulation Header(EtherNet/IP 功能字)
| 偏移 | 字节 | 字段 | 功能字说明 |
|---|---|---|---|
| 0x00 | 2 | Command | EtherNet/IP 功能字 |
| 0x02 | 2 | Length | 后续 CPF 长度 |
| 0x04 | 4 | Session Handle | 会话 ID |
| 0x08 | 4 | Status | 返回状态 |
| 0x0C | 8 | Sender Context | 标识 |
| 0x14 | 4 | Options | 固定 0 |
Command 功能字全集
| Command | Hex | 作用 |
|---|---|---|
| RegisterSession | 0x0065 | 建立会话 |
| UnRegisterSession | 0x0066 | 关闭会话 |
| SendRRData | 0x006F | 显式 CIP(读 / 写) |
| SendUnitData | 0x0070 | 隐式 IO |
| ListIdentity | 0x0063 | 设备发现 |
Address Item(是否连接)
| 字段 | 功能 |
|---|---|
| Type = 0x0000 | Null Address(无连接)用于显式消息 / CIP 无连接请求 |
| Type = 0x00A1 | TCP/IP Target Address(隐式消息 / I/O 消息) |
| Type = 0x8002 | UDP Target Address(特定厂商扩展) |
Data Item(承载 CIP)
| TypeID | 名称 | 含义 / 使用场景 |
|---|---|---|
| 0x00B2 | Unconnected Message | 最常用的显式 CIP 消息,未连接消息,适用于单次读写标签(Read Tag / Write Tag) |
| 0x00B1 | Connected Message | 已连接消息(通常用于实时 I/O),需要建立 CIP Connection |
| 0x00A1 | TCP/IP Target Address | 隐式消息(实时 I/O)目标地址,用于 I/O 连接 |
| 0x00A2 | UDP Target Address | 隐式消息(UDP)目标地址 |
| 0x8000+ | 厂商扩展 | 设备特定消息类型 |
CIP Message(真正的功能字核心)
Service (1)
Path Size (1)
Path (n)
Service Data (n)
Service(CIP 功能字全集)
Tag 访问(Logix PLC)
| 功能 | Service | 响应 |
|---|---|---|
| Read Tag | 0x4C | CC |
| Write Tag | 0x4D | CD |
| Read Fragmented | 0x52 | |
| Write Fragmented | 0x53 | |
| Multiple Service | 0x0A | 8A |
对象访问(标准 CIP)
| 功能 | Service |
|---|---|
| Get Attribute Single | 0x0E |
| Set Attribute Single | 0x10 |
Path 功能字(路径编码)
Tag 名
| 字节 | 含义 |
|---|---|
| 0x91 | ANSI Symbol |
| N | Tag 名长度 |
| ASCII | TAG |
Class / Instance
| 类型 | Code |
|---|---|
| Class | 0x20 |
| Instance | 0x24 |
| Attribute | 0x30 |
数据类型功能字
| 类型 | Code |
|---|---|
| BOOL | 0x00C1 |
| BYTE | 0x00C2 |
| INT | 0x00C3 |
| DINT | 0x00C4 |
| REAL | 0x00CA |
完整 EtherNet/IP 显式通信流程
1️⃣ RegisterSession → 建立会话(获取 Session Handle)
2️⃣ SendRRData (Read/Write)→ 显式 CIP 消息(读 / 写 / 多标签)
3️⃣ SendRRData Response → PLC 返回 CIP 响应
4️⃣ UnRegisterSession → 注销会话
建立会话

提取 SessionHandle(0x000E0171)用于后续 CIP 通信。
显式 CIP 消息
单标签读取

BOOL变量返回报文

DINT变量返回报文

变量类型
| Type Name | Type Code | 描述 / 备注 |
|---|---|---|
| BOOL | 0xC1 | 单个位,1字节存储 |
| SINT (Short Int) | 0xC2 | 8位有符号整数 |
| INT (Integer) | 0xC3 | 16位有符号整数 |
| DINT (Double Int) | 0xC4 | 32位有符号整数 |
| LINT (Long Int) | 0xC5 | 64位有符号整数 |
| USINT | 0xC6 | 8位无符号整数 |
| UINT | 0xC7 | 16位无符号整数 |
| UDINT | 0xC8 | 32位无符号整数 |
| ULINT | 0xC9 | 64位无符号整数 |
| REAL | 0xCA | 32位浮点数 |
| LREAL | 0xCB | 64位浮点数 |
| STRING | 0xD0 | ASCII字符串,前2字节长度 |
| STRING2 | 0xD1 | ASCII字符串,前1字节长度 |
| STRINGN | 0xD2 | 可变长度字符串 |
| BYTE | 0xD1/D0? | 单字节数组,有时和 USINT 等价 |
| WORD | 0xD2 | 16位数据 |
| DWORD | 0xD3 | 32位数据 |
| LWORD | 0xD4 | 64位数据 |
| STRUCT | 0xA0 | 结构体类型 |
| ARRAY | 0x91 | 数组类型 |
常见场景对应类型
| PLC 标签类型 | CIP Data Type |
|---|---|
| BOOL | 0xC1 |
| SINT | 0xC2 |
| INT | 0xC3 |
| DINT | 0xC4 |
| REAL | 0xCA |
| LREAL | 0xCB |
| STRING | 0xD0 / 0xD1 |
| ARRAY[BOOL] | 0x91 + 0xC1 |
| ARRAY[DINT] | 0x91 + 0xC4 |
| STRUCT | 0xA0 + 子字段类型 |
变量类型与 Address Item Data 使用规则
| 场景 / 变量类型 | Address Item Data 内容 | 说明 |
|---|---|---|
| 单点 BOOL(简单 I/O、单变量) | 可以为空 0B 或占位 4B | PLC 允许逻辑寻址,报文简化,不需要指定路径 |
| 单 DINT / REAL / INT / WORD 等标量变量 | 通常 ≥ 4B | 需要指定目标对象路径(Connection Path)或 Logical Address,告诉客户端数据来源 |
| BOOL 数组 / WORD 数组 / DINT 数组 | ≥4B | 同样需要 Connection Path 或 Logical Address,通常还要加 Padding 保证 4B 对齐 |
| 结构体 / UDT(自定义数据类型) | ≥4B | 返回报文中必须包含 Address Item Data 指向结构体实例 |
| 多实例 / 多模块访问 | ≥4B | 必须明确目标模块或实例路径,否则客户端无法解析返回数据 |
| 隐式 I/O 读(Unconnected / I/O 模块) | 可空或占位 4B | 因为 PLC 端已经知道 I/O 地址,可省略明确路径 |
| 显式消息(Explicit Message)访问远程对象 | ≥4B | 必须包含完整 Connection Path,确保报文可以定位到对象 |
IP 与 Port 的规则
-
IP 只有
-
当你访问 本地 PLC、单模块对象或逻辑寻址的变量
-
EtherNet/IP 协议允许 Unconnected Message 或 Logical Addressing
-
PLC 端已经知道端口号 → 所以报文里只需要 IP 地址(4B)
-
Port 可以省略,报文更短
单 DINT 返回报文就是这种情况:只读 PLC 内部一个数据点(变量),只需要 IP 占位 4B
-
IP + Port
-
当你访问 远程模块或通过 Explicit Message 访问非本地对象
-
端口号必须明确,告诉客户端如何路由报文
-
EtherNet/IP 文档里提到:
-
Port ID 主要用于 CIP Explicit Message
-
对于 I/O 模块或连接到其他 PLC 的对象,如果报文需要发送到不同端口,必须包含 Port(2B)
-
-
什么时候需要 Connection Parameters / Extended Path
-
复杂对象,如多实例、多模块、多属性访问
-
Address Item Data = IP + Port + Path + Padding
-
保证总长度是 4B 的倍数
| 类型 | 本地 PLC / 逻辑寻址 | 远程模块 / Explicit Message |
|---|---|---|
| 单 BOOL | Address Item Data 可以空 | 需要完整 IP/Port/Path |
| BOOL 数组(本地) | 也可以空 | 需要完整 IP/Port/Path |
| DINT / REAL / 数组 | 可空或 4B 占位 | 需要 IP/Port/Path |
| 结构体 / UDT | 必须有 | 必须有 |
数组标签读取

BOOL数组变量返回报文

-
Byte0 =
B2→ 0b10110010 -
Byte1 =
69→ 0b01101001 -
Byte2 =
C8→ 0b11001000 -
Byte3 =
00→ Padding,忽略
Index : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Value : 0 1 0 0 1 1 0 1 1 0 0 1 0 1 1 0 0 0 1 1
DINT数组变量返回报文

多标签读取
请求报文

返回报文

单标签写
浙公网安备 33010602011771号