I2C経由のDDMポーリングをスクリプト化する、A2hのどのバイトがライブ値でどのバイトが閾値か
うちのホワイトボックス機器のモジュールから温度、電圧、バイアス、光パワーを直接取得する小さなポーラーを書いています。誰かがエラーを出し始めてからリンクを目で確認するのではなく、トレンドラインが欲しいからです。NOSは見栄えのいい値を表示してくれますが、アラームレベルが機種ごとの手書きではなく混在オプティクス間で一貫するように、生の数値とベンダーの閾値を並べて欲しいのです。
構成:
- Linuxホスト、モジュールケージは素のI2Cマルチプレクサの先、バス1
- 3ベンダー混在の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
すでにやったこと:
- 自分で計算した値をNOSの表示と比較した。近いモジュールもあれば、明らかにずれているモジュールもある
- SFF-8472を読み込んだが、閾値ブロックがどこで終わってキャリブレーション領域がどこから始まるのか、まだ自信を持って言えない
- 同じモジュールを直結バスでダンプしてマルチプレクサを除外したが、数値は同じだった
つまり、A2hの実際のマップはどうなっていて、閾値はどこにあり、リアルタイムの値はどこから始まるのでしょうか。そしてその生のワードを信用する前に、モジュールが自分に何か処理を要求しているかどうかを示すフラグはどこかにあるのでしょうか。
Comments 7
明らかにずれている値はどれですか。4つ全部ですか、それともバイアスとパワーだけですか。たいていこれで答えの大部分が決まります。ついでにA0hもダンプして、バイト92を見てください。モジュールがそもそも診断情報を報告するかどうか、内部キャリブレーションか外部キャリブレーションかが分かります。もしあなたの機材の一部が外部キャリブレーションで、パーサが全部を同じように扱っているなら、その不一致は想定通りの挙動であって、あなたの計算のバグではありません。
トレイ全体でA0hのバイト92を取得したところ、均一ではありませんでした。外部キャリブレーションを示すモジュールもあればそうでないものもあり、NOSの出力と食い違うのはまさに外部キャリブレーションのものでした。温度と電圧はどれもノイズの範囲内で、ずれるのはバイアスと2つのパワーです。つまり間違ったオフセットを読んでいるのではなく、何か手順を1つ見落としているようです。そのサブセットの生のワードに対して、実際何をする必要があるのでしょうか。
0x51のA2hは、あなたに関係する4つの塊に分かれます。
ライブブロックの単位は、温度が符号付きで1LSBあたり1/256℃、電圧は1LSBあたり100uV、バイアスは2uA、TXとRXパワーは0.1uWです。あなたのコード片はすでに正しくスケーリングしているので、オフセットはあなたの問題ではありません。
欠けているのは、あなたがさっき見つけたフラグです。外部キャリブレーションのモジュールでは、96-105のワードは生のADC出力で、意味を持たせるには56-95の定数を適用する必要があります。内部キャリブレーションのモジュールでは、それはすでにモジュール側でやってくれています。その分岐が、あなたの2つのグループの違いです。
自分の言葉を鵜呑みにせず照合したいなら、FreeBSDのsff8472.hヘッダーとpy-sfp-eepromはどちらもオフセットをフィールドごとに書き出しています。それでもアラームをぶら下げる前に、ベンダーごとに1台は信頼できる値と照合することをお勧めします。
なぜ閾値ブロックが面白い半分なのか、付け加えておく価値があります。0-55の値はライブブロックと同じ単位なので、スケーリングさえ正しければ、ベンダー自身のアラームと警告のポイントがそのまま手に入り、機種ごとに限界値を考え出す必要が一切なくなります。それだけでも、誰かの見栄えのいいプリンタをパースするのではなく、A2hを直接読む理由になります。
混在トレイでこれを運用している実務上の注意点が1つあります。ポーリング間隔は控えめにしてください。あのページはただのI2C読み取りで、モジュールのコントローラは速くありません。マルチプレクサの先にあるバスで全モジュールを毎秒叩くのは、グラフ上でまさにオプティクスがフラッピングしているように見える短い読み取りを集める良い方法です。
その言い方には気をつけてください。「常に定数を適用する」と読む人がいて、後で数値が悪化した理由に首をかしげることになります。56-95の定数は、A0hのバイト92がモジュールは外部キャリブレーションだと言っている場合にのみ適用します。内部キャリブレーションのモジュールにそれをかけると、まったく問題のない読み取り値がでたらめになります。モジュールがすでにその作業を終えているからです。まずフラグを読んで、それで分岐し、パーサには両方の経路を残しておき、どちらの経路を通ったかをモジュールごとにログしておけば、後で2種類の故障モードを見分けられます。
温度についても同種の罠があります。これは符号付きです。符号なしとしてパースすると、ゼロ未満の値はとんでもなく大きな数字として返ってきます。それが原因で最初の寒い朝にポケベルが鳴ったときは、なかなか面白いことになります。
こちらからの更新です。A0hのバイト92で分岐させ、モジュールが外部と言っている場合にのみ定数を適用するようにしました。バイアスと両方のパワーは、照合できたすべてのモジュールでNOSの表示に追従するようになり、温度と電圧はそもそも最初から問題ではありませんでした。2台のモジュールはまだ診断情報ありと報告するものの、信用できない閾値を返してくるので、それらについては自分の限界値にフォールバックし、知らんふりをせずインベントリでそのモジュールにフラグを立てています。これで全部解決とは言いませんが、上のマップはまさに自分に欠けていたものでした。
本番投入前にもう一点。バイト110は同じページにあり、ステータスと制御を兼ねていて、制御側にはTXディセーブルが含まれます。ポーラーがA2hに書き込む必要はそもそもないはずですが、もしライブラリのどこかでread-modify-writeをしていたり、稼働中の機器でテスト中にi2csetを打ち間違えたりすると、ユーザースペースから顧客のリンクを落とすことになりかねません。ポーラーではバスを読み取り専用で開き、書き込み経路はすべて意図的に実行しなければならない別のツールに分けておいてください。
同じバイトからTXフォルトとRX LOSも得られ、どちらもアナログ値と並べてエクスポートする価値があります。まともなRXパワーなのにLOSが立っているモジュールは、単に値が低いだけのモジュールとはまったく違う話を伝えています。