🐕 hal::watchdog
Watchdog Timer - Sistem Güvenilirliği ve Reset Yönetimi
~280 satır
~8 fonksiyon
STM32/GD32/ESP32
📖 Genel Bakış
Watchdog timer, yazılım hatalarından kaynaklanan sistem donmalarını otomatik olarak tespit edip sistemi resetler. Mikrokontrolcü beklenmedik bir duruma girerse (sonsuz döngü, kilitlenme), watchdog sayacı sıfırlanmadığı için timeout olur ve sistem yeniden başlatılır.
İki tip watchdog vardır: IWDG (Independent Watchdog - LSI saatle çalışır, düşük güç modlarında bile aktif) ve WWDG (Window Watchdog - pencere kontrolü ile daha hassas zamanlama).
🔑 Temel Özellikler
- Independent watchdog (IWDG) - LSI clock (32 kHz)
- Window watchdog (WWDG) - APB1 clock
- Konfigüre edilebilir timeout (ms - saniyeler)
- Early warning interrupt (WWDG)
- Reset source detection
- Debug mode freeze desteği
- Sleep/Stop mode'da çalışma
- Prescaler ayarları (4 - 256)
🚀 Hızlı Başlangıç
içe_aktar hal::watchdog, hal::core
// Independent watchdog (4 saniye timeout)
değişken wdg = watchdog.init_iwdg(yap
timeout_ms: 4000,
window_mode: yanlış
son)
// Ana döngü
döngü yap
// Normal işlemler
core.delay_ms(500)
// Watchdog'u besle (refresh)
watchdog.refresh(wdg)
// Eğer bu satır çalışmazsa sistem 4 saniye içinde resetlenir
son
📦 Tipler ve Enum'lar
// Watchdog Tipi
enum WatchdogType {
IWDG, // Independent watchdog
WWDG // Window watchdog
}
// Prescaler değerleri
enum Prescaler {
DIV_4,
DIV_8,
DIV_16,
DIV_32,
DIV_64,
DIV_128,
DIV_256
}
// Reset Source
enum ResetSource {
POWER_ON, // Power-on reset
PIN_RESET, // External pin reset
SOFTWARE, // Software reset
IWDG_RESET, // Independent watchdog
WWDG_RESET, // Window watchdog
LOW_POWER, // Low-power reset
BROWNOUT // Brown-out reset
}
yapı WatchdogConfig yap
type: WatchdogType,
timeout_ms: sayı, // Milliseconds
window_mode: mantık, // Window watchdog only
prescaler: Prescaler,
reload_value: sayı
son
💡 Örnek 1: Basic IWDG Kullanımı
2 saniyelik watchdog ile sistem koruması
içe_aktar hal::watchdog, hal::gpio, hal::core
değişken led_green = gpio.pin_init(gpio.PORT_C, 13, gpio.MODE_OUTPUT)
değişken led_red = gpio.pin_init(gpio.PORT_C, 14, gpio.MODE_OUTPUT)
fonksiyon ana() yap
// Check reset source
değişken reset_cause = watchdog.get_reset_source()
eğer reset_cause == watchdog.IWDG_RESET ise yap
// Watchdog reset occurred!
gpio.pin_write(led_red, gpio.HIGH)
core.delay_ms(2000)
gpio.pin_write(led_red, gpio.LOW)
son
// Initialize watchdog (2 second timeout)
değişken wdg = watchdog.init_iwdg(yap
timeout_ms: 2000,
window_mode: yanlış
son)
// Main loop
döngü yap
// Normal operation
gpio.pin_toggle(led_green)
core.delay_ms(100)
// Feed watchdog every 100ms (well before 2s timeout)
watchdog.refresh(wdg)
son
son
💡 Örnek 2: Task Monitor ile Watchdog
Çoklu task izleme ve watchdog besleme
içe_aktar hal::watchdog, hal::time
değişken son_beslenme_zamani: Zaman
değişken watchdog_aktif = doğru
fonksiyon kritik_gorev_1() yap
// Kritik işlemler
core.delay_ms(50)
// İşlem başarılı
watchdog_besleme_istegi()
son
fonksiyon kritik_gorev_2() yap
// Başka kritik işlemler
core.delay_ms(75)
// İşlem başarılı
watchdog_besleme_istegi()
son
fonksiyon watchdog_besleme_istegi() yap
son_beslenme_zamani = time.now()
son
fonksiyon watchdog_yonetici(wdg: WatchdogHandle) yap
döngü yap
// Check if tasks are healthy
değişken elapsed = time.now() - son_beslenme_zamani
eğer elapsed < time.milliseconds(500) ise yap
// Tasks are running OK, feed watchdog
watchdog.refresh(wdg)
yoksa yap
// Tasks hung! Let watchdog reset the system
io.println("UYARI: Görevler askıda! Watchdog resetleyecek...")
son
core.delay_ms(100)
son
son
fonksiyon ana() yap
// 1 saniye watchdog timeout
değişken wdg = watchdog.init_iwdg(yap
timeout_ms: 1000,
window_mode: yanlış
son)
son_beslenme_zamani = time.now()
// Start tasks
thread.spawn(|| kritik_gorev_1())
thread.spawn(|| kritik_gorev_2())
thread.spawn(|| watchdog_yonetici(wdg))
thread.join_all()
son
💡 Örnek 3: Window Watchdog (WWDG)
Pencere kontrolü ile hassas zamanlama
içe_aktar hal::watchdog
// WWDG: Hem çok erken hem çok geç beslemeyi engeller
fonksiyon wwdg_demo() yap
// Window: 50-100ms aralığında beslenmeli
değişken wwdg = watchdog.init_wwdg(yap
timeout_ms: 100,
window_ms: 50, // Pencere başlangıcı
early_wakeup_interrupt: doğru
son)
// Early warning interrupt handler
watchdog.set_interrupt_handler(wwdg, || yap
io.println("Watchdog erken uyarı!")
// Burası early wakeup interrupt (zamanında besle)
son)
değişken sayac = 0
döngü yap
// İşlemler
core.delay_ms(30)
// 30ms + 30ms = 60ms (pencere içinde: 50-100ms ✓)
core.delay_ms(30)
// Watchdog'u besle
watchdog.refresh(wwdg)
sayac += 1
// Simulate hang every 10 iterations
eğer sayac % 10 == 0 ise yap
io.println("Simüle edilen gecikme...")
core.delay_ms(150) // Too late! WWDG will reset
son
son
son
💡 Örnek 4: Watchdog + Backup Register
Reset nedeni kaydetme ve analiz
içe_aktar hal::watchdog, hal::rtc
yapı ResetInfo yap
count: sayı,
last_reason: ResetSource,
timestamp: sayı
son
fonksiyon reset_bilgisi_kaydet() yap
değişken reason = watchdog.get_reset_source()
// Backup register'dan önceki bilgiyi oku
değişken reset_count = rtc.backup_read(0)
reset_count += 1
// Yeni bilgiyi kaydet
rtc.backup_write(0, reset_count)
rtc.backup_write(1, reason.to_int())
rtc.backup_write(2, time.timestamp())
io.println("Reset sayısı: " + reset_count.yazıya())
io.println("Reset nedeni: " + reason.to_string())
son
fonksiyon ana() yap
// Initialize RTC for backup registers
rtc.init()
// Log reset information
reset_bilgisi_kaydet()
// Check for excessive resets
değişken reset_count = rtc.backup_read(0)
eğer reset_count > 10 ise yap
io.println("HATA: Çok fazla reset! Sistem unstable.")
// Enter safe mode or disable some features
rtc.backup_write(0, 0) // Reset counter
son
// Initialize watchdog
değişken wdg = watchdog.init_iwdg(yap
timeout_ms: 3000,
window_mode: yanlış
son)
// Normal operation
döngü yap
// Your code here
watchdog.refresh(wdg)
core.delay_ms(500)
son
son
📊 API Referansı
Initialization
fonksiyon init_iwdg(config: WatchdogConfig) -> WatchdogHandle
fonksiyon init_wwdg(config: WatchdogConfig) -> WatchdogHandle
fonksiyon deinit(handle: WatchdogHandle)
Control
fonksiyon refresh(handle: WatchdogHandle)
fonksiyon start(handle: WatchdogHandle)
fonksiyon is_running(handle: WatchdogHandle) -> mantık
Reset Information
fonksiyon get_reset_source() -> ResetSource
fonksiyon clear_reset_flags()
fonksiyon software_reset()
Window Watchdog (WWDG Only)
fonksiyon set_interrupt_handler(handle: WatchdogHandle, callback: Fonksiyon)
fonksiyon get_counter(handle: WatchdogHandle) -> sayı
⚙️ Platform Desteği
| Platform | IWDG | WWDG | Max Timeout |
|---|---|---|---|
| STM32F4 | ✓ | ✓ | 32 saniye |
| STM32F1 | ✓ | ✓ | 26 saniye |
| ESP32 | ✓ | ✗ | configurable |
| GD32VF103 | ✓ | ✓ | 26 saniye |
💡 Best Practices
- Timeout seçimi: En uzun task süresinin 2-3 katı olmalı
- Beslenme sıklığı: Timeout süresinin %50-75'i aralıklarla besleyin
- Debug mode: Geliştirme sırasında watchdog'u freeze edin (debugger breakpoint'lerde)
- Critical sections: Interrupt disable edilen yerlerde watchdog timeout'u hesaplayın
- Reset logging: Reset nedenlerini backup register'da saklayın
- IWDG vs WWDG: Production'da IWDG (LSI bağımsız), critical timing için WWDG
- Power modes: IWDG low-power modlarda çalışır, WWDG durur
⚠️ Önemli Notlar
- IWDG bir kez başlatıldı mı durdurulamaz (hardware restriction)
- Debug sırasında watchdog reset'lerini önlemek için DBGMCU_APB1_FZ register'ını ayarlayın
- LSI clock toleransı %40'a kadar olabilir - timeout hesaplamalarında dikkate alın
- Flash programming sırasında watchdog'u disable edin (erase uzun sürebilir)
🔗 İlgili Modüller
- hal::rtc - Backup register for reset logging
- hal::power - Low-power modes and watchdog
- hal::clock - LSI clock configuration