🐕 hal::watchdog
Watchdog Timer - Sistem Güvenilirliği ve Reset Yönetimi
~280 lines
~8 function
STM32/GD32/ESP32
📖 Overview
Watchdog timer, yazılım hatalarından kaynaklanan sistem donmalarını otomatik olarak tespit edip sistemi resetler. Mikrokontrolcü beklenmedik bir duruma girerse (sonsuz loop, kilitlenme), watchdog sayacı sıfırlanmadığı for 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).
🔑 Key Features
- 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)
🚀 Quick Start
import hal::watchdog, hal::core
// Independent watchdog (4 saniye timeout)
let wdg = watchdog.init_iwdg(do
timeout_ms: 4000,
window_mode: yanlış
end)
// Ana loop
loop do
// Normal işlemler
core.delay_ms(500)
// Watchdog'u besle (refresh)
watchdog.refresh(wdg)
// Eğer bu satır çalışmazsa sistem 4 saniye in resetlenir
end
📦 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
}
struct WatchdogConfig do
type: WatchdogType,
timeout_ms: int, // Milliseconds
window_mode: bool, // Window watchdog only
prescaler: Prescaler,
reload_value: int
end
💡 Example 1: Basic IWDG Kullanımı
2 saniyelik watchdog ile sistem koruması
import hal::watchdog, hal::gpio, hal::core
let led_green = gpio.pin_init(gpio.PORT_C, 13, gpio.MODE_OUTPUT)
let led_red = gpio.pin_init(gpio.PORT_C, 14, gpio.MODE_OUTPUT)
function ana() do
// Check reset source
let reset_cause = watchdog.get_reset_source()
if reset_cause == watchdog.IWDG_RESET do
// Watchdog reset occurred!
gpio.pin_write(led_red, gpio.HIGH)
core.delay_ms(2000)
gpio.pin_write(led_red, gpio.LOW)
end
// Initialize watchdog (2 second timeout)
let wdg = watchdog.init_iwdg(do
timeout_ms: 2000,
window_mode: yanlış
end)
// Main loop
loop do
// Normal operation
gpio.pin_toggle(led_green)
core.delay_ms(100)
// Feed watchdog every 100ms (well before 2s timeout)
watchdog.refresh(wdg)
end
end
💡 Example 2: Task Monitor ile Watchdog
Çoklu task izleme ve watchdog besleme
import hal::watchdog, hal::time
let son_beslenme_zamani: Zaman
let watchdog_aktif = doğru
function kritik_gorev_1() do
// Kritik işlemler
core.delay_ms(50)
// İşlem başarılı
watchdog_besleme_istegi()
end
function kritik_gorev_2() do
// Başka kritik işlemler
core.delay_ms(75)
// İşlem başarılı
watchdog_besleme_istegi()
end
function watchdog_besleme_istegi() do
son_beslenme_zamani = time.now()
end
function watchdog_yonetici(wdg: WatchdogHandle) do
loop do
// Check if tasks are healthy
let elapsed = time.now() - son_beslenme_zamani
if elapsed < time.milliseconds(500) do
// Tasks are running OK, feed watchdog
watchdog.refresh(wdg)
else do
// Tasks hung! Let watchdog reset the system
io.println("UYARI: Görevler askıda! Watchdog resetleyecek...")
end
core.delay_ms(100)
end
end
function ana() do
// 1 saniye watchdog timeout
let wdg = watchdog.init_iwdg(do
timeout_ms: 1000,
window_mode: yanlış
end)
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()
end
💡 Example 3: Window Watchdog (WWDG)
Pencere kontrolü ile hassas zamanlama
import hal::watchdog
// WWDG: Hem çok erken hem çok geç beslemeyi engeller
function wwdg_demo() do
// Window: 50-100ms aralığında beslenmeli
let wwdg = watchdog.init_wwdg(do
timeout_ms: 100,
window_ms: 50, // Pencere başlangıcı
early_wakeup_interrupt: doğru
end)
// Early warning interrupt handler
watchdog.set_interrupt_handler(wwdg, || do
io.println("Watchdog erken uyarı!")
// Burası early wakeup interrupt (zamanında besle)
end)
let sayac = 0
loop do
// İşlemler
core.delay_ms(30)
// 30ms + 30ms = 60ms (pencere in: 50-100ms ✓)
core.delay_ms(30)
// Watchdog'u besle
watchdog.refresh(wwdg)
sayac += 1
// Simulate hang every 10 iterations
if sayac % 10 == 0 do
io.println("Simüle edilen gecikme...")
core.delay_ms(150) // Too late! WWDG will reset
end
end
end
💡 Example 4: Watchdog + Backup Register
Reset nedeni kaydetme ve analiz
import hal::watchdog, hal::rtc
struct ResetInfo do
count: int,
last_reason: ResetSource,
timestamp: int
end
function reset_bilgisi_kaydet() do
let reason = watchdog.get_reset_source()
// Backup register'dan önceki bilgiyi oku
let 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())
end
function ana() do
// Initialize RTC for backup registers
rtc.init()
// Log reset information
reset_bilgisi_kaydet()
// Check for excessive resets
let reset_count = rtc.backup_read(0)
if reset_count > 10 do
io.println("HATA: Çok fazla reset! Sistem unstable.")
// Enter safe mode or disable some features
rtc.backup_write(0, 0) // Reset counter
end
// Initialize watchdog
let wdg = watchdog.init_iwdg(do
timeout_ms: 3000,
window_mode: yanlış
end)
// Normal operation
loop do
// Your code here
watchdog.refresh(wdg)
core.delay_ms(500)
end
end
📊 API Referansı
Initialization
function init_iwdg(config: WatchdogConfig) -> WatchdogHandle
function init_wwdg(config: WatchdogConfig) -> WatchdogHandle
function deinit(handle: WatchdogHandle)
Control
function refresh(handle: WatchdogHandle)
function start(handle: WatchdogHandle)
function is_running(handle: WatchdogHandle) -> bool
Reset Information
function get_reset_source() -> ResetSource
function clear_reset_flags()
function software_reset()
Window Watchdog (WWDG Only)
function set_interrupt_handler(handle: WatchdogHandle, callback: Fonksiyon)
function get_counter(handle: WatchdogHandle) -> int
⚙️ 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 for 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 for 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)
🔗 Related Modules
- hal::rtc - Backup register for reset logging
- hal::power - Low-power modes and watchdog
- hal::clock - LSI clock configuration