CodingBox Q&A Ask question

用脚本通过 I2C 轮询 DDM:A2h 里哪些字节是实时值,哪些是阈值

Asked Active Viewed 319 AI translation from English
7

我在写一个小型轮询程序,直接从白盒设备上的模块里取温度、电压、偏置电流和光功率,这样我们能得到一条趋势曲线,而不是等链路已经开始报错了才有人去盯着看。网管系统会打印出好看的数值,但我想要原始数字,连同厂商设定的阈值一起,这样在混用不同光模块的情况下告警门限也能保持一致,而不是每个型号都手写一套。

环境:

  • Linux 主机,模块笼位挂在一个普通的 I2C 多路复用器后面,bus 1
  • 三家厂商混用的 SFP、SFP+ 和 SFP28 光模块
  • 只用 i2c-tools 读取,不用厂商 SDK

我这样读诊断页:

# i2cdump -y 1 0x51

这是我的解析代码草稿,也是我不确定的地方:

temp = s16(a2[96:98]) / 256.0
vcc  = u16(a2[98:100]) * 100e-6
bias = u16(a2[100:102]) * 2e-6

已经做过的:

  • 把我算出来的值和网管系统打印的值做了对比:有些模块很接近,有些明显对不上
  • 通读了 SFF-8472,但还是没法笃定地说清楚阈值区块到哪里结束、标定区又从哪里开始
  • 排除了多路复用器的因素:在直连的总线上重新读同一个模块,数字是一样的

所以想请教:A2h 的实际布局到底是什么样的,阈值在哪,实时数值从哪开始,有没有什么标志位能告诉我,在信任这些原始字之前,模块是不是要求我先对它们做点什么处理?

Comments 7

哪些值明显对不上,是四个都不对,还是只有偏置电流和两个功率值不对?这通常能决定整个答案。顺便把 A0h 也读一下,看看第 92 字节:它会告诉你这个模块到底有没有诊断信息可报,以及它是内部标定还是外部标定的。如果你这批设备里有一部分是外部标定的,而你的解析代码对所有模块一视同仁,那出现偏差是预期中的行为,而不是你的算术错了。

1 United Statescoaxhawk46US Show original (English) AI translation

把整个托架里所有模块的 A0h 第 92 字节都读了一遍,结果并不统一。有些模块标记为外部标定,有些不是,而和网管系统对不上的那些,正好都是外部标定的那批。温度和电压在所有模块上都在误差范围内;偏置电流和两个功率值才是偏移的地方。所以看起来我是漏了一个处理步骤,而不是读错了偏移地址。对这一部分模块的原始字,我具体还需要做点什么?

2 South KoreanetrunnerKR Show original (English) AI translation

0x51 上的 A2h 分成对你有意义的四块:

  • 字节 0-55:告警和预警的阈值,温度、电压、偏置电流、TX 功率、RX 功率各自的高低门限
  • 字节 56-95:外部标定常数
  • 字节 96-105:实时数值
  • 字节 110:状态与控制位,包括 TX disable、TX fault 和 RX LOS

实时数值区的单位:温度是有符号数,每 LSB 为 1/256 摄氏度;电压每 LSB 为 100 uV;偏置电流每 LSB 为 2 uA;TX 和 RX 功率每 LSB 为 0.1 uW。你贴的代码片段这几个换算都是对的,所以偏移地址不是你的问题。

缺的那一环正是你刚发现的那个标志位。在外部标定的模块上,96-105 处的字是原始 ADC 输出,必须先套用 56-95 处的标定常数才有意义;内部标定的模块已经替你做完这一步了。这个分支正是你那两组数据表现不同的原因。

如果你想要一份可以核对的布局说明,而不是只信我一面之词,FreeBSD 的 sff8472.h 头文件和 py-sfp-eeprom 都逐字段列出了这些偏移地址。不过我还是建议每个厂商都拿一个模块,对着一个你信得过的数值验证一遍,再把告警挂上去。

3 United Statesporttech22US Show original (English) AI translation

值得补充一下为什么阈值那一块才是有意思的一半。0-55 里的数值和实时数据区用的是同一套单位,所以只要换算做对了,你就能白得厂商自己设定的告警和预警门限,不用再给每个型号单独发明限值。光凭这一点就足以说明为什么要直接读 A2h,而不是去解析别人打印出来的漂亮界面。

实际在混用模块的托架上跑这套东西的一个经验:轮询间隔别设得太激进。那一页是普通的 I2C 读操作,模块的控制器速度并不快。如果对每个模块每秒都猛读一次,而总线上还挂着一个多路复用器,很容易读出短读错误,在你的图表上看起来就跟光模块在抖动一模一样。

1 Brazilopticnerd31BR Show original (English) AI translation

这句话措辞要小心,因为有人会理解成「永远都要套用这些常数」,然后纳闷自己的数字怎么反而变差了。56-95 处的常数只在 A0h 第 92 字节说这个模块是外部标定时才适用。拿它去套一个内部标定的模块,会把本来完全正常的读数变成一堆没有意义的数字,因为模块已经替你做过这一步了。先读那个标志位,根据它分支处理,解析代码里两条路径都要保留,并且记录每个模块走的是哪条路径,以后好区分这两种失败模式。

温度上有同一类陷阱:它是有符号数。按无符号解析,任何低于零的值都会变成一个高得离谱的数字,第一个寒冷的早晨它就会给你发一条挺有意思的告警。

4 United StatesqsfpwolfUS Show original (English) AI translation

更新一下我这边的进展。我按 A0h 第 92 字节做了分支,只在模块标记外部标定时才套用那些常数。偏置电流和两个功率值现在在我能对比的每个模块上都和网管系统一致了,温度和电压本来就没出过问题。还有两个模块虽然报告说有诊断信息,但给出的阈值我不敢信,对这两个我改用自己设定的限值,并在设备清单里标记出来,而不是假装一切正常。还不能说整件事已经完全解决,但上面那份布局说明正是我之前缺的那块。

3 South KoreanetrunnerKR Show original (English) AI translation

在这套东西上生产环境之前,还有一点要说。第 110 字节在同一页里,是状态加控制位,控制那一半里包括 TX disable。一个轮询程序本来就不该往 A2h 写任何东西,但如果你用的库在什么地方做了读-改-写操作,或者你在一台生产设备上测试时手滑敲错了 i2cset,就可能从用户态直接把客户的链路打掉。让轮询程序只以只读方式打开总线,任何写操作路径都放进一个需要专门手动运行的独立工具里。

同一个字节还能给你 TX fault 和 RX LOS,这两个值也值得和模拟量一起导出。一个 RX 功率读数正常但 LOS 被置位的模块,讲的是和一个单纯读数偏低的模块完全不同的故事。

0 Indiawaverunner21IN Show original (English) AI translation
Log in to comment. Log in