ByteScope

Intel HEX Converter

ファームウェアを 1 行ずつ読んで、どのバイトがどの番地に載るのかを見てから、書き込みツールが欲しがる形式で出し直す。

ファームウェアはブラウザの外に出ません。読み取りも書き出しも全部この場で行います。

ファイル

ファームウェアをここに落としてください。形式は中身のバイトから判別します。拡張子は見ません。外したときはファイルごとに指定できます。

.hex / .s19 / .uf2 / .bin をここへ

クリックして選ぶこともできます。ページ内で読むだけで、アップロードはしません。

まだ何もありません。ファームウェアを落とすか、HEX のテキストを貼ってください。

このファイルが言っていること

選んだファイルの 1 行ずつの結果です。チェックサムが合わない行は 2 つの数字を並べます。行に書いてある値と、レコードの中身から計算した値です。

まだ何もありません。ファームウェアを落とすか、HEX のテキストを貼ってください。

結合後のアドレス地図

オフセットを適用した全ファイルを、1 つのアドレス空間に並べたものです。すき間は、平坦なバイナリにするなら埋めなければならない穴です。

まだ何もありません。ファームウェアを落とすか、HEX のテキストを貼ってください。

変換

入力がどれでも、出力はどれにでもできます。下の設定はファイルの見た目を変えるもので、中身は変えません。

firmware.bin

このツールについて

入れ物は 4 種類、中身は同じ「番地つきのバイト列」

Intel HEX も Motorola S-record も UF2 も、言っていることは同じで *このバイトをこの番地へ* だけです。生の .bin はその前半しか持っていません。番地を捨てた状態なので、BIN 単体ではどこへ置けばいいのか誰にも分かりません。4 つのうちどれを投げ込んでも、判別はファイルの中身だけで行います。先頭 4 バイトが UF2 と改行かどうか、行頭の :、S の直後に数字が続くかどうか。拡張子は一切見ません。S-record を .hex と名づける人もいれば .s19、.s28、.srec、.mot と名づける人もいるからです。ヘッダが欠けているなどで判別を外した場合は、ファイルごとに手で指定できますし、こちらが何だと思ったかも表示します。

チェックサムが合わないときは、数字が 2 つ要る

Intel HEX を読むツールなら「この行は壊れています」まではどれも言います。*どう* 壊れているかまで言うものはほとんどありません。ここでは 2 つのバイトを並べます。行に書いてあるチェックサムと、そのレコードの中身から計算したチェックサムです。1 ビットしか違わなければ転送中に化けた線を疑えばよく、バイト数のぶんだけずれていれば手で書き換えて再計算を忘れたファイルであることがほとんどです。壊れた行が後続の行を巻き込むこともありません。5 行目が落ちても 6 行目には何の影響もないので、20 万行の中の 1 レコードが壊れても失うのはその 1 レコードだけです。構造的におかしいものにも全部名前を付けます。EOF レコードより後ろのデータ、長さの合わない番地レコード、定義されていないレコード種別。

セグメント、すき間、そして 2 つのファイルが取り合うバイト

レコードを読み終えるとセグメント、つまり開始番地と長さを持つ連続した塊にまとまり、その間の穴はサイズつきのすき間として並びます。書き込む前に見たいのはまさにこの絵です。0x0000 にブートローダ、0x8000 にアプリ、その間に 30 KB の空白があり、平坦な BIN にするならそこを何かで埋めなければならない、という絵です。1 つのファイルが同じバイトに二度書いている場合は、その範囲を黙って解決せず一覧に出します。*2 つの* ファイルが取り合っている場合は結合そのものを拒否し、衝突した範囲を両方のファイル名つきで見せます。後から読み込んだほうを勝たせる、という代替案こそが、ブートローダが黙って消えて基板が起動しなくなるまで誰も気づかない道だからです。

書き戻す

入力がどれであっても、出力はどれにでもできます。Intel HEX は 1 行あたりのバイト数を指定でき、type-04 の拡張リニアアドレスレコードを付けるかどうかも選べます。S-record は番地幅を固定できます(16 ビットなら S1/S9、24 ビットなら S2/S8、32 ビットなら S3/S7)。指定しなければ、実際に書かれる最上位のバイトが収まる一番狭い形を選びます。UF2 はペイロードサイズと family id を取り、id は公開されている family 表と突き合わせるので、打ち間違いは「基板がドラッグ&ドロップを黙って無視する」ではなく「未知の id」として出てきます。平坦な BIN はすき間を埋めるバイトを取り、既定は 0xFF です。消去済みフラッシュがそう読めるからです。処理は全部このタブの Web Worker の中で、どこにもアップロードされません。

よくある質問

元の HEX より BIN のほうがずっと大きくなるのはなぜ?

平坦なバイナリには番地がないからです。0x0000 に 4 KB、0x0800_0000 に 4 KB 書くイメージなら、BIN はその間も全部含めなければなりません。中身の量ではなく、その広がりぶんのサイズになります。変換前にセグメント地図ですき間とその大きさが見えますし、とんでもない大きさになるときは確認を挟みます。広がりが予想外なら、たいていは迷子のレコードが数バイトだけ遠くに置かれているのが原因で、セグメント表に小さな塊として現れます。

生の BIN にはどの番地を指定すればいい?

書き込みツールが置くはずだった番地です。ファイル自身は知りません。ここでは BIN は 0 に置かれ、実際のロード番地はオフセット欄で指定します。STM32 の内蔵フラッシュなら 0x08000000、よくある ESP32 アプリなら 0x10000、ブートローダなら 0x0 といった具合です。ここを間違えても分かりにくい失敗にはなりません。そのあと Intel HEX に変換すれば、各行の番地が狙いどおりかどうかをすぐ教えてくれます。

ブートローダとアプリを結合できないのはなぜ?

同じバイトを両方が書いていて、どちらを勝たせるのが正しいという答えが存在しないからです。衝突した範囲は両方のファイル名と正確な番地つきで出ます。原因はたいてい、片方がリンカスクリプト違いでビルドされているか、アプリ側がベクタテーブルの写しを抱えたままかのどちらかです。重なりを直すか、片方のオフセットでずらせば結合は通ります。まったく同じ内容の重なりでも拒否します。同じものを二度ビルドしたファイルが同じバイトを書いている状況は、なめらかに隠されるより知りたい種類の事実だからです。

UF2 の family id は何を入れればいい?

ブートローダが期待している値です。RP2040 は 0xE48BFF56、ESP32 は 0x1C5F21B0、SAMD21 は 0x68ED2B88、SAMD51 は 0x55114460、nRF52 は 0x1B57745F、STM32F4 は 0x57755A57。入力した値は公開されている表と照合します。family id を持たない UF2 も正当で、flags が 0 というのがまさにその状態です。ドラッグした UF2 を基板が黙って無視するなら、まず疑うのは id 違いか id なしです。

ファームウェアはどこかに送られる?

送られません。File API で読み、このタブの Web Worker で解析し、タブを閉じれば消えます。アップロードも、アカウントも、サーバ側の処理もありません。未公開のファームウェアは「オンライン変換サイトに貼るな」と言われる典型なので、ここは他のツールよりも大事な点です。