Перейти до основного вмісту

Модуль IWDG MCAL

Підтримувані родини STM32: H5
Не підтримуються: G4, H7, L4, U5

Цей репозиторій містить драйвер MCAL (Microcontroller Abstraction Layer) для незалежного сторожового таймера (Independent Watchdog) (IWDG) у мікроконтролерах STM32.
Він пропонує простий і безпечний інтерфейс для запуску, налаштування та оновлення (refresh) сторожового таймера без роботи з дільниками, значеннями перезавантаження чи прапорцями оновлення регістрів.

Кожна родина STM32 підтримується в окремій гілці цього репозиторію:

  • STM32G4
  • STM32U5
  • STM32L4
  • STM32H5
  • та інші за потреби.

📘 Огляд​

Драйвер IWDG MCAL абстрагує незалежний сторожовий таймер STM32 до інтерфейсу, заснованого на часі.
Користувач налаштовує сторожовий таймер у мілісекундах, а решту робить модуль:

  • Обчислення дільника (4 - 1024) і значення перезавантаження за потрібним тайм-аутом та частотою LSI
  • Опційне вікно (window) - оновлення дозволене лише в останній частині тайм-ауту
  • Опційне переривання раннього пробудження (early wakeup) - користувацький callback викликається до того, як сторожовий таймер скине MCU
  • Автоматичне оновлення з Iwdg_Task() або ручне оновлення через Iwdg_Set_Refresh()
  • Зчитування стану сторожового таймера та досягнутого тайм-ауту

Доступ на запис до регістрів (ключовий регістр), прапорці оновлення регістрів і перевірка зворотним зчитуванням кожного запису конфігурації обробляються всередині модуля.

✅ Користувачеві не потрібно підключати чи використовувати жодні додаткові модулі, як-от драйвери RCC або NVIC.
Частота LSI зчитується з модуля RCC, а переривання раннього пробудження налаштовується через модуль NVIC всередині.

⚠️ Після запуску сторожовий таймер неможливо зупинити (апаратне обмеження). Його зупиняє лише системне скидання, якщо тільки в option bytes не вибрано апаратний режим сторожового таймера. Iwdg_Deinit() лише вимикає переривання та автоматичне оновлення - застосунок має продовжувати оновлювати сторожовий таймер.


🧩 Архітектура​

Архітектура відповідає стандартній багаторівневій структурі MCAL, що використовується в усіх репозиторіях STM32 MCAL:

┌────────────────────────────┐
│ Application │
└────────────┬───────────────┘
│
┌────────────▼───────────────┐
│ HAL │
│(Hardware Abstraction Layer)│
└────────────┬───────────────┘
┌────────────▼───────────────┐
│ MCAL - Iwdg │
│ ├── Iwdg_Port.h │
│ ├── Iwdg_Types.h │
│ └── Iwdg.c/.h │
└────────────┬───────────────┘
│
┌────────────▼───────────────┐
│ RAL │
│(Register Abstraction Layer)│
└────────────────────────────┘

🧠 Рекомендації щодо використання​

Користувач має взаємодіяти лише з такими двома публічними заголовками:

ФайлПризначення
Iwdg_Port.hМістить усі функції публічного API (ініціалізація, оновлення, зчитування стану та тайм-ауту, конфігурація за замовчуванням)
Iwdg_Types.hМістить визначення типів, що використовуються в API (структура конфігурації, тип часу, тип callback-а, стани запиту)

Усе інше — таблиці дільників, допоміжні функції, обробник переривання — є внутрішнім і не повинно використовуватися напряму.

Публічний API​

ФункціяОпис
Iwdg_Get_ModuleVersion()Повертає версію ПЗ модуля
Iwdg_Init( config )Обчислює конфігурацію, запускає та налаштовує сторожовий таймер
Iwdg_Deinit()Вимикає переривання раннього пробудження та автоматичне оновлення (сторожовий таймер продовжує працювати)
Iwdg_Task()Автоматично оновлює сторожовий таймер (лише коли вікно не використовується)
Iwdg_Get_DefaultConfig( config )Заповнює конфігурацію за замовчуванням: тайм-аут 1 с, без вікна, без переривання раннього пробудження
Iwdg_Get_State( state )Повертає IWDG_FUNCTION_ACTIVE, якщо сторожовий таймер працює
Iwdg_Get_Timeout( timeout )Повертає досягнутий тайм-аут у мс, обчислений за регістрами
Iwdg_Set_Refresh()Оновлює (перезавантажує) лічильник сторожового таймера

Конфігурація​

ЕлементОпис
TimeoutПотрібний тайм-аут у мс. З LSI 32 кГц діапазон приблизно 1 мс - 131 с.
WindowТривалість вікна перед тайм-аутом у мс, коли оновлення дозволене. IWDG_TIME_UNUSED вимикає вікно. Має бути коротшою за Timeout.
EarlyWakeupЧас до тайм-ауту в мс, коли спрацьовує переривання раннього пробудження. IWDG_TIME_UNUSED вимикає переривання. Має бути коротшим за Timeout.
EarlyWakeupIsrКористувацький callback переривання раннього пробудження, може бути NULL
IrqPriorityПріоритет переривання раннього пробудження (0 - найвищий)

Некоректна конфігурація (тайм-аут поза діапазоном, вікно або раннє пробудження не коротші за тайм-аут) відхиляється функцією Iwdg_Init() до запису в будь-який регістр.

Примітки​

  • Режим вікна - оновлення до початку вікна негайно скидає MCU (апаратна поведінка), програмно про це повідомити неможливо. Iwdg_Task() не виконує оновлення в режимі вікна, застосунок має викликати Iwdg_Set_Refresh() всередині вікна.
  • Апаратний режим сторожового таймера - якщо Iwdg_Get_State() повертає IWDG_FUNCTION_ACTIVE до Iwdg_Init() після скидання, сторожовий таймер було запущено через option bytes.
  • Причина скидання - скидання від IWDG можна виявити після запуску за допомогою Rcc_Get_ResetSource( RCC_RESET_SRC_IWDG, &flag ) і очистити за допомогою Rcc_Set_ResetSourceClear() у модулі RCC.
  • Точність тайм-ауту - частота LSI змінюється залежно від температури та напруги (дивіться datasheet), тож реальний тайм-аут відрізняється від обчисленого.

⚙️ Типовий приклад використання​

#include "Iwdg_Port.h"

static void App_WatchdogWarning( void )
{
// Last chance to store diagnostic data before the watchdog reset
}

int main(void)
{
iwdg_Config_t iwdgConfig;
iwdg_Time_ms_t achievedTimeout = 0u;
iwdg_RequestState_t iwdgState = IWDG_REQUEST_ERROR;

iwdgState = Iwdg_Get_DefaultConfig( &iwdgConfig );

iwdgConfig.Timeout = 500u; // Reset after 500 ms without refresh
iwdgConfig.EarlyWakeup = 50u; // Callback 50 ms before reset
iwdgConfig.EarlyWakeupIsr = App_WatchdogWarning;
iwdgConfig.IrqPriority = 0u;

if( IWDG_REQUEST_OK == iwdgState )
{
iwdgState = Iwdg_Init( &iwdgConfig );
}

if( IWDG_REQUEST_OK == iwdgState )
{
iwdgState = Iwdg_Get_Timeout( &achievedTimeout );
}

while (1)
{
// Refreshes the watchdog automatically (no window configured)
Iwdg_Task();
}
}

🧾 Стратегія гілкування​

Кожна родина STM32 має власну гілку:

ГілкаОпис
STM32G4Драйвер MCAL для родини STM32G4
STM32U5Драйвер MCAL для родини STM32U5
STM32L4Драйвер MCAL для родини STM32L4
STM32H5Драйвер MCAL для родини STM32H5

Ці гілки містять специфічні для родини визначення регістрів, діапазони дільників і прив'язки до RCC/NVIC, зберігаючи спільний інтерфейс.


🧩 Залежності​

  • Rcc_Lib – частота тактування LSI (RCC_PERIPH_IWDG)
  • Nvic_Lib – обробка переривання раннього пробудження
  • RAL (Register Abstraction Layer) – використовується всередині для доступу до низькорівневих регістрів

Усі обов'язкові конфігурації RCC і NVIC обробляються всередині.


🧱 Приклад структури каталогів​

Iwdg/
├── Iwdg_Port.h
├── Iwdg_Types.h
├── Iwdg.c
├── Iwdg.h
├── CMakeLists.txt
├── LICENSE.md
└── README.md

🛠 Інтеграція з CMake​

  1. Додайте Iwdg_Lib до вашої CMake-бібліотеки.
  2. Підключіть Iwdg_Port.h у вашому проєкті.
  3. Злінкуйте з файлами реалізації модуля Iwdg.
  4. Налаштуйте модуль відповідно до вашого апаратного забезпечення.

Ліцензія​

Цей проєкт ліцензовано за Creative Commons Attribution–NonCommercial 4.0 International (CC BY-NC 4.0).

Ви вільні використовувати, змінювати та поширювати цю роботу в некомерційних цілях за умови належного зазначення авторства.

Повні умови дивіться у LICENSE.md або на creativecommons.org/licenses/by-nc/4.0.


Автори​

Внески вітаються! Будь ласка, відкрийте pull request.