4. R-Car以太网驱动与数据包收发实战

R-Car SoC 内部集成的 EtherAVB 控制器是车载以太网通信的核心硬件单元,它向上对接 Linux 网络子系统,向下通过 MII/RGMII 接口连接外部 PHY 芯片。理解数据包从应用层到物理介质的完整路径,是驱动移植与性能调优的前提。本节围绕 Linux 网络子系统、EtherAVB 驱动移植、DMA 描述符环配置、NAPI 与中断合并、吞吐与延迟基准测试五个环节展开,重点说明实际工程中如何配置、观察与判断。

Linux 网络子系统与 EtherAVB 的对接关系

Linux 网络子系统采用分层结构:应用层通过 socket 系统调用进入协议栈,网络设备层(net_device)负责统一抽象,驱动层则实现具体的收发操作。EtherAVB 驱动注册一个 net_device 实例,并实现 ndo_open、ndo_start_xmit、ndo_stop 等回调。发送时,协议栈调用 ndo_start_xmit 将 sk_buff 交给驱动;接收时,驱动通过 NAPI 轮询将数据包送入协议栈。EtherAVB 使用 DMA 描述符环管理收发缓冲区,CPU 只负责填充描述符和处理中断,数据搬运由 DMA 完成,这是实现高吞吐的关键。

应用层 / Socket send() / recv() TCP/IP 协议栈 sk_buff 封装/解析 网络设备层 net_device / NAPI EtherAVB 驱动 ndo_start_xmit / ISR EtherAVB 硬件 DMA / MII / RGMII DMA 描述符环(TX / RX) TX Ring Desc 0 Desc 1 Desc 2 … RX Ring Desc 0 Desc 1 Desc 2 … 描述符关键字段 • buf_addr:DMA 缓冲区物理地址 • status:OWN / RD / WR 标志位 • length:数据帧长度 外部 PHY RGMII / MII 100/1000 Mbps 车载以太网链路 100BASE-T1 / 1000BASE-T1 对端 ECU / 交换机 数据流:应用层 → 协议栈 → 驱动 → DMA 描述符环 → EtherAVB 硬件 → PHY → 链路

EtherAVB 驱动移植要点

在 R-Car 平台上移植 EtherAVB 驱动,首先需要在设备树中正确描述控制器节点。典型节点包含 compatible = "renesas,etheravb-r8a7795"、寄存器基地址、中断号、时钟以及 PHY 连接信息。以 R-Car H3 为例,EtherAVB 节点通常引用 ethernet0 别名,并配置 phy-mode = "rgmii" 或 "rgmii-id"。若 PHY 需要内部延迟,应使用 rgmii-id,否则需在 PHY 驱动中配置延迟寄存器。

驱动初始化阶段会调用 dma_alloc_coherent 分配描述符环和缓冲区,并通过 writel 配置 DMAC 寄存器。关键寄存器包括 ARSTR(软件复位)、TGC(发送门控)、RGC(接收门控)以及 DMAC 中的 TX_RING 和 RX_RING 基址。移植时常见问题是时钟未使能导致寄存器读写失败,或 PHY 地址不匹配导致链路无法建立。可通过 ethtool eth0 查看链路状态,若显示 Link detected: no,应检查设备树中的 phy-handle 和 phy-mode。

DMA 描述符环配置

EtherAVB 使用环形描述符数组管理收发。每个描述符包含缓冲区物理地址、状态标志和长度字段。发送时,驱动将 sk_buff 数据映射为 DMA 地址,填充描述符,设置 OWN 位为 1 表示硬件拥有,然后写 TGC 寄存器触发发送。接收时,硬件将数据写入缓冲区,清除 OWN 位并产生中断,驱动在 NAPI 轮询中读取描述符,将数据封装为 sk_buff 上交协议栈。

描述符环大小直接影响吞吐和延迟。以 1000 Mbps 链路为例,若环大小为 256,每个描述符对应 1536 字节缓冲区,则单环可缓存约 384 KB 数据。环太小会导致频繁中断和丢包,环太大则增加内存占用和缓存失效开销。实际工程中,TX 环常设为 256~512,RX 环设为 512~1024。可通过 ethtool -g eth0 查看当前环大小,使用 ethtool -G eth0 rx 1024 tx 512 调整。

NAPI 与中断合并

NAPI 的核心思想是“中断触发、轮询收包”。当第一个数据包到达时,硬件产生中断,驱动在中断处理程序中禁用该中断源并调度 NAPI 轮询。轮询函数 ravb_poll 在预算内(通常 64 个包)处理接收描述符,处理完毕后重新启用中断。这种方式在高负载下显著减少中断次数,降低 CPU 占用。

中断合并进一步优化性能。EtherAVB 支持通过 RAVB_ICR 寄存器配置中断合并参数,包括接收中断延迟和发送中断延迟。例如,设置接收中断延迟为 100 μs,发送中断延迟为 200 μs,可在吞吐和延迟之间取得平衡。对于车载场景,控制类报文要求低延迟,可减小合并延迟;视频流类报文要求高吞吐,可增大合并延迟。可通过 ethtool -c eth0 查看当前合并参数,使用 ethtool -C eth0 rx-usecs 100 tx-usecs 200 调整。

吞吐与延迟基准测试

基准测试是验证驱动配置是否达标的必要环节。吞吐测试常用 iperf3,在 R-Car 端运行 iperf3 -s,在 PC 端运行 iperf3 -c <R-Car IP> -t 30 -P 4,观察 30 秒内平均带宽。若 1000 Mbps 链路下吞吐低于 800 Mbps,应检查描述符环大小、中断合并参数和 CPU 亲和性。延迟测试常用 ping 或 cyclictest,例如 ping -c 100 -i 0.01 <目标IP>,观察平均 RTT 和抖动。车载控制报文通常要求 RTT 小于 1 ms,抖动小于 200 μs。

以下是一个可参考的测试记录表,用于记录不同配置下的吞吐和延迟数据。表中数值为示例,实际结果需根据硬件和网络环境测量。

配置项 TX 环 RX 环 rx-usecs tx-usecs 吞吐(Mbps) 平均 RTT(μs) 抖动(μs)
默认配置 256 512 0 0 720 420 85
增大环 512 1024 0 0 880 410 70
合并优化 512 1024 100 200 940 480 120
低延迟优先 256 512 20 50 810 350 45
调试提示:若吞吐远低于预期,可先通过 cat /proc/interrupts | grep eth0 观察中断分布。若所有中断集中在 CPU0,可通过 echo 2 > /proc/irq/<irq>/smp_affinity 将中断绑定到其他核心,减少单核瓶颈。同时检查 dmesg 中是否有 DMA 映射失败或描述符耗尽告警。
注意:调整描述符环大小和中断合并参数后,需重新运行基准测试并记录数据。不同 R-Car 型号(如 H3、M3、V3M)的 EtherAVB 寄存器布局和 DMA 能力存在差异,移植时应以对应硬件手册为准,不可直接套用其他型号的配置。

综合来看,R-Car EtherAVB 驱动的数据包收发性能取决于描述符环、NAPI 预算和中断合并三者的协同。实际工程中建议先以默认配置建立基线,再逐步调整环大小和合并参数,每次只改一个变量并记录吞吐与延迟变化,最终根据车载业务对带宽和实时性的要求确定最优配置。