├── .gitattributes ├── library.properties ├── examples ├── watchdog_interrupt_mode │ └── watchdog_interrupt_mode.ino ├── watchdog_reset_mode │ └── watchdog_reset_mode.ino ├── watchdog_alarm_mode │ └── watchdog_alarm_mode.ino ├── watchdog_reset_with_alert │ └── watchdog_reset_with_alert.ino ├── watchdog_support_test │ └── watchdog_support_test.ino └── watchdog_double_reset │ └── watchdog_double_reset.ino ├── .github └── workflows │ └── tg-send.yml ├── keywords.txt ├── LICENSE ├── README_EN.md ├── README.md └── src └── GyverWDT.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=GyverWDT 2 | version=2.3.1 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Advanced WDT control library for ATmega328p/32U4/2560 & ATtiny85/84/167 6 | paragraph=Advanced WDT control library for ATmega328p/32U4/2560 & ATtiny85/84/167 7 | category=Other 8 | url=https://github.com/GyverLibs/GyverWDT 9 | architectures=avr -------------------------------------------------------------------------------- /examples/watchdog_interrupt_mode/watchdog_interrupt_mode.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Пример использования watchdog в качестве генератора прерываний 5 | Зависимость таймаутов от делителей см. в GyverWDT.h 6 | */ 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | pinMode(13, OUTPUT); 11 | Watchdog.enable(ISR_MODE, WDT_TIMEOUT_1S); // Режим генерации прерываний , таймаут ~1с 12 | } 13 | 14 | void loop() { 15 | /* Загруженный цикл */ 16 | digitalWrite(13, HIGH); 17 | delay(5000); 18 | digitalWrite(13, LOW); 19 | delay(5000); 20 | } 21 | 22 | /* Прерывание watchdog */ 23 | ISR(WATCHDOG) { 24 | Serial.println("Hello from interrupt"); 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/tg-send.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Telegram Message 3 | on: 4 | release: 5 | types: [published] 6 | jobs: 7 | build: 8 | name: Send Message 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: send telegram message on push 12 | uses: appleboy/telegram-action@master 13 | with: 14 | to: ${{ secrets.TELEGRAM_TO }} 15 | token: ${{ secrets.TELEGRAM_TOKEN }} 16 | disable_web_page_preview: true 17 | message: | 18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }} 19 | ${{ github.event.release.body }} 20 | https://github.com/${{ github.repository }} 21 | -------------------------------------------------------------------------------- /examples/watchdog_reset_mode/watchdog_reset_mode.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Пример классического применения watchdog - сброс устройства при зависании 5 | Если не вызвать Watchdog.reset() вовремя - произойдет сброс 6 | Зависимость таймаутов от делителей см. в GyverWDT.h 7 | */ 8 | 9 | void setup() { 10 | pinMode(13, OUTPUT); 11 | Watchdog.enable(RST_MODE, WDT_TIMEOUT_4S); // Режим сторжевого сброса , таймаут ~4с 12 | } 13 | 14 | void loop() { 15 | /* Ваш полезный код */ 16 | digitalWrite(13, HIGH); 17 | delay(1000); 18 | digitalWrite(13, LOW); 19 | delay(1000); 20 | 21 | Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло 22 | } 23 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For GyverWDT 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | 10 | ####################################### 11 | # Methods and Functions (KEYWORD2) 12 | ####################################### 13 | GyverWDT KEYWORD2 14 | Watchdog KEYWORD2 15 | reset KEYWORD2 16 | disable KEYWORD2 17 | enable KEYWORD2 18 | ####################################### 19 | # Constants (LITERAL1) 20 | ####################################### 21 | WDT_PRESCALER_2 LITERAL1 22 | WDT_PRESCALER_4 LITERAL1 23 | WDT_PRESCALER_8 LITERAL1 24 | WDT_PRESCALER_16 LITERAL1 25 | WDT_PRESCALER_32 LITERAL1 26 | WDT_PRESCALER_64 LITERAL1 27 | WDT_PRESCALER_128 LITERAL1 28 | WDT_PRESCALER_256 LITERAL1 29 | WDT_PRESCALER_512 LITERAL1 30 | WDT_PRESCALER_1024 LITERAL1 31 | WATCHDOG LITERAL1 32 | RESET_MODE LITERAL1 33 | INTERRUPT_MODE LITERAL1 34 | INTERRUPT_RESET_MODE LITERAL1 -------------------------------------------------------------------------------- /examples/watchdog_alarm_mode/watchdog_alarm_mode.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | Пример использования watchdog в "будильника" 6 | Зависимость таймаутов от делителей см. в GyverWDT.h 7 | */ 8 | 9 | void setup() { 10 | pinMode(13, OUTPUT); 11 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Выбираем нужный режим сна 12 | } 13 | 14 | void loop() { 15 | 16 | /* Мигаем светодиодом , а в паузах спим */ 17 | digitalWrite(13, HIGH); 18 | 19 | Watchdog.enable(ISR_MODE, WDT_TIMEOUT_1S); // Режим прерываний , таймаут ~1c 20 | sleep_enable(); // Разрешаем сон 21 | sleep_cpu(); // Уходим в сон 22 | 23 | digitalWrite(13, LOW); 24 | 25 | Watchdog.enable(ISR_MODE, WDT_TIMEOUT_1S); // Режим прерываний , таймаут ~1c 26 | sleep_enable(); // Разрешаем сон 27 | sleep_cpu(); // Уходим в сон 28 | 29 | } 30 | 31 | /* Прерывание watchdog , в нем мы просыпаемся */ 32 | ISR(WATCHDOG) { 33 | sleep_disable(); // Запрещаем сон 34 | Watchdog.disable(); // Выключаем watchdog 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/watchdog_reset_with_alert/watchdog_reset_with_alert.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Пример использования watchdog в комбинированном режиме 5 | Может использоваться для оповещения в случае зависания 6 | Первый тайм-аут вызывает прерывание, второе - сброс 7 | Перенастройте watchdog чтобы избежать сброса 8 | Зависимость таймаутов от делителей см. в GyverWDT.h 9 | */ 10 | 11 | void setup() { 12 | Serial.begin(9600); 13 | Serial.println("Program started"); 14 | Watchdog.enable(ISR_RST_MODE, WDT_TIMEOUT_1S); // Комбинированный режим , таймаут ~1c 15 | Serial.println("watchdog enabled"); 16 | while (1); // Причина зависания 17 | Serial.println("loop started"); // Этого мы не увидим из-за зависания 18 | } 19 | 20 | void loop() { 21 | /* этого кода программа не достигнет - зависание в setup */ 22 | Serial.println("hello"); 23 | delay(500); 24 | } 25 | 26 | /* Первый тайм-аут вызывает прерывание */ 27 | ISR(WATCHDOG) { 28 | // Если причина зависания программная - тут можно попытаться исправить ее */ 29 | Serial.println("warning!"); 30 | // Если исправить причину не вышло - следующий таймаут вызывает сброс 31 | // Watchdog.enable(INTERRUPT_RESET_MODE, WDT_PRESCALER_128); // Если перенастроить watchdog здесь - сброса не будет 32 | } 33 | -------------------------------------------------------------------------------- /examples/watchdog_support_test/watchdog_support_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Пример тестирующий поддержку всех функций watchdog на вышем устройстве 5 | > После 10 секунд отсчета программа стартует заного -> поддерживаются все функции 6 | > После таймаута устройство зависает, светодиод на D13 начинает мигать -> подерживается только INTERRUPT_MODE 7 | В случае bootloop у вас будет 10 секунд на перепрошивку устройства после подачи питания 8 | Для добавления поддержки всего функционала watchdog загрузите optiboot или откажитесь от загрузчика 9 | */ 10 | 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | 15 | Serial.println("Program started , wait 10 seconds"); 16 | delay(10000); // 10 секунд на перепрошивку в случае bootloop 17 | 18 | Watchdog.enable(RST_MODE, WDT_TIMEOUT_8S); // Режим сторжевого сброса , таймаут ~8с 19 | Serial.println("watchdog enabled"); 20 | 21 | while (1) { // Бесконечный цикл , эмуляция "зависания" 22 | if (!(millis() % 1000)) { // Каждую секунду 23 | Serial.println((uint16_t)((millis() / 1000) - 10)); // Вывести время после включения watchdog в секундах 24 | delay(10); 25 | } 26 | } 27 | 28 | } 29 | 30 | void loop() {} 31 | -------------------------------------------------------------------------------- /examples/watchdog_double_reset/watchdog_double_reset.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Пример работы watchdog для контроля сразу за двумя устройствами 5 | В данном случае - arduino + esp8266 модуль 6 | Зависимость таймаутов от делителей см. в GyverWDT.h 7 | */ 8 | 9 | void setup() { 10 | Serial.begin(9600); // На этом последовательном порту у нас wifi-модуль 11 | pinMode(8, INPUT); // Этот пин сбрасывает wifi-модуль при переходе в режим OUTPUT 12 | Watchdog.enable(ISR_RST_MODE, WDT_TIMEOUT_8S); // Комбинированный сторжевой режим , таймаут ~8с 13 | } 14 | 15 | 16 | void loop() { 17 | /* Ваш полезный код */ 18 | } 19 | 20 | /* Если wifi-модуль нам что то отправил , а мы его поняли - никто из нас не завис */ 21 | void serialEvent() { 22 | Watchdog.reset(); // Сбросить watchdog 23 | } 24 | 25 | /* Если wifi-модуль не отправлял нам что то более 8с - он завис */ 26 | ISR(WATCHDOG) { 27 | pinMode(8, OUTPUT); // Тянем за reset модуля 28 | Watchdog.enable(ISR_RST_MODE, WDT_TIMEOUT_8S); // Если мы не смогли перенастроить watchdog - значит мы зависли 29 | Watchdog.reset(); // Если не зависли - сбросить watchdog и продолжить 30 | pinMode(8, INPUT); // Отпускаем reset модуля 31 | } 32 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Gyverwdt 4 | Library for managing WDT on AVR Atmega328P/32U4/2560 & Attiny85/84/167 5 | - Setting the operating mode WDT 6 | - Setting up interruptions 7 | 8 | ## compatibility 9 | AVR Atmega328P/32U4/2560 & Attiny85/84/167 10 | 11 | ### Documentation 12 | There is [extended documentation] to the library (https://alexgyver.ru/gyverwdt/) 13 | 14 | ## Content 15 | - [installation] (# Install) 16 | - [initialization] (#init) 17 | - [use] (#usage) 18 | - [Example] (# Example) 19 | - [versions] (#varsions) 20 | - [bugs and feedback] (#fedback) 21 | 22 | 23 | ## Installation 24 | - The library can be found by the name ** gyverwdt ** and installed through the library manager in: 25 | - Arduino ide 26 | - Arduino ide v2 27 | - Platformio 28 | - [download the library] (https://github.com/gyverlibs/gyverwdt/archive/refs/heads/main.zip). Zip archive for manual installation: 29 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 30 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 31 | - unpack and put in *documents/arduino/libraries/ * 32 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 33 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 34 | ### Update 35 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 36 | - through the IDE library manager: find the library how to install and click "update" 37 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors! 38 | 39 | 40 | 41 | ## initialization 42 | No 43 | 44 | 45 | ## Usage 46 | `` `CPP 47 | VOID Reset (VOID);// Reset 48 | VOID DISABLE (VOID);// Disable WDT 49 | VOID Enable (Uint8_t Mode, Uint8_t PressCaler);// Turn on WDT with settings 50 | // Mode: 51 | // reset_mode - reset during freezing (at a time -out WDT) 52 | // Interrupt_Mode - interruption when freezing (at a time -out WDT) 53 | // Interrupt_Reset_Mode - first timout - interruption, second - reset 54 | // PressCaler: 55 | // wdt_prescaler_2, wdt_prescaler_4 ... wdt_prescaler_1024 56 | `` ` 57 | 58 | 59 | ## Example 60 | The rest of the examples look at ** Examples **! 61 | `` `CPP 62 | #include 63 | #include 64 | 65 | /* 66 | An example of using Watchdog in the "alarm clock" 67 | Dependence of Tymauts on dividers, see gyverwdt.h 68 | */ 69 | 70 | VOID setup () { 71 | Pinmode (13, output); 72 | set_sleep_mode (Sleep_mode_pwr_down);// Select the desired sleep mode 73 | } 74 | 75 | VOID loop () { 76 | 77 | / * We blink a LED, and we sleep in pauses */ 78 | DigitalWrite (13, High); 79 | 80 | Watchdog.enable (Interrupt_mode, WDT_PRESCALER_128);// interruption mode, timaut ~ 1c 81 | Sleep_enable ();// We allow a dream 82 | Sleep_cpu ();// We go to sleep 83 | 84 | digitalWrite (13, LOW); 85 | 86 | Watchdog.enable (Interrupt_mode, WDT_PRESCALER_128);// interruption mode, timaut ~ 1c 87 | Sleep_enable ();// We allow sleep 88 | Sleep_cpu ();// We go to sleep 89 | 90 | } 91 | 92 | / * Interruption Watchdog, in it we wake up */ 93 | ISR (Watchdog) { 94 | Sleep_disable ();// We prohibit sleep 95 | Watchdog.disable ();// Turn off Watchdog 96 | } 97 | `` ` 98 | 99 | 100 | ## versions 101 | - V2.1 102 | - v2.2 - optimization and small corrections 103 | 104 | 105 | ## bugs and feedback 106 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 107 | The library is open for refinement and your ** pull Request ** 'ow! 108 | 109 | 110 | When reporting about bugs or incorrect work of the library, it is necessary to indicate: 111 | - The version of the library 112 | - What is MK used 113 | - SDK version (for ESP) 114 | - version of Arduino ide 115 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 116 | - what code has been loaded, what work was expected from it and how it works in reality 117 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![latest](https://img.shields.io/github/v/release/GyverLibs/GyverWDT.svg?color=brightgreen)](https://github.com/GyverLibs/GyverWDT/releases/latest/download/GyverWDT.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/GyverWDT.svg)](https://registry.platformio.org/libraries/gyverlibs/GyverWDT) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/GyverWDT?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs) 8 | 9 | # GyverWDT 10 | Библиотека для управления WDT на AVR ATmega328p/32U4/2560 & ATtiny85/84/167 11 | - Настройка режима работы WDT 12 | - Настройка прерываний 13 | 14 | ### Совместимость 15 | AVR ATmega328p/32U4/2560 & ATtiny85/84/167 16 | 17 | ### Документация 18 | К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverWDT/) 19 | 20 | ## Содержание 21 | - [Установка](#install) 22 | - [Инициализация](#init) 23 | - [Использование](#usage) 24 | - [Пример](#example) 25 | - [Версии](#versions) 26 | - [Баги и обратная связь](#feedback) 27 | 28 | 29 | ## Установка 30 | - Библиотеку можно найти по названию **GyverWDT** и установить через менеджер библиотек в: 31 | - Arduino IDE 32 | - Arduino IDE v2 33 | - PlatformIO 34 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverWDT/archive/refs/heads/main.zip) .zip архивом для ручной установки: 35 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 36 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 37 | - Распаковать и положить в *Документы/Arduino/libraries/* 38 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 39 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 40 | ### Обновление 41 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 42 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 43 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 44 | 45 | 46 | 47 | ## Инициализация 48 | Нет 49 | 50 | 51 | ## Использование 52 | ```cpp 53 | void reset(void); // сброс 54 | void disable(void); // отключить WDT 55 | void enable(uint8_t mode, uint8_t prescaler); // включить WDT с настройками 56 | // mode: 57 | // RESET_MODE - сброс при зависании (при тайм-ауте WDT) 58 | // INTERRUPT_MODE - прерывание при зависании (при тайм-ауте WDT) 59 | // INTERRUPT_RESET_MODE - первый таймаут - прерывание, второй - сброс 60 | // prescaler: 61 | // WDT_PRESCALER_2, WDT_PRESCALER_4... WDT_PRESCALER_1024 62 | ``` 63 | 64 | 65 | ## Пример 66 | Остальные примеры смотри в **examples**! 67 | ```cpp 68 | #include 69 | #include 70 | 71 | /* 72 | Пример использования watchdog в "будильника" 73 | Зависимость таймаутов от делителей см. в GyverWDT.h 74 | */ 75 | 76 | void setup() { 77 | pinMode(13, OUTPUT); 78 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Выбираем нужный режим сна 79 | } 80 | 81 | void loop() { 82 | 83 | /* Мигаем светодиодом , а в паузах спим */ 84 | digitalWrite(13, HIGH); 85 | 86 | Watchdog.enable(INTERRUPT_MODE, WDT_PRESCALER_128); // Режим прерываний , таймаут ~1c 87 | sleep_enable(); // Разрешаем сон 88 | sleep_cpu(); // Уходим в сон 89 | 90 | digitalWrite(13, LOW); 91 | 92 | Watchdog.enable(INTERRUPT_MODE, WDT_PRESCALER_128); // Режим прерываний , таймаут ~1c 93 | sleep_enable(); // Разрешаем сон 94 | sleep_cpu(); // Уходим в сон 95 | 96 | } 97 | 98 | /* Прерывание watchdog , в нем мы просыпаемся */ 99 | ISR(WATCHDOG) { 100 | sleep_disable(); // Запрещаем сон 101 | Watchdog.disable(); // Выключаем watchdog 102 | } 103 | ``` 104 | 105 | 106 | ## Версии 107 | - v2.1 108 | - v2.2 - оптимизация и мелкие исправления 109 | - v2.3 - исправлена ошибка компиляции на тини 110 | 111 | 112 | ## Баги и обратная связь 113 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 114 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 115 | 116 | 117 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 118 | - Версия библиотеки 119 | - Какой используется МК 120 | - Версия SDK (для ESP) 121 | - Версия Arduino IDE 122 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 123 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 124 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код 125 | -------------------------------------------------------------------------------- /src/GyverWDT.h: -------------------------------------------------------------------------------- 1 | /* 2 | Библиотека для управления watchdog таймером, список поддерживаемых МК ниже. 3 | ВНИМАНИЕ! Использование watchdog с Arduino-загрузчиком версии 'OLD' НЕДОСТУПНО 4 | Документация: https://alexgyver.ru/gyverwdt/ 5 | GitHub: https://github.com/GyverLibs/GyverWDT 6 | 7 | Возможности: 8 | - Настройка режима работы watchdog 9 | - Настройка прерываний 10 | Поддержка МК: 11 | > AVR ATmega48p/88p/168p/328p (Arduino UNO/NANO/MINI/PRO MINI) 12 | > AVR ATmega32u4 (Arduino LEONARDO/PRO MICRO) 13 | > AVR ATmega1280/2560 (Arduino MEGA) 14 | > AVR ATtiny87/167 (Naked chip) 15 | > AVR ATtiny45/85 (Naked chip) 16 | > AVR ATtiny44/84 (Naked chip) 17 | > AVR ATtiny13 (Naked chip) 18 | Доступные режимы: 19 | > RST_MODE (RESET_MODE) - Сброс МК при тайм-ауте 20 | > ISR_MODE (INTERRUPT_MODE) - Прерывание при тайм-ауте 21 | > ISR_RST_MODE (INTERRUPT_RESET_MODE) - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) 22 | 23 | Egor 'Nich1con' Zaharov for AlexGyver, alex@alexgyver.ru 24 | https://alexgyver.ru/ 25 | MIT License 26 | 27 | Версии: 28 | v2.3 ~ 08.11.2021 29 | */ 30 | 31 | #ifndef GyverWDT_h 32 | #define GyverWDT_h 33 | #include 34 | 35 | /************************ 36 | * Режим работы watchdog * 37 | ************************/ 38 | /* Краткие - определения */ 39 | #define RST_MODE (RESET_MODE) // - Сброс МК при тайм-ауте 40 | #define ISR_MODE (INTERRUPT_MODE) // - Прерывание при тайм-ауте 41 | #define ISR_RST_MODE (INTERRUPT_RESET_MODE) // - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) 42 | 43 | /* Legacy - определения */ 44 | #define RESET_MODE (1 << WDE) 45 | #define INTERRUPT_MODE (1 << WDIE) 46 | #define INTERRUPT_RESET_MODE (1 << WDE | 1 << WDIE) 47 | 48 | /* Вектор прерывания watchdog */ 49 | #define WATCHDOG WDT_vect 50 | /* 51 | ISR(WATCHDOG){ 52 | ... 53 | } 54 | */ 55 | 56 | /**************************************************** 57 | * Предделители watchdog и приблизительные тайм-ауты * 58 | ****************************************************/ 59 | /* Выбор по тайм-ауту, примерный разброс ~ 10% */ 60 | #define WDT_TIMEOUT_16MS (WDT_PRESCALER_2) // (16 ± 1.6) ms 61 | #define WDT_TIMEOUT_32MS (WDT_PRESCALER_4) // (32 ± 3.2) ms 62 | #define WDT_TIMEOUT_64MS (WDT_PRESCALER_8) // (64 ± 6.4) ms 63 | #define WDT_TIMEOUT_128MS (WDT_PRESCALER_16) // (128 ± 12.8) ms 64 | #define WDT_TIMEOUT_256MS (WDT_PRESCALER_32) // (256 ± 25.6) ms 65 | #define WDT_TIMEOUT_512MS (WDT_PRESCALER_64) // (512 ± 51.2) ms 66 | #define WDT_TIMEOUT_1S (WDT_PRESCALER_128) // (1024 ± 102.4) ms 67 | #define WDT_TIMEOUT_2S (WDT_PRESCALER_256) // (2048 ± 204.8) ms 68 | #define WDT_TIMEOUT_4S (WDT_PRESCALER_512) // (4096 ± 409.6) ms 69 | #define WDT_TIMEOUT_8S (WDT_PRESCALER_1024) // (8192 ± 819.2) ms 70 | 71 | /* Выбор по предделителю */ 72 | #define WDT_PRESCALER_2 0x00 // (16 ± 1.6) ms 73 | #define WDT_PRESCALER_4 0x01 // (32 ± 3.2) ms 74 | #define WDT_PRESCALER_8 0x02 // (64 ± 6.4) ms 75 | #define WDT_PRESCALER_16 0x03 // (128 ± 12.8) ms 76 | #define WDT_PRESCALER_32 0x04 // (256 ± 25.6) ms 77 | #define WDT_PRESCALER_64 0x05 // (512 ± 51.2) ms 78 | #define WDT_PRESCALER_128 0x06 // (1024 ± 102.4) ms 79 | #define WDT_PRESCALER_256 0x07 // (2048 ± 204.8) ms 80 | #define WDT_PRESCALER_512 0x08 // (4096 ± 409.6) ms 81 | #define WDT_PRESCALER_1024 0x09 // (8192 ± 819.2) ms 82 | 83 | /***************** 84 | * Класс watchdog * 85 | *****************/ 86 | /* 87 | Проверка совместимости выбранного МК с библиотекой 88 | */ 89 | #if not( \ 90 | defined(__AVR_ATmega48P__) || \ 91 | defined(__AVR_ATmega88P__) || \ 92 | defined(__AVR_ATmega168P__) || \ 93 | defined(__AVR_ATmega328P__) || \ 94 | defined(__AVR_ATmega32u4__) || \ 95 | defined(__AVR_ATmega32U4__) || \ 96 | defined(__AVR_ATmega1280__) || \ 97 | defined(__AVR_ATmega2560__) || \ 98 | defined(__AVR_ATtiny87__) || \ 99 | defined(__AVR_ATtiny167__) || \ 100 | defined(__AVR_ATtiny44__) || \ 101 | defined(__AVR_ATtiny84__) || \ 102 | defined(__AVR_ATtiny45__) || \ 103 | defined(__AVR_ATtiny85__) || \ 104 | defined(__AVR_ATtiny13__)) 105 | #error "This MCU is not supported in GyverWDT.h library" 106 | #endif 107 | 108 | #if defined(WDTCSR) 109 | #define _WD_CONTROL_REG WDTCSR 110 | #elif defined(WDTCR) 111 | #define _WD_CONTROL_REG WDTCR 112 | #else 113 | #define _WD_CONTROL_REG WDT 114 | #endif 115 | 116 | class GyverWDT { 117 | public: 118 | void reset() { // Сбросить watchdog таймер 119 | asm volatile("WDR"); // ASM команда 'watchdog reset' 120 | } 121 | /* 122 | Watchdog.reset(); 123 | Сбросить watchdog таймер, чтобы избежать тайм-аута 124 | После вызова watchdog начнет считать заного 125 | Размещается в коде, после всех ответственных операций 126 | Можно размещать по своему усмотрению 127 | */ 128 | 129 | void disable() { // Сбросить watchdog таймер 130 | uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) 131 | noInterrupts(); // Запрещаем глобальные прерывания 132 | _WD_CONTROL_REG = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК 133 | _WD_CONTROL_REG = 0x00; // Очищаем все настройки watchdog 134 | SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого 135 | } 136 | /* 137 | Watchdog.disable(); 138 | Остановить watchdog таймер 139 | После вызова все настройки watchdog сбросятся 140 | Размещается в начале setup или main, чтобы избежать bootloop 141 | Можно использовать перед выполнением долгих атомарных операций 142 | */ 143 | 144 | void enable(uint8_t mode, uint8_t prescaler) { // Настроить и запустить watchdog таймер 145 | uint8_t _WDT_REG = mode | ((prescaler > 7) ? ((1 << WDP3) | (prescaler - 8)) : prescaler); // Cоставляем содержимое регистра WDT 146 | uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) 147 | noInterrupts(); // Запрещаем глобальные прерывания 148 | _WD_CONTROL_REG = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК 149 | _WD_CONTROL_REG = _WDT_REG; // Сразу же загружаем готовые настройки watchdog 150 | SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого 151 | } 152 | /* 153 | Watchdog.enable(mode, prescaler); 154 | Запустить watchdog таймер с новыми параметрами 155 | После вызова все настройки watchdog перезапишутся, но счет НЕ сбросится 156 | Размещается в начале setup или main, и на усмотрение программиста 157 | Можно использовать перед выполнением ответственных операций 158 | 159 | Доступные режимы (mode): 160 | RST_MODE (RESET_MODE) - Сброс МК при тайм-ауте 161 | ISR_MODE (INTERRUPT_MODE) - Прерывание при тайм-ауте 162 | ISR_RST_MODE (INTERRUPT_RESET_MODE) - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) 163 | 164 | Доступные предделители (prescaler): 165 | WDT_PRESCALER_2 0x00 // (16 ± 1.6) ms 166 | WDT_PRESCALER_4 0x01 // (32 ± 3.2) ms 167 | ... 168 | WDT_PRESCALER_1024 0x09 // (8192 ± 819.2) ms 169 | 170 | Примеры использования: 171 | ЕСЛИ не вызывать Watchdog.reset(); 172 | Watchdog.enable(RST_MODE, WDT_PRESCALER_128); - Сбросить МК через ~1с, 173 | Watchdog.enable(ISR_MODE, WDT_PRESCALER_2); - Вызывать прерывание ISR(WATCHDOG){} каждую секунду 174 | Watchdog.enable(ISR_RST_MODE, WDT_PRESCALER_1024); - Вызвать прерывание ISR(WATCHDOG){} через ~8с, переключиться в режим RST_MODE 175 | */ 176 | 177 | private: 178 | }; 179 | 180 | extern GyverWDT Watchdog; 181 | #endif --------------------------------------------------------------------------------