Menyimpan data dengan aman di firmware: karakteristik flash memory dan batas erase, perbandingan LittleFS dan FATFS, wear leveling, ketahanan terhadap putusnya listrik, NVS key-value, serta praktik membangun storage firmware dengan LittleFS di flash eksternal.

Setelah di episode 16 kita menjamin timing, pada episode ini kita menjamin data tetap ada. Banyak produk harus menyimpan data meski listrik mati: log sensor, konfigurasi, state terakhir, sertifikat. Menulis ke flash bukan seperti menulis ke file di PC — flash punya aturan keras yang, jika dilanggar, merusak perangkat.
Mengapa topik ini penting? Karena kesalahan storage adalah kategori bug paling jahat: perangkat bisa "lupa" konfigurasi, mengembalikan data korup, atau — jika wear leveling diabaikan — flash-nya aus lebih cepat dan perangkat mati total setelah beberapa bulan. Di episode ini kita membangun pemahaman yang akan menyelamatkan produk kalian dari semua itu.
Flash memory (NOR di kebanyakan MCU, atau SPI flash eksternal) punya tiga aturan fundamental:
10.000 – 100.000 siklus program/erase (P/E cycles).Menyimpan counter log tiap detik di sector yang sama
= 86.400 erase/hari = aus dalam hitungan hari.
Maka: BUTUH wear leveling + filesystem yang mengelolanya.Ada dua kategori utama untuk firmware:
| Aspek | LittleFS | FATFS |
|---|---|---|
| Desain | Untuk flash MCU | Untuk kartu SD/USB (dengan kontroller) |
| Wear leveling | Bawaan (metadata round-robin) | Tidak ada (tidak butuh, SD punya kontroller) |
| Power-loss safe | Ya (copy-on-write) | Butuh langkah ekstra |
| Kompatibilitas PC | Tidak (format khusus) | Ya (bisa dibuka di PC) |
| Cocok untuk | SPI NOR flash, log, konfigurasi | SD card, USB, interoperabilitas |
LittleFS dirancang khusus untuk flash kecil yang kehilangan daya sewaktu-waktu — sangat cocok untuk SPI NOR flash dan konfigurasi. FATFS cocok saat kalian perlu SD card yang bisa dibaca PC, atau perangkat dengan media berkontroller.
Mekanisme yang menyebar write ke seluruh blok agar tidak ada sector yang "aus" lebih dulu. LittleFS melakukannya secara otomatis di lapisan metadata; kalian tetap harus menghindari menulis file yang sama terus-menerus dalam waktu pendek.
Listrik bisa mati kapan saja — di tengah penulisan, di tengah erase. LittleFS menggunakan copy-on-write: tulis dulu ke tempat baru, lalu update metadata; jika daya putus, data lama tetap utuh (atau transisi yang terdefinisi).
Warning
Jangan pernah memformat ulang atau menimpa sector flash di tengah update kecuali benar-benar diperlukan — dan jika ada operasi panjang, rancang state machine update yang bisa di-resume setelah reboot. Perangkat yang "format ulang saat boot" karena bug adalah perangkat yang kehilangan semua data pengguna.
Untuk konfigurasi kecil, filesystem sering berlebihan. NVS (Non-Volatile Storage) menyediakan key-value sederhana dengan wear leveling — bawaan di ESP-IDF (nvs_flash), dan pola serupa ada di STM32/Zephyr:
nvs_handle_t h;
nvs_open("config", NVS_READWRITE, &h);
nvs_set_u32(h, "brightness", 128); // simpan nilai
nvs_commit(h); // tulis ke flash
nvs_close(h);NVS ideal untuk: brightness, koneksi tersimpan, counter boot, flags. Data besar (log, gambar) tetap butuh filesystem.
Skema praktis: SPI NOR flash eksternal (misal W25Q128) + LittleFS untuk log dan konfigurasi:
#include "lfs.h"
lfs_t lfs; // instance filesystem
static int read_flash(const struct lfs_config *c, lfs_block_t b,
lfs_off_t off, void *buf, lfs_size_t size) {
// baca sektor dari SPI flash -> buf
}
static int prog_flash(const struct lfs_config *c, lfs_block_t b,
lfs_off_t off, const void *buf, lfs_size_t size) {
// tulis (program) data ke flash
}
static int erase_flash(const struct lfs_config *c, lfs_block_t b) {
// erase satu block
}
void storage_init(void) {
struct lfs_config cfg = {0};
cfg.read = read_flash;
cfg.prog = prog_flash;
cfg.erase = erase_flash;
cfg.read_size = 1;
cfg.prog_size = 256;
cfg.block_size = 4096; // ukuran sector flash
cfg.block_count = 4096; // total sector
cfg.cache_size = 256;
cfg.lookahead_size = 256;
if (lfs_mount(&lfs, &cfg) != LFS_ERR_OK) {
lfs_format(&lfs, &cfg); // flash kosong/korup -> format
lfs_mount(&lfs, &cfg);
}
// tulis file konfigurasi
lfs_file_t f;
lfs_file_open(&lfs, &f, "/cfg.bin", LFS_O_RDWR | LFS_O_CREAT);
lfs_file_write(&lfs, &f, "hello", 5);
lfs_file_close(&lfs, &f);
}Perhatikan: lfs_mount gagal → format → mount ulang. Untuk log, gunakan mode append dan jangan buka-tutup file di setiap detik — buffer dulu, flush berkala.
Tip
Simpan config dalam blok kecil + CRC/checksum + version. Saat upgrade firmware membawa format baru, adanya versi dan checksum memungkinkan migrasi yang aman. Perangkat yang membaca config "ngasal" karena format berubah adalah sumber bug lapangan paling umum.
Inti yang harus dibawa pulang:
Di episode 18 selanjutnya kita mengamankan semuanya: Firmware Security — secure boot, kriptografi, anti-tamper, dan hardening firmware agar perangkat tidak bisa dibajak. Produk kalian akan kebal terhadap serangan!