3. MAC 统计计数器概述(RF/CRC 错误计数器等)

搞网络调试,说白了就是跟各种计数器打交道。你敲一行命令,出来一堆数字,外行人看着头晕,内行人却能从中读出设备的“健康状况”。

这一章我们聚焦 MAC 层统计计数器里的几个关键角色——尤其是跟 CRC 错误相关的那些。我刚开始做嵌入式网络驱动时,觉得这些计数器只是给网管看的,后来有一次定位一个丢包问题,啃了三天寄存器手册,才明白这些数字背后全是门道。

3.1 为什么先看计数器?

MAC 硬件在工作时,每收一个包、每发一个帧,都会自动把结果记录下来。你想想看,这是芯片自带的“黑匣子”。不用打 log,不用加断点,读寄存器就行。

常见的 MAC 统计计数器分几大类:

  • 帧计数类:收了多少帧、发了多少帧。
  • 字节计数类:总流量、平均帧长。
  • 错误计数类:CRC 错误、对齐错误、帧过长/过短。
  • 冲突/重传类:碰撞次数、重试次数。

咱们要分析的 CRC 错误计数器,就藏在第三类里。

核心原则:错误计数器只增不减,除非软件清零。如果某个计数器在短时间内暴涨,基本可以断定物理层或链路层有问题。

3.2 RF 错误 vs. CRC 错误

很多新手容易把 RF 错误和 CRC 错误搞混。我在项目里见过有人拿着 RF 错误计数器去怀疑对端芯片,结果查了半天,其实是本端天线接触不良。

错误类型 检测位置 触发原因 典型场景
RF 错误(物理层) 基带/射频前端 信号弱、干扰、失锁 天线没接、距离过远、同频干扰
CRC 错误(MAC 层) MAC 接收引擎 FCS 校验失败、比特翻转 信号畸变、时序错位、芯片内部逻辑误码

简单判断法:如果 RF 错误多但 CRC 错误少,说明链路质量差但接收端还能凑合忍;如果 RF 错误不多但 CRC 错误猛增,那多半是 MAC 层自身逻辑或时钟出了问题。嗯,这个区别在实战中非常关键。

3.3 CRC 错误计数器的工作原理

以太网帧末尾有 4 字节的 FCS(Frame Check Sequence),由发送端对帧头到 Payload 算出的 CRC32 值。接收端收到后重新算一遍,如果结果不一致,硬件就直接把该帧丢掉,同时把 CRC Error 计数器加 1。

// 伪代码:接收端 CRC 校验判断
if (CRC32(da + sa + type + payload) != received_fcs) {
    mac_frame_drop();           // 丢帧
    stats.crc_error_count++;    // 计数器+1
}

注意,丢帧不意味着你不感知——上层的 TCP/UDP 重传会告诉你“网不好”。但 MAC 层的计数器能告诉你到底是“网不好”还是“芯片不好”。

查代码小技巧:读 MAC 寄存器时,最好先把 CRC 错误计数器清零,然后发送几个已知错误的测试帧,看计数器会不会增长。很多芯片支持“错误帧注入”模式,用来验证硬件计数器是否工作正常。

3.4 计数器读取与清零方法

不同厂家的寄存器实现略有差别,但通用操作不外乎两类:

  1. MMIO 直接读取:通过基地址偏移访问。
  2. MDIO 管理接口:PHY/MAC 混合芯片常用。

我习惯在驱动初始化时把关键错误计数器存一份快照,隔几秒再读一次,算出差值。这样比看数值直观得多。

// 演示:多次读取 CRC 错误计数器
uint32_t crc_before = read_reg(MAC_CRC_ERR_CNT);
wait(5000); // 等5秒
uint32_t crc_after  = read_reg(MAC_CRC_ERR_CNT);
printf(“CRC errors in 5s: %u\n”, crc_after - crc_before);

清零方式常见有两种:

  • 写清除:往该寄存器写任意值,计数器归零。
  • 读清除:读一次自动清零(少见,需看手册确认)。
注意:千万别在业务收发包时随意清零!我曾有一次在驱动中断处理里顺手把 CRC 计数器清零了,结果排查问题时发现计数器始终是 0,白白浪费半天时间。清零操作最好留在调试 init 阶段做。

3.5 实战:从计数器反推问题

拿一个实际案例来说。一个 AP 在某个位置总是发生关联闪断,抓空口看不明显,但读 MAC 计数器发现:

  • CRC Error:连续 10 秒内从 0 涨到 879。
  • RF Error:只从 0 涨到 23。

CRC 错误远多于 RF 错误?这说明信号本身不差,但 MAC 接收端的时钟同步出现了偏移,导致比特采样错位。最后查出是晶振受温度影响漂移,换了温补晶振解决。

你看,有时候数字会撒谎,但两张数字之间的比率不会。

3.6 MAC 统计计数器核心知识图谱

下面这张图总结了本章涉及的核心结构,以及错误计数器在排查链路问题时的定位路径。

MAC 统计计数器分析与 CRC 错误定位路径 MAC 统计计数器分析体系 MAC 统计计数器 帧/字节计数器 错误计数器 (CRC+RF+对齐) 冲突/重传计数器 RF 错误计数器 CRC 错误计数器 对齐错误计数器 CRC >> RF → 疑时钟/芯片逻辑问题 ; CRC ≈ RF → 疑物理链路/干扰问题

图里最关键的判断路径写在底部说明框里:CRC 错误数量远超 RF 错误,症状指向芯片内部;两者同步上涨,病因大概率在外部链路。这个思维模型你记住了,以后排查定位会快很多。

3.7 总结几条实战建议

  • 定期读取 CRC 错误计数器,做成时间序列曲线,波动异常时立刻介入。
  • 量产测试中加入“错误计数器快检”,筛出硬件批次问题。
  • 升级固件后对比 CRC 错误率,防止代码改动引入新问题。
  • 多读几遍寄存器手册——很多芯片隐藏了“接收帧数”和“CRC 错误帧数”的比值寄存器,能直接算出误码率。

说实话,搞了这么多年网络,我觉得最趁手的工具不是昂贵的分析仪,而是芯片里这些不起眼的小计数器。关键是你得知道怎么看、怎么比、怎么结合场景下判断。下一层咱们就动手,真刀真枪地读一次寄存器。