ESP32のカスタムパーティションテーブルの設定方法と実装手順

Published on: | Last updated:

最近ESP32をいじってて、ふと思ったんだけど、みんなパーティションテーブルってちゃんと意識してる?正直、僕も最初は「なんかよくわからんけどデフォルトで動いてるし、まあいっか」って感じで触ってた。でもね、これを知ってるかどうかで、できることの幅が全然違ってくるんだよね。特に「設定値を再起動しても残したい」とか「OTAアップデートを実装したい」ってなったら、避けては通れない道。

要するに、ESP32のフラッシュメモリっていう一枚の大きな土地を、どういう区画に分けるか決めるのがパーティションテーブルの役割。アプリを置く「居住区」、設定を保存する「倉庫」、ファームウェア更新用の「予備地」みたいに、役割分担をさせるための設計図みたいなものかな。

で、なんでこれがそんなに大事なの?

なんでかっていうと、これをちゃんとやらないと、例えばファームウェアを更新(OTA)しただけで、ユーザーが設定したWi-Fiのパスワードとかが全部消えちゃう、みたいな悲劇が起こりうるから。アプリとデータがごちゃ混ぜになってると、片方をいじっただけでもう片方に影響が出ちゃう。分離させておくのが、やっぱり基本だよね。

デフォルトのパーティション構成だと、`nvs`(設定とかを保存する場所)と`factory`(アプリ本体)の2つがメイン。これでも簡単なことであれば十分なんだけど、ちょっと凝ったこと、例えばOTA(Over-The-Air)アップデートをやろうとすると、もう全然足りない。

フラッシュメモリの区画整理のイメージ
フラッシュメモリの区画整理のイメージ

じゃあ、どうやって作るの?

「難しそう…」って思うかもしれないけど、実はただのCSVファイルなんだ。びっくりするくらいシンプル。構造はこんな感じ。

# <a href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/partition-tables.html" target="_blank" class="blogHightLight_css nobox">ESP-IDF</a> Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
otadata, data, ota, 0xf000, 0x2000,
ota_0, app, ota_0, 0x20000, 0x200000,
ota_1, app, ota_1, 0x220000, 0x200000,
storage, data, spiffs, 0x420000, 0x200000,

この6つのカラムの意味さえ分かれば、もうこっちのもの。

  • Name: パーティションの名前。自分で分かりやすい名前をつければOK(ただし16文字まで)。`nvs`っていう名前だけはシステムが特別扱いするから、基本的にはそのまま使う。
  • Type: `app`(アプリ用)か`data`(データ用)の二択。シンプルでしょ。
  • SubType: ここが一番のキモ。`data`の中でも「これはNVS用」「これはSPIFFSファイルシステム用」みたいに、具体的な用途を決める場所。`app`なら`factory`(工場出荷時)とか`ota_0`, `ota_1`(OTA用)とかを指定する。
  • Offset: パーティションの開始アドレス。…なんだけど、正直ここは空欄にしとくのが一番。そうすればESP-IDFが前のパーティションの終わりから自動で計算してくれる。自分でやると計算ミスでハマる元。マジで。
  • Size: パーティションのサイズ。`4K`とか`1M`みたいに書ける。アプリのサイズが将来大きくなることを見越して、特に`app`領域は余裕を持たせておくのがセオリー。
  • Flags: 今のところは`encrypted`ってフラグを立てて、フラッシュの暗号化を有効にするかどうかに使うくらいかな。

このCSVファイルを作って、`menuconfig`で「Custom partition table CSV file」にそのファイル名を指定してあげれば、ビルド時に反映される。簡単だよね。

あ、ちなみにESP-IDFのバージョンはv4.2以降を想定してる。古いバージョンだと微妙に違うかもしれないから注意して。Espressifの公式ドキュメントは英語だけど、一番正確だから困ったらそこを見るのが確実。でも、日本のM5StackのコミュニティとかQiitaの記事とかを見ると、もっと具体的な使い方が日本語で議論されてて、そっちの方がとっつきやすいかもね。

VS Code拡張機能ならGUIで編集できて便利
VS Code拡張機能ならGUIで編集できて便利

どのデータタイプ(SubType)を使えばいいの?

データ用のパーティションを作るとき、`nvs`, `fat`, `spiffs` のどれを使うか迷うと思う。僕なりの使い分けはこんな感じ。

SubType どんなとき使う? メリット デメリット
nvs Wi-FiのSSID/パスワード、デバイスの個体設定値とか、数キロバイト程度の少量のキーバリューデータを保存したいとき。 ・APIがシンプルで使いやすい。
・暗号化もサポートされててセキュア。
・大量のデータとか、頻繁な書き換えには向かない。
・ファイルっていう概念がない。
spiffs 画像ファイルやJSONの設定ファイルみたいに、ある程度まとまったサイズのファイルをいくつか置きたいとき。Webサーバーのコンテンツ置き場とか。 ・ウェアレベリング(書き込み平準化)を自動でやってくれる。
・ファイル単位で管理できる。
・ディレクトリ(フォルダ)が作れない。
・公式ではもう非推奨で、FAT FSへの移行が推奨されてる。
fat SDカードみたいに使いたいとき。データロガーでどんどんログを貯めたり、PCでファイルを読み書きしたり。一番汎用性が高いかも。 ・みんな知ってるFATファイルシステム。
・ディレクトリも作れる。
・ウェアレベリングと組み合わせられる。
・SPIFFSに比べると、ちょっとだけメモリ使用量が大きい…かな?でも最近のESP32なら誤差みたいなもん。

個人的には、ちょっとした設定なら`nvs`、ファイルとして何かを保存したいならもう`fat`でいいかなって思うことが多い。`spiffs`も悪くないんだけど、公式が「今後はFATを使ってね」って言ってるから、これから新しく作るならFATの方が安心感あるよね。

よくあるハマりどころと解決策

カスタムパーティションで絶対一回は通るエラーと、その解決策をメモしとく。

「Failed to find X partition...」

これは、コードから探そうとしたパーティションがCSVファイルに存在しないってこと。大体は`SubType`の指定ミスか、単純なタイポ。CSVファイルを見直せばすぐわかるはず。

「Partition overlapping issue」

これ、一番よく見るやつ。「パーティションが重なってるよ!」って怒られてる。自分で`Offset`を手計算してるとマジでよくやる。前のパーティションのサイズを間違えたりとか。
解決策: だから言ったじゃん!`Offset`は空欄にしとこう!それが一番安全で確実。

「Offset is not aligned to 0x10000」

`app`タイプのパーティション(`ota_0`とか)は、64KB(0x10000)の境界に配置しないといけないっていうルールがある。これも自分で`Offset`を計算してるとやらかしがち。
解決策: やっぱり`Offset`は空欄で!コンパイラは神。

そもそも変更が反映されない

CSVファイルを書き換えてビルドして書き込んだのに、なんか挙動が変わらない…ってとき。パーティションテーブル自体を変更したときは、一回フラッシュを全部消去しないとダメ。

idf.py -p <COM_PORT> erase_flash

これをやってから、もう一回書き込んでみて。パーティションテーブルはメモリの超基本構造だから、これを変えるってのは、いわば更地にして家を建て直すようなもの。前の家の基礎が残ってたらおかしくなるでしょ?それと同じ。

デフォルト構成とOTA対応構成の比較
デフォルト構成とOTA対応構成の比較

まとめというか、 TL;DR

正直、最初は面倒くさい。でも、一回このパーティションテーブルの考え方を理解しちゃうと、ESP32のフラッシュメモリを本当に隅々まで使い倒せるようになる。外部にEEPROMとかSDカードを追加しなくても、本体のメモリだけで結構いろんなデータを永続化できるから、コスト的にもサイズ的にも有利。

怖がらずに、まずは`Offset`を空欄にした簡単なCSVから試してみるのがおすすめ。一度OTA対応の構成が作れるようになると、もうあなたはESP32中級者以上を名乗っていいと思うよ、マジで。


それで、あなたならどんなカスタムパーティションを作ってみたいですか? データロガー用に巨大なFAT領域を作りますか?それとも、たくさんの小さな設定を管理するために、複数のNVSパーティションを用意しますか?ぜひコメントであなたのアイデアを教えてください!

Related to this topic:

Comments

  1. Guest 2025-10-22 Reply
    うちの子が最近ずっとESP32に夢中で、正直カスタムパーティションテーブルとか…聞いただけで頭痛くなった。最初CSVを開いたら「何この列?」ってなるし、親も子も同時にフリーズした。でもさ、とりあえず一緒にVS Code立ち上げて、あーだこーだ言いながら設定ファイルをちょっといじってデモするとき、ピタッとはまった瞬間が来る。「おぉーー」って、一緒に変なテンションになって。なんかこう、不器用だけど理系っぽい親子時間?あとたまに謎エラーとか出てきて、お互い黙り込んで調べたりして。それでも結局わかった時は二人して「よし!」みたいな。不思議と家族でもこういうので楽しめるもんなんだなぁ、と静かに思った夜だった。
  2. Guest 2025-10-06 Reply
    ・ESP32カスタムパーティションテーブル、いきなりCSV修正。列追加、「本当に合ってる?」ってちょっとドキッとした。 ・VS Code+ESP-IDF拡張、操作楽。問題出ても、公式ドキュメント検索→たいてい解決。 ・実験でデータ領域を少し増やして試す。なるほど、けっこう手応えあった。メモ:わからない点=都度調べて確認必須。 ・他にハマる箇所出たら…うん、とりあえずまたあとで整理するかも。
  3. Guest 2025-09-16 Reply
    おお、ESP32のパーティションテーブルってマジ奥深いよね!CSVファイルの構造とか、めっちゃ興味あるわ。実際のプロジェクトでどう使うか、もっと知りたいな。デモとか見てみたい〜
  4. Guest 2025-08-21 Reply
    ESP32のパーティションテーブル、めっちゃ難しそう!CSVファイルの構造とか、どんな感じで設定すればいいんですか?初心者目線で詳しく教えてください。実際の使い方とかサンプルがあると、もっと分かりやすいかも!
  5. Guest 2025-07-27 Reply
    なんで、こんなに複雑なパーティションテーブルを作らないといけないの?素人には難しすぎない?ESP32って普通のマイコンボードじゃん、もっとシンプルな方法ないの?
  6. Guest 2025-05-14 Reply
    ESP32のカスタムパーティションテーブルについての情報、非常に興味深いですね!特にデモを通じて学ぶ部分が役立ちそうです。もし他にもリソースや参考になる資料があれば、ぜひ教えていただけませんか?よろしくお願いします!