USB WatchDog ARU-P2 (TOIC)
Наш самый функциональный сторожевой таймер: встроенный язык программирования TOIC позволяет модифицировать логику под самые разные задачи.
Зачем нужны сторожевые таймеры?
Сторожевой таймер используется для контроля ПК и обеспечения его бесперебойной работы в случаях, когда встроенные средства не спасают.

Типовые примеры применения:
  • Обеспечение бесперебойной работы терминала.
  • Автономный компьютер выполняет работу без присмотра персонала.
  • Увеличение надёжности промышленного ПК.
  • GPU-майнер работает нестабильно, а программные средства не помогают.
Как это работает?
Сторожевой таймер подключается через USB интерфейс к ПК. Проводом он напрямую соединяется с контактами Reset или Power материнской платы.
Программа-монитор запускается на ПК и переодически передает сигнал устройству. Если компьютер завис, то зависает и программа: watchdog перестаёт получать сигнал. Через заданное время USB WatchDog автоматически подает сигнал на контакт Reset материнской платы, чтобы перезагрузить систему.
Если Reset не сработал, активируется канал Power, который выключает и снова включает компьютер.
Чем отличается от WatchDog Pro2
Благодаря встроенному языку программирования TOIC пользователь может изменять алгоритм работы в очень широких пределах. Пример программы устройства приведён в нижней части страницы.
Установка USB WatchDog ARU-P2
Это краткая инструкция, полную версию можно посмотреть на примере USB WatchDog Pro2. Открыть.

1. Перед установкой необходимо выключить ПК.
2. Так как устройство бескорпусное, будьте с ним предельно острожны - не допускайте касания металлических поверхностей. Это может привести к порче устройства!
3. Провода Reset и Power необходимо подключить вместо кнопок от системного блока.
4. Как подключать PBD10

Для при установке устройства в материнскую плату убедитесь, что вы подключаете именно к разъему USB. Некоторые интерфейсы (например ieee1394 или COM-порт) имеют на плате такие же 10-выводные разъемы.

Подключение к интерфейсу, отличному от USB, приведет к порче устройства
(возможно с дымом и запахом)!


  • На плате с PBD10 разъемом на плате имеется точка. При подключении к материнской плате ПК она должна быть совмещена со стороной разъема где отсутствует 1 металлический контакт
5. Сами кнопки можно подключить к сторожевому таймеру, чтобы ими тоже можно было пользоваться.
WatchDog Pro2 PBD10
Осн.1 и Доп.1. - параллельно соединённые контакты канала 1. По-умолчанию, подключаются к контактам Reset: например, Осн.1 - на reset мат.платы и Доп.1 - на кнопку reset.
Осн.2 и Доп.2. - параллельно соединённые контакты канала 2. По-умолчанию, подключаются к контактам Power: например, Осн.2 - на power мат.платы и Доп.2-
на кнопку power.
Пример подключения к материнской плате
Драйвер
Работа в ОС ниже Windows7 не поддерживается.
В Windows7 понадобится установить драйвер CDC.
В Windows 8, Windows 10, Linux, macOS установка драйвера не требуется.
Если в Windows8 не заработал системный драйвер CDC, воспользуйтесь инструкцией.
wdtmon3
Программа, которая работает с USB WatchDog Pro2, Lite.

В ARU-P2 поддержан следующий функционал программы:
1. Контроль зависания, процесса, сетевого ресурса.
2. Информация об устройстве;
3. Температура
4. Пауза
5. Тестовый Reset и Power.
6. Отключение светодиода.

Прим.: wdtmon3 не изменяет настроек USB WatchDog ARU-P2, это нужно делать из кода программы.

Страница подробной инструкции по программе доступна по ссылке.
Программируем сами
Модификация встроенного ПО
Сердцем сторожевого таймера является микроязык TOIC, который позволяет легко модифицировать встроенное программное обеспечение устройства.

Скачать среду разработки можно по ссылке.
Код, работающий в устройстве.
Код, который работает в устройстве по-умолчанию. Чтобы в устройстве хватило места, в IDE необходимо включить оптимизацию кода.
//Main settings
#define TIMER_MAX 5500
#define TIMER_DELTA 50
#define RESET_TIME 200
#define POWER_OFF_T1 5000
#define POWER_OFF_DELAY 3000
#define POWER_OFF_T2 200

//hw defines
#define LED_PIN PF0
#define RESET_PIN PA3
#define POWER_PIN PA2

#define FW_STR "4.1U 01 Dec 2020"
#define CFG_STR "11111120300"

//global
var led_on();
var counter;
var phase = 0;
var t_answ = ["~GEEE\n", "~G%d\n", "~G0%d\n", "~G00%d\n", "~G000%d\n"];

//functions
var led_off(){ 
    LED_PIN.VALUE = 0;
}

var reset() {
    RESET_PIN.VALUE = 1;
    sleep(RESET_TIME);
}

var reboot() {
    led_off();
    POWER_PIN.VALUE = 1;
    sleep(POWER_OFF_T1);
    POWER_PIN.VALUE = 0; 
    sleep(POWER_OFF_DELAY);
    POWER_PIN.VALUE = 1;
    sleep(POWER_OFF_T2);
}

var reinit() {
    RESET_PIN.VALUE = POWER_PIN.VALUE = 0;
    counter = TIMER_MAX;
    timer(TIMER_MAX, led_on);
}

var get_temp()
{
  DS18.INIT = DS18_PORT_B|8;
  if(DS18.INIT == 1)
  {
    DS18.VALUE = 1;
    delay(150);
    return DS18.VALUE-2730; //K -> C
   }
   return 0;
}

var temp_sender(var temp) {
    var idx = 4;
    if (temp>1280) { idx = 0; }
    else if (temp>1000) { idx = 1; }
    else if (temp>100) { idx = 2; }
    else if (temp>10) { idx = 3; }
    sprintf(&UART0.TX, t_answ[idx], temp); 
}

var led_on() {     
    LED_PIN.VALUE = 1;
    if (counter) {
      __disable_irq();
      counter -= TIMER_DELTA;
      __enable_irq();
      timer(TIMER_DELTA-1, led_off);
      timer(counter, led_on);
    }
    else { //time is up
        if (phase) {
            reboot();
            phase = 0;
        }
        else {
            reset();
            phase = 1;
        }
        reinit();
    }
}

var io_setup() {
    LED_PIN.MODE = GPIO_MODE_OUTPUT|GPIO_OTYPE_PP|GPIO_INIT_LOW;
    RESET_PIN.MODE = GPIO_MODE_OUTPUT|GPIO_OTYPE_PP|GPIO_INIT_LOW;
    POWER_PIN.MODE = GPIO_MODE_OUTPUT|GPIO_OTYPE_PP|GPIO_INIT_LOW;
    UART0.CFG = UART_MODE_PLAIN | UART_CONFIG_START;
    __enable_irq();
}

var _msg() {
    if(MSG.PORT == 4) {
        memcpy(&RING.BUF, &MSG.RX, MSG.SIZE);       
    }
}

var main() {
    var c;
    var pstate = 0;
    io_setup();
    
    if((RING.ALLOC = 16) != 16) {
        return 1;
    }
    
    SYS.WDG = 1;
    reinit();
    while(1){
       if(RING.QUEUE > 0) {
           c = RING.PULL;
           if (c == '~') {pstate = 1;}
           else {
               if (pstate == 1) {
                   pstate = 0;
                   switch (c) {
                        case 'U':
                            tstop(led_on);
                            counter = TIMER_MAX;
                            LED_PIN.VALUE = 1;
                            delay(100);     
                            LED_PIN.VALUE = 0;
                            delay(100);
                            LED_PIN.VALUE = 1;
                            delay(100);
                            LED_PIN.VALUE = 0;
                            timer(counter, led_on);
                            sprintf(&UART0.TX, "~A\n");
                            break;
                        case 'G':
                            temp_sender(get_temp());
                            break;
                        case 'I':
                            sprintf(&UART0.TX, "~I%s\n", FW_STR);
                            break;
                        case 'W':
                        case 'F':
                            sprintf(&UART0.TX, "~F%s\n", CFG_STR);
                            break;
                        case 'T':
                            pstate = 2;
                            break;
                        case '1': 
                            pstate = 3;
                            break;
                        case '2': 
                            pstate = 4;
                            break;
                        case 'P': 
                            pstate = 5;
                            break;
                        case 'L': 
                            pstate = 6;
                            break;                       
                        default:
                            break; 
                      }
               }else if (pstate>1)
                {
                 
                switch (pstate) { 
                           case 2: //~T
                               if (c == '1') {
                                    reset();
                                    reinit();
                               } else if (c == '2') {
                                    reboot();
                                    reinit();
                               }
                           break;
                           case 3: //~1
                               RESET_PIN.VALUE = (c == 'S');
                               break;
                           case 4: //~2
                               POWER_PIN.VALUE = (c == 'S');
                               break;
                           case 5:  //~P
                               if (c == '1') {
                                   tstop(led_on);
                               } else if (c == '0') {
                                   reinit();
                               } 
                               break;
                           case 6: //~L
                                if (c == '1') {
                                    LED_PIN.MODE = GPIO_MODE_OUTPUT|GPIO_OTYPE_PP|GPIO_INIT_LOW;
                               } else if (c == '0') {
                                    LED_PIN.MODE = GPIO_MODE_INPUT;
                               } 
                               break;
                            default:
                                break; 
                   }
                   pstate = 0;
               }              
               
           }
                      
       }else delay(10);
       SYS.WDG = 42;
    }

    return 0;
}
Чтобы подключиться к устройству нужно открыть среду ToicIDE, для этого необходимо нажать на кнопку в левом верхнем углу и выбрать USB HID интерфейс устройства.
Работа с готовой программой
1. Скачать архив по ссылке.
2. В ToicIDE выбрать Проект->Импорт.
3. В ToicIDE нажать Проект->Открыть и найти в папке импортированный проект.
4. В ToicIDE подключиться к устройству.
5. В ToicIDE нажать кнопку "Компиляция".
6. В ToicIDE нажать кнопку "Загрузить скрипт в устройство".
Дополнительные ресурсы

  • TOIC IDE
    Среда разработки под разные платформы. Перейти.
  • TOIC book
    Справочник по языку TOIC. Перейти.
  • Большая инструкция USB WatchDog
    В прошивке по-умолчанию устройство частично повторяет поведение USB WatchDog Pro2, поэтому инструкция, ПО и скрипты подходят к обоим типам устройств. Открыть.