← Back to list

Mengenal Partisi di ESP32: Hal Pertama yang Wajib Dipahami Sebelum Ngulik ESP-IDF

Akhir-akhir ini saya mulai serius ngulik lebih dalam soal embedded system, khususnya ESP32. Selama ini pengalaman saya di dunia IoT lebih…

Nadia Wartiningrum · 2026-06-19 09:42 · 0 claps · 7.6 min read
#esp32 #partition #esp-idf #embedded-systems #firmware
Open on Medium ↗
Wiki topics: 📟 · Gadgets & IoT

Mengenal Partisi di ESP32: Hal Pertama yang Wajib Dipahami Sebelum Ngulik ESP-IDF

Akhir-akhir ini saya mulai serius ngulik lebih dalam soal embedded system, khususnya ESP32. Selama ini pengalaman saya di dunia IoT lebih banyak berkutat di sisi infrastruktur — Raspberry Pi, cloud, orchestration — sementara sisi firmware dan low-level hardware masih jadi area yang belum banyak saya sentuh.

Sebagai langkah awal, saya memutuskan untuk mulai belajar ESP-IDF, framework resmi dari Espressif untuk development di ESP32. Dan ternyata, sebelum sampai ke logic aplikasi atau konfigurasi sensor, ada satu konsep dasar yang harus dipahami lebih dulu: partition table.

Tulisan ini adalah dokumentasi pribadi saya dalam memahami apa itu partisi di ESP32, kenapa konsep ini penting, dan fungsi dari masing-masing partisi yang ada.

Apa Itu Partisi di ESP32?

ESP32 punya flash memory (umumnya berkapasitas 4MB, 8MB, atau 16MB) yang tidak digunakan sebagai satu blok besar tanpa struktur. Memory ini dibagi menjadi beberapa partisi, di mana setiap partisi punya alamat (offset), ukuran, dan fungsi spesifiknya masing-masing.

Layout pembagian ini didefinisikan dalam sebuah file bernama partitions.csv, yang dibaca oleh bootloader saat ESP32 menyala untuk menentukan di mana letak setiap komponen penting.

Penting dicatat: bootloader dan partition table itu sendiri berada di area yang sudah fixed dan tidak didefinisikan di partitions.csv. Bootloader menempati offset awal flash (0x1000), sedangkan partition table berada tepat setelahnya di 0x8000. Partisi pertama yang kita definisikan sendiri baru bisa dimulai dari 0x9000 ke atas.

Contoh Partition Table

Berikut contoh sederhana struktur partition table dalam format CSV:

# Name,   Type, SubType, Offset,  Size
nvs,      data, nvs,     0x9000,  0x6000
otadata,  data, ota,     0xf000,  0x2000
app0,     app,  ota_0,   0x10000, 0x140000
app1,     app,  ota_1,   0x150000,0x140000
spiffs,   data, spiffs,  0x290000,0x170000

Berikut adalah partisi-partisi utama yang umum ditemukan, beserta fungsinya.

1. Bootloader

Bootloader adalah kode pertama yang dieksekusi begitu ESP32 dinyalakan. Posisinya berada di awal flash memory (offset 0x1000). Tugas utamanya adalah membaca partition table, melakukan verifikasi, lalu mengarahkan eksekusi ke partisi aplikasi yang sesuai.

Offset bootloader bersifat fixed dari ROM chip itu sendiri (0x1000 untuk ESP32 original dan ESP32-S2, sementara 0x0000 untuk chip berbasis RISC-V seperti ESP32-C3/S3). Ukurannya sendiri dapat sedikit berubah tergantung konfigurasi (misalnya jika fitur secure boot atau flash encryption diaktifkan), namun dihitung otomatis oleh build system.

2. Partition Table

Partisi ini menyimpan “peta” dari seluruh partisi lain — alamat dan ukuran masing-masing. Bootloader membaca informasi ini untuk mengetahui ke mana harus melanjutkan proses boot.

3. NVS (Non-Volatile Storage)

NVS digunakan untuk menyimpan data dalam format key-value yang bersifat persisten, artinya tidak hilang meskipun device di-restart. Contoh penggunaannya antara lain menyimpan kredensial WiFi, konfigurasi device, nilai kalibrasi sensor, atau counter.

4. OTA Data

Partisi ini menyimpan informasi terkait proses OTA (Over-The-Air) update, secara spesifik partisi aplikasi mana yang sedang aktif digunakan (ota_0 atau ota_1). Informasi ini penting terutama untuk mekanisme rollback apabila proses update gagal.

Partisi ini hanya relevan jika project menggunakan mekanisme OTA. Jika tidak menggunakan OTA (cukup satu app partition factory), maka otadata tidak diperlukan sama sekali, karena tidak ada slot yang perlu di-track statusnya.

5. App Partition (Factory / OTA_0 / OTA_1)

Ini adalah lokasi tempat firmware atau aplikasi utama disimpan dalam bentuk binary hasil kompilasi.

Jika project menggunakan OTA, biasanya disediakan dua slot aplikasi (ota_0 dan ota_1). Device akan melakukan update ke slot yang sedang tidak aktif, dan baru beralih (switch) ke slot baru tersebut setelah proses update dipastikan berhasil. Apabila gagal, device dapat melakukan rollback ke slot sebelumnya.

Jika project tidak menggunakan mekanisme OTA, biasanya hanya tersedia satu partisi aplikasi yang disebut factory.

6. PHY Init

Partisi ini digunakan untuk menyimpan data kalibrasi radio (WiFi dan Bluetooth) pada layer PHY. Setiap chip ESP32 yang keluar dari fabrik memiliki karakteristik fisik radio yang sedikit berbeda satu sama lain, sehingga diperlukan data kalibrasi spesifik per-chip agar transmisi radio akurat — baik dari sisi power output maupun frequency offset.

Jika partisi ini tidak didefinisikan secara eksplisit, ESP-IDF secara default akan menggabungkan phy_init ke dalam partisi NVS, atau device akan melakukan self-calibration saat boot pertama kali.

7. SPIFFS / LittleFS / FATFS

Berbeda dengan NVS yang berbasis key-value, partisi jenis ini berfungsi sebagai filesystem untuk menyimpan file dalam bentuk yang lebih kompleks — misalnya file konfigurasi berformat JSON, asset, log, atau certificate.

LittleFS bersifat persistent sama seperti NVS, namun dengan konsep yang berbeda:

Persamaan dengan NVS — sama-sama menyimpan ke flash (bukan RAM), sehingga data tetap ada setelah restart maupun mati listrik (selama proses tulis sebelumnya sudah selesai), dan hanya hilang jika di-erase manual atau partisinya ditimpa ulang.

Perbedaan dengan NVS — NVS dirancang untuk data sederhana berbentuk key-value (string, integer, blob kecil), sedangkan LittleFS dirancang untuk menyimpan file yang lebih kompleks dan terstruktur, lengkap dengan dukungan folder.

Contoh konkret perbedaannya:

// NVS - menyimpan value sederhana
nvs_set_str(handle, "wifi_ssid", "BoboboxPod01");
nvs_set_i32(handle, "device_id", 12345);
// LittleFS - menyimpan file utuh
FILE* f = fopen("/littlefs/config.json", "w");
fprintf(f, "{\"device_id\": 12345, \"sensors\": [\"temp\", \"humidity\"]}");
fclose(f);
// Atau buat buffer log MQTT yang gagal terkirim
FILE* log = fopen("/littlefs/mqtt_buffer.log", "a");
fprintf(log, "2026-06-19T10:30:00 | sensor_data | {...}\n");
fclose(log);

Perlu dicatat, SPIFFS dan LittleFS didesain khusus untuk internal flash ESP32 dan tidak bisa digunakan langsung di SD card. Jika membutuhkan storage eksternal seperti SD card, filesystem yang umum digunakan adalah FATFS — karena SD card secara natural diformat dalam format FAT, dan ESP-IDF menyediakan driver khusus (esp_vfs_fat_sdcard_mount()) yang terpisah dari konsep partition table internal flash.

Saat ini, LittleFS lebih direkomendasikan dibanding SPIFFS karena memiliki ketahanan yang lebih baik terhadap power-loss — jika device mati listrik tepat di tengah proses tulis file, LittleFS memiliki mekanisme rollback ke state sebelumnya yang konsisten, sementara SPIFFS lebih rentan mengalami corrupt pada kondisi yang sama.

8. FAT (File Allocation Table)

FAT adalah format filesystem klasik dan universal yang umum digunakan pada flashdisk, SD card, dan berbagai embedded device. Berbeda dari SPIFFS/LittleFS yang didesain khusus untuk flash NOR embedded, FAT dirancang sebagai filesystem yang kompatibel secara universal — bisa langsung dibaca di Windows, Mac, maupun Linux.

FAT bisa digunakan di dua tempat: sebagai partisi di internal flash (didefinisikan di partitions.csv dengan SubType fat), atau sebagai filesystem pada SD card (dimount melalui driver esp_vfs_fat_sdmmc_mount(), terpisah dari partition table internal).

FAT menjadi pilihan yang tepat ketika project membutuhkan kompatibilitas dengan SD card, atau ketika data perlu bisa dibaca langsung di komputer tanpa tools khusus. Sementara SPIFFS/LittleFS lebih cocok untuk kebutuhan storage di internal flash yang tidak perlu kompatibel dengan ekosistem di luar ESP32.

9. Coredump

Partisi opsional ini digunakan untuk menyimpan crash dump apabila ESP32 mengalami panic atau crash. Konsepnya dapat dibayangkan seperti black box recorder pada pesawat — sebelum device melakukan restart akibat crash fatal, sistem menyimpan kondisi memory saat itu ke partisi ini, mencakup register CPU, call stack, dan task yang sedang berjalan di FreeRTOS.

Tanpa coredump, sebuah crash biasanya hanya diketahui sebatas “device restart sendiri”, tanpa informasi mengapa hal itu terjadi — terutama menyulitkan untuk bug yang bersifat intermiten dan sulit di-reproduce di development environment.

Untuk membaca hasil coredump, dapat di-extract dan dianalisis menggunakan:

idf.py coredump-info

Atau export ke file untuk analisis lebih detail:

idf.py coredump-debug

Output yang dihasilkan biasanya berupa informasi seperti:

Crash in task "main_task"
Backtrace: app_main → mqtt_publish → null_pointer_deref

Fitur ini menjadi krusial khususnya untuk device yang sudah di-deploy di lapangan dan tidak memiliki akses fisik langsung — memungkinkan proses debugging tanpa harus mendatangi lokasi device secara langsung.

Memahami Kolom Type, SubType, Offset, Size, dan Flags

Setelah memahami fungsi masing-masing partisi secara konsep, pertanyaan berikutnya yang muncul adalah: bagaimana sebenarnya struktur file partitions.csv itu didefinisikan? Setiap baris dalam file ini memiliki enam kolom dengan format sebagai berikut:

# Name,   Type, SubType,  Offset,   Size,    Flags
nvs,      data, nvs,      0x9000,   0x6000,
otadata,  data, ota,      0xf000,   0x2000,
app0,     app,  ota_0,    0x10000,  0x140000,
app1,     app,  ota_1,    0x150000, 0x140000,
spiffs,   data, spiffs,   0x290000, 0x170000,
coredump, data, coredump, ,         0x10000,

Berikut penjelasan masing-masing kolom.

Name

Kolom ini bebas diberi nama apapun, karena sifatnya hanya sebagai label untuk manusia — yang sebenarnya dibaca oleh sistem adalah kolom Type dan SubType. Meski demikian, tetap ada beberapa aturan teknis yang berlaku:

  • Maksimal 16 karakter, karena ESP-IDF membatasi panjang nama partisi maksimal 16 byte
  • Nama antar partisi tidak boleh sama
  • Bersifat case-sensitive — Nvs dianggap berbeda dengan nvs

Ada satu pengecualian penting: beberapa komponen built-in ESP-IDF mencari partisi berdasarkan nama tertentu secara default. Misalnya, library WiFi/Bluetooth mencari partisi bernama nvs untuk menyimpan kalibrasi dan konfigurasinya, begitu juga sistem kalibrasi PHY yang mencari partisi phy_init. Apabila nama-nama ini diubah, konfigurasi terkait di menuconfig perlu disesuaikan agar sistem tetap dapat menemukan partisi yang dimaksud.

Type

Kolom ini menentukan kategori besar dari sebuah partisi. Hanya terdapat dua nilai yang valid:

  • **app** — partisi yang berisi firmware atau aplikasi yang dapat dieksekusi.
  • **data** — partisi yang berisi data, bukan kode yang dieksekusi, seperti NVS, SPIFFS, atau informasi OTA.

Nilai ini juga dapat direpresentasikan dalam bentuk angka (0x00 untuk app, 0x01 untuk data), namun penggunaan string lebih umum karena lebih mudah dibaca.

SubType

Kolom ini memberikan detail lebih spesifik dari Type, dan menjadi penentu utama fungsi partisi tersebut.

Untuk Type app:

SubType Fungsi factory Aplikasi utama tanpa mekanisme OTA (single slot) ota_0, ota_1 Slot aplikasi untuk OTA

Untuk Type data:

SubType Fungsi nvs Key-value storage ota Informasi state OTA (slot mana yang sedang aktif) phy Kalibrasi RF spiffs Filesystem SPIFFS coredump Crash dump fat Filesystem FAT

Offset

Offset menunjukkan alamat awal sebuah partisi di flash memory, ditulis dalam format hexadecimal. Nilai ini menentukan lokasi penempatan partisi tersebut.

Dalam praktiknya, kolom ini sering dibiarkan kosong, karena ESP-IDF akan menghitung offset secara otomatis berdasarkan urutan partisi dan aturan alignment yang berlaku. Apabila diisi secara manual, terdapat aturan alignment yang wajib dipatuhi:

  • Partisi dengan Type app harus berada pada alamat yang merupakan kelipatan 0x10000 (64KB).
  • Partisi dengan Type data umumnya mengikuti alignment kelipatan 0x1000 (4KB).

Kesalahan alignment akan menyebabkan proses build gagal dengan error.

Size

Kolom ini menentukan ukuran partisi dalam satuan byte, ditulis dalam format hexadecimal. Total keseluruhan ukuran partisi tidak boleh melebihi kapasitas flash chip yang digunakan — informasi kapasitas flash dapat dicek melalui idf.py menuconfig pada bagian Serial Flasher Config → Flash Size, atau langsung dari hardware menggunakan esptool.py flash_id.

Pembahasan lebih detail mengenai cara menghitung size yang tepat untuk setiap jenis partisi akan dibahas dalam artikel terpisah **disini** .

Flags

Kolom ini jarang digunakan dan umumnya dibiarkan kosong. Satu-satunya flag yang umum dijumpai adalah:

app0, app, ota_0, 0x10000, 0x140000, encrypted

Flag **encrypted** menandakan bahwa partisi tersebut perlu dienkripsi apabila fitur flash encryption diaktifkan. Flag ini biasanya digunakan pada app partition atau NVS yang menyimpan data sensitif seperti kredensial.

Pendekatan Praktis dalam Mengatur Partition Table

Beberapa langkah yang dapat diikuti ketika mulai mengatur partition table:

  1. Gunakan template default terlebih dahulu. ESP-IDF menyediakan beberapa template siap pakai di direktori $IDF_PATH/components/partition_table/, di antaranya partitions_singleapp.csv (tanpa OTA) dan partitions_two_ota.csv (dengan OTA, dua slot).
  2. Buat custom partition table apabila diperlukan, dengan membuat file partitions.csv di root project, kemudian mengaktifkannya melalui:
idf.py menuconfig
   → Partition Table → Custom partition table CSV

3. Validasi sebelum melakukan flashing, dengan menjalankan:

idf.py partition-table

Perintah ini akan menampilkan layout partition table final, termasuk offset yang telah dihitung secara otomatis, sehingga dapat diperiksa terlebih dahulu sebelum benar-benar di-flash ke device.

Kenapa Konsep Ini Penting Dipahami Lebih Dulu

Sebelum masuk ke logic aplikasi, memahami partition table membantu menjawab beberapa pertanyaan praktis yang sering muncul di project IoT berbasis ESP32:

  • Bagaimana strategi OTA dirancang agar update firmware tidak menyebabkan device menjadi bricked.
  • Di mana sebaiknya data konfigurasi seperti device ID atau kredensial WiFi disimpan, alih-alih di-hardcode langsung ke dalam binary.
  • Bagaimana mekanisme buffering data secara lokal dapat dilakukan ketika koneksi ke broker terputus, sebelum data tersebut dikirim ulang.

Memahami fondasi ini terasa penting sebelum melangkah lebih jauh ke topik lain seperti FreeRTOS task management, driver komunikasi (I2C, SPI, UART), atau integrasi dengan MQTT.


메타데이터
post_id
5af93fe4dc18
slug
mengenal-partisi-di-esp32-hal-pertama-yang-wajib-dipahami-sebelum-ngulik-esp-idf-5af93fe4dc18
url
https://medium.com/@nadiawaa/mengenal-partisi-di-esp32-hal-pertama-yang-wajib-dipahami-sebelum-ngulik-esp-idf-5af93fe4dc18
canonical_url
https://medium.com/@nadiawaa/mengenal-partisi-di-esp32-hal-pertama-yang-wajib-dipahami-sebelum-ngulik-esp-idf-5af93fe4dc18
author_url
https://medium.com/@nadiawaa
status
ok
fetched_at
2026-06-23 17:05:31