Raspberry Pi. Поднимаем watchdog


При встраивании RPi, в отличии от устройств на МК есть два «тонких момента»:
1. RPi имеет операционную систему;
2. Операционная система может зависнуть.

В случае, если на RPi построена система, допустим, мониторинга процесса в реальном времени, любое зависание ОС приведет к неприятным последствиям. А теперь на минуту представим, что железка стоит за 3000 км от вас и по SSH вы уже не можете к ней подключиться. Поэтому необходима система автоматической проверки состояния системы и ее перезагрузки в случае, если произошло зависание RPi. Этим и занимается watchdog, или по-русски «сторожевой таймер». Важно заметить, что нельзя застраховаться от всех возможных причин зависания, т.к. кроме программных сбоев могут произойти сбои из-за внешней среды — перегрев, нестабильное питание, электромагнитные помехи, и т.д. Так что «надо обезопаситься и застраховаться. Вдруг что, а тут тебе на, компенсация» (c) Ноггано =))

Исходная точка:
1. Raspberry Pi (версия не важна)
2. Raspbian Debian Wheezy Version: January 2014 Release date: 2014-01-07.

Начинаем. И начнем, пожалуй, с теории.

Данил Борчевкин
www.lab409.ru

ТЕОРИЯ

Сторожевой таймер, watchdog timer или просто watchdog — аппаратная (железка), программная (программа, скрипт, часть программы) или программно-аппаратная (железка, управляемая программно) схема контроля за зависанием системы (операционной системы, GSM-модема, банкомата, роутера или чего-то еще). Представляет из себя таймер, который необходимо периодически сбрасывать контролируемой системой; если контролируемая система не сбрасывает watchdog в течении определенного времени, то происходит ее перезагрузка. В некоторых случаях сторожевой таймер может посылать системе сигнал на перезагрузку («мягкая» перезагрузка, soft reset), в других же — перезагрузка происходит аппаратно (например, подачей нуля на ножку RST микроконтроллера; это т.н. hard reset).

С железной точки зрения, watchdog — это таймер, работающий в режиме прямого счета до определенного значения, которое может задаваться как программно, так и железно, в зависимости от его реализации. Можно обратиться по этой ссылке и посмотреть в картинках, что это значит. Зачастую, применительно к микроконтроллерам, если сторожевой таймер не используется по прямому назначению, его можно использовать как обычный таймер

Логика работы сторожевого таймера такова:
1. Запуск контролируемой системы;
2. Инициализация watchdog’а. В случае, если данный таймер программно-аппаратный, указываем период сброса (допустим, 1 секунда);
3. Если watchdog каждую секунду принимает сигнал сброса от контролируемой системы (в виде подачи какого-либо уровня на ножку МК, записи в файл, передачи параметров программе), то система работает в штатном режиме;
4. Если watchdog не принял сигнал сброса в течении более, чем 1 секунда, посредством сигнала о том, что «все очень плохо» он перезагружает контролируемую систему (soft reset, hard reset).

Более просто — представим себе сторожевой таймер реальным злым сторожевым псом, как на картинке выше. Если ему каждый час (период сброса) кидать кость (сигнал сброса), то он молчит. Но если более чем час не кидать ему кость, он может начать громко лаять и рычать(формирование сигнала о неправильной работе системы, зависании).

В англоязычных источниках можно чаще можно встретить выражение не «кинуть кость» — «throw a bone», еще вариант «кормить собаку» — «feeding the dog», а «пнуть собаку» — «kick the dog». Я так понимаю, это вопрос воспитания =))

ПРОГРАММНЫЙ WATCHDOG. СКРИПТ АВТОРЕКОННЕКТА WIFI

К примеру, программный watchdog для программы — это кусок кода, работающий параллельно и контролирующий основную программу.

Хорошим примером сторожевого таймера может являться следубщий пример — если вы конфигурируете подключение к сети Raspberry Pi без сторонних менеджеров, то есть через /etc/network/interfaces, встает следующая проблема — нет автоматического реконнекта при дропе. Решено это может быть программным сторожевым таймером — скриптом на Python 2.x, приведенном ниже:

#!/bin/python
#network_watchdog.py - script for autoreconnect WiFi

import os
import time

DELAY = 30 # delay in seconds

while True:
    time.sleep(DELAY)
    if os.system("ping google.com -c 1") != 0:
        print "Connection loss. Reconnecting"
        os.system("sudo ifup --force wlan0")

Для запуска в фоновом режиме:

$ sudo python network_watchdog.py &

Для прерывания работы скрипта сначала вернуть его из фонового режиме командой

$ fg

и завершить его работу нажатием Ctrl+C.

Вариант на тему — скрипт, взятый отсюда:

#!/bin/bash
#network_watchdog.sh
while true ; do
   if ifconfig wlan0 | grep -q "inet addr:" ; then
      sleep 60
   else
      echo "Network connection down! Attempting reconnection."
      ifup --force wlan0
      sleep 10
   fi
done

Запуск:

$ sudo ./network_watchdog.sh &

Прерывание работы аналогично скрипту на Питоне. Если вам не нравится то, что скрипты имеют бесконечные циклы, можно почитать

$ man crontab

.

АППАРАТНЫЙ WATCHDOG

Чисто аппаратный сторожевой таймер представляет из себя отдельную схему, выполненную как на дискретных компонентах, так и в виде микросхемы. Одним из хороших примеров, может являться микросхема от Maxim Integrated MAX6323/24, схема включения которой показана на рисунке ниже.

Как нам говорит даташит и опыт, выход RESET — отрытый сток, в случае, если необходимо сбросить контролируемую микросхему, то данный выход сажается на землю, на RESET контролируемой микрухи подается 0 и выполняется hard reset.

Спектр применения таких микросхем — устройства промышленной, медицинской и автомобильной электроники, где необходима высокая надежность работы устройства.

ПРОГРАММНО-АППАРАТНЫЙ WATCHDOG

Watchdog превратился в современном понимании в программно-аппаратную реализацию. То есть, теперь watchdog — это встроенный, допустим, в микроконтроллер, управляемый регистрами таймер, формирующий сигнал сброса в случае, если кость ему не кидать в определенный период. Таким образом, в отличие от железного сторожевого таймера, программно-аппаратный имеет настройки, которые задают его поведение. Например, на msp430 это делается так. Также, если микросхема, которую мы хотим контролировать, не имеет встроенного сторожевого таймера, он может быть реализован на внешнем микроконтроллере (рекурсия — у которого тоже есть сторожевой таймер) с соответствующей прошивкой. Ну вот — на лицо и железка, и возможность конфигурации.

Таким образом, программно-аппаратный wathcdog может быть:
1. Частью микроконтроллера, системы-на-кристалле;
2. Внешним устройством, выполненном на микроконтроллере.

В Raspberry Pi он именно такой.

ПОДНИМАЕМ WATCHDOG НА RASPBERRY PI

Используемая в Raspberri Pi система-на-кристалле (SoC — System on Crystal) BCM2835 имеет встроенный сторожевой таймер, который умеет считать до 15 секунд.

Для его работы необходимо загрузить модуль в ядро:

$ sudo modprobe bcm2708_wdog
$ sudo sh -c "echo 'bcm2708_wdog' >> /etc/modules"

Кроме этого, необходимо добавить в начало файла /etc/init.d/mathkernel следующие строки

#!/bin/sh
### BEGIN INIT INFO
# Provides:          mathkernel
# Required-Start:    $syslog
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: mathkernel
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO
#
# rest of file here

Далее, как и во всем мире linux, есть два подхода — заморочиться и делать на самом низком уровне абстракции или воспользоваться готовым. Остановимся на втором варианте, а первый оставим для желающих позаниматься самостоятельно=))

Конечно же, уже есть готовый watchdog daemon. Установим его и chkconfig

$ sudo apt-get install watchdog chkconfig

После установки включим в автозагрузку watchdog и запустим его:

$ sudo chkconfig watchdog on
$ sudo service watchdog start

Далее отредактируем /etc/watchdog.conf

$ sudo nano /etc/watchdog.conf

путем раскомментирования строчки watchdog-device = /dev/watchdog, тем самым указав точку монтирования сторожевого таймера демону. Для того, чтобы watchdog срабатывал и в тех случаях, когда список ожидающих выполнения процессов зашкаливает (говорит нам о том, что идет сильно не так), раскомментируем строчку max-load-1 = 24. тем самым мы говорим таймеру, что «если load average за минуту превысит 24, то watchdog должен перезагрузить операционку»

Также укажем параметры загрузки в ядро:

echo "options bcm2708_wdog nowayout=1 heartbeat=13" | sudo tee /etc/modprobe.d/watchdog.conf

тем самым указывая параметры:
nowayout=1, данный параметр устанавливает, что watchdog не может быть остановлен другими программами, если он уже запущен;
heartbeat=13, где 13 — это время сброса в секундах. То есть не кинули кость за 13 секунд — получай резет.

Перезапустим Raspberry:

$ sudo reboot

После перезагрузки если выполнить команду dmesg | grep watchdog, получим такой вывод:

 [email protected]~ $ dmesg | grep watchdog
[   16.012628] bcm2708 watchdog, heartbeat=13 sec (nowayout=1)

На этом watchdog появился и в вашей малинке. Остался один вопрос — а как проверить его работу?!

FORK-БОМБА
Чтобы посмотреть на сторожевой таймер в боевых условиях применим известный подход — Fork-Bomb (советую полностью прочитать и усвоить материал).

Для этого возьмем стандартную реализацию форк-бомбы на Питоне:

#/bin/python
#fork_bomb.py

import os

while True:
      os.fork()

и запуcтим:

$ python fork_bomb.py

Система будет перезагружена через какое-то время. При форк-бомбах желательно отключить своп (в описанном примере это необязательно):

$ sudo swapoff -a

УБИВАЕМ WATCHDOG ЧЕРЕЗ kill -9

Кроме описанной форк-бомбы, можно проверить работу нашего сторожевого таймера посредством комманды

$ sudo kill -9 $(pidof watchdog)

UPD ДЛЯ RASPBIAN JESSIE

Участник сообщества RoboCraft VecH в комментариях указал, что описанный выше способ не работает для Raspbian Jessie и предоставил следующие исправления:

На Debian Jessie надо изменить строку в файле /etc/default/watchdog добавив туда название модуля

watchdog_module="bcm2708_wdog"

Далее в файле /lib/systemd/system/watchdog.service надо добавить строчку после секции [install], должно стать вот таким:

[Install]
WantedBy=multi-user.target

И после включаем сервис средствами systemd

systemctl enable watchdog

РЕЗЮМЕ

Вот таким вот нехитрым образом мы подняли сторожевой таймер и обезопасили нашу железку от возможной неработоспособности в течении длительного времени. Конечно, статья не охватила все — остался не рассмотрен hard reset по превышению температуры, минимальному количеству свободной памяти и т.д — да и таковая цель не преследовалась. Для дальнейшего изучения данной темы могу порекомендовать полезные ссылки (см. ниже) и гугл.

ПОЛЕЗНЫЕ ССЫЛКИ

Raspberry Pi Watchdog Timer
Enabling the watchdog timer on the Raspberry Pi
WatchDog Daemon not restarting PI after fork bomb
How do I permanently disable the swap service?
How to automatically hard reboot the system once the load average reaches a certain value?
watchdog(8) — Linux man page
watchdog errors on startup
Watchdog «ping» function
dpkg: error processing watchdog (—configure)
Подкачка страниц
Fork-Bomb
Understanding load average vs. cpu usage
Understanding Linux CPU Load — when should you be worried?

КНИГИ

Книга "Современные операционные системы" Э. Таненбаум - купить книгу Modern Operating Systems ISBN 978-5-496-00301-8 с доставкой по почте в интернет-магазине OZON.ru Книга "Современные операционные системы" Э. Таненбаум — купить книгу Modern Operating Systems ISBN 978-5-496-00301-8 с доставкой по почте в интернет-магазине OZON.ru
Книга "Архитектура компьютера" Э. Таненбаум, Т. Остин - купить книгу Structured Computer Organization ISBN 978-5-496-00337-7 с доставкой по почте в интернет-магазине OZON.ru Книга "Архитектура компьютера" Э. Таненбаум, Т. Остин — купить книгу Structured Computer Organization ISBN 978-5-496-00337-7 с доставкой по почте в интернет-магазине OZON.ru

15 комментариев на «“Raspberry Pi. Поднимаем watchdog”»

  1. На Raspbian обновленном до Jessie Watchdog не срабатывает
    модуль загружен, параметры есть, после запуска бомбы сыпет в консоль кучу мусора, в итоге малине виснет, но не перезагружается

  2. На Raspbian обновленном до Jessie Watchdog не срабатывает
    модуль загружен, параметры есть, после запуска бомбы спустя некоторое время сыпет в консоль кучу мусора, отваливается WiFi
    в итоге малине виснет, но не перезагружается

  3. в мусоре на экране периодически видно что проскакивают строки в которых успеваю увидеть out of memory и потом заново таблица с мусором где в последнем столбце «python»
    и все, так бесконечно, зависания или перезагрузки не дождался, отключил малину

  4. С обновление ядра в малине до 4.4.х что то поломали, теперь модуля bcm2708_wdog нет
    его упразднили или что то произошло

    теперь вроде за него отвечает унифицированный bcm2835_wdt загружающийся параметров в /boot/config.txt
    dtparam=watchdog=on

    Но сервис watchdog все равно грохает систему
    Итог:
    Редактируем или добавляем строку в /boot/config.txt
    dtparam=watchdog=on
    Это загрузит модуль bcm2835_wdt при загрузке ядра
    в файле /etc/default/watchdog добавив туда название нового модуля
    watchdog_module=«bcm2835_wdt»

    Далее по тексту выше

    • После kill-а watchdog-а плата не перезагружается! Что я делаю не так? Конфиги:
      /boot/config.txt:
      dtparam=watchdog=on

      /etc/modprobe.d/bcm2835-wdt.conf:
      options bcm2835_wdt heartbeat=13 nowayout=1

      dmesg | grep watchdog:
      [ 7.835700] bcm2835-wdt 20100000.watchdog: Broadcom BCM2835 watchdog timer

      Плата rPI Model B, Jessie, ядро 4.4.48.

    • UPD: sudo systemctl status watchdog:
      watchdog[802]: cannot open /dev/watchdog (errno = 16 = ‘Device or resource busy’)

    • Проблема описана по ссылке, предложенное решение (с udel rules) не помогло:
      stackoverflow(dot)com/questions/30484167/watchdog-device-or-resource-busy

  5. Нашел проблему и ее решение
    в общем на Jessie надо изменить строку в файле /etc/default/watchdog добавив туда название модуля

    watchdog_module="bcm2708_wdog"

    Далее в файле /lib/systemd/system/watchdog.service
    надо добавить строчку после секции [install]
    должно стать вот таким

    [Install]
    WantedBy=multi-user.target

    И после включаем сервис средствами systemd

    systemctl enable watchdog

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна конкурс манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение