Перейти к содержанию
    

Очень странная перезагрузка attiny85 по Watchdog Reset Flag

Прошу помощи!

Счетчик импульсов (watchdog в режиме генерации прерываний) на attiny85 считает импульсы просыпаясь раз в 250мс и раз в сутки выходит из цикла и общается по i2c.
Возникла проблема — очень редко (!) attiny85 перезагружается после общения по i2c.

Как я это понял: я вижу на сервере увеличение на единицу счетчика перезагрузок и MCUSR в setup().
MCUSR обычно 1, а становится равен 8 (1000 - WDRF: Watchdog Reset Flag. Завершение работы таймера.).

Подозрения на некорректную настройку watchdog. Проблема проявляется крайне редко и не понятно как отловить.

Код: main.cpp

main.cpp "избранное":

int16_t wakeup_period_min;

volatile int wdt_count; 

ISR( WDT_vect ) { 
	wdt_count--;
}  

void resetWatchdog() {
	MCUSR = 0;
	WDTCR = bit( WDCE ) | bit( WDE );
	WDTCR = bit( WDIE ) | bit( WDP2 );     // 250 ms
	wdt_reset();
} 

#define ONE_MINUTE 240

void setup() {
	info.service = MCUSR; //причина перезагрузки

	noInterrupts();
	ACSR |= bit( ACD ); 
	interrupts();
	resetWatchdog(); 

	wakeup_period_min = WAKEUP_DEFAULT_PER_MIN;

    if (storage.get(info.data)) { //не первая загрузка
		info.resets = EEPROM.read(storage.size());
		info.resets++;
		EEPROM.write(storage.size(), info.resets);
	} else {
		EEPROM.write(storage.size(), 0);
	}
}


void loop() {
	power_all_disable();  
	set_sleep_mode( SLEEP_MODE_PWR_DOWN );  
	resetWatchdog(); 
	for (unsigned int i = 0; i < ONE_MINUTE && !button.pressed(); ++i)  {
		wdt_count = wakeup_period_min;
		while ( wdt_count > 0 ) {
			noInterrupts();
			if (button.pressed()) { 
				interrupts();
				break;
			} else 	{
				counting();
				interrupts();
				sleep_mode(); 
			}
		}
	}
	wdt_disable();

	....
	....Связь по i2c
	....
	
}


Выдержка из даташита

photo_2021-04-02_23-59-59.jpg.b539379f21534eeb99a4ae69eeccb125.jpg

photo_2021-04-02_23-59-50.thumb.jpg.46e3be252a0176e70979309cb3cbf332.jpg

Какие гипотезы тестируются:
1. по даташиту нужно "To avoid the Watchdog Reset, WDIE must be set after each interrupt." 
добавил в ISR(WDT_vect):   WDTCR |= bit( WDIE );

2. Убрать WDE из WDTCR = bit( WDCE ) | bit( WDE );

Почему я уверен, что устройства не зависают:
а) attiny продолжает считать импульсы корректно
б) я посмотрел статистику и 70% attiny вышли на связь через WAKEUP_DEFAULT_PER_MIN, который получают в setup(). В остальных случаях через Х * WAKEUP_DEFAULT_PER_MIN из-за проблем со связью.

Почему я думаю, что проблема в начале функции loop(), а не в цикле подсчета импульсов:
a) attiny выходит на связь через дефалтный период, а не хаотично.
б) attiny выходит на связь ПОСЛЕ цикла подсчета импульсов, значит ошибка была не в цикле, а перед ним. 

Проблема появляется с вероятностью около 0,0002%.

К сожалению, моих знаний не достаточно, чтобы предположить, что может быть причиной перезагрузки. Прошу помощи!

Изменено пользователем dontsov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 тестовых устройств с WDTCR |= bit( WDIE ) в ISR(WDT_vect) продолжают исправно работать, когда без него через сутки точно зависали.
Дополнительно убрал WDE из WDTCR = bit( WDCE ) | bit( WDE ), т.к. бит отвечает за перезагрузку МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все таки зависает прошивка. Не понятно отчего.

Да, она не перезагружается по watchdog аварийно. 
Тему продолжил тут:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...