Catatan Belajar oleh : Reza Ervani bin Asmanu
Dalam seri pembelajaran sebelumnya mengenai arsitektur x86, kita telah mempelajari bagaimana prosesor berinteraksi dengan memori dalam ruang lingkup yang terbatas (1 MB). Namun, ketika kita beralih ke mikrokontroler modern seperti ESP32, kita berhadapan dengan sistem 32-bit yang jauh lebih kompleks dan bertenaga.
Bagi seorang pengembang embedded system, memahami peta memori (Memory Map) ESP32 adalah langkah fundamental untuk keluar dari keterbatasan library standar Arduino. Pemahaman ini memungkinkan kita untuk melakukan optimasi kode, manajemen daya tingkat lanjut (Deep Sleep), dan pengendalian perangkat keras dengan presisi tinggi.
Artikel ini akan membedah struktur memori ESP32, menjelaskan zona-zona krusial yang mengatur jalannya instruksi kode, penyimpanan data, hingga pengendalian periferal.
Arsitektur Harvard Modifikasi
Berbeda dengan PC tradisional (x86) yang umumnya menggunakan arsitektur Von Neumann—di mana instruksi program dan data berbagi jalur bus yang sama—ESP32 menggunakan arsitektur Harvard yang dimodifikasi.
Arsitektur ini memisahkan ruang alamat untuk Instruksi (Kode) dan Data. Tujuannya adalah efisiensi: CPU dapat membaca instruksi berikutnya (fetch) dan menulis data ke memori secara bersamaan melalui bus yang berbeda. Inilah sebabnya mengapa dalam pemrograman ESP32 kita mengenal istilah IRAM (Instruction RAM) dan DRAM (Data RAM).
Peta Memori ESP32 (The Memory Map)
Meskipun ESP32 memiliki ruang alamat teoritis sebesar 4 GB (32-bit), tidak semua alamat tersebut dapat digunakan. Berikut adalah diagram blok yang memetakan area-area fungsional utama dalam ESP32:
ALAMAT (Hex) FUNGSI / KEGUNAAN
---------------------------------------------------------
0x6000_0000 [ RESERVED / EXTERNAL MEMORY ]
| Area yang dialokasikan untuk PSRAM
| (RAM Eksternal) jika terpasang pada modul.
---------------------------------------------------------
0x5000_2000
| RTC FAST MEMORY (8 KB)
| Dapat diakses CPU saat booting dari Deep Sleep.
0x5000_0000 RTC SLOW MEMORY (8 KB)
| Area retensi data (Non-Volatile sementara).
| Tempat variabel dengan atribut 'RTC_DATA_ATTR'.
| Data di sini TIDAK HILANG saat Deep Sleep.
---------------------------------------------------------
|
| ( Celah Alamat / Reserved )
|
---------------------------------------------------------
0x400C_2000
| INTERNAL ROM
| Berisi kode bawaan pabrik (Bootloader,
| Fungsi Enkripsi/WiFi Stack dasar). Read-Only.
0x4000_0000
---------------------------------------------------------
0x4008_0000
| INTERNAL IRAM (Instruction RAM)
|-------------> [ KODE KRITIS / INTERRUPT ]
| Area eksekusi kode berkecepatan tinggi.
| Target untuk fungsi dengan atribut 'IRAM_ATTR'.
|
0x4000_0000 (Instruction Bus - Jalur Instruksi)
---------------------------------------------------------
0x3FF8_0000 (Data Bus - Jalur Data)
| INTERNAL DRAM (Data RAM)
|-------------> [ HEAP & STACK ]
| Tempat variabel global, alokasi dinamis (malloc),
| dan tumpukan fungsi (stack).
0x3FFB_0000
---------------------------------------------------------
0x3FF7_FFFF
| PERIPHERALS (Register Hardware)
| Area kendali perangkat keras (Memory Mapped I/O).
|-------------> [ GPIO, UART, SPI, TIMER, WIFI ]
| Menulis ke alamat ini berarti mengirim sinyal
| listrik ke komponen (misal: GPIO.out_w1ts).
0x3FF0_0000
---------------------------------------------------------
0x3F40_0000
| EXTERNAL FLASH (Memory Mapped)
| Penyimpanan utama kode program Anda.
| CPU mengaksesnya melalui mekanisme Cache.
---------------------------------------------------------
0x0000_0000 [ RESERVED / SYSTEM ]
---------------------------------------------------------
Analisis Zona Memori
Berikut adalah penjelasan mendetail mengenai empat zona utama yang wajib dipahami oleh pengembang firmware:
1. Zona Periferal (0x3FF0_0000 – 0x3FF7_FFFF)
Zona ini adalah “kokpit” dari ESP32. Di dalam rentang alamat ini, terdapat register-register yang mengendalikan seluruh fitur perangkat keras.
Dalam pemrograman tingkat rendah, kita tidak menggunakan fungsi abstraksi. Sebagai contoh, untuk menyalakan LED, kita tidak memanggil fungsi, melainkan menulis nilai 1 ke alamat register GPIO yang spesifik di dalam zona ini. Konsep ini dikenal sebagai Memory Mapped I/O: mengendalikan perangkat keras seolah-olah kita sedang menulis data ke memori RAM biasa.
2. Zona DRAM (0x3FFB_0000 – 0x3FF8_0000)
DRAM (Data RAM) adalah memori kerja standar. Saat Anda mendeklarasikan variabel global int skor = 0; atau melakukan alokasi memori dinamis, data tersebut disimpan di sini.
Penting untuk dicatat bahwa DRAM terhubung ke Bus Data. Artinya, CPU dapat membaca dan menulis data ke sini dengan cepat, namun DRAM tidak dirancang untuk menyimpan kode instruksi yang akan dieksekusi.
3. Zona IRAM (0x4000_0000 – 0x4008_0000)
Di sinilah letak keunikan optimasi ESP32. Sebagian besar kode program kita sebenarnya tersimpan di Flash Memory Eksternal (0x3F40...). Flash memori itu lambat. Untuk mengatasinya, ESP32 menyalin blok kode dari Flash ke Cache secara otomatis saat dibutuhkan.
Namun, untuk kode yang sangat kritis—seperti Interrupt Service Routine (ISR) yang harus merespons dalam hitungan mikrodetik—kita tidak bisa mengambil risiko keterlambatan (latency) akibat pengambilan data dari Flash. Oleh karena itu, kita menggunakan atribut khusus IRAM_ATTR pada kode C/C++ kita.
Atribut ini memerintahkan compiler untuk menempatkan fungsi tersebut secara permanen di IRAM internal yang super cepat, bukan di Flash eksternal.
4. Zona RTC Memory (0x5000_0000)
Zona ini sering disebut sebagai “bunker memori”. ESP32 memiliki fitur hemat daya ekstrim bernama Deep Sleep. Dalam mode ini, CPU dimatikan, dan aliran listrik ke RAM utama (DRAM & IRAM) diputus. Akibatnya, semua variabel di RAM akan hilang.
Namun, ESP32 mendesain blok memori khusus bernama RTC Slow Memory yang tetap dialiri daya listrik rendah saat Deep Sleep.
Dengan mendeklarasikan variabel menggunakan atribut RTC_DATA_ATTR, variabel tersebut akan dialokasikan di alamat 0x5000.... Hasilnya, nilai variabel tersebut akan “selamat” dan dapat dibaca kembali saat ESP32 bangun dari tidurnya. Ini sangat krusial untuk aplikasi bertenaga baterai, seperti sensor yang hanya bangun sehari sekali untuk mengirim data.
Kesimpulan
Memahami peta memori ESP32 memberikan kita wawasan bahwa tidak semua memori diciptakan sama. Ada memori untuk kendali hardware (Periferal), memori untuk kecepatan eksekusi (IRAM), dan memori untuk ketahanan data (RTC).
Penguasaan terhadap pemetaan ini adalah kunci transisi dari sekadar “penulis kode Arduino” menjadi “arsitek sistem embedded” yang mampu memanfaatkan setiap transistor dalam mikrokontroler secara efisien.
