реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Неправильная работа Watch Dog Timer'a, WDT не работает
SerSh
сообщение Jun 19 2013, 11:50
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Прошу помощи у Клуба!

Проблема в неправильной работе Watch Dog Timer'a на ATmega640-16AU.
Суть в следующем: после запуска Watch Dog Timer'a в режиме "System Reset Mode" через запрограммированое (2 сек) время камень не перезапускается (System Reset), а тупо виснет.
Проверку осуществляю при помощи вставленных циклов ожидания функции __delay_cycles().

Компилятор IAR EWB v.6.21.1.
Прошивка в железо - AVReal.
Инициализация в основной программе (main):
// Инициализация Watchdog-таймера
_WDR(); // Сброс Watchdog
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с
_SEI(); // Глобальное разрешение прерывания

Фьюз WDTON=1.
Сама программа без WDT или с включённым WDT, но без принудительной сверхзадержки работает без проблем.
Аналогичные варианты других программ, но на камнях ATmega64 с идентичными параметрами (инициализация, фьюзы, способы проверки срабатывания WDT) работают тоже без проблем.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 19 2013, 13:16
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (SerSh @ Jun 19 2013, 14:50) *
WDTCSR |= (1<<WDCE)|(1<<WDE);

Попробуйте тут убрать "ИЛИ".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 13:33
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Убрал.
Стало:
// Инициализация Watchdog-таймера
_WDR(); // Сброс Watchdog
WDTCSR = (1<<WDCE)|(1<<WDE);
WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с
_SEI(); // Глобальное разрешение прерывания

В работе ничего не поменялось!
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 19 2013, 13:40
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(SerSh @ Jun 19 2013, 16:33) *
Убрал.
Стало:
// Инициализация Watchdog-таймера
_WDR(); // Сброс Watchdog
WDTCSR = (1<<WDCE)|(1<<WDE);
WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с
_SEI(); // Глобальное разрешение прерывания

В работе ничего не поменялось!

Возможно инициализация WDT не укладывается в нужное время. Покажите сгенерированный код.

Ещё вариант: у вас нет сброса флагов в регистре MCUSR. Что у вас там?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 19 2013, 13:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(SerSh @ Jun 19 2013, 17:33) *
В работе ничего не поменялось!

А, если убрать глобальное разрешение прерываний ?
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 14:02
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



К регистру MCUSR я вообще не обращаюсь.

Листинг функции main:
448 // Инициализация Watchdog-таймера
449 _WDR(); // Сброс Watchdog
\ 000002A8 95A8 WDR
450 WDTCSR = (1<<WDCE)|(1<<WDE);
\ 000002AA E108 LDI R16, 24
\ 000002AC 9300.... STS _A_WDTCSR, R16
451 // WDTCSR = (1<<WDE)|(1<<WDP3); // Установка времени срабатывания ~4 с
452 WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с
\ 000002B0 E00F LDI R16, 15
\ 000002B2 9300.... STS _A_WDTCSR, R16
453 _SEI(); // Глобальное разрешение прерывания
\ 000002B6 9478 SEI

Сам файл листинга = 1,2Мб загружаться не хочет.

Цитата(Палыч @ Jun 19 2013, 16:48) *
А, если убрать глобальное разрешение прерываний ?


Тогда ничего работать не будет: В проге задействовано 4 USARTa, SPI, 2T/C.
А, вцелом, я вначале описал, что если отключить WDT, то всё прекрасно работает.

Ещё одна подозрительная тонкость: после зависа проги по WDT и дальнейшей перепрошивки проги заново - завис не прекращается, нужно обязательно передёрнуть питание. После этого прога начинает работать (до следующего срабатывания WDT).
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 19 2013, 14:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(SerSh @ Jun 19 2013, 17:02) *
Ещё одна подозрительная тонкость: после зависа проги по WDT и дальнейшей перепрошивки проги заново - завис не прекращается, нужно обязательно передёрнуть питание.

Возможно это связано с несброшенным битом WDRF в регистре MCUSR.
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 14:12
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Цитата(_Артём_ @ Jun 19 2013, 17:11) *
Возможно это связано с несброшенным битом WDRF в регистре MCUSR.


И когда его сбрасывать?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 19 2013, 14:19
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(SerSh @ Jun 19 2013, 17:12) *
И когда его сбрасывать?

В самом начале программы. Желательно до инициализации переменных, так как инициализация может занять слишком много времени и опять произойдёт сброс по WDT.
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 14:20
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Цитата(SerSh @ Jun 19 2013, 17:12) *
И когда его сбрасывать?


Перед инициализацией WDT сбросил этот бит: clrbit (MCUSR, WDRF);.
Не помогло!
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 19 2013, 15:07
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(SerSh @ Jun 19 2013, 18:02) *
Тогда ничего работать не будет: В проге задействовано 4 USARTa, SPI, 2T/C.
А, вцелом, я вначале описал, что если отключить WDT, то всё прекрасно работает.

Давайте "отделим мух от котлет"!
Без WDT Ваша программа правильно работает. Вот и чудесно.
WDT без Вашей программы работает ? Проверяли ? Если - нет, проверьте... Я думаю, что тоже будет работать...
Для проверки работы WDT с программой Вы вставили задержку __delay_cycles(), вероятно, перед сбросом WDT (может, я и не прав, но так понял из Вашего первого сообщения). Как предположение: эта задержка приводит к краху части функционала программы, но та часть, что отвечает за сброс WDT продолжает работать, при этом, поскольку остальная часть не работает, то время на __delay_cycles(), вероятно, уменьшилось и сброс WDT производится с периодом меньшим 2 сек, что приводить к отсутствию сброса МК.
Для проверки работы WDT совместно с программой я бы убрал __delay_cycles(), а вместо него либо - "глухой" цикл при запрещенных прерываниях, либо флаг и проверка флага: взведен - то сброс WDT не производить.

Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 15:51
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Цитата(Палыч @ Jun 19 2013, 18:07) *
WDT без Вашей программы работает ?

Кажется работает. Я вводил задержку специально чтобы сымитировать ситуацию "зависание - рестарт".
Если задержку не вводить, то программа работает, и WDT как-то там себе живёт, не беспокоит.

Цитата(Палыч @ Jun 19 2013, 18:07) *
Как предположение: эта задержка приводит к краху части функционала программы...

Как может цикл портить функционал программы мне не понятно.

Цитата(Палыч @ Jun 19 2013, 18:07) *
, но та часть, что отвечает за сброс WDT продолжает работать, при этом, поскольку остальная часть не работает, то время на __delay_cycles(), вероятно, уменьшилось и сброс WDT производится с периодом меньшим 2 сек, что приводить к отсутствию сброса МК.

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

Цитата(Палыч @ Jun 19 2013, 18:07) *
Для проверки работы WDT совместно с программой я бы убрал __delay_cycles(), а вместо него либо - "глухой" цикл при запрещенных прерываниях, либо флаг и проверка флага: взведен - то сброс WDT не производить.

Не совсем понятна идея. Если поставить просто глухой цикл типа while(1);, то всё повторяется - зависание. При этом не важно: открыты или закрыты все прерывания (проверял только что).

Сообщение отредактировал SerSh - Jun 19 2013, 15:52
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 19 2013, 16:43
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(SerSh @ Jun 19 2013, 19:51) *
Кажется работает.
Кажется? Или, всё-таки - работает?

Цитата(SerSh @ Jun 19 2013, 19:51) *
Как может цикл портить функционал программы мне не понятно.
А, нам-то и подавно не понятно, поскольку Вы как партизан молчите о том, куда Вы задержку вставили...

Цитата(SerSh @ Jun 19 2013, 19:51) *
Если поставить просто глухой цикл типа while(1);, то всё повторяется - зависание. При этом не важно: открыты или закрыты все прерывания (проверял только что).
А, если вместо всяких циклов/задержек просто закомментировать стоку сброса WDT - будет ли Ваша программа рестартовать каждые 2 сек ?
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 19 2013, 20:45
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Цитата(Палыч @ Jun 19 2013, 19:43) *
Кажется? Или, всё-таки - работает?

Я в предыдущем посте описал работу программы. А слово "кажется" использовал специально для Вас. )))

Цитата(Палыч @ Jun 19 2013, 19:43) *
А, нам-то и подавно не понятно, поскольку Вы как партизан молчите о том, куда Вы задержку вставили...

Задержку вставил сразу после инициализации WDT. И вовсе я не партизан, просто это не имеет значения. Её куда ни вставь, она и в Африке задержка.

Цитата(Палыч @ Jun 19 2013, 19:43) *
А, если вместо всяких циклов/задержек просто закомментировать стоку сброса WDT - будет ли Ваша программа рестартовать каждые 2 сек ?

А вот это завтра утром на работе попробую. А сейчас - спать.
Спокойной ночи, господа, спокойной ночи!...
Go to the top of the page
 
+Quote Post
SerSh
сообщение Jun 20 2013, 06:15
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608



Закомментировал все команды WDR, но всё осталось по-прежнему: через 2 сек. после старта - завис.
Такое впечатление, что он уходит в рестарт, но попадает не на начальный адрес старта, а на какой-нибудь бутлоадер, которого на самом деле нет, и, пробегая по пустым местам, возвращается обратно, при этом портя стек.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 11:15
Рейтинг@Mail.ru


Страница сгенерированна за 0.0148 секунд с 7
ELECTRONIX ©2004-2016