HN 日本語サマリー

← 一覧へ戻る
科学・技術

E-Paperパネルは壊れていない:リテインド・ステートがドライバーをバグのように見せる仕組み

E-Paper Panel Isn't Broken: How Retained State Makes Drivers Look Buggy (msj.prose.sh)

6 pointsby lukastyrychtr1 コメント

要約

電子ペーパー(E-Paper)ディスプレイのドライバー開発において、著者はリテインド・ステート(電源を切っても状態を保持する性質)が原因で発生する、一見バグのように見える問題を解決しました。E-Paperパネルだけでなく、そのコントローラーも状態を保持しており、リフレッシュ処理の中断などが原因でコントローラーがBUSY状態に固定されると、以降のコマンドが無視され、ドライバーがタイムアウトする現象が発生します。この状態はハードウェアリセットでは解消されず、電源の抜き差しのみでリセットされるため、デバッグを困難にします。

全文翻訳

私は午後を費やして、E-Paperドライバーの3つのバグを修正しました。それらはどれも存在しませんでした。そのドライバーはepdsiという、私が電子ペーパーディスプレイ用にメンテナンスしているno_std Rustフレームワークです。RP2350で動作していた例をESP32-C3に移植していました。同じドライバークレート、同じパネル、異なるボードです。20分で済むはずでした。丸一日かかり、最終的に出荷したコードは、本質的には開始したコードと同じでした。以下は、それを引き起こした失敗モードです。なぜなら、どこにも書かれていないと思うからです。そして、E-Paperを扱う人は誰でも最終的にそれに遭遇するでしょう。 誰も警告してくれないこと E-Paperは電源なしで画像を保持します。それがセールスポイントです――技術を使用する理由そのものです。すべてのデータシートはそれを最初に示しています。データシートが強調していないのは、コントローラーも状態を保持しており、その状態が常に無害であるとは限らないということです。リフレッシュの途中で中断する――モニターをCtrl-Cする、ボードを再フラッシュする、チャージポンプが動作中に電源を切る――と、コントローラーはBUSY状態にラッチされたままになる可能性があります。それはBUSYがアサートされたまま、決して完了しない操作を待っています。今、プログラムを再度実行します。ドライバーはリフレッシュを発行し、BUSYを待ちます。BUSYはすでにアサートされており、決してクリアされないため、待機はタイムアウトまで実行されます。epdsiではそれは60秒です。SSD1680では、1回のリフレッシュは3つのステージ――電源投入、更新、電源オフ――からなり、それぞれに待機時間があります。それは1回の更新で3分かかり、私の例では6回行いました。さらに悪いことに、それは自己増殖的です。タイムアウトしたリフレッシュは、パネルを同じラッチ状態のままにするため、次の実行も同様に失敗します。あなたは今、毎回同じように失敗するシステムをデバッグしています。それは決定論的なバグと全く同じように感じられます。そして、これが私に最もコストがかかった部分です:ハードウェアリセットではクリアされません。ドライバーのhard_resetはRSTピンをトグルし、パネルはそれを認識し、BUSYは正しくパルスします――そして基盤となる状態は持続します。電源を外すことだけが実際にそれをリセットします。 同じ問題の4つの顔 リテインド・ステートは自己主張しません。それはあなたの現在の仮説に合うどんな衣装でも着ます。ある午後、それはこれらすべてを生成し、私はそれぞれを異なるバグとして診断しました。 シフトまたはクリップされたコンテンツ。 書き込みが途中でカットオフされると、フレームバッファが半分転送されたままになります。パネルは結果を忠実に表示します。これは2.13インチのモノクロパネルです。上部のヘッダーは正しいですが、その下のすべてが約40px右にシフトし、端から外れています。それはRAMウィンドウまたはストライドの誤計算と全く同じように見えます――そして私は最近RAMアドレス指定コードに触れたばかりだったので、すぐにそれを信じました。 中断された書き込みがフレームを2つ並べてノイズの帯を挟んで描画した、4.26インチパネルでの同じ失敗です。 10ミリ秒で戻るリフレッシュ。 パネルはコマンドを受け付けていないため、BUSYは決してアサートされず、待機はアイドルラインを見てすぐに戻ります。私はこれをレース条件として診断しました――ドライバーがパネルがそれを上げる前にBUSYをポーリングしていました。私はそのレース条件のために3つの連続した修正を書きました。レース条件は存在しません。 ハングしているように見えるリフレッシュ。 ハングしているのではなく、タイムアウトしています。しかし、3分はターミナルを見ているときは永遠と区別がつかないので、あなたはそれを中断します――それはそれを引き起こした正確な条件を再作成します。 何も起こらない。 コマンドは無視され、ディスプレイは変更されず、プログラムは完了まで実行され、成功を報告します。 4つの症状、4つのもっともらしいドライバーバグ、1つの実際の原因。 私がそれを悪化させた方法 3つの間違い、すべてが他人の書き込みでは明白だったと呼んだでしょう。私は汚染されたデータから推論し続けました。実行が中断されていることは知っていました。それでも、その後の出来事から結論を導き出しました。ある時点で、私はパネルの状態を正しく疑い、電源サイクルを試みるべきだと自分に言い聞かせ、理論に合わない結果を得て――理論を放棄しました。私は嘘をつく診断ツールを構築しました。より細かいタイミングを得るために、ドライバー自身のrefreshを呼び出す代わりに、コントローラーのトリガーシーケンスを手作業で作成しました。それは9つの測定値を報告し、すべて正確に100ミリ秒でした。私はそれらをデータとして読みました: 1--- A: フルフレーム、フルモード (0xF7) --- 2 電源投入 (0xE0): BUSYが100ミリ秒後に解放される 3 更新 (0xF7): BUSYが100ミリ秒後に解放される 4 電源オフ (0x83): BUSYが100ミリ秒後に解放される それらはアイドルライン上のノイズでした。コードはパネルを全く駆動していませんでした。それを露呈させたのはログではなく――ログは完全に妥当に見えました――ディスプレイが全く変化しないことに気づいたことでした。私はソフトウェアに固執しました。なぜなら、私はソフトウェアに取り組んでいたからです。既知の良いサードパーティ製コードは、ずっとそこにありました。私はずっと後にそれを手に取るまで使いませんでした。 実際に機能したこと 3つのテクニック、それぞれが数時間の憶測を単一の実験に圧縮しました。 ストックのサードパーティ製コードを複数のボードで実行する。 私は同じアダプターとパネルで、4つの異なるマイクロコントローラーに標準のArduino GxEPD2デモをフラッシュしました。3つは完璧に動作しました。1つはノイズを生成しました。その単一の実験は、私のドライバーではなく、ボードレベルの障害であることを証明しました――これは私が数時間のコード分析では到達できなかった結論です。私は後に、異なるパネルでこのトリックを繰り返し、同様にクリーンな結果を得ました。 既知の測定値に対してインストゥルメントを検証する。 信頼できるベースライン(このパネルのフルリフレッシュには3891ミリ秒かかる)が得られれば、100ミリ秒を報告するあらゆる診断は、それ自体で壊れていることが明らかです。そのベースラインは、「興味深い結果」を「私のツールが嘘をついている」に即座に変えます。必要になる前にそれを確立してください。 ログではなく、ディスプレイを見る。 ファームウェアは、達成していない成功を喜んで報告します。パネルはできません。この時点以降に私が書いたすべての診断は、明白なもの――真っ黒、次に真っ白――を描画したので、ハードウェア自体が質問に答えました。 プロトコル これは今私のリポジトリに必須の読み物としてあります: 電源サイクルを実行し、一度だけ実行し、中断せず、それから判断する。 ボードの電源がオフの状態でFPCを接続および切断する。 地味ですが、これで丸一日節約できたでしょう。 いくつかの補足。 電源を抜くまで、中断された実行、またはそれに続く実行から推論しないでください。リセットではなく、電源です。 参照タイミングを知る。 偏差はベースラインに対してのみ認識可能です: パネル フルリフレッシュ 部分リフレッシュ 4.26インチモノクロ ~3.9秒 ~1.0秒 2.13インチモノクロ ~3.9秒 ~1.0秒 1.54インチトリカラー ~14秒 ~14秒 4,000バイトのフレームを4MHzのSPIで転送するには8ミリ秒かかります。データ転送は実質的に問題にならないため、誘惑的な仮説のファミリー全体が排除されます。カラーパネルは遅く、それは物理学です。トリカラーおよびクアッドカラーパネルには高速波形がありません――着色顔料はより重い粒子であり、移動するために完全な波形を必要とします。すべての更新には数秒かかります。私の1.54インチトリカラーの例では、約14秒ごとに6回の更新を実行します:90秒間、画面はフリーズしたように見えますが、すべて正しいです。これは、完璧に動作していた実行を中断させる最も可能性の高いことです。 一般化する部分 これが20分ではなく午後かかった理由は、E-Paperが異常に難しいからではありません。それは、私の対象と私のインストゥルメントの両方が私に嘘をつく可能性があり、私がチェックしたのは片方だけだったシステムをデバッグしていたからです。パネルは実行をまたいで状態を保持することで嘘をつき、すべての実験が前のものによって汚染されました。私の診断ツールは、実際には起こらなかった操作に対して妥当な数値を報告することで嘘をつきました。ソフトウェアだけではどちらのケースも区別できません――だからこそ、修正は物理的なものでした:電源を引き抜き、画面を見る。 状態を保持するディスプレイ、EEPROM、永続的な設定を持つラジオ、チャージポンプを持つものなど、デバッグしているものは何でも、電源を抜いて証明するまで、前の実験が現在の実験に影響を与えていると仮定してください。そして、測定値があなたを驚かせたときは、コードを書き直す前に定規をチェックしてください。 これは、上記の2つの失敗写真と同じボードとアダプターです――XIAO ESP32-C3とSeeed ePaper Driver Board――4色すべてを意図したとおりにレンダリングしています。 ドライバー