deus97 0 4 октября, 2010 Опубликовано 4 октября, 2010 · Жалоба В общем, где-то год назад было сделано устройство на ATmega168, которое нормально работает, но вот обнаружилось, что оно периодически (до 5 раз в день) программно зависает и перезагружается по сторожевому таймеру. Как определить где именно зависает? Устройство имеет светодиод, но им отлаживать, учитывая частоту зависания, не хочется. Есть выход в локальную сеть для передачи UDP-пакетов, в режиме прерывания по watchdog всё вполне работоспособно, как узнать в каком месте зависает? Программа написана на CVAVR. Заранее спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 5 октября, 2010 Опубликовано 5 октября, 2010 · Жалоба Расставить контрольные точки и в каждой выдавать тестовые сообщения в UART или ещё куда-нибудь. При старте - специальная метка старта. Потом посмотрите полученный лог и увидите последнее сообщение перед рестартом Проверьте ещё целостность стека - не наползает ли он на область глобальных переменных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deus97 0 5 октября, 2010 Опубликовано 5 октября, 2010 · Жалоба UART не предусмотрен, поэтому хотелось бы использовать имеющийся ethernet интерфейс, возможно ли, например по прерыванию от вотчдога, сохранить в еепром какую-то информацию о месте где была программа в момент этого прерывания, чтоб после перезагрузки передать её по сети? Например значение программного счётчика? Как в CVAVR обратиться к этому счётчику? Просто давно это уже было и сейчас приходится заново вникать:( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 8 5 октября, 2010 Опубликовано 5 октября, 2010 · Жалоба UART не предусмотрен Замените в сообщении MrYuran UART на LAN, далее по тексту Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xelax 0 6 октября, 2010 Опубликовано 6 октября, 2010 · Жалоба Можно также при зависании, в прерывании по вачдогу, сливать весь стек и регистры... Далее пишите какой-нибудт скриптик например на питоне, который получает на вход слитый стек и дизасм вашего проекта и по процессорному стеку разматывает стек вызовов функций.... 99% найдёте место зависания. Мы таким образом все jump на NULL отловили в своём коде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
king2 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба Все тупо, но придется много писать. :) Заводите две глобальные переменные, пусть будет trace_fn и trace_cp. На входе в функцию: unsigned int old_tfn = trace_fn; unsigned int old_tcp = trace_cp; trace_fn = <номер_функции>; Внутри функции: trace_cp = 1; trace_cp = 2; и так далее. На выходе из функции восстанавливаете значения из переменных old. Внутри функции watchdog отправляете на отладку обе глобальные переменные и видите, какой checkpoint в какой функции был последним. Там поблизости и ищите... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба в режиме прерывания по watchdog всё вполне работоспособно Перепишите его так, чтобы не сохранять в стеке регистры. РС будет сверху. Дальше-дамп Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deus97 0 22 октября, 2010 Опубликовано 22 октября, 2010 · Жалоба Всем спасибо отловил место зависания весьма нехитрым способом: наставил в коде несколько меток, которые устанавливались при выполнении конкретной части кода, при зависании WDT давал прерывание, в обработчике которого значения меток сливались в eeprom, далее происходит ресет по WDT и слив полученных меток в сеть при старте программы. Соответственно, последняя активированная метка перед не активированной и показала место зависания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться