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

 
 
 
Reply to this topicStart new topic
> Как определить где зависает?, без отладчика
troy97
сообщение Oct 4 2010, 15:29
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 12-01-09
Из: Донецк, Украина
Пользователь №: 43 218



В общем, где-то год назад было сделано устройство на ATmega168, которое нормально работает, но вот обнаружилось, что оно периодически (до 5 раз в день) программно зависает и перезагружается по сторожевому таймеру. Как определить где именно зависает? Устройство имеет светодиод, но им отлаживать, учитывая частоту зависания, не хочется. Есть выход в локальную сеть для передачи UDP-пакетов, в режиме прерывания по watchdog всё вполне работоспособно, как узнать в каком месте зависает? Программа написана на CVAVR. Заранее спасибо.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 5 2010, 05:45
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Расставить контрольные точки и в каждой выдавать тестовые сообщения в UART или ещё куда-нибудь.
При старте - специальная метка старта.
Потом посмотрите полученный лог и увидите последнее сообщение перед рестартом
Проверьте ещё целостность стека - не наползает ли он на область глобальных переменных.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
troy97
сообщение Oct 5 2010, 18:26
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 12-01-09
Из: Донецк, Украина
Пользователь №: 43 218



UART не предусмотрен, поэтому хотелось бы использовать имеющийся ethernet интерфейс, возможно ли, например по прерыванию от вотчдога, сохранить в еепром какую-то информацию о месте где была программа в момент этого прерывания, чтоб после перезагрузки передать её по сети? Например значение программного счётчика? Как в CVAVR обратиться к этому счётчику? Просто давно это уже было и сейчас приходится заново вникатьsad.gif
Go to the top of the page
 
+Quote Post
V_G
сообщение Oct 5 2010, 22:40
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(troy97 @ Oct 6 2010, 05:26) *
UART не предусмотрен

Замените в сообщении MrYuran UART на LAN, далее по тексту
Go to the top of the page
 
+Quote Post
xelax
сообщение Oct 6 2010, 06:41
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Можно также при зависании, в прерывании по вачдогу, сливать весь стек и регистры... Далее пишите какой-нибудт скриптик например на питоне, который получает на вход слитый стек и дизасм вашего проекта и по процессорному стеку разматывает стек вызовов функций.... 99% найдёте место зависания. Мы таким образом все jump на NULL отловили в своём коде.
Go to the top of the page
 
+Quote Post
king2
сообщение Oct 10 2010, 17:02
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 255
Регистрация: 17-08-06
Из: Москва
Пользователь №: 19 646



Все тупо, но придется много писать. smile.gif
Заводите две глобальные переменные, пусть будет 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 в какой функции был последним.
Там поблизости и ищите...

Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 10 2010, 20:32
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(troy97 @ Oct 4 2010, 19:29) *
в режиме прерывания по watchdog всё вполне работоспособно

Перепишите его так, чтобы не сохранять в стеке регистры. РС будет сверху. Дальше-дамп
Go to the top of the page
 
+Quote Post
troy97
сообщение Oct 22 2010, 10:08
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 12-01-09
Из: Донецк, Украина
Пользователь №: 43 218



Всем спасибо отловил место зависания весьма нехитрым способом: наставил в коде несколько меток, которые устанавливались при выполнении конкретной части кода, при зависании WDT давал прерывание, в обработчике которого значения меток сливались в eeprom, далее происходит ресет по WDT и слив полученных меток в сеть при старте программы. Соответственно, последняя активированная метка перед не активированной и показала место зависания.
Go to the top of the page
 
+Quote Post

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

 


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


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