Как узнать, что сработал сторожевой таймер?

Seriga
Offline
Зарегистрирован: 01.06.2015
Здравствуйте.
Arduino Mega 2560
В скетче:
wdt_enable(WDTO_8S);
wdt_reset();
Как в программе можно определить, что перезагрузка была произведена сторожевым таймером, а не простым отключением питания?
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Хороший вопрос, подпишусь.

Клапауций 777
Offline
Зарегистрирован: 21.11.2015

Seriga пишет:

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

ага. и, как в программе определить, что питание было отключено?

Seriga
Offline
Зарегистрирован: 01.06.2015

Клапауций 777 пишет:

ага. и, как в программе определить, что питание было отключено?

Естественно не в тот момент, когда питание отключено и на оставшемся заряде в кандерах выполнить какую-то часть кода!!!
Речь идет о том моменте когда Ардуинка уже перезагрузилась и например в разделе
void setup()
{
}
определить, что произошла критическая ошибка которая привела к срабатыванию сторожевика. 
Клапауций 777
Offline
Зарегистрирован: 21.11.2015

Seriga пишет:

определить, что произошла критическая ошибка которая привела к срабатыванию сторожевика. 

ISR(WDT_vect) {}

не?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

В atmega328p, например, есть регистр MCUSR, который после загрузки показывает причину перезагрузки.

В ДШ это звучит так:

The MCU Status Register provides information on which reset source caused an MCU reset.

Этот регистр используется в некоторых бутлоадерах и после чтения сбрасывается, нужно про это помнить.

Только почитайте ДШ, прежде чем использовать этот метод, там есть тонкости.

 

Seriga
Offline
Зарегистрирован: 01.06.2015

Клапауций 777 пишет:

ISR(WDT_vect) {}

не?

Ребят я понимаю вы все гуру. Для меня эти кракозябры темный лес.  
Как я понимаю вы предлагаете выполнить какую-то часть кода, когда сработает сторожевик. 
Но он может сработать из-за некорректного обращение к памяти, затер часть переменных. А как в таком состоянии выполнять кусок программы, она то будет в целости?. И чтобы информация осталась после перезагрузки ее надо как-то сохранить, например записать в EEROM, передать через WiFi, GSM могут ли такие достаточно большие операции гарантировано выполнится после ошибки? 
 
 

 

Клапауций 777
Offline
Зарегистрирован: 21.11.2015

Seriga пишет:

Ребят я понимаю вы все гуру. Для меня эти кракозябры темный лес.  

дык и я ничего не понимаю, чего не понимаю, вбиваю в хугл и понимаю.

но не суть - сторожевой таймер срабатывает, когда всё зависло, программно что-то отработать невозможно.

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

Seriga
Offline
Зарегистрирован: 01.06.2015

Спасибо всем за помощь. Так хотелось абстрагироваться от железа. Видимо не прокатит. Может действительно есть что-то типа регистра MCUSR но ели бутлоадер трет… Будем пошматреть.

Клапауций 777
Offline
Зарегистрирован: 21.11.2015

а, если бы я такое делал, то сделал бы на тиньке 13-й аппаратный сигнализатор перезагрузки контроллера-поциента с двумя цифровыми входами следящими за наличием питания и за ногой, которой бы дёргал контроллер в сетапе при запуске - если питание не пропадало, а контроллер дёргает ногой с частотой WDTO, то что-то делать.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Seriga пишет:

Так хотелось абстрагироваться от железа. Видимо не прокатит.

Умение работать с железом на низком уровне очень пригодится, и не раз.

Seriga пишет:

Может действительно есть что-то типа регистра MCUSR 

Есть. Такой же MCUSR, как и в ATmega328P. В даташите  стр. 64. 

В регистре MCUSR бит WDRF: Watchdog Reset Flag. This bit is set if a Watchdog Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the flag.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Seriga пишет:

Так хотелось абстрагироваться от железа.

Если абстрагироваться от железа, задача выглядит так:

При старте контроллер должен получить некоторую информацию. Без этого - НИКАК. Следовательно, есть только два варианта:

1. В том железе, что мы используем есть специальная фича для сохранения нужной нам информации - ее и используем.

2. В используемом нами железе нужной фичи нет, либо мы по каким-то причинам не хотим ею пользоваться. Тогда нам нужно добавить в систему некоторое дополнительное железо, которое будет обеспечивать сохрарение нужной нам информации и выдачу ее по запросу основного железа.

Т.е. без железа, которое хранит нужную нам информацию, - никак. Вопрос только в том, что это за жалезо.

Seriga
Offline
Зарегистрирован: 01.06.2015

Jeka_M пишет:

В регистре MCUSR бит WDRF: Watchdog Reset Flag. This bit is set if a Watchdog Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the flag.

"The bit is reset by a Power-on Reset, or by writing a logic zero to the flag."
Получается когда МК включится этот регистр затрется. Или его как-то можно выцепить при старте?
Во всяком случае из void setup() он уже сброшен.

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Seriga пишет:

Получается когда МК включится этот регистр затрется. Или его как-то можно выцепить при старте?
Во всяком случае из void setup() он уже сброшен.

В Ардуино есть точка входа ранее setup(). Если описать глобальный объект, то его конструктор будет выполняться ранее setup() и ранее по крайней мере некоторых действий по инициализации.

Seriga
Offline
Зарегистрирован: 01.06.2015

andriano пишет:

В Ардуино есть точка входа ранее setup(). Если описать глобальный объект, то его конструктор будет выполняться ранее setup() и ранее по крайней мере некоторых действий по инициализации.

#include <avr/wdt.h>   
 
class Reg
{
  public:
    Reg()
    {
      if (MCUSR&(1 << WDRF)) mdrf = 1; else mdrf = 0;
    }
  bool mdrf;
};
Reg reg;
 
void setup() 
{
  Serial.begin(9600);
  Serial.print("WDRF=["); Serial.print(reg.mdrf); Serial.println("]");
  Serial.print("MCUSR=["); Serial.print(MCUSR); Serial.println("]");
  wdt_enable(WDTO_1S); 
}
 
void loop() 
{   
  delay(2000);
  wdt_reset();
}
 
Результат:
WDRF=[0]
MCUSR=[0]
 

 

andy_baka
Offline
Зарегистрирован: 24.10.2017

Seriga пишет:

andriano пишет:

В Ардуино есть точка входа ранее setup(). Если описать глобальный объект, то его конструктор будет выполняться ранее setup() и ранее по крайней мере некоторых действий по инициализации.

#include <avr/wdt.h>   
 
class Reg
{
  public:
    Reg()
    {
      if (MCUSR&(1 << WDRF)) mdrf = 1; else mdrf = 0;
    }
  bool mdrf;
};
Reg reg;
 
void setup() 
{
  Serial.begin(9600);
  Serial.print("WDRF=["); Serial.print(reg.mdrf); Serial.println("]");
  Serial.print("MCUSR=["); Serial.print(MCUSR); Serial.println("]");
  wdt_enable(WDTO_1S); 
}
 
void loop() 
{   
  delay(2000);
  wdt_reset();
}
 
Результат:
WDRF=[0]
MCUSR=[0]
 

 

 

А поясните плз в чем смысл этой процедуры? В setup включили сторожевой таймер - он раз в секунду ресетит процессор. Не могу понять смысла. 

b707
Offline
Зарегистрирован: 26.05.2017

Seriga пишет:

 
Результат:
WDRF=[0]
MCUSR=[0]
 

 

Большинство бутлоадеров, насколько я знаю, очищают эти флаги. Наверно и ваш бул делает то же самое. Я правда не понимаю, зачем это надо (бутлоадеру чистить флаги )

В общем, видимо надо копать исходный код бутлоадера, например оптибута.

b707
Offline
Зарегистрирован: 26.05.2017

andy_baka пишет:

А поясните плз в чем смысл этой процедуры? В setup включили сторожевой таймер - он раз в секунду ресетит процессор. Не могу понять смысла. 

Отойди мальчик, не мешай.

А если серьезно - вместо того чтоб задавать глупые вопросы, может сначала почитаете про вотчдог?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

b707, тоже как то раз интересовался этим. С чтением состояния были проблемы, может в свежих версиях всё исправили?

b707
Offline
Зарегистрирован: 26.05.2017

b707 пишет:

В общем, видимо надо копать исходный код бутлоадера, например оптибута.

Вот тут обсуждается, как править бут и как потом читать флаг WDRF - надо пробовать

http://forum.arduino.cc/index.php?topic=27162.0

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Сделай собаку двухступенчатой, в прерывании пиши состояние в епром, делай jmp 0