🐕 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

🚀 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

PlatformIWDGWWDGMax Timeout
STM32F432 saniye
STM32F126 saniye
ESP32configurable
GD32VF10326 saniye

💡 Best Practices

⚠️ Önemli Notlar

🔗 Related Modules

← HAL Modules | 🇬🇧 Turkish