Optymalizacja watchdogów w modułach AGD (STM32)

/pomiary/watchdog-optymalizacja-stm32-agd • STM32F1/F4 • IWDG/WWDG • jitter i recovery

1. Zakres i cel

Konfiguracja i rozmieszczenie kicka IWDG/WWDG, ograniczenie jitteru i unikanie fałszywych resetów przy intensywnych ISR/DMA. Zawiera wzorce logów, kod inicjalizacji i politykę odzyskiwania.

2. Objawy i sygnatury

2.1 Telemetria

[00:12.417] WDG: IWDG timeout (Δt kick=2.060 s)
[00:12.418] RCC_CSR: IWDGRSTF=1 BORRSTF=0 SFTRSTF=0
[00:12.700] SysTick jitter RMS=3.1 ms (próg 1.5 ms)

2.2 Wzorce

  • Kick wykonywany w ISR o niskim priorytecie — ryzyko opóźnień.
  • WWDG reset po zbyt wczesnym/za późnym odświeżeniu (naruszenie okna).
  • Skoki jitteru podczas burstów DMA/EXTI.
Uwaga: Kick w pętli głównej bywa maskowany przez sekcje krytyczne. Preferowany dedykowany timer lub SysTick z gwarantowanym priorytetem.

3. IWDG — konfiguracja i kick

ParametrF1 (typowo)F4 (typowo)Uwagi
LSI~40 kHz~32 kHzkalibracja zależna od partii
Prescaler6464przykład: timeout ≈ 1.6–2.1 s
Reload~1000–1300~1200–1500dobrać do najgorszego jitteru
Kick źródłoSysTick/TimerSysTick/Timerpoza sekcjami krytycznymi
// Inicjalizacja IWDG (szkic)
static void iwdg_init(uint16_t presc, uint16_t reload){
  IWDG->KR = 0x5555;
  IWDG->PR = presc;           // 0..6
  IWDG->RLR = reload;         // 0..0x0FFF
  IWDG->KR = 0xCCCC;          // start
}

static inline void iwdg_kick(void){
  IWDG->KR = 0xAAAA;
}
// Kick z SysTick (priorytet ustaw zgodnie z profilem NVIC)
void SysTick_Handler(void){
  systick_tick();
  static uint32_t acc; acc++;
  if((acc % 8) == 0){ iwdg_kick(); } // np. co 8 ms przy 1 kHz
}
Praktyka: Kick tylko po udanym cyklu głównym (commit), aby wykrywać zakleszczenia parserów/driverów.

4. WWDG — okno i prewencja zakleszczeń

WWDG wykrywa odświeżenia zbyt wczesne/późne. Stosować jako strażnika „tempa” pętli, gdy ISR mogą wahać czas cyklu.

ParametrWartość startowaUwagi
PrescalerDIV8krok czasu okienka
Window0x50–0x70akceptowalne okno odświeżenia
Counter0x7Flicznik malejący
Early WakeupEWIE=1IRQ ostrzegające o progu
// Konfiguracja WWDG (F1/F4 z rejestrami per rodzina)
void wwdg_init(void){
  // clock enable wg. rodziny
  WWDG->CFR = (WWDG_CFR_W_6 | WWDG_CFR_WDGTB_1) | WWDG_CFR_EWI; // okno + preskaler + EWI
  WWDG->CR  = 0x7F | WWDG_CR_WDGA; // start z maks. licznikiem
}

void WWDG_IRQHandler(void){
  // flaga EWI — odśwież okienkowo
  (void)WWDG->SR; // czyść zgodnie z RM
  wwdg_refresh_in_window();
}
Uwaga: Unikaj odświeżania WWDG w ISR niskiego priorytetu. Naruszenie okna może generować trudne do reprodukcji restarty.

5. Jitter, SysTick i sekcje krytyczne

// Pomiar jitteru ticka (RMS) w ms
static void jitter_update(uint32_t now_ms){
  static uint32_t last_ms, n;
  static int64_t sum, sum2;
  if(last_ms){ int32_t d = (int32_t)(now_ms - last_ms) - 1; sum += d; sum2 += (int64_t)d*d; n++; }
  last_ms = now_ms;
}

static float jitter_rms(void){
  extern int64_t sum, sum2; extern uint32_t n;
  if(n<2) return 0;
  double mean = (double)sum/n;
  return (float)sqrt(((double)sum2/n) - mean*mean);
}
// Sekcja krytyczna dla swapów DMA/WSKAŹNIKÓW — BASEPRI
uint32_t b = __get_BASEPRI();
__set_BASEPRI(0x30);      // próg wg. profilu
// operacje atomowe
__DSB(); __ISB();
__set_BASEPRI(b);

Kick watchdogów poza sekcjami krytycznymi; skracaj ISR i unikaj kopiowania dużych buforów w przerwaniach.

6. Polityka recovery i logowanie

  • Logowanie przyczyny resetu: RCC->CSR, licznik bootów awaryjnych, znacznik czasu.
  • Po starcie: czyszczenie flag RCC_CSR_RMVF, zapis histogramu opóźnień kicka.
  • Tryb bezpieczny po ≥N resetach w horyzoncie T (ograniczenie funkcji obciążających).
// Odczyt i czyszczenie przyczyn resetu
uint32_t csr = RCC->CSR;
log_reset_csr(csr);
RCC->CSR |= RCC_CSR_RMVF;
// Polityka awaryjna
if(reset_counter_in_window() >= 3){
  enter_safe_mode(); // ogranicz PWM/kompresor, minimalny profil ISR
}
Praktyka: W logach przechowuj również minimalny/maksymalny odstęp między kickami i wynik RMS jitteru.

7. Kryteria akceptacji

KryteriumCelPo korektach
Jitter kick IWDG (RMS)<1.5 ms0.6–1.0 ms
Fałszywe resety IWDG / tydzień00
Naruszenia okna WWDG / 10⁶ cykli<0.01%≤0.004%
Resety łączone (IWDG+BOR) / tydzień≤10–1

8. Uwagi serwisowe

Kick nie powinien występować w tej samej sekcji co swap buforów DMA. Zalecane pomiary jitteru w testach regresyjnych oraz logowanie histogramu odstępów między odświeżeniami. W środowisku z falownikiem rozważyć wydłużenie timeoutu IWDG o 10–20% względem wartości nominalnej LSI.