disket.net Beta
Konu Listesine Dön

ESP32'de FreeRTOS ile Task Önceliklendirme Sorunu - Watchdog Reset Yiyorum

Programlama Açılış: 26.07.2026 13:48 7 Görüntülenme
Selam beyler, uzun süredir okurum ama ilk defa konu açıyorum. Şöyle bir derdim var: ESP32-WROOM-32 modülü üzerinde FreeRTOS kullanarak bir proje geliştiriyorum. İki adet task'im var: biri yüksek öncelikli (priority 5) bir sensör okuma task'i (MPU6050'den I2C ile veri çekiyor, yaklaşık 10ms'de bir döngü yapıyor), diğeri düşük öncelikli (priority 1) bir HTTP POST task'i (JSON payload'ları server'a yolluyor, bazen 500ms'yi bulabiliyor). Sorun şu ki, yüksek öncelikli task sürekli çalıştığı için düşük öncelikli task bir türlü CPU zamanı alamıyor ve belirli bir süre sonra ESP32, Task Watchdog Timer (TWDT) hatası verip reset atıyor. vTaskDelay(10 / portTICK_PERIOD_MS) kullanıyorum yüksek öncelikli task'te ama yine de olmuyor. Acaba priority değerlerini mi yanlış veriyorum, yoksa I2C kütüphanesi içinde bir blokaj mı var? Yardımcı olursanız sevinirim, kod parçasını da aşağıya bırakıyorum:

```c
void vHighPriorityTask(void *pvParameters) {
while(1) {
readMPU6050(); // I2C read
processData();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}

void vLowPriorityTask(void *pvParameters) {
while(1) {
httpPostRequest(); // blocking HTTP
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

void app_main() {
xTaskCreatePinnedToCore(vHighPriorityTask, "HighTask", 4096, NULL, 5, NULL, 0);
xTaskCreatePinnedToCore(vLowPriorityTask, "LowTask", 8192, NULL, 1, NULL, 1);
}
```

Cevaplar (2)

Kanka, öncelikle hoş geldin. TWDT hatası genelde bir task'in uzun süre CPU'yu bloke etmesinden kaynaklanır. Senin durumunda yüksek öncelikli task (priority 5) sürekli ready state'te kalıyor ve düşük öncelikli task (priority 1) hiçbir zaman çalışamıyor. FreeRTOS'ta aynı öncelik seviyesindeki task'ler round-robin ile çalışır, ama farklı önceliklerde yüksek olan her zaman düşük olanı preempt eder. Yani priority 5 olan task, priority 1 olan task'i ezer geçer. Çözüm için birkaç önerim var:

1. **Öncelikleri eşitle veya yaklaştır:** Her iki task'i de aynı priority'ye (örneğin 3) al. Bu sayede round-robin ile çalışırlar ve her ikisi de zaman alır. vTaskDelay ile de süreleri ayarlarsın.

2. **vTaskDelay yerine vTaskDelayUntil kullan:** Eğer yüksek öncelikli task'in belirli bir periyotta çalışması gerekiyorsa, vTaskDelayUntil ile sabit zamanlama yap. Ama yine de priority farkı sorun yaratabilir.

3. **I2C işlemini event-driven yap:** readMPU6050() fonksiyonu içinde I2C işlemi blocking olabilir. I2C kütüphanesinin timeout ayarlarını kontrol et. ESP32'nin I2C driver'ında `i2c_set_timeout()` ile timeout süresini artırabilirsin.

4. **Core'ları doğru kullan:** İki task'i farklı core'lara pinledin (Core 0 ve Core 1). Bu iyi bir yaklaşım, ama priority farkından dolayı yine de düşük öncelikli task Core 1'de çalışırken, yüksek öncelikli task Core 0'da sürekli çalışıyorsa, TWDT yine devreye girebilir. Çünkü TWDT her core için ayrı çalışır. Yani Core 1'deki task çalışmazsa, Core 1'in watchdog'u reset atar.

Ben olsam öncelikleri eşitlerdim. Ayrıca HTTP POST işlemini non-blocking yapmak için `esp_http_client` kütüphanesinin async modunu kullanabilirsin. Denemek için priority'leri 3 yap ve dene, büyük ihtimalle çözülür. Kolay gelsin!



Kanka, öncelikle hoş geldin. TWDT hatası genelde bir task'in uzun süre CPU'yu bloke etmesinden kaynaklanır. Senin durumunda yüksek öncelikli task (priority 5) sürekli ready state'te kalıyor ve düşük öncelikli task (priority 1) hiçbir zaman çalışamıyor. FreeRTOS'ta aynı öncelik seviyesindeki task'ler round-robin ile çalışır, ama farklı önceliklerde yüksek olan her zaman düşük olanı preempt eder. Yani priority 5 olan task, priority 1 olan task'i ezer geçer. Çözüm için birkaç önerim var:

1. **Öncelikleri eşitle veya yaklaştır:** Her iki task'i de aynı priority'ye (örneğin 3) al. Bu sayede round-robin ile çalışırlar ve her ikisi de zaman alır. vTaskDelay ile de süreleri ayarlarsın.

2. **vTaskDelay yerine vTaskDelayUntil kullan:** Eğer yüksek öncelikli task'in belirli bir periyotta çalışması gerekiyorsa, vTaskDelayUntil ile sabit zamanlama yap. Ama yine de priority farkı sorun yaratabilir.

3. **I2C işlemini event-driven yap:** readMPU6050() fonksiyonu içinde I2C işlemi blocking olabilir. I2C kütüphanesinin timeout ayarlarını kontrol et. ESP32'nin I2C driver'ında `i2c_set_timeout()` ile timeout süresini artırabilirsin.

4. **Core'ları doğru kullan:** İki task'i farklı core'lara pinledin (Core 0 ve Core 1). Bu iyi bir yaklaşım, ama priority farkından dolayı yine de düşük öncelikli task Core 1'de çalışırken, yüksek öncelikli task Core 0'da sürekli çalışıyorsa, TWDT yine devreye girebilir. Çünkü TWDT her core için ayrı çalışır. Yani Core 1'deki task çalışmazsa, Core 1'in watchdog'u reset atar.

Ben olsam öncelikleri eşitlerdim. Ayrıca HTTP POST işlemini non-blocking yapmak için `esp_http_client` kütüphanesinin async modunu kullanabilirsin. Denemek için priority'leri 3 yap ve dene, büyük ihtimalle çözülür. Kolay gelsin!



Dostum çok teşekkür ederim, dediğin gibi öncelikleri eşitledim (priority 3 yaptım) ve ayrıca HTTP POST için `esp_http_client` kütüphanesinin async moduna geçtim. Ayrıca I2C timeout'u da `i2c_set_timeout(I2C_NUM_0, 10000)` ile artırdım. Şu an 2 saattir test ediyorum, hiç reset yemedi ve sensör verileri de düzgün geliyor. Sorun çözüldü, destek veren herkese teşekkürler!

Bu konuya cevap yazabilmek için retro topluluğumuza üye olmalı veya giriş yapmalısınız.

İlgili Konular & Benzer Paylaşımlar

PIC16F628A ile C'de RF alıcı-verici protokolü: Manchester kodlama sorunu Kategori: Programlama
PHP'de PDO ile MySQL bağlantısı neden hata veriyor? (Fatal error: Uncaught PDOException) Kategori: Programlama
Turbo Pascal ile COM port üzerinden veri okurken program donuyor, yardım! Kategori: Programlama