Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глюки watchdoga в меге 2560
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
superbizzon
Здарасьте всем! Такая проблема - делаю проектик на меге 2560, шла без нареканий пока не понадобилось организовать програмный сброс - просто перестаю обнулять watchdog. Резет-то происходит но только мега остается в зарезеченом состоянии.... приэтом сброс от программатора не помогает, ещё интересно что в этом состоянии можно перепрошить - но после прошивки остаётся в такомже состоянии %| .... помогает только снятие питания и перезапуск...

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

Много раз проделывал такой фокус с другими контроллерами АВР ( не 2560) - ваще никаких проблем, а тут полдня потерял всё бестолку....

ПОМОЖИТЕ! Что делать, как бороться!?
Kuzmi4
2 superbizzon - как писал недавно тут товарисч - "...к величайшему сожалению телепатов тут нет.."

Желательно было б увидеть код, или его ключевые части для начала...
superbizzon
Цитата(Kuzmi4 @ Feb 20 2008, 11:31) *
2 superbizzon - как писал недавно тут товарисч - "...к величайшему сожалению телепатов тут нет.."

Желательно было б увидеть код, или его ключевые части для начала...


Мда... как раз ирония в том что кода три строчки -

int main()
{
_WDR();
WDTCSR=0x38;
WDTCSR=0x28;

DDRD|=0x01;

while(1)
{
PORTD^=0x01;
}
}

Даём питание, прошиваем... смотрим осцылом - дрыгает ногой PD1 две секунды.... потом перестаёт.... и всё, пока питалово не выключишь-включишь не начинает .... проходит две секунды опять виснет.
VladimirYU
Цитата(superbizzon @ Feb 20 2008, 11:43) *
Мда... как раз ирония в том что кода три строчки -

int main()
{
_WDR();
WDTCSR=0x38;
WDTCSR=0x28;

DDRD|=0x01;

while(1)
{
PORTD^=0x01;
}
}

Даём питание, прошиваем... смотрим осцылом - дрыгает ногой PD1 две секунды.... потом перестаёт.... и всё, пока питалово не выключишь-включишь не начинает .... проходит две секунды опять виснет.

Проверьте фуз WDTON, может быть Вы уходите в прерывание по WDT, а не в сброс. А дальше бегом по памяти куда глаза глядят.
superbizzon
Цитата(VladimirYU @ Feb 20 2008, 12:03) *
Проверьте фуз WDTON, может быть Вы уходите в прерывание по WDT, а не в сброс. А дальше бегом по памяти куда глаза глядят.


Тогда почему не помогает внешний резет? ( пробывал через програматор, да и ~RESET замыкал на ноль - ничего не происходит)

Ну и выставлено вроде всё верно, так -
WDTON - 1 (всмысле отключен) , WDE - 1, WDIE - 0

Пробывал WDTON выставлять в 0 - вообще не запускается. стоит после прошивки и ни БЭ ни МЭ...
VladimirYU
Цитата(superbizzon @ Feb 20 2008, 12:12) *
Тогда почему не помогает внешний резет? ( пробывал через програматор, да и ~RESET замыкал на ноль - ничего не происходит)

Ну и выставлено вроде всё верно, так -
WDTON - 1 (всмысле отключен) , WDE - 1, WDIE - 0

Пробывал WDTON выставлять в 0 - вообще не запускается. стоит после прошивки и ни БЭ ни МЭ...

Да вроде все правильно, попробуйте перед инициализацией WDT обнулить MCUSR = 0;
superbizzon
Цитата(VladimirYU @ Feb 20 2008, 12:50) *
Да вроде все правильно, попробуйте перед инициализацией WDT обнулить MCUSR = 0;


Попробую канешна... но дело в том что после подачи питания до момента переполнения WDT всё идёт правильно... а когда происходит сброс конртроллер какбы замирает - никакие команды не выполняются ( пробывал первой строчкой ставить поднятие ноги на другом порте а потом её опускал... так вот после WDReseta она не поднимается) , это я к тому, что если первой строкой поставить обнуление MCUSRа то оно пройдет только в первый раз после подачи питания, и при резете от WDT не возымеет никакого действия... sad.gif

но хотя это чисто предположения - обязательно проверю, спасибо!
VladimirYU
Цитата(superbizzon @ Feb 20 2008, 13:18) *
Попробую канешна... но дело в том что после подачи питания до момента переполнения WDT всё идёт правильно... а когда происходит сброс конртроллер какбы замирает - никакие команды не выполняются ( пробывал первой строчкой ставить поднятие ноги на другом порте а потом её опускал... так вот после WDReseta она не поднимается) , это я к тому, что если первой строкой поставить обнуление MCUSRа то оно пройдет только в первый раз после подачи питания, и при резете от WDT не возымеет никакого действия... sad.gif

но хотя это чисто предположения - обязательно проверю, спасибо!

В меге128 пока вот так не сделал тоже была какая то лажа, к сожалению, подробности не помню.
// Инициализация WDT
_WDR();
WDTCR=0x1f;
WDTCR=0x0f; // init WDT
MCUCR=0x00;
В предыдущем посте ошибся не до, а после инициализации. Структура регистров у 128 и 2560 аналогичная, отличается немного битами прескалера и несколькими дополнительными, которые Вы не используете.

Цитата(VladimirYU @ Feb 20 2008, 14:24) *
В меге128 пока вот так не сделал тоже была какая то лажа, к сожалению, подробности не помню.
// Инициализация WDT
_WDR();
WDTCR=0x1f;
WDTCR=0x0f; // init WDT
MCUCR=0x00;
В предыдущем посте ошибся не до, а после инициализации. Структура регистров у 128 и 2560 аналогичная, отличается немного битами прескалера и несколькими дополнительными, которые Вы не используете.

И еще. Посмотрел несколько своих проектов везде аналогичная конструкция, везде работает на разных мегах 16,32,64, 128. Ничего не хочу утверждать, пользуюсь ей "на автопилоте" после того, как поимел схожие проблемы. Перед инциализацией все прерывания запрещаю.
superbizzon
Цитата(VladimirYU @ Feb 20 2008, 14:39) *
И еще. Посмотрел несколько своих проектов везде аналогичная конструкция, везде работает на разных мегах 16,32,64, 128. Ничего не хочу утверждать, пользуюсь ей "на автопилоте" после того, как поимел схожие проблемы. Перед инциализацией все прерывания запрещаю.


Спасибо за ответ!
К сожалению попробывать смогу только вечером... так что отпишусь только завтра.
=GM=
Цитата(superbizzon @ Feb 20 2008, 08:43) *
Рисет-то происходит, но только мега остается в зарисеченом состоянии.... приэтом сброс от программатора не помогает, ещё интересно что в этом состоянии можно перепрошить - но после прошивки остаётся в таком же состоянии %| .... помогает только снятие питания и перезапуск...

Похоже, у вас таблица векторов прерываний (и адрес сброса в том числе) находится в области загрузчика, и по рисету (неважно ручному или от охранного таймера) вы направляете программу в область загрузчика. Чтобы избежать подобного, перед настройкой вотчдога поставьте две команды
MCUCR=0x01;
MCUCR=0x00; //вектора прерываний в начале флеша

Вся программа примерно такая
int main()
{
_WDR();
MCUCR=0x01;
MCUCR=0x00; //вектора прерываний в начале флеша
WDTCSR=0x38;
WDTCSR=0x28; //системный сброс и период на 4с
DDRD|=0x01;
while(1)
{
PORTD^=0x01;
}
}

Должно помочь.
superbizzon
Цитата(=GM= @ Feb 20 2008, 17:30) *
Похоже, у вас таблица векторов прерываний (и адрес сброса в том числе) находится в области загрузчика, и по рисету (неважно ручному или от охранного таймера) вы направляете программу в область загрузчика. Чтобы избежать подобного, перед настройкой вотчдога поставьте две команды
MCUCR=0x01;
MCUCR=0x00; //вектора прерываний в начале флеша

Вся программа примерно такая
int main()
{
_WDR();
MCUCR=0x01;
MCUCR=0x00; //вектора прерываний в начале флеша
WDTCSR=0x38;
WDTCSR=0x28; //системный сброс и период на 4с
DDRD|=0x01;
while(1)
{
PORTD^=0x01;
}
}

Должно помочь.


2VladimirYU - не спасло sad.gif ... ничего не изменилось


2 =GM=

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

пробывал вчера так -
int main()
{
_WDR();
WDTCSR=0x38;
WDTCSR=0x28; //системный сброс и период на 4с

MCUCR=0x00;

DDRD|=0x01;
while(1)
{
PORTD^=0x01;
}
}


Тоесть не -
MCUCR=0x01;
MCUCR=0x00;

а просто
MCUCR=0x00;

- не помогло.... Но обязательно вечером попробую Ваш вариант, спасибо! smile.gif
VladimirYU
Цитата(superbizzon @ Feb 21 2008, 09:12) *
- не помогло.... Но обязательно вечером попробую Ваш вариант, спасибо! smile.gif

В продолжение идеи от =GM=, проверьте фузы определяющие адрес вектора RESET, может на самом деле там "собака порылась".
=GM=
Цитата(superbizzon @ Feb 21 2008, 06:12) *
2 =GM=
Тоесть не -
MCUCR=0x01;
MCUCR=0x00;

а просто
MCUCR=0x00;

- не помогло.... Но обязательно вечером попробую Ваш вариант, спасибо! smile.gif

Просто MCUCR=0x00 не поможет, поскольку бит <1>, который отвечает за положение веторов прерывания, защищён от прямой записи. Поэтому сначала надо выставить бит <0> в единицу, а потом в течение 4 тактов сбросить бит <1>. Читайте дейташит, там всё подробно расписано.
superbizzon
Цитата(=GM= @ Feb 21 2008, 14:26) *
Просто MCUCR=0x00 не поможет, поскольку бит <1>, который отвечает за положение веторов прерывания, защищён от прямой записи. Поэтому сначала надо выставить бит <0> в единицу, а потом в течение 4 тактов сбросить бит <1>. Читайте дейташит, там всё подробно расписано.


ДА, всё правильно... попробывал так,но не спасает sad.gif
Перерыл datashIt вдоль и поперек... всё должно работать, но не работает..... Запустил в Astudiю ассемблерный файл - и вот что получается :
После загрузки - стоит на нулевом адресе, где сидит команда на прыжок на адрес начала программы (0х00083)... она прыгает.... там проходит seg_init и ещё какието initы.... далее переходит к моим командам...... жду - происходит сброс.... программа возвращается на нулевой адрес, откуда прыгает опятьже на (0х00083) и вязнет в initaх.... тоесть вектора сброса тут не причём абсолютно.... это пакостит IAR.... пытался отключить вставку этих самых initoв - пока не нашел как....


Добавлю -
вот что наковырял по теме - http://electronix.ru/forum/index.php?showt...mp;#entry358180
видимо должно помочь..
Сергей Борщ
Цитата(superbizzon @ Feb 26 2008, 09:07) *
и вязнет в initaх....
Вот это смущает. Поставьте точку останова на вектор сброса и посмотрите - происходит ли повторный сброс собаки. Если да - то
Цитата(superbizzon @ Feb 26 2008, 09:07) *
вот что наковырял по теме - http://electronix.ru/forum/index.php?showt...mp;#entry358180
как раз ваш случай, но непонятно - что же может ИАР в стартапе вашей программе из нескольких строчек делать столько времени? Ведь если нет глобальных переменных, то обнулять и копировать нечего, а больше там ничего и не делается.
xelax
Как проблема то разрешилась?

Получил точно такую же проблему на меге1281.

Происходит ресет по вачдогу, а затем контроллер стоит мёртвый, на внешний ресет не реагирует. Помогает только передёргивание питания.

Что самое интересное, так только в некотороых преложениях, а в некоторых работает.
При попытке подебажить в авр студии, после ресета, программа остаётся на нулевом адресе, а при попытке сделать шаг или просто стартовать до точки останова дебаггер слетает.
mdmitry
Я ничего подобного не наблюдал. Может от ревизии кристалла что-то зависит?
Был проект, где были AtMega128/1251/2561. Проблем не было, делал тесты с вечными циклами, все корректно сбрасывалось и перезапускалось.
Использовал WinAVR-20071221 со следующим кодом
Код
void avr_init (void) __attribute__ ((naked)) __attribute__ ((section (".init3")));

void avr_init(void)
{
/* Конфигурирование AtMega128/1251/2561*/
/* куча инициализации*/

        /* WatchDog */
    wdt_enable(WDTO_2S);
    
}
xelax
Если кому интересно, то разобрал проблему.

Всё дело было в ошибке в makefile. Был неправильный путь при линковке стартовой секции, где происходила остановка WDT после ресета. В итоге процессор стартовал с копирования данных в озу и очистки bss секции, пока происходила очистка, wdt успевал сработать ещё раз и так до бесконечности.

После того, как правильно собрал проект, проблема исчезла. yeah.gif
no_d@t@
Столкнулся с точно такой же проблемой в Меге2560 правда под IAR, см. http://electronix.ru/forum/index.php?showtopic=48161.
Добавил в функцию __low_level_init() остановку watchdog - помогло.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.