ERTEC 系列 PROFINET 芯片级硬件过滤器分析文档
版权声明:本文为本文为博主原创文章,转载请注明出处。如有问题,欢迎指正。博客地址:https://www.cnblogs.com/wsg1100/
前言
实时控制系统(Real-Time Control Systems)的生命线在于"确定性"。无论是基于裸机(Bare-metal)架构还是实时操作系统(RTOS),这类系统对响应延迟和执行精度有着近乎苛刻的要求,任何非预期的故障都可能导致灾难性后果。然而,当我们需要通过以太网将这些封闭的实时系统接入开放的互联网(包括公网)时,网络环境固有的"不确定性"便成为了系统中最大的风险变量。
广播风暴、TCP SYN泛洪攻击、异常错误帧等网络事件,不仅会严重侵蚀系统的实时性能,更可能直接导致任务调度阻塞甚至系统瘫痪。由于我们无法掌控外部网络的复杂行为,唯一的生存之道便是"向内求索"------在设备自身构建坚不可摧的网络防线。我们需要在数据进入协议栈之前,就在硬件层面拦截并清洗掉所有恶意或无效流量。
业界标杆西门子(Siemens)的PROFINET为何能在复杂的工业现场保持极高的稳定性?其核心秘诀之一,便在于其底层驱动中精妙的芯片级硬件过滤机制。本文将深入剖析 PROFINET IO Runtime Software (EDDP - Ethernet Device Driver for PN-IP) 中的硬件过滤规则配置系统,揭示其如何在网卡硬件层面实现高效的数据包分类与过滤,从而确保实时系统在洪流般的网络攻击中依然稳如磐石。
1. 概述
本文档详细分析了 PROFINET IO Runtime Software (EDDP - Ethernet Device Driver for PN-IP) 中的芯片级硬件过滤规则配置系统。该系统用于在硬件层面快速过滤和分类接收到的以太网帧,实现高效的网络包处理。
1.1 支持的芯片版本
| 芯片版本 | 宏定义 | 说明 |
|---|---|---|
| ERTEC200P Rev1 | EDDP_HAL_HW_PNIP_REV1 | PNIP 修订版 1 |
| ERTEC200P Rev2 | EDDP_HAL_HW_PNIP_REV2 | PNIP 修订版 2 |
| HERA Rev3 | EDDP_HAL_HW_PNIP_REV3 | HERA 芯片修订版 3 |
| I8/ERTEC Rev4 | EDDP_HAL_HW_PNIP_REV4 | I8 芯片修订版 4 |
2. 整体架构与运行原理
2.1 系统架构
┌─────────────────────────────────────────────────────────────────────────┐
│ 以太网帧到达 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 硬件过滤器 (API Filter Engine) │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 16个过滤器代码片段 (Filter Code Fragments 0-15) │ │
│ │ ├── Fragment 00: OTHER (丢弃未知类型) │ │
│ │ ├── Fragment 01: IP (IPv4) │ │
│ │ ├── Fragment 02: ARP │ │
│ │ ├── Fragment 03: MRP │ │
│ │ ├── Fragment 04: LLDP │ │
│ │ ├── Fragment 05: PN_DCP │ │
│ │ ├── Fragment 06: ALARM │ │
│ │ ├── Fragment 07: LEN │ │
│ │ ├── Fragment 08: PTCP │ │
│ │ ├── Fragment 09: IP6 (HERA/I8) │ │
│ │ ├── Fragment 10: HSYNC (HERA/I8) │ │
│ │ ├── Fragment 14: RT_CT (实时周期) │ │
│ │ └── Fragment 15: RT_SF (实时非周期) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ SDT (String Descriptor Table) - 字符串描述符表 │ │
│ │ 用于存储需要匹配的字符串模式(如DCP Hello TLV、ARP IP地址等) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Store Memory - 存储器 │ │
│ │ 临时存储帧中的数据用于后续比较 │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ DROP │ │ PASS │ │ CYCLIC │
│ 丢弃帧 │ │ 传递帧 │ │ 周期帧 │
└─────────┘ └─────────┘ └─────────┘
│ │ │
▼ ▼ ▼
(丢弃) ┌─────────────────┐ ┌─────────┐
│ RX Ring 0-31 │ │ ACW列表 │
│ (NRT处理队列) │ │ (周期) │
└─────────────────┘ └─────────┘
2.2 运行流程
- 帧接收: 以太网帧到达网卡接口
- EtherType提取: 从帧中提取EtherType字段
- 片段选择: 根据EtherType选择对应的过滤器代码片段
- 指令执行: 执行过滤器代码中的指令序列
- 决策输出: 生成FDC (Filter Decision Code) 和RX Ring索引
- 帧分发: 根据决策将帧放入对应的RX Ring或丢弃
3. API-Ctrl 内存布局
3.1 ERTEC200P (Rev1/Rev2) 内存布局
地址偏移 大小 内容描述
─────────────────────────────────────────────────────────────
0x0000 0x600 过滤器代码 (FilterCode)
0x0600 0x180 TX/RX DMACW IFA (RX:32×8Byte, TX:16×8Byte)
0x0780 0x10 Store_MEM_IFA (最多8个数据字)
0x0790 0x140 SDT IFA (80条目 × 4字节)
0x08D0 0x180 TX/RX DMACW IFB
0x0A50 0x10 Store_MEM_IFB
0x0A60 0x140 SDT IFB
0x0BE0 变长 Strings IFA/B (比较字符串空间)
3.2 HERA (Rev3) 内存布局
地址偏移 大小 内容描述
─────────────────────────────────────────────────────────────
0x0000 0x1000 过滤器代码 (FilterCode)
0x1000 0x180 TX/RX DMACW
0x1180 0x10 Store Memory
0x1190 0x140 SDT (String Descriptor Table)
0x12D0 变长 比较字符串空间
4. 过滤器指令格式
每条过滤器指令为 8字节,格式如下:
字节0 字节1 字节2 字节3 字节4 字节5 字节6 字节7
┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│ Opcode │ Label │ MaskH │ MaskL │ Skip │ Jump │ DataH │ DataL │
│ (操作码)│(标签) │(掩码高)│(掩码低)│(跳过) │(跳转) │(数据高)│(数据低)│
└────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
4.1 操作码 (Opcode) 详解
| 操作码 | 名称 | 说明 |
|---|---|---|
| 0x00 | SKIP | 跳过指定字节数,移动数据指针 |
| 0x01 | PASS | 通过帧,输出FDC和索引 |
| 0x02 | DROP | 丢弃帧 |
| 0x03 | CYCLIC | 周期帧处理 |
| 0x00-0x0F | SCMP | 字符串比较 (与SDT表比较) |
| 0x80 | SV_EQU | 静态值相等比较 |
| 0x81 | SV_NEQ | 静态值不等比较 |
| 0x83 | SV_LT | 静态值小于比较 |
| 0x84 | SV_GTE | 静态值大于等于比较 |
| 0x87 | SM_STORE | 存储数据到Store Memory |
| 0x89 | SM_NEQ | 存储器值不等比较 |
| 0x11 | PASS with index | 带索引的通过 |
4.2 指令字段解析
Opcode (字节0):
- 决定指令类型和基本行为
Label (字节1):
- 跳转目标标签或条件跳转目标
MaskH/MaskL (字节2-3):
- 16位掩码,用于数据比较
- 0xFFFF表示比较所有位
- 0x0000表示不比较(总是匹配)
Skip (字节4):
- 执行后跳过的字节数
- 用于移动数据指针
Jump (字节5):
- 条件不满足时的跳转偏移
- 0表示继续下一条指令
DataH/DataL (字节6-7):
- 16位比较值
- 与帧数据(经过掩码)进行比较
5. 过滤器代码片段详解
5.1 Fragment 00: OTHER (丢弃过滤器)
目的: 丢弃所有不匹配已知EtherType的帧
EtherType范围: 0x0000-0x07FF, 0x0806(ARP), 0x8892(PN), 0x88F7(PTP), 0x88CC(LLDP), 0x88E3(MRP) 之外的所有类型
代码示例:
c
// EDDP_API_TYPE_OTHER - 丢弃过滤器
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11
// --> PASS | 0 | 1
// 含义: 通过到RX Ring 0,标记为丢弃
FDC : 0x8000 (EDDP_HWF_FDC_OTHER_DROP)
5.2 Fragment 01: IP (IPv4过滤器)
EtherType : 0x0800
功能: 识别并分类IPv4协议帧
处理流程:
1. 跳过6字节 (DA+SA)
2. 循环跳过VLAN标签 (0x8100)
3. 检查IP版本和头长度 (Version=4, IHL=5 → 0x45)
4. 根据Protocol字段分类:
- Protocol 1 (0x01): ICMP
- Protocol 2 (0x02): IGMP
- Protocol 6 (0x06): TCP
- Protocol 17 (0x11): UDP
5. 对于UDP,进一步检查端口:
- Port 34964 (0x8894): DCP over UDP
- Port 50000+ (0xC350+): DCP Hello over UDP
代码示例 (部分):
c
// 跳过DA+SA
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00
// --> SKIP | 6
// 检查并跳过VLAN
0x00, 0x81, 0xFF, 0xFF, 0x01, 0x02, 0x00, 0x80
// --> SV_EQU | 0 | 2 | 1 | ffffh | 8100h
// 检查IP版本/IHL
0x00, 0x45, 0x00, 0xFF, 0x04, 0x00, 0x0A, 0x81
// --> SV_NEQ | Lbl_NO_IP_RT_OVER_UDP=10 | 0 | 4 | ff00h | 4500h
// 检查Protocol=ICMP(1)
0x01, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x05, 0x80
// --> SV_EQU | Lbl_IPICMP=5 | 0 | 0 | ffh | 1h
FDC定义:
| FDC值 | 名称 | 说明 |
|---|---|---|
| 0x8010 | IP_UDP_DROP | IP UDP丢弃 |
| 0x10 | IP_ICMP | ICMP帧 |
| 0x11 | IP_IGMP | IGMP帧 |
| 0x12 | IP_TCP | TCP帧 |
| 0x13 | IP_UDP | UDP帧 |
| 0x15 | UDP_DCP | DCP over UDP |
| 0x16 | UDP_DCP_HELLO | DCP Hello over UDP |
| 0x17 | UDP_ASRT | Alarm over UDP |
5.3 Fragment 02: ARP (地址解析协议过滤器)
EtherType : 0x0806
功能: 过滤ARP请求/应答帧,验证SPA(源协议地址)与TPA(目标协议地址)
处理流程:
1. 跳过DA+SA (6字节)
2. 跳过VLAN标签
3. 验证ARP帧格式:
- Hrd (硬件类型) = 1 (以太网)
- Prot (协议类型) = 0x0800 (IP)
- hln (硬件地址长度) = 6
- pln (协议地址长度) = 4
4. 检查opcode:
- opcode 1: ARP Request
- opcode 2: ARP Reply
5. 比较SPA和TPA (使用SDT表)
6. 存储SPA到Store Memory用于后续比较
代码示例 (部分):
c
// 验证Hrd=1
0x01, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x0B, 0x81
// --> SV_NEQ | Lbl_ARP_DROP=11 | 0 | 1 | ffffh | 1h
// 验证Prot=0x0800
0x00, 0x08, 0xFF, 0xFF, 0x01, 0x00, 0x0A, 0x81
// --> SV_NEQ | Lbl_ARP_DROP=10 | 0 | 1 | ffffh | 800h
// 验证hln=6, pln=4
0x04, 0x06, 0xFF, 0xFF, 0x01, 0x00, 0x09, 0x81
// --> SV_NEQ | Lbl_ARP_DROP=9 | 0 | 1 | ffffh | 604h
// 检查SPA字段 (使用SDT索引0x4A)
0x4A, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x06, 0x0F
// --> SCMP | Lbl_ARP_PASS=6 | 0 | 0 | ffffh | 4ah
// 存储SPA HiWord
0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x87
// --> SM_STORE | 1 | 65535 | 0
// 存储SPA LoWord
0x01, 0x00, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x87
// --> SM_STORE | 4 | 65535 | 1
SDT索引 : EDDP_SDT_IDX_ARP_IP = 0x4A
FDC:
| FDC值 | 名称 | 说明 |
|---|---|---|
| 0x8020 | ARP_DROP | ARP丢弃 |
| 0x20 | ARP | ARP通过 |
5.4 Fragment 03: MRP (媒体冗余协议过滤器)
EtherType : 0x88E3 (MRP), 0x80E1 (EIP/DLR)
功能: 识别MRP和DLR协议帧
代码:
c
// 跳过DA+SA
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00
// 跳过VLAN
0x00, 0x81, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x80
// 检查EtherType=0x88E3 (MRP)
0xE3, 0x88, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x80
// --> SV_EQU | Lbl_MRP_PASS=3 | 0 | 0 | ffffh | 88e3h
// 检查EtherType=0x80E1 (EIP/DLR)
0xE1, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0x80
// --> SV_EQU | Lbl_MRP_PASS=2 | 0 | 0 | ffffh | 80e1h
// 丢弃
0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x10
// --> DROP | 32816 | 0
// 通过
0x09, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x11
// --> PASS | 48 | 9
FDC : 0x30 (MRP通过), 0x8030 (MRP丢弃)
5.5 Fragment 04: LLDP (链路层发现协议过滤器)
EtherType : 0x88CC
功能: 简单识别LLDP帧
代码:
c
0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x11
// --> PASS | 64 | 8
FDC : 0x40 (LLDP)
5.6 Fragment 05: PN_DCP (PROFINET DCP过滤器)
EtherType : 0x8892
功能: 识别DCP (Discovery and Configuration Protocol) 帧,包括DCP-Hello
处理流程:
1. 跳过DA+SA和VLAN
2. 验证EtherType=0x8892
3. 检查FrameID:
- 0xFEFC: DCP-Hello (多播)
- 0xFEFE: 非DCP多播
4. 对于DCP-Hello:
- 检查TLV结构
- 使用SDT表匹配32个Hello过滤器
5. 对于普通DCP:
- 检查TLV结构
- 使用SDT表匹配5个DCP过滤器
SDT索引结构:
DCP过滤器 (SDT 0x00-0x09):
├── 0x00: DCP_01TYPE (类型快速预扫描)
├── 0x01: DCP_01TLV (完整字符串)
├── 0x02: DCP_02TYPE
├── 0x03: DCP_02TLV
├── 0x04: DCP_03TYPE
├── 0x05: DCP_03TLV
├── 0x06: DCP_04TYPE
├── 0x07: DCP_04TLV
├── 0x08: DCP_05TYPE
└── 0x09: DCP_05TLV
DCP-Hello过滤器 (SDT 0x0A-0x49):
├── 0x0A: DCP_HELLO_01_LEN
├── 0x0B: DCP_HELLO_01TLV
├── ...
├── 0x48: DCP_HELLO_32_LEN
└── 0x49: DCP_HELLO_32TLV
FDC定义:
| FDC值 | 名称 | 说明 |
|---|---|---|
| 0x8050 | DCP_DROP | DCP丢弃 |
| 0x50 | DCP | 普通DCP |
| 0x51 | DCP_HELLO | Hello过滤器1 |
| 0x451 | DCP_HELLO2 | Hello过滤器2 |
| ... | ... | ... |
| 0x7C51 | DCP_HELLO32 | Hello过滤器32 |
5.7 Fragment 06: ALARM (报警过滤器)
EtherType : 0x8892
功能: 识别PROFINET报警帧 (FrameID: 0xFC00-0xFCFF 高优先级, 0xFE00-0xFEFC 低优先级)
代码:
c
0x05, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x11
// --> PASS | 96 | 5
FDC : 0x60 (ASRT - Alarm Soft Real Time)
5.8 Fragment 07: LEN (长度类型过滤器)
EtherType : < 0x0800 (长度字段)
功能: 处理802.3帧,识别特殊协议
处理流程:
1. 跳过DA+SA和VLAN
2. 检查EtherType < 0x0800
3. 检查DSAP/SSAP:
- 0xFDFD: SINEC-FWL
- 0xAAAA: SNAP
4. 对于SNAP帧,检查OUI:
- 0x080063: DCP (cd7)
- 0x080000: TSYNC
- 0x011000: SINEC-FWL
- 0x0110FB: STDBY
5. 检查HSR (High-availability Seamless Redundancy)
FDC定义:
| FDC值 | 名称 | 说明 |
|---|---|---|
| 0x8070 | LEN_DROP | LEN丢弃 |
| 0x70 | LEN_DCP | DCP over 802.3 |
| 0x71 | LEN_TSYNC | 时间同步 |
| 0x72 | LEN_STDBY | 备用协议 |
| 0x73 | LEN_HSR | HSR帧 |
| 0x74 | LEN_SINEC_FWL | SINEC防火墙 |
5.9 Fragment 08: PTCP (精确时间协议过滤器)
EtherType : 0x88F7 (PTP), 0x8892 (PROFINET时间同步)
功能: 识别PTP (Precision Time Protocol) 和PROFINET时间同步帧
处理流程:
1. 检查EtherType:
- 0x88F7: PTP
- 0x8892: PROFINET
2. 对于PTP:
- 检查transportSpecific == 0x1 (gPTP)
- 检查messageType:
- 0x2/0x3: DELAY_REQ/DELAY_FURSP
- 0xA: DELAY_FU
3. 对于PROFINET:
- 检查FrameID:
- 0xFF00/0xFF01: ANNOUNCE
- 0xFF40-0xFF43: DELAY
- 0x0020/0x0021: Sync0/1
- 0x0080/0x0081: Sync0/1
- 0xFF20/0xFF21: SyncFU 0/1
4. 分发到KRISC RX Ring或NRT
RX Ring定义 (KRISC):
c
#define RING_K32_SYNC_CLOCK 0x1D // PTCP时钟同步
#define RING_K32_SYNC_TIME 0x1E // gPTP时间同步
#define RING_K32_SYNC_DELAY 0x1F // PTCP延迟
FDC定义:
| FDC值 | 名称 | 说明 |
|---|---|---|
| 0x8080 | PTCP_DROP | PTCP丢弃 |
| 0x80 | PTCP_ANNOUNCE | PTCP通告 |
| 0x81 | PTCP_K32_SYNC_0 | K32时钟同步 |
| 0x82 | PTCP_K32_SYNC_1 | K32时间同步 |
| 0x83 | PTCP_K32_DELAY | K32延迟 |
| 0x84 | PTCP_K32_SNC_0_FU | Sync0 Follow Up |
| 0x85 | PTCP_K32_SNC_1_FU | Sync1 Follow Up |
| 0x86 | K32_GPTP | gPTP帧 |
5.10 Fragment 09: IP6 (IPv6过滤器) - HERA/I8专用
EtherType : 0x86DD
功能: 识别并分类IPv6协议帧
SDT索引:
c
#define EDDP_HERA_SDT_IDX_BC_MAC 0x50 // 广播MAC地址
Store索引:
c
#define EDDP_HERA_STORE_IDX_IP6_MAC_TYPE 0x2 // MAC类型
#define EDDP_HERA_STORE_IDX_HEADERLENGTH 0x3 // 头长度
#define EDDP_HERA_STORE_IDX_NEXT_HEADER 0x4 // 下一个头
#define EDDP_HERA_STORE_IDX_IP6_POSSIBLE_RTA_OVER_UDP 0x5 // 可能的RTA over UDP
#define EDDP_HERA_STORE_IDX_IP6_FRAGMENTED 0x6 // 分片标志
FDC: 类似IPv4,但处理IPv6协议栈
5.11 Fragment 10: HSYNC (硬件同步过滤器) - HERA/I8专用
EtherType : 0x800A
功能: 识别硬件同步帧
代码:
c
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12
// --> CYCLIC | 0 | 0
FDC : 0x90 (HSYNC)
5.12 Fragment 14: RT_CT (实时周期帧)
EtherType : 0x8892
FrameID范围 : 0x0100-0xBFFF (RT_FRAME), 0xC000-0xFBFF (RT_FRAME_UDP)
功能: 识别实时周期通信帧,直接放入周期缓冲区
代码:
c
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12
// --> CYCLIC | 0 | 0
FDC : 0x80E0 (RT_CT_DROP)
5.13 Fragment 15: RT_SF (实时非周期帧)
EtherType : 0x8892
FrameID范围: 不匹配RT_CT的帧
功能: 识别实时非周期帧
代码:
c
0x00, 0x00, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x10
// --> DROP | 33008 | 0
FDC : 0x80F0 (RT_SF_DROP)
6. FDC (Filter Decision Code) 字段解析
6.1 FDC位域结构
┌────────┬────────────────────┬──────────────┬────────────┐
│ Bit 15 │ Bit 14-10 │ Bit 9-4 │ Bit 3-0 │
├────────┼────────────────────┼──────────────┼────────────┤
│ Drop │ Reserved/TBD │ Group │ Sub-Group │
│ 标志 │ (保留) │ (组) │ (子组) │
└────────┴────────────────────┴──────────────┴────────────┘
6.2 位域说明
| 位域 | 掩码 | 说明 |
|---|---|---|
| Bit 15 | 0x8000 | Drop标志: 0=接受, 1=丢弃 |
| Bit 14-10 | - | 保留/未来使用 |
| Bit 9-4 | 0x3F0 | 组ID (对应RX Ring索引) |
| Bit 3-0 | 0xF | 子组ID |
6.3 FDC组映射
| 组ID | 组掩码 | 协议类型 | RX Ring索引 |
|---|---|---|---|
| 0x00 | 0x0 | OTHER | 0 (DROP) |
| 0x10 | 0x10 | IP/UDP | 2-4 |
| 0x20 | 0x20 | ARP | 2 |
| 0x30 | 0x30 | MRP | 9 |
| 0x40 | 0x40 | LLDP | 8 |
| 0x50 | 0x50 | DCP | 6 |
| 0x60 | 0x60 | ALARM | 5 |
| 0x70 | 0x70 | LEN | 0xA |
| 0x80 | 0x80 | PTCP | 0x1D-0x1F |
| 0x90 | 0x90 | HSYNC | 0xB |
| 0xE0 | 0xE0 | RT_CT | - (CYCLIC) |
| 0xF0 | 0xF0 | RT_SF | - (DROP) |
7. SDT (String Descriptor Table) 机制
7.1 SDT条目格式 (32位)
┌─────────────────────────────────────────────────────────────────┐
│ Bit 31-24 │ Bit 23-16 │ Bit 15-8 │ Bit 7-0 │
├────────────┼─────────────┼─────────────┼────────────────────────┤
│ Enable │ Length │ Offset │ PStringTable Number │
│ 使能 │ 长度 │ 偏移 │ 并行字符串表编号 │
└────────────┴─────────────┴─────────────┴────────────────────────┘
7.2 SDT条目类型
c
// 禁用条目 (通配符不匹配)
#define PNIP_FILTER_STRING_DESCR_DEF_OFF 0x00000000
// 启用条目 (通配符匹配)
#define PNIP_FILTER_STRING_DESCR_DEF_ON 0x01000000
7.3 ERTEC200P SDT索引分配
索引范围 用途
───────────────────────────────────────────────────────────
0x00-0x09 DCP过滤器 (5组 TYPE+TLV)
0x0A-0x49 DCP-Hello过滤器 (32组 LEN+TLV)
0x4A ARP IP地址过滤器
0x4B-0x4F 保留
7.4 HERA SDT索引分配
索引范围 用途
───────────────────────────────────────────────────────────
0x00-0x03 DCP并行字符串表 (PSTable)
├── 0x00 DCP_HELLO_TLV_PSTABLE_1
├── 0x01 DCP_HELLO_TLV_PSTABLE_2
├── 0x02 DCP_IDENTIFY_TLV_PSTABLE
└── 0x03 DCP_IDENTIFY_TYPE_PSTABLE
0x04-0x06 ARP IP地址过滤器 (3个IP地址)
├── 0x04 ARP_IP_0
├── 0x05 ARP_IP_1
└── 0x06 ARP_IP_2
0x50 广播MAC地址 (IPv6)
8. RX Ring 机制
8.1 Ring索引定义
c
// ERTEC200P / HERA 通用
#define EDDP_HWF_ARD_INDEX_DROP 0x0 // 丢弃
#define EDDP_HWF_ARD_INDEX_OTHER 0x1 // 其他
#define EDDP_HWF_ARD_INDEX_IP_MISC 0x2 // IP杂项
#define EDDP_HWF_ARD_INDEX_IP_TCP 0x3 // TCP
#define EDDP_HWF_ARD_INDEX_IP_UDP 0x4 // UDP
#define EDDP_HWF_ARD_INDEX_ALARM 0x5 // 报警
#define EDDP_HWF_ARD_INDEX_DCP 0x6 // DCP
#define EDDP_HWF_ARD_INDEX_PTCP_ANN 0x7 // PTCP通告
#define EDDP_HWF_ARD_INDEX_LLDP 0x8 // LLDP
#define EDDP_HWF_ARD_INDEX_MRP 0x9 // MRP
#define EDDP_HWF_ARD_INDEX_MISC 0xA // 杂项(TSYNC/FWL)
// KRISC专用 (时间同步)
#define EDDP_HWF_ARD_IDX_K32_SNC_CLOCK 0x1D // 时钟同步
#define EDDP_HWF_ARD_IDX_K32_SNC_TIME 0x1E // 时间同步
#define EDDP_HWF_ARD_IDX_K32_SNC_DELAY 0x1F // 延迟
// HERA专用
#define EDDP_HERA_HWF_ARD_INDEX_HSYNC 0xB // 硬件同步
8.2 Ring使用掩码
c
// ERTEC200P
#define EDDP_HWF_ARD_HWF_USED_RINGS 0xE0000FFF // 所有使用的Ring
#define EDDP_HWF_ARD_K32_USED_RINGS 0xE0000000 // KRISC处理的Ring
#define EDDP_HWF_ARD_NRT_USED_RINGS 0x00000FFF // NRT处理的Ring
// HERA
#define EDDP_HERA_HWF_ARD_HWF_USED_RINGS 0xE0000FFF
#define EDDP_HERA_HWF_ARD_NRT_RINGS_HIGH 0x00000B00 // 高优先级NRT Ring
#define EDDP_HERA_HWF_ARD_NRT_RINGS_LOW 0x000004FF // 低优先级NRT Ring
9. 过滤器使能掩码
9.1 ERTEC200P掩码
c
#define EDDP_HWF_OTHER_MASK 0x0001 // Fragment 00
#define EDDP_HWF_IP_MASK 0x0002 // Fragment 01
#define EDDP_HWF_ARP_MASK 0x0004 // Fragment 02
#define EDDP_HWF_MRP_MASK 0x0008 // Fragment 03
#define EDDP_HWF_LLDP_MASK 0x0010 // Fragment 04
#define EDDP_HWF_PN_DCP_MASK 0x0020 // Fragment 05
#define EDDP_HWF_ALARM_MASK 0x0040 // Fragment 06
#define EDDP_HWF_LEN_MASK 0x0080 // Fragment 07
#define EDDP_HWF_PTCP_MASK 0x0100 // Fragment 08
#define EDDP_HWF_CT_MASK 0x4000 // Fragment 14
#define EDDP_HWF_SF_MASK 0x8000 // Fragment 15
#define EDDP_HWF_ALL_CODE_MASK 0xC1FF // 全部启用
9.2 HERA掩码
c
#define EDDP_HERA_HWF_OTHER_MASK 0x0001 // Fragment 00
#define EDDP_HERA_HWF_IP4_MASK 0x0002 // Fragment 01
#define EDDP_HERA_HWF_ARP_MASK 0x0004 // Fragment 02
#define EDDP_HERA_HWF_MRP_MASK 0x0008 // Fragment 03
#define EDDP_HERA_HWF_LLDP_MASK 0x0010 // Fragment 04
#define EDDP_HERA_HWF_PN_DCP_MASK 0x0020 // Fragment 05
#define EDDP_HERA_HWF_ALARM_MASK 0x0040 // Fragment 06
#define EDDP_HERA_HWF_LEN_MASK 0x0080 // Fragment 07
#define EDDP_HERA_HWF_PTCP_MASK 0x0100 // Fragment 08
#define EDDP_HERA_HWF_IP6_MASK 0x0200 // Fragment 09
#define EDDP_HERA_HWF_HSYNC_MASK 0x0400 // Fragment 10
#define EDDP_HERA_HWF_ALL_CODE_MASK 0x07FF // 全部启用
10. 初始化流程
10.1 EDDP_HWCInitFilterCode()
c
EDD_RSP EDDP_HWCInitFilterCode(
EDDP_LOCAL_DDB_PTR_TYPE pDDB,
LSA_UINTPTR nApiCtrlCodeHostAddr)
功能: 将过滤器代码加载到API-CtrlRAM并设置片段寄存器
流程:
- 将物理地址转换为主机地址
- 根据芯片版本选择对应的过滤器代码:
- Rev1/Rev2:
eddp_hwfiltercode[] - Rev3 (HERA):
eddp_herahwfiltercode[] - Rev4 (I8):
eddp_I8hwfiltercode[]
- Rev1/Rev2:
- 写入过滤器代码到RAM
- 配置16个FILTERCODEBASE_IFA寄存器
10.2 EDDP_HWCInitDisabledSdtEntries()
c
EDD_RSP EDDP_HWCInitDisabledSdtEntries(
EDDP_LOCAL_DDB_PTR_TYPE pDDB,
LSA_UINTPTR nApiCtrlSdtBaseHostAddr)
功能: 初始化SDT表,设置默认禁用状态
流程:
- 遍历所有SDT条目
- 对于ARP条目,设置为通配符匹配
- 对于DCP条目,配置并行字符串表参数
- 其他条目设置为禁用状态
10.3 EDDP_HWCSetRegisterToDefaults()
c
EDD_RSP EDDP_HWCSetRegisterToDefaults(
EDDP_LOCAL_DDB_PTR_TYPE pDDB)
功能: 重置统计和错误寄存器
流程:
- 清除错误状态寄存器
- 清除错误事件寄存器
- 禁用LOG功能
- 清除DROP计数器
- 对于Rev4,清除公共存储寄存器
11. 辅助函数
11.1 数据读写函数
| 函数名 | 功能 |
|---|---|
| EDDP_HWCWriteDataToRAM | 写数据到API-CtrlRAM |
| EDDP_HWCReadDataFromRAM | 从API-CtrlRAM读数据 |
| EDDP_HWCWriteSdtEntry | 写SDT条目 |
| EDDP_HWCReadSdtEntry | 读SDT条目 |
| EDDP_HWCUpdateSdtString | 更新SDT字符串 |
11.2 查询函数
| 函数名 | 功能 |
|---|---|
| EDDP_HWCGetHWFilterVersion | 获取过滤器版本字符串 |
| EDDP_HWCGetFilterCtrlStructurePtr | 获取过滤器控制结构指针 |
12. 过滤器版本信息
12.1 版本字符串位置
| 芯片 | 偏移 | 大小 |
|---|---|---|
| ERTEC200P | 0x5D8 | 8字节 |
| HERA | 0x7A8 | 8字节 |
| I8 | (定义在对应头文件) | 8字节 |
12.2 版本格式
c
0x56, 0x31, 0x2E, 0x30, 0x30, 0x72, 0x31, 0x00
// 'V', '1', '.', '0', '0', 'r', '1', '\0'
13. 帧类型匹配汇总表
| EtherType | FrameID/特征 | 过滤器片段 | FDC | RX Ring | 处理方式 |
|---|---|---|---|---|---|
| 其他 | - | 00 (OTHER) | 0x8000 | 0 | DROP |
| 0x0800 | IP/ICMP | 01 (IP) | 0x10 | 0xA | PASS |
| 0x0800 | IP/IGMP | 01 (IP) | 0x11 | 0xA | PASS |
| 0x0800 | IP/TCP | 01 (IP) | 0x12 | 0x3 | PASS |
| 0x0800 | IP/UDP | 01 (IP) | 0x13 | 0x4 | PASS |
| 0x0800 | UDP/DCP | 01 (IP) | 0x15 | 0x6 | PASS |
| 0x0806 | ARP | 02 (ARP) | 0x20 | 0x2 | PASS |
| 0x88E3 | MRP | 03 (MRP) | 0x30 | 0x9 | PASS |
| 0x80E1 | DLR | 03 (MRP) | 0x30 | 0x9 | PASS |
| 0x88CC | LLDP | 04 (LLDP) | 0x40 | 0x8 | PASS |
| 0x8892 | DCP | 05 (PN_DCP) | 0x50 | 0x6 | PASS |
| 0x8892 | DCP-Hello | 05 (PN_DCP) | 0x51-0x7C51 | 0x6 | PASS |
| 0x8892 | Alarm | 06 (ALARM) | 0x60 | 0x5 | PASS |
| <0x0800 | 802.3/DCP | 07 (LEN) | 0x70 | 0x6 | PASS |
| <0x0800 | TSYNC | 07 (LEN) | 0x71 | 0xA | PASS |
| 0x88F7 | PTP | 08 (PTCP) | 0x80-0x86 | 0x1D-0x1F | PASS |
| 0x8892 | PTCP | 08 (PTCP) | 0x80-0x86 | 0x1D-0x1F | PASS |
| 0x86DD | IPv6 | 09 (IP6) | - | - | PASS |
| 0x800A | HSYNC | 10 (HSYNC) | 0x90 | 0xB | PASS |
| 0x8892 | 0x0100-0xBFFF | 14 (RT_CT) | - | - | CYCLIC |
| 0x8892 | 其他 | 15 (RT_SF) | 0x80F0 | - | DROP |
14. 调试与诊断
14.1 错误状态寄存器
PNIP_REG_FILTERERRSTATUS_IFA: 过滤器错误状态PNIP_REG_FILTERERREVENT_IFA: 过滤器错误事件
14.2 DROP计数器
每个过滤器片段有对应的DROP计数器:
c
for (idx = 0; idx < 16*4; idx += 4) {
EDDP_HAL_REG32_WRITE(pDDB, PNIP_REG_DROPCOUNT_IFA_00 + idx, 0);
}
14.3 LOG控制
c
EDDP_HAL_REG32_WRITE(pDDB, PNIP_REG_LOGCONTROL_IFA, 0); // 禁用LOG
15. 安全考虑
- 边界检查: 所有SDT索引和Store索引都有编译时检查
- 版本验证: 初始化时检查芯片版本,不支持版本触发FATAL错误
- 内存对齐: HERA芯片使用32位对齐访问
- 缓冲区验证: 读写操作前验证指针非空
16. 性能优化
- 硬件加速: 过滤在硬件层面执行,零CPU开销
- 并行匹配: HERA支持并行字符串表(PSTable)加速DCP匹配
- Ring隔离: 高/低优先级帧使用不同RX Ring,避免优先级反转
- KRISC卸载: 时间同步帧直接由KRISC协处理器处理
附录 A: 指令集参考
| Opcode | 名称 | 语法 | 说明 |
|---|---|---|---|
| 0x00 | SKIP | `SKIP | n` |
| 0x01 | PASS | `PASS | FDC |
| 0x02 | DROP | `DROP | FDC` |
| 0x03 | CYCLIC | `CYCLIC | 0 |
| 0x0x | SCMP | `SCMP | lbl |
| 0x80 | SV_EQU | `SV_EQU | lbl |
| 0x81 | SV_NEQ | `SV_NEQ | lbl |
| 0x83 | SV_LT | `SV_LT | lbl |
| 0x84 | SV_GTE | `SV_GTE | lbl |
| 0x87 | SM_STORE | `SM_STORE | skip |
| 0x89 | SM_NEQ | `SM_NEQ | lbl |
附录 B: 相关寄存器
| 寄存器 | 说明 |
|---|---|
| PNIP_REG_FILTERCODEBASE_IFA_00-15 | 过滤器代码基址 |
| PNIP_REG_FILTERERRSTATUS_IFA | 错误状态 |
| PNIP_REG_FILTERERREVENT_IFA | 错误事件 |
| PNIP_REG_LOGCONTROL_IFA | LOG控制 |
| PNIP_REG_DROPCOUNT_IFA_00-15 | DROP计数 |
| PNIP_R4_REG_APIFILTER_CONTROL_STORE_R45 | Rev4控制存储 |
| PNIP_R4_REG_APIFILTER_CONTROL_STORE_R67 | Rev4控制存储 |
附录 C: PROFINET Frame Identification Table
| Destination MAC | EtherType (Hex) | FrameID / Feature (Hex) | Meaning | Protocol |
|---|---|---|---|---|
01-0E-CF-00-00-00 |
0x8892 |
0xFEFE |
DCP Identify Request/Response | DCP |
01-0E-CF-00-00-01 |
0x8892 |
0xFEFC |
DCP Hello Request | DCP |
| Unicast | 0x8892 |
0xFEFD |
DCP Get/Set Request & Response | DCP |
01-0E-CF-00-00-02 -- 00-00-1F |
0x8892 |
N/A | Reserved for other applications | DCP |
01-0E-CF-00-00-20 -- 00-00-3F |
0x8892 |
0xFEFE |
Identifiable DCP Identify Request | DCP |
01-0E-CF-00-00-40 -- 00-00-FF |
0x8892 |
N/A | Reserved for other applications | DCP |
Unicast/Multicast 01-0E-CF-00-01-01 |
0x8892 |
0x0100 -- 0x06FF |
RT_CLASS_3 Real-time Data (Non-redundant/DFP) | RTC |
| Unicast/Multicast | 0x8892 |
0x0700 -- 0x0FFF |
RT_CLASS_3 Real-time Data (Redundant Ring) | RTC |
| Unicast/Multicast | 0x8892 |
0x1000 -- 0x47FF |
Reserved | RTC |
| Unicast/Multicast | 0x8892 |
0x1000 -- 0x2FFF |
Time-aware Streams (Unicast) | RTC (Streams) |
| Unicast/Multicast | 0x8892 |
0x3800 -- 0x3FFF |
Time-aware Streams (Multicast) | RTC (Streams) |
| Multicast | 0x8892 |
0x8000 -- 0xBBFF |
Non-redundant Real-time Data RT_CLASS_1 (GREEN) | RTC / RTA |
| Unicast | 0x8892 |
0xBC00 -- 0xBFFF |
Non-redundant Real-time Data RT_CLASS_1 (GREEN) | RTC / RTA |
| Unicast | 0x8892 |
0xC000 -- 0xCFFF |
RT_CLASS_UDP (Unicast) | RTC1 (UDP) |
| Unicast | 0x8892 |
0xD000 -- 0xDFFF |
RT_CLASS_UDP (Unicast) with Security | RTC1 (UDP) Security |
| Multicast | 0x8892 |
0xE000 -- 0xF3FF |
Reserved | Reserved |
| Multicast | 0x8892 |
0xF400 -- 0xF7FF |
RT_CLASS_UDP (Unicast) with Security | RTC1 (UDP) |
| Unicast/Multicast | 0x8892 |
0xF800 -- 0xFBFF |
RT_CLASS_UDP (Unicast) | RTC1 (UDP) |
| Unicast/Multicast | 0x8892 |
0xFC01 |
High Priority Alarm (Alarm_High) | RTA |
| Unicast/Multicast | 0x8892 |
0xFC41 |
High Priority Alarm (Alarm_High) with Security | RTA |
| Unicast/Multicast | 0x8892 |
0xFE01 |
Low Priority Alarm (Alarm_Low) | RTA |
| Unicast/Multicast | 0x8892 |
0xFE41 |
Low Priority Alarm (Alarm_Low) with Security | RTA |
| Unicast/Multicast | 0x8892 |
0xFE02 |
Remote Service Interface (FREQ, FRSP, ACK, ERR) | RSI |
| Unicast/Multicast | 0x8892 |
0xFE42 |
Remote Service Interface (FREQ, FRSP, ACK, ERR) Security | RSI |
Multicast (01-0E-CF-00-04-20 etc.) |
0x8892 |
0x0020 |
PTCP RTSync PDU (with FollowUp) | PTCP |
Multicast (01-0E-CF-00-04-80 etc.) |
0x8892 |
0x0080 |
PTCP RTSync PDU (without FollowUp) | PTCP |
Multicast (01-0E-CF-00-04-00) |
0x8892 |
0xFF00 |
PTCP Announce PDU (Working Clock Sync) | PTCP |
Multicast (01-0E-CF-00-04-40 etc.) |
0x8892 |
0xFF20 |
PTCP FollowUp PDU (Working Clock Sync) | PTCP |
Multicast (01-80-C2-00-00-0E etc.) |
0x8892 |
0xFF40 |
PTCP Delay Request PDU | PTCP |
Multicast (01-80-C2-00-00-0E etc.) |
0x8892 |
0xFF41 |
PTCP Delay Response PDU (with FollowUp) | PTCP |
Multicast (01-80-C2-00-00-0E etc.) |
0x8892 |
0xFF42 |
PTCP Delay FollowUp Response PDU (with FollowUp) | PTCP |
Multicast (01-80-C2-00-00-0E etc.) |
0x8892 |
0xFF43 |
PTCP Delay Response PDU (without FollowUp) | PTCP |
| Any | 0x8892 |
0xFF80 -- 0xFF8F |
Fragmentation Protocol Frames | FRAG |
Multicast (01-80-C2-00-00-00 ~ 0F) |
0x88E3 |
N/A | Media Redundancy Protocol | MRP |
Multicast (01-80-C2-00-00-00 ~ 0F) |
0x88CC |
N/A | Link Layer Discovery Protocol | LLDP |
| Any | 0x0800 |
N/A | IPv4 Packets (TCP, UDP, ICMP, etc.) | IP Suite |
| Any | 0x0806 |
N/A | Address Resolution Protocol | ARP |
| Any | 0x88F7 |
N/A | Precision Time Protocol (gPTP / IEEE 1588) | PTP |
| Any | 0xF1C1 |
N/A | Seamless Redundancy (IEEE 802.1CB) | RTI (Redundancy) |
Multicast (01-00-5E-xx-xx-xx) |
0x0800 |
N/A | IP Multicast Traffic (Mapped to RT_CLASS_UDP range) | IP/UDP |