ESP32'nin 520 KB SRAM'ı ve dual-core yapısı çoğu projenin ihtiyacını karşılıyor; ama "yeter de artar" yaklaşımı pil ömrünü ve cevap süresini öldürüyor. Bellek ve güç optimizasyonu küçük detaylarda saklı.
Aşağıda heap fragmantasyonundan deep-sleep kullanımına, RTOS task önceliklerinden Wi-Fi ayarlarına kadar pratik optimizasyon kalemleri var.
Bu yazıda ESP32 firmware'ini üretim seviyesine çıkarmak için bellek optimizasyonu, güç tasarrufu ve performans iyileştirme stratejilerini ele alıyoruz.
ESP32 Bellek Mimarisi
ESP32'nin bellek yapısını anlamadan optimizasyon mümkün değildir:
| Bellek Tipi | Boyut | Özellik |
|---|---|---|
| Internal SRAM | 520 KB | Hızlı, RAM olarak kullanılır |
| RTC SRAM | 8 KB + 8 KB slow | Deep sleep'te korunur |
| Flash (kullanıcı) | 4 MB tipik | Kod, NVS, SPIFFS partition |
| PSRAM (opsiyonel) | 2-8 MB | Modüllerde dahili, yavaş ama büyük |
| eFUSE | 1024 bit | Tek seferlik yazılan güvenlik bitleri |
Bellek Optimizasyon Stratejileri
1. Stack Boyutunu Doğru Belirleme
FreeRTOS task'larının her biri kendi stack'ine sahiptir. Default değer çoğu zaman ihtiyaçtan büyük veya yetersizdir. uxTaskGetStackHighWaterMark() ile gerçek kullanımı ölçün, %25 marjla ayarlayın. 10 task'ın her birinde 4 KB gereksiz alan = 40 KB heap kazancı.
2. Heap Yönetimi
ESP-IDF, heap'i farklı kapasitelerde (DRAM, IRAM, DMA-capable) sınıflandırır. heap_caps_malloc() ile spesifik tip talep edebilirsiniz. PSRAM'li modüllerde büyük buffer'lar (örn. JPEG, ses) PSRAM'e yönlendirilebilir; SRAM kritik fonksiyonlara kalır.
3. String Constant'ları PROGMEM'e
Sürekli kullanılan string'ler (debug mesajları, JSON şablonları) flash'ta tutulmalıdır. ESP-IDF'te bu zaten default davranıştır ama Arduino framework'ünde dikkat gerekir. F() makrosu veya "PROGMEM" qualifier'ı ile string'ler RAM'e kopyalanmaz.
4. Gereksiz Kütüphaneleri Çıkarma
Arduino framework'ünde include edilen her kütüphane otomatik linklenir. ESP-IDF kullanıyorsanız sadece gereken bileşenleri component listesine ekleyin. Wi-Fi tabanlı uygulamada Bluetooth stack'ini disable etmek 100+ KB tasarruf sağlar.
5. JSON ve Buffer Yönetimi
ArduinoJson v6+ statik allocator kullanır; bu sayede heap fragmantasyonu yaşanmaz. cJSON yerine ESP-IDF'in kendi cjson componentini kullanın. JSON parse ve serialization için ortak buffer kullanmak heap baskısını azaltır.
Güç Tasarrufu Stratejileri
ESP32 Güç Modları
| Mod | Akım Tüketimi | Wake-up Süresi |
|---|---|---|
| Active (RF aktif) | 180-260 mA | - |
| Active (modem sleep) | ~30 mA | Anında |
| Light Sleep | ~0.8 mA | <1 ms |
| Deep Sleep | 5-150 µA | ~280 ms |
| Hibernation | 5 µA | ~280 ms |
Deep Sleep Stratejisi
Pille çalışan sensörler için tipik desen: %1 zaman aktif, %99 deep sleep. 10 saniyede bir uyanıp veri okuyup gönderen ve gerisinde uyuyan bir sensör, 2x AA pil ile 1-2 yıl çalışabilir. esp_deep_sleep_start() çağrısı öncesinde GPIO'ları doğru konfigüre edin (giriş pull-up/down, çıkış sabit).
Wi-Fi Güç Optimizasyonu
- Modem sleep + DTIM listening: Veri yokken Wi-Fi modülü uykuya geçer, AP'den sinyal beklerken uyanır
- Static IP: DHCP süresi (1-3 saniye) tasarruf
- Connection caching: Önceki BSSID/channel'a doğrudan bağlanma (esp_wifi_set_config_caching)
- WPA2-PSK fast roaming: Ağ değişiminde tekrar handshake yapmamak
- OTA firmware'i sadece şarj edildiğinde indirmek
CPU Frekans Yönetimi
ESP32 80, 160, 240 MHz frekanslarında çalışabilir. esp_pm_lock ile dinamik frekans kontrolü mümkündür. Ağ veri transferi sırasında 240 MHz, idle'da 80 MHz kullanmak ortalama tüketimi %30 azaltabilir.
Performans Optimizasyonu
IRAM Kullanımı
Sık çağrılan ve hızlı çalışması gereken fonksiyonlar IRAM_ATTR ile işaretlenir; bunlar SRAM'de tutulur ve flash'tan okuma gecikmesi yaşamaz. Tipik kullanım: ISR, time-critical loop'lar. Aşırı kullanım SRAM'i tüketir.
DMA Kullanımı
ADC, I2S, SPI gibi periferal'larda DMA kullanmak CPU'yu serbest bırakır. ESP32'nin I2S DMA, ses akışı veya hızlı ADC sampling için kritiktir; CPU yardımı olmadan continuous data transfer mümkündür.
Dual Core Yönetimi
ESP32'nin iki çekirdeği (PRO_CPU ve APP_CPU) vardır. Wi-Fi/BT stack'i default olarak PRO_CPU'da çalışır. Yoğun uygulama mantığını APP_CPU'ya pin'lemek (xTaskCreatePinnedToCore) Wi-Fi performansını korurken uygulama hızını artırır.
Flash Kullanım Optimizasyonu
Partition Table Düzenlemesi
Default partition table iki app slot (OTA için) içerir. Her biri ~1.3 MB. Eğer OTA gerekmiyor ise tek slot kullanarak SPIFFS/LittleFS için daha çok yer açabilirsiniz. esp_partition_table.csv ile özelleştirin.
LittleFS vs SPIFFS
SPIFFS, ESP32'de eski bir filesystem olup performans ve güvenilirlik açısından zayıftır. LittleFS modern bir alternatiftir; power loss'a dayanıklı, daha hızlı. ESP-IDF v4.4+ ile native destek var.
OTA Stratejisi
- Differential OTA: Tüm firmware yerine sadece değişiklikleri indirme
- Compressed OTA: gzip ile sıkıştırılmış firmware indirme
- Background OTA: Wi-Fi boşken arka planda parça parça indirme
- Rollback mechanism: Yeni firmware başarısız olursa eski versiyona dönüş
Debug ve Profiling
ESP-IDF Monitor Araçları
- idf.py monitor: Serial loglar + crash dump çözümleme
- heap_caps_print_heap_info(): Heap durumu raporu
- vTaskList(): Tüm task'ların CPU kullanım oranı
- esp_pm_dump_locks(): Güç yönetimi lock'larının analizi
SystemView Entegrasyonu
Segger SystemView, FreeRTOS task'larının real-time görselleştirmesini yapan bir araç. ESP-IDF ile entegrasyonu kolaydır; task switch'leri, interrupt'lar, queue/semaphore aktiviteleri gerçek zamanlı izlenebilir.
Sıkça Yapılan Hatalar
1. Hâlâ Arduino Framework'ünde Israr Etmek
Üretim seviyesi bir cihaz için ESP-IDF native framework çok daha esnek ve verimlidir. Arduino, prototip için harika; ama deep sleep, OTA, security gibi konularda kısıtlıdır.
2. Default Wi-Fi Konfigürasyonu
Default ayarlarla Wi-Fi güç tüketimi optimal değildir. Modem sleep, DTIM listening, listen interval ayarlamadan üretime gönderilen cihazlar pil ömrü beklentisini karşılayamaz.
3. NVS Yığması
Non-Volatile Storage (NVS) sürekli yazma için tasarlanmamıştır. Her saniye konfigürasyon yazmak flash sektörlerini hızla tüketir. Sık değişen veriler için RTC RAM veya RAM cache + periyodik flush kullanın.
4. Stack Overflow'u Geç Tespit Etmek
FreeRTOS configCHECK_FOR_STACK_OVERFLOW = 2 yapın; stack overflow olduğunda anında hook çağrılır. Aksi halde rastgele crash'ler haftalar boyu sürebilir.
5. printf Yığması
Production firmware'inde her function entry/exit için printf bırakmayın. ESP_LOG_LEVEL_LOCAL ile log seviyelerini kontrol edin; production'da sadece WARN/ERROR seviyesi açık kalsın.
Sonuç
ESP32 firmware'i prototip seviyesinden üretim seviyesine taşımak; bellek yönetimi, güç optimizasyonu ve doğru framework seçimi konularında bilinçli kararlar gerektirir. Doğru optimize edilmiş bir ESP32 cihazı, küçük pillerle yıllar boyunca çalışabilir; OTA güncellemeleriyle sahada uzun yıllar yaşayabilir.
EA ARGE olarak, müşterilerimizin ESP32 tabanlı IoT ürünlerini hem prototip aşamasında hızlı geliştiriyor hem de üretime hazırlık fazında derin optimizasyonlardan geçiriyoruz.
Optimizasyon önce gelir
Optimizasyon çoğu zaman yeni özellik eklemekten önce gelir. Cihaz uyku moduna nasıl giriyor, açılışta hangi periferi kapanıyor; bu kararlar pil ömrünü iki-üç katına çıkarabiliyor. Ölçüm yapmadan optimize etmeye kalkmayın; akım probu ile yarım gün vakit ayırmak yön gösteriyor.