ESP32のカスタムパーティションテーブル作成ガイド:フラッシュメモリの効率的な活用方法


Summary

このガイドでは、ESP32におけるカスタムパーティションテーブルの作成方法について解説します。特にフラッシュメモリを効率的に活用するための重要なポイントと、その価値についてお話しします。私自身もこの手法を試してみて、その効果に驚きました。 Key Points:

  • ESP32のカスタムパーティションテーブルを作成することで、フラッシュメモリの効率的な利用が可能になります。
  • ウェアレベリング技術やECC(エラー訂正符号)を活用し、データ保護とシステムの安定性を向上させることができます。
  • 動的パーティション管理によって、アプリケーションのアップデートやデータ量に応じた柔軟なメモリ管理が実現します。
この記事では、ESP32のカスタムパーティションテーブル設計によって得られるメリットや実践したい技術について深く掘り下げています。

ESP32のカスタムパーティションテーブルの使い方

ESP32プロジェクトを始めるとき、時には再起動や電源オフの後もデータを保持する必要が出てくることがあります。以前はEEPROMを使用していましたが、これでは保存できるデータ量が限られていたため、大きなデータには不向きでした。一方、ESP32はファームウェアやブートローダーなどの重要な情報を格納するためにフラッシュメモリを使用しています。このフラッシュメモリのサイズはバージョンによって異なるものの、ほとんどのアプリケーションコードを収めつつ、ある程度のストレージ領域も確保できます。

ただし、ファームウェアだけでなく、いくつかの他の重要なデータもフラッシュメモリに保存されます。例えば、パーティションマップやRFキャリブレーションデータ、Wi-Fi情報、Bluetoothペアリング情報、およびOTA(Over-the-Air)アップデートなど、多くの場合で必要となる情報です。したがって、このようなストレージ管理について考慮することは非常に重要です。

パーティションテーブルの基本を理解する

ESP32のパーティションテーブルについて理解するには、まずその基本的な仕組みを知っておくことが大切です。これは、コンピュータのストレージと同じように機能します。つまり、特定の種類のデータをどこに保存するかをシステムに指示し、そのパーティションのタイプやサイズを設定することで、データを論理的に分けることができるということです。

このパーティションテーブルのおかげで、一方にはアプリケーションを格納し、もう一方には設定情報やその他のデータなどを別々に保存できます。このようにしてアプリとデータを異なるメモリ領域に保持できるため、新しいバージョンのアプリケーションへの更新時にもデータはそのまま残すことが可能になります。また、各パーティションのサイズや種類(例えばアプリケーション用やSPIFFS、NVSなど)もカスタマイズできるため、用途に応じた効率的なメモリ管理が実現します。

さらに、データ損失を防ぐためにはウェアレベリング技術についても考慮すると良いでしょう。これによって耐久性が向上し、全体的な性能も改善されます。
Extended Perspectives Comparison:
ポイント説明
ESP32のフラッシュメモリ最大16MBのストレージを持ち、アプリケーションや重要なデータを格納するために利用される。
パーティションテーブルデータを論理的に分けるために使用され、特定の種類のデータごとに保存場所を指示する。
NVSパーティションWi-Fi設定やBluetoothペアリング情報など、小さなデータを保存するために使用され、標準サイズは24kB。
OTA機能ファームウェアのリモートアップデートが可能で、少なくとも3つの追加パーティションが必要。
カスタムパーティション作成CSVファイルで定義され、各列には名前、タイプ、サブタイプなどが含まれ、自分のプロジェクトニーズに合わせた設計が可能。

主要なパーティションとその役割

デフォルトのパーティションスキームは、主に二つの主要なパーティションで構成されています。### **nvs**デフォルトのNVSパーティションは、ユニークなデバイスのPHYキャリブレーションやWiFiデータ、Bluetoothペアリング情報などをNVS形式で保存するために使用されます。このパーティションの標準サイズは24kB(0x6000バイト)です。### **factory**ファクトリーパーティションは、アプリケーションファームウェア自体を格納します。ブートローダーは、このパーティションを起点としてアプリケーションを初期化します。また、**[OTA]**を使用する場合、このファクトリーパーティションはすべてのOTAパーティションが空であるときのみ利用され、それ以外の場合には実際のOTAパーティションが使われるため、ファクトリーパーティションはもはや使用されません。

カスタムパーティションテーブルが必要なケース

このパーティションのもう一つの利用方法は、デフォルトアプリケーションを保持し、OTA APIを使用してブートパーティションを変更することです。たとえば、デバイスをOTAパーティションに更新した後や、OTA更新中に何らかの失敗が発生した際に工場出荷時設定に戻す場合などです。## **ユースケース**カスタムパーティションテーブルの最も一般的な用途は、ファームウェアをリモートでOTA(Over-The-Air)アップデートによって更新する必要がある場合です。この機能には、少なくとも3つの追加パーティションが必要で、それぞれOTAデータ用(_ota_)、および2つのアプリケーション用(_ota_0_ と _ota_1_)として使用されます。また、この機能はファイル保存やログデータ、デバイス設定、GPIOステータスなど、多種多様なデータを保存するための別のストレージエリアとしても利用できます。さらに、この拡張ストレージエリアにはクラウド証明書を保管できるため、アプリケーション内にハードコーディングする必要がなくなり、安全性が向上します(これは推奨されていません)。


カスタムパーティションテーブルが必要なケース Free Images


カスタムパーティションの作成方法

ESP32およびESP32-S2のフラッシュメモリは最大16MBまでと制限されています。そのため、もし16MB以上のストレージが必要な場合は、別途フラッシュメモリやSDカードを追加することができます。## **カスタムパーティションテーブルの作成**新しいパーティションを作成するには、まずパーティションのファイル構造を理解する必要があります。カスタムパーティションテーブルはCSVファイルで定義されており、以下の構造になっています:
# ESP-IDF パーティションテーブル# 名前, タイプ, サブタイプ, オフセット, サイズ, フラグ
このCSVファイルには6つの列が含まれており、2行目でそれぞれ定義されています。### **名前**最初の列はパーティション名であり、そのパーティションのラベルを定義します。このフィールドには特別な意味はありませんが(デフォルトNVSパーティションを除く)、用途に応じた意味ある名前にするべきです。また、名前のサイズは最大16文字までに制限されています(それ以上の場合は切り捨てられます)。### **タイプ**第二列はパーティションタイプを示し、現在2種類あります: _data_ と _app_です。_**data (0x01)**_ タイプは一般データを保存するために使用されるパーティションを定義します。一方、_**app (0x00)**_ タイプはアプリケーションを保存するために使用されます。注意: このタイプは[esp_partition_type_t 列挙体]で定義されています。### **サブタイプ**第三列では、その _**app**_ または _**data**_ パーティションの用途によってサブタイプが決まります。**データパーティション用サブタイプ:**次のように指定できます:- **ota (0x00):** OTA情報を保存するために使用されるオタサブタイプ。このパーティションはOTA機能が使用される際のみ必要です。それ以外の場合、このカスタムテーブルには含めなくても大丈夫です。このサイズは固定で8kB(0x2000バイト)とすべきです。- **nvs (0x02):** 一般データ(WiFi設定やPHYキャリブレーションデータなど)を保存するために使われるnvsサブタイプ。この種のパ partition は、小さな設定データやクラウド証明書などにも適しています。またNVSでは暗号化も可能なので、機密性が求められるデータにも利用できます。少なくとも1つ名付けられた_nvs_ パティショントして12kB(0x3000バイト)のサイズで追加することが推奨されます。ただし、大容量向けにはFATやSPIFFSファイルシステムをご利用ください。- **coredump (0x03):** フラッシュ上にコアダンプ情報を保存します。不具合分析やエラー検出時に役立ちます。この機能についてプロジェクト設定から有効化しなければいけませんので、ご注意ください。そのサイズとして64kB(0x10000)がおすすめです.- **nvs_keys (0x04):** NVS暗号化キー専用として4kB(0x1000)確保します.- **fat (0x81):** FATファイルシステム用として、大きな更新頻度高いデータ向けとなります。そしてウェアレベリング技術も活用でき、安全性も求められる場合にも対応しています。FAT FSとウェアレベリング機能について詳しく知りたい方はこちらをご覧ください。[例].- **spiffs (0x82):** SPIFFSファイルシステム専用となっていて、大きなファイル管理向けでもあります。ただしSPIFFSではフラッシュ暗号化未対応なのをご留意ください。

アプリケーション用サブタイピング: -  工場出荷時 (factory ) : 初期状態アプリケーションとして動作します 。 OTA の場合 、 通常 ota 0 および ota 1 が 必要なので 対応 関係 を 見直す と よろしいかと思います 。

CSVファイル構造をマスターする

最大で16のOTAパーティションを定義できますが、基本的なOTA機能には2つだけが必要です。- **テスト (0x20):** _テスト_ パーティションのサブタイプは、**[工場出荷時テスト手順]** に使用されます。 ### **オフセット** 第4列はメモリオフセットを示し、パーティションの開始アドレスを定義します。このオフセットは、前のパーティションのサイズとオフセットの合計によって決まります。最初のパーティション(私たちの場合はnvs)は必ず0x9000から始まる必要があります。これはブートローダー(オフセット0x1000、サイズ0x7000)やパーティションテーブルセクション(オフセット0x8000、サイズ0x1000)が関わっているためです。また、これらのパーティションはCSVファイルには記載されていません。もしブートローダーのサイズをカスタマイズなどにより増加させる必要がある場合は、プロジェクト設定メニューで(_Partition Table → Offset of partition table_) オフセットを増やす必要があります。その際には最初のパーティションにも新しいオフセットを追加することが求められます。

各列の詳細と設定方法

オフセットは4kB(0x1000)の倍数である必要があり、_app_パーティションについては64kB(0x10000)で整列されている必要があります。もし空白のままにすると、オフセットは前のパーティションの終わりに基づいて自動的に計算されるので、必要な整列も含まれます。### **サイズ**五番目の列はサイズを表し、このパーティションに割り当てるメモリ量を定義します。サイズは10進数や16進数(0xプレフィックス)、またはK(キロ)やM(メガ)の単位接頭辞を使用してフォーマットできます。つまり、4096 = 4K = 0x1000として表現できます。サイズはバイト数で定義されており、最小サイズは4kBです。また、大きなパーティションの場合、そのサイズも4kBの倍数でなければなりません。そして最大サイズはフラッシュメモリ全体の容量によって制限されています。このように、自分のプロジェクトに最適な構成を選ぶ際には、フラッシュメモリの特性やスキームによるデータアクセス速度への影響も考慮することが重要です。

実際のデモで学ぶカスタムパーティション

フラグはCSVファイルの最後の列で、これは「フラッシュ暗号化」機能によってパーティションが暗号化されるかどうかを定義するために使用されます。CSVファイルを作成した後、新しいパーティションテーブルのファイルを読み込むようにプロジェクト設定を変更する必要があります。ここで重要なのは、パーティションテーブルの構造に変更がある場合、フラッシュメモリを消去し、新しいパーティションバイナリファイルとともにデバイスを再プログラムする必要があるということです。この変換は手動でも行えるツールがありますが、ビルドプロセス中には自動的に実行されます。

さて、カスタムパーティションテーブルの使い方を示すために、拡張されたNVSパーティションとSPIFFS用の一つのパーティションを持つシンプルなデモを作成します。これによってESP32のフラッシュメモリを効率よく活用できる方法についても理解が深まります。アプリケーションやファイルシステムのサイズに応じて特定のデータ領域を割り当てることで性能向上につながるでしょう。また、異なるブロックサイズやアクセス速度に基づく最適な構成選択も安定性向上には欠かせません。このようなカスタマイズによって、それぞれのプロジェクトニーズに合った柔軟な設計が可能になります。

ESP-IDF VS Code拡張機能を活用する

ESP-IDF v4.2を使用した_partition_find_の例に基づいてコードを作成します。このデモでは、デバイス設定やその他の小さな関連データを保存するために、拡張NVS(Non-Volatile Storage)を使用します。NVSは少量のデータを保存するために非常に推奨されますが、大きなデータストレージにはFATファイルシステムやSPIFFSへの移行が必要です。また、ファイルやその他の大きなデータを保存するためのパーティションも作成し、その形式としてSPIFFSを利用します。

私たちの開発ボードはESP32ベースで、8MBのフラッシュメモリが搭載されています。カスタムパーティションテーブルは以下の通りです:

# ESP-IDF パーティションテーブル
# 名前, タイプ, サブタイプ, オフセット, サイズ, フラグ
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 ,
nvs_ext , data , nvs , 0x620000 , 0x10000 ,


このパーティションテーブルでは、_storage_ はSPIFFS用に使用され、_nvs_ext_ は追加的なNVSデータストレージとして機能します。OTAパーティションは同じサイズで確保し、将来的な機能追加に向けて十分なスペースを確保しておくことが重要です。

一般的な問題とトラブルシューティング

もしOTAを使用しない場合、ファクトリーパーティションのサイズを2MBに設定する必要はありません。ファームウェアのサイズが1MB未満であれば、そのままで大丈夫です。新しいCSVファイルを追加する必要があります。このファイルは「**partitions_example.csv**」という名前で、例を変更してパーティションスキームを見つけます。フラッシュしてこの例を実行すると、出力には検出されたすべてのパーティションが表示されます。コマンドは以下の通りです:
.py -p <COM_PORT> flash monitor
ターミナルのログ出力は次のようになります:
# ESP-IDF パーティションテーブル# 名前, タイプ, サブタイプ, オフセット, サイズ, フラグ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,0x20000,nvs_ext,data,nvs ,0x620000,0x10000,I (380) example: ----------------Find partitions---------------I (390) example: ESP_PARTITION_TYPE_DATA のタイプとサブタイプ ESP_PARTITION_SUBTYPE_DATA_NVS を持つパーティションを見つける...I (400) example: 'nvs' パーティションがオフセット 0x9000 とサイズ 0x6000 にて見つかりました I (410) example: Find partition with type ESP_PARTITION_TYPE_DATA and subtype ESP_PARTITION_SUBTYPE_DATA_PHY...E (420) example: パーティションが見つかりません!I (430) example: Find partition with type ESP_PARTITION_TYPE_APP and subtype ESP_PARTITION_SUBTYPE_APP_FACTORY...E (440) example: パーティションが見つかりません!I (450) example: Find partition with type ESP_PARTITION_TYPE_DATA and subtype ESP_PARTITION_SUBTYPE_DATA_FAT...E(460)example:パーティションが見つかりません!I(460)example:ESP_PARTITION_TYPE_DATAの型およびUNKNOWN_PARTITION_SUBTYPEとして指定されたパーティションを検索します… I(480) example : 'storage' がオフセット 目標データ「スペース」部分から取得しました559.I(570)...

拡張NVSパーティション(nvs_ext)を使用するには、NVS初期化時に_[nvs_flash_init_partition_ptr]_ を利用し、NVSパーティション名を渡す必要があります。

## **ESP-IDF VS Code Extension の利用**
パーテーションテーブル CSVファイルについて作業する別の方法として、[ESP-IDF VS Code Extension] を参考にすると便利です。このエクステンションでは、ESP-IDF をインストールし、Microsoft Visual Studio Code IDE 上でプロジェクト管理や作成ができます。特に便利なのは GUI ツールであるESP-IDF Partition Table Editorです。このエディターにアクセスするには、「Command Palette」を開き、「Partition Table Editor UI」と入力します(コマンドメニューは F1 キーで開きます)。

これで前述したフィールドと同様に、あなた自身のパーテーションテーブル構造を作成できます。構造体を書いた後、このCSVファイルをプロジェクト内に保存し、その後バイナリビルド及びボードへの書き込みをご確認ください。

### **一般的な問題(トラブルシュート)**
カスタムパーテーションとの関連性によく発生する問題はいくつかありまして、その中でもアライメントや重複について注意深く考えるべきです。まず初めて変更した場合、新しいバイナリファイルを書く際には必ずフラッシュ消去してください。そのためには次のコマンドをご利用下さい:
.py -p <COM_PORT> erase_flash


### **X パーツが見当たらない…**
この問題がおこる理由としてその部分は存在せずまた欠落していることがあります。またこれはCSV内で誤った値によって引き起こされることもあります。その一因として不正確なタイプやサブタイプなどがあります。

### **重複した分割問題**
もしあなたのオフセットポイントが他のセクター内になってしまうと下記エラーを見ることでしょう:
CSV エラー:分割間隔重複。
つまりCSV内6行目では始まる位置`(line=6)` が `offset=210000`となっていますので前回終わった `end=220000` よりも開始時間よりも高い位置から始まっていることになります。このエラー解決策としては CSV 内該当行数値を書き換えて下さい。

### **メモリーサイズ問題**
最もよくあるサイズ関連した課題とは整列性です。「app」型の場合、そのサイズは64kB (=16進数表現では´10000´)単位整列されなければいけません。それゆえ各「app」部門全般にも適用されます。
例えば:
, app , ota_01 , ox12000 , ox20000

ここならば以下エラーになるでしょう。
Partition ota _o 無効 : Offset ox12000 は align to ox10000 に合致しない
解決法としてオフセット値 `ox12000` を `ox20000` に修正してください。そして次以降再計算します。
こういう調整手間なく自動的な魔法的処理させたいならば空白保持すると良いでしょう。

例えば8MB フラッシュ使う事例を書く際には、
プロジェクト設定内『Serial flasher config → Flash size』 メニューでも適切量へ変えておいてくださいね。


カスタム・パーテーションテーブル作成というもの、ご自身プロジェクトへの利点多々ありそうですね。また外部SDカードなしでもデータ保管可能になる点非常素敵だと思います。ただ独自定義後しっかりデータ量・アライメント守って頂いて無駄なく資源活用出来るよう意識してみてくださいね

Reference Articles

ESP32のPartition Tableの書き方

ESP32 のフラッシュメモリを効果的に使うために、アドレスとサイズを指定したブロックを定義し、機能を割りあてることができる。 その指定をするファイルが ...

Source: Qiita

ESP32マイクロコントローラとそのESP-IDFを使用してOTA ...

ESP32 には、マイクロコントローラにどのようなタイプのデータがあり、どこに配置されているかを記したパーティションテーブルが含まれています。たとえば ...

Source: DigiKey

AquesTalk ESP32 の辞書を内蔵Flashに書き込んで使う

ESP32 は、フラッシュメモリの領域を複数のパーティションに分割しています。 ... エンジニアリング的に現実的な解決方法として、CDDBに曲名などと共に ...

AquesTalk ESP32 の辞書を内蔵Flashに書き込んで使う

ESP32 は、フラッシュメモリの領域を複数のパーティションに分割しています。 パーティションについては、記事「ESP32のパーティション設定」が参考になり ...

wolfSSL Documentation

組み込み機器向けの SSL ソリューションとして wolfSSL を選択する理由はたくさんあります。最大の理由. としてはそのサイズ (典型的なフットプリント ...

Source: wolfSSL

記事・ニュース一覧

第57回自作ツールによる日常業務効率化―初歩的なコードだけで身近な問題を解決 ... 第2章PostgreSQLの内部構造―プロセスやメモリの流れ、特徴的な機能のしくみ.

Source: gihyo.jp

Interface(インターフェース)のバックナンバー (2ページ目 45 ...

Interface(インターフェース)のバックナンバー187点の一覧です。(2ページ目 45件表示)コンピュータ・サイエンス&テクノロジ専門誌 定期購読なら割引や送料無料も。

Source: Fujisan.co.jp

製品・サービス一覧|テガラ - イプロスものづくり

遺伝的アルゴリズムにより回折効率の最適化に役立ちます。 【主な特徴】 ・視覚的な格子構造エディタ・一般的な回折格子プロファイルを自動生成 ...

Source: ipros.com

Alois Knoll

Expert

Related Discussions

❖ Related Articles