前言
基于 Microchip LAN8650/LAN8651 + OA TC6 协议栈的现有 Arduino 10BASE-T1S 库(lwIP + UDP/IP 架构),本文分析切换到 RCP(Remote Control Protocol)/AVTP 协议栈的可行性、架构差异、所需移植修改的模块,以及如何利用 oa-tc6-lib 和 Open1722 开源库实现二次开发。
一、现有架构回顾
1.1 当前分层结构
1 | 应用层 (Arduino Sketch) |
1.2 编译产物实测数据(已知)
| 模块 | Flash 占用 |
|---|---|
| lwIP | ~45KB |
| libtc6 | ~15KB |
| 库包装层 | ~8KB |
| Arduino Core | ~30KB |
| FSP HAL | ~12KB |
| 总计 | ~110KB(剩余 130KB 给应用) |
1.3 现有库关键文件
| 文件 | 职责 |
|---|---|
src/Arduino_10BASE_T1S_UDP.cpp |
UDP Socket API 实现 |
src/microchip/TC6_Arduino_10BASE_T1S.cpp |
TC6 + lwIP 绑定层 |
src/microchip/TC6_Io.cpp |
SPI HAL 抽象 |
src/lib/liblwip/ |
lwIP 源码 |
src/microchip/lib/libtc6/ |
OA TC6 协议库 |
二、RCP/AVTP 协议栈本质分析
2.1 RCP 与 AVTP 的关系
RCP(Remote Control Protocol) 构建在 IEEE 1722 AVTP 之上,是一个汽车专用扩展。理解这个关系至关重要:
1 | ┌──────────────────────────────────┐ |
关键点:RCP 完全工作在 Ethernet Layer 2,EtherType = 0x22F0,不需要 IP/UDP 协议栈。
2.2 RCP 的核心价值:架构解耦
1 | 传统架构(现状): |
这正是用户提到的”基于底层 MACPHY 数字电路,做网络包处理”——MCU 只做 Ethernet Frame 的收发,所有协议解析和业务逻辑集中在远端。
2.3 AVTP 的两种传输头部
Open1722 库支持两种 AVTP 传输格式,RCP 协议依赖它们:
| 头部类型 | 用途 | AVTP Timestamp | Stream ID | 适用场景 |
|---|---|---|---|---|
| NTSCF (Non-TSCF) | 立即执行/响应 | 无 | 64-bit | 标准请求、ACK、带时间戳的响应 |
| TSCF (Time-SCF) | 定时执行 | 32-bit | 64-bit | 定时请求(呈现时间控制) |
NTSCF 头部结构(12 字节):
1 | Byte 0 : subtype (0x82) + sv + version |
ACF_GBB 消息头结构(16 字节,在 AVTP payload 中):
1 | Byte 0-3 : ACF common (msg_type=0x0D, length) |
2.4 RCP 端点类型
RCP 定义了 13 种端点类型,对应不同的外设:
| EP 编号 | 类型 | 说明 |
|---|---|---|
| EP0 | RC Server | 配置、状态、发现(必须实现) |
| EP1 | 唤醒控制 | 休眠/唤醒(可选) |
| SPI | SPI Controller | 远程访问 SPI 外设 |
| GPIO | GPIO | 数字输入输出 |
| I²C | I²C Controller | I²C 总线访问 |
| UART | UART | 串口通信 |
| ADC | ADC | 模数转换读取 |
| CAN | CAN Controller | CAN 总线 |
| PWM_OUT/IN | PWM | 脉宽调制 |
| LIN | LIN Commander | LIN 总线 |
| MDIO | MDIO | PHY 管理 |
三、UDP/IP vs RCP/AVTP:核心对比
3.1 协议栈复杂度
| 维度 | UDP/IP 方案(现有) | RCP/AVTP 方案(目标) |
|---|---|---|
| 协议层数 | 5层 (App→UDP→IP→Eth→TC6) | 3层 (App→AVTP→TC6) |
| 最大 Flash 节省 | 基准 | ~45KB(去掉 lwIP) |
| 最大 RAM 节省 | 基准 | ~15-20KB |
| EtherType | 0x0800 (IPv4) | 0x22F0 (AVTP) |
| 需要 IP 地址 | 是 | 否(纯 MAC 寻址) |
| 需要 ARP | 是 | 否 |
| 需要 DHCP | 是(通常) | 否 |
| 网络发现 | ARP/NDP | RCP 发现协议(EP0) |
| 时间同步 | NTP(可选) | gPTP(可选,但 RCP 推荐) |
| 路由支持 | 是(IP 层) | 否(纯广播/单播 MAC) |
3.2 性能与资源
| 指标 | UDP/IP | RCP/AVTP |
|---|---|---|
| 最大包长 | 1472B (UDP) | 受 MTU 限制,典型 1500B |
| 协议开销 | IP(20)+UDP(8)=28B | AVTP(12)+ACF(16~)≈28B+ |
| 网络发现延迟 | ARP ~1s | RCP 发现更快 |
| 确定性 | 尽力而为 | 可通过 TSCF + gPTP 实现确定性 |
| 多节点访问 | Socket 绑定端口 | byte_bus_id 端点寻址 |
3.3 场景适配性评估
| 场景 | UDP/IP | RCP/AVTP | 推荐 |
|---|---|---|---|
| 通用数据通信 | ✅ | ⚠️ | UDP/IP |
| 高速流媒体 | ⚠️ | ✅ | AVTP |
| 远程外设控制(SPI/GPIO/I2C) | ❌ | ✅ | RCP |
| 低资源嵌入式节点 | ⚠️ | ✅ | RCP |
| 需要路由的多子网 | ✅ | ❌ | UDP/IP |
| 汽车 ECU 远程控制 | ❌ | ✅ | RCP |
结论:用户提到”基于底层 MACPHY 数字电路,做网络包处理”——这正是 RCP/AVTP 的设计目标。去掉 lwIP 是合理的,节省 ~45KB Flash。
四、开源库嫁接方案
4.1 库文件映射
现有库依赖两个开源项目,可以与 RCP/AVTP 栈组合:
1 | 开源库 作用 保留? |
4.2 Open1722 库关键模块
Open1722 提供了完整的 IEEE 1722 实现,文件组织如下:
1 | Open1722/ |
关键发现:
AVTP_ACF_TYPE_BYTE_BUS = 0x0D是 RCP 的 ACF 消息类型Avtp_Gbb_*函数族提供 ACF_GBB 格式的完整解析Avtp_Ntscf_*函数族提供 NTSCF 头部的完整解析- 全部是 header-only 内联函数,无需额外编译
4.3 RCP 消息构建示例
基于 Open1722 + oa-tc6-lib,RCP 请求的构建流程:
1 |
|
五、架构重新设计方案
5.1 目标架构
1 | ┌─────────────────────────────────────────┐ |
节省:去掉 lwIP (45KB) + UDP 包装层 (8KB) = ~53KB
5.2 模块保留/修改/新增矩阵
| 模块 | 动作 | 原因 |
|---|---|---|
libtc6/ |
保留 | TC6 协议状态机是 LAN8650 通信基础 |
TC6_Io.cpp |
修改 | SPI 速率可能调整(TC6 最高 25MHz),但基本架构不变 |
TC6_Arduino_10BASE_T1S.cpp |
大幅修改 | 去掉 lwIP 绑定,换接 RCP/AVTP 栈 |
Arduino_10BASE_T1S_UDP.cpp |
删除/替换 | 替换为 RCP Client API |
lwIP/ |
删除/禁用 | 不再需要,节省 ~45KB |
Open1722/ |
新增 | 从 Open1722/include/avtp/ 引入 |
RCP Client/ |
新增 | RCP 协议状态机、消息编解码、端点管理 |
AVTP Listener/ |
新增 | 接收 RCP 响应帧,路由到 RCP Client |
5.3 数据流对比
发送路径(去掉 lwIP 后):
1 | Arduino Sketch |
接收路径:
1 | LAN8650 MAC-PHY |
六、移植修改详细计划
阶段 1:基础通信验证(保留 lwIP,逐步替换)
引入 Open1722
- 将
Open1722/include/avtp/复制到src/lib/open1722/include/ - 验证编译:AVTP 头部解析(
Avtp_Ntscf_Init,Avtp_Gbb_Init)
- 将
创建 AVTP 帧收发测试
- 利用现有
TC6_CB_OnRxEthernetPacket回调 - 在
TC6_Arduino_10BASE_T1S层添加 EtherType 过滤 - 当 EtherType = 0x22F0 时,走 AVTP 路径;否则走 lwIP 路径
- 利用现有
验证 LAN8650 对 0x22F0 帧的收发
- LAN8650 硬件支持 EtherType = 0x22F0(AVTP 标准)
- 通过
TC6Regs_Init配置 MAC 接收过滤器
阶段 2:RCP Client 实现
实现 RCP Client 状态机
- 状态:
Idle → Request_Sent → Awaiting_Response → Response_Rx - transaction_num 分配器(8-bit,0-255)
- 请求存储队列(支持多事务并发)
- 状态:
实现 RCP 请求类型
- 标准请求(ACF_ABB):写 SPI/GPIO
- 标准请求(ACF_ABB):读 SPI/GPIO
- ACK 响应处理(evt = 0xF)
- 数据响应处理(evt = 0x0,op = 0)
gPTP 时间戳集成(可选)
- LAN8650 内置 gPTP 硬件时间戳(通过 TC6 寄存器访问)
TSC(Transmit Timestamp Capture) 字段在 TC6 头部
阶段 3:lwIP 逐步退出
创建 RCP API 替代层
RCP_Client.begin()RCP_Client.writeRegister(byte_bus_id, reg_addr, value)RCP_Client.readRegister(byte_bus_id, reg_addr, callback)RCP_Client.setStreamId(uint64_t stream_id)
替换 Arduino_10BASE_T1S_UDP
- 保留
Arduino_10BASE_T1S主类接口风格 - 将
beginUDP(port)替换为beginRCP(stream_id) - 测试现有 sketch 示例的兼容迁移
- 保留
阶段 4:完整验证
与远端 RC Server 通信验证
- 使用开源 RCP Server 实现(如有)或模拟 PC 端
- 抓包验证:EtherType=0x22F0,ACF_GBB 格式正确
性能与资源测量
- Flash/RAM 占用对比(去掉 lwIP 前 vs 后)
- 吞吐量测试(UDP pingpong vs RCP 请求响应延迟)
七、关键风险与注意事项
7.1 gPTP 时间同步
RCP 的复合请求(定时执行)和 TSCF 头部依赖 gPTP 同步:
- 需要:LAN8650 内置 gPTP 支持,或在 MCU 侧实现软件 gPTP
- 现状:现有库没有 gPTP 实现
- 建议:先从 NTSCF(无时间戳)开始,等通信稳定后再加 gPTP
7.2 RC Server 端
RCP 是客户端-服务器协议,需要有对应的 RC Server 端点:
- 如果目标是与现有设备通信:确认对端是否支持 RCP
- 如果是自研 RC Server:需要独立实现(或使用 COVESA 社区参考实现)
- 注意:Open1722 库只提供 AVTP 层的编解码,不包含 RCP Server 实现
7.3 EtherType 配置
LAN8650 默认可能只接收特定 EtherType 的帧:
- 需要通过 TC6 寄存器配置 MAC 接收过滤器
TC6Regs_Init中的promiscuous参数控制是否开启混杂模式
7.4 PLCA vs CSMA/CD
10BASE-T1S 使用 PLCA(Physical Layer Collision Avoidance)作为总线仲裁机制:
- RCP 请求-响应模式天然适配 PLCA 的单节点发送特性
- 与 lwIP 的广播/多播场景不同,RCP 倾向于点对点事务
7.5 Flash 预算
去掉 lwIP 后的预期 Flash 占用:
| 模块 | 估算 Flash |
|---|---|
| Arduino Core | ~30KB |
| FSP HAL | ~12KB |
| libtc6 | ~15KB |
| Open1722 | ~5KB |
| TC6 HAL 封装 | ~5KB |
| RCP Client | ~8KB |
| 总计 | ~75KB(节省 ~35KB) |
八、总结
8.1 架构决策
| 决策点 | 选择 | 理由 |
|---|---|---|
| 协议栈 | RCP/AVTP Layer 2 | 去掉 lwIP,节省 ~45KB,符合”网络包处理”定位 |
| 传输层 | NTSCF(非时间同步) | 最简实现,先跑通再优化 |
| 消息格式 | ACF_GBB | 兼容 ABB,支持 byte_bus_id 端点寻址 |
| 时间戳 | 暂不使用 | 先跳过 gPTP 依赖 |
| lwIP | 条件移除 | 提供条件编译开关,保留调试能力 |
8.2 下一步行动
- 立即执行:将
Open1722/include/avtp/集成到项目src/lib/open1722/ - 第一个里程碑:实现 AVTP NTSCF 帧的收发解析,验证 EtherType = 0x22F0 在 LAN8650 上正常工作
- 第二个里程碑:实现 RCP Client 状态机和 ACF_GBB 编解码
- 第三个里程碑:替换
Arduino_10BASE_T1S_UDP,保留Arduino_10BASE_T1S主类 API
8.3 参考资源
- OA TC6 lib (Microchip, v3.1.6)
- Open1722 (COVESA, BSD-3-Clause)
- OPEN Alliance RCP Specification v0.4.7 rev1
- IEEE 1722-2025 Standard for Layer 2 Transport Protocol
本文基于 Arduino 10BASE-T1S 项目现有上下文数据库、oa-tc6-lib v3.1.6 源码、Open1722 库源码、RCP 协议规范 v0.4.7 rev1 和 IEEE 1722-2025 标准综合分析。协议细节以官方规范为准。