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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> WinAVR 200701.., Не могу понять где глюк
defunct
сообщение Apr 18 2007, 22:54
Сообщение #16


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(aesok @ Apr 18 2007, 19:53) *
На 99% ошибка в вашей программе. Только не подумайте что я заявляю что GCC совершенно безглючный.

Это хорошо! А то компилятор менять совсем не хотелось.

Цитата
Чем отлаживаете? Поробуйте поставить брейк на переменной К, вернув ей тип long. Проверте работу с указателями, самая частая ошибка.

Dragon'ом

Цитата
Возможно гдето пропустили ILock()/ IUnlock(). Поодключайте в программе разные блоки.

Да да, я присмотрелся к коду представленному выше, и похоже там промах с ILock (не в том месте стоит).

Код
if (slot[i] != NULL)
{
   U8 iStatus = ILock()
   __func *temp = __slot[i];
   __slot[i] = NULL;
   IUnlock( iStatus );
   temp();
}


между проверкой на NULL и запретом прерываний slot мог обнулиться..
Написал так:

Код
U8 iStatus = ILock()
__func *temp = __slot[i];
__slot[i] = NULL;
IUnlock(iStatus);
if (temp != NULL)
    temp();


Оставлю на ночь с этим изменением, завтра отпишу рез-тат.
Большое спасибо за помощь cheers.gif


Цитата(singlskv @ Apr 18 2007, 19:52) *
А по-моему зря Вы убрали U32 переменную.
Как Вы теперь узнаете что прога близка к перезагрузке ?

Дык и раньше эти два события были мало взаимосвязаны. Т.е. программа могла продолжать работать с неверным K, а это для меня гораздо хуже чем перезагрузка..
Go to the top of the page
 
+Quote Post
singlskv
сообщение Apr 19 2007, 21:40
Сообщение #17


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Apr 18 2007, 23:54) *
Дык и раньше эти два события были мало взаимосвязаны. Т.е. программа могла продолжать работать с неверным K, а это для меня гораздо хуже чем перезагрузка..

Ну наверное это все-таки как-то связанные события учитывая то что Вы заполнили перед этим
стек константой 0xA5, ну да ладно. не суть...

Лучше раскажите, удалось победить глюк, и если удалось то как победили и в чем он был ?
ilock ? или что-то другое
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 19 2007, 22:40
Сообщение #18


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Да, проблема-таки была связана с ILock! С изменением приведенным выше девайс уже проработал 24 часа без ребутов.

Причина банальна - дребезг... Счетчик секунд который чуть-чуть опережал показание RTC это подтвердил.
Прерывание, которое должно происходить строго раз в секунду - иногда (очень редко) происходило едва ли не сразу после предыдущего. Если в момент запуска callback'а происходило повторное прерывание с повторной установкой этого же callback'a, то старый еще не запущенный но уже проверенный на NULL удалялся из очереди (у меня не допускается держать в очереди дубликаты событий) - ну а потом уже NULL() - и ребут....

Подправил расположение ILock и сместил время выполнения события на 20ms.
SetCallback( ..., 20, ...);
Теперь работает все как надо.

Еще раз спасибо всем кто принимал участие в обсуждении! cheers.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение Apr 19 2007, 22:54
Сообщение #19


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Apr 19 2007, 23:40) *
Да, проблема-таки была связана с ILock! С изменением приведенным выше девайс уже проработал 24 часа без ребутов.

Причина банальна - дребезг... Счетчик секунд который чуть-чуть опережал показание RTC это подтвердил.
Прерывание, которое должно происходить строго раз в секунду - иногда (очень редко) происходило едва ли не сразу после предыдущего. Если в момент запуска callback'а происходило повторное прерывание с повторной установкой этого же callback'a, то старый еще не запущенный но уже проверенный на NULL удалялся из очереди (у меня не допускается держать в очереди дубликаты событий) - ну а потом уже NULL() - и ребут....

Подправил расположение ILock и сместил время выполнения события на 20ms.
SetCallback( ..., 20, ...);
Теперь работает все как надо.

Еще раз спасибо всем кто принимал участие в обсуждении! cheers.gif

А стек при этом таки переполнялся или нет ?
прошу прощения за навязчивость, просто вопрос возникновения таких
ошибок меня сейчас очень интересует, точнее интересуют способы борьбы с такими ошибками...
вобщем вопрос в том как можно програмно конролировать выполнение собственной программы

типа статистику собираю, а Ваш случай интересный...
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 19 2007, 23:25
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ Apr 19 2007, 21:54) *
А стек при этом таки переполнялся или нет ?

Стек не переполнялся это 100%, и объяснить появление 0xA5A5xxxx я не могу, кроме как предположить, что GCC при оптимизации держит константу 0, где-то в памяти, а при моем вмешательстве с заполнием стека паттерном "заполнило" и ее. (у меня там была довольно существенная прослойка "гуляющей" памяти - байт в 200 между стеком и переменными).

Сейчас я затрудняюсь сказать память портилась до перезагрузки или после.. Скорее всего после - тогда это многое объясняет, т.к инициализация проходила при разрешенных прерываниях.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Apr 19 2007, 23:58
Сообщение #21


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Apr 20 2007, 00:25) *
Стек не переполнялся это 100%, и объяснить появление 0xA5A5xxxx я не могу, кроме как предположить, что GCC при оптимизации держит константу 0, где-то в памяти, а при моем вмешательстве с заполнием стека паттерном "заполнило" и ее. (у меня там была довольно существенная прослойка "гуляющей" памяти - байт в 200 между стеком и переменными).

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

GCC держит константу 0 в регистре R1 кажись,
вроде бы были сообщения от userов что при определенных условиях там может оказатся не 0.
но это бабушка на двое сказала...

Вобщем если Вы пнете в меня своим hexом хотябы то мне будет очень интересно посмотреть
чего там протсходит, а если елфом то тады ваще очень интересно,
обесчаю перед прочтением Вашего кода его съесть...smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 20 2007, 00:03
Сообщение #22


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ Apr 19 2007, 22:58) *
GCC держит константу 0 в регистре R1 кажись,
вроде бы были сообщения от userов что при определенных условиях там может оказатся не 0.
но это бабушка на двое сказала...

При умножении! (mul/fmul используют R0/R1)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Apr 20 2007, 00:13
Сообщение #23


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Apr 20 2007, 01:03) *
При умножении! (mul/fmul используют R0, R1). А у меня там как раз и было умножение..

типа того, к сожалению точно не помню(не пользуюсь умножением/делением
на авр без особой нужды)

но если не етот глюк, то hex все таки пните...
если этот то тогда не надоsmile.gif
Go to the top of the page
 
+Quote Post
_artem_
сообщение Apr 20 2007, 01:32
Сообщение #24


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Я бы блокировал прерывания прежде чем проверять очередь на наличие задачи, а не проверять результат после того как фунцкия выбрана из очереди, а дребезг подавлял бы до того как он сгенерирует событие. имхо.
Один вопрос - а Вы используете Ilock из прерывания ? Если нет то зачем статус регистр запоминать? Вроде бы Set_Callback для того чтобы запускать тасковые функции после прерывания.


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 20 2007, 02:34
Сообщение #25


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(_artem_ @ Apr 20 2007, 00:32) *
Я бы блокировал прерывания прежде чем проверять очередь на наличие задачи, а не проверять результат после того как фунцкия выбрана из очереди

Резонно.

Цитата
, а дребезг подавлял бы до того как он сгенерирует событие. имхо.

Дребезг теперь сам-собой подавляется, из-за этих условий:
- два одинаковых события в очереди находиться не могут,
- время до запуска события - 20ms с момента попадания в очередь.
тобиш если приходит неожидаемое второе событие вызванное дребезгом - старое удалится - новое добавится, в очереди останется только одно такое событие.

Цитата
Один вопрос - а Вы используете Ilock из прерывания ? Если нет то зачем статус регистр запоминать? Вроде бы Set_Callback для того чтобы запускать тасковые функции после прерывания.

Некоторые функции, например запись в eeprom, могут выполняться как в обработчиках прерываний так и вне, в них требуется запрещать прерывания. ILock/Unlock у меня сделаны так чтобы не задумываться где я сейчас нахожусь. Думаю они себя оправдывают, 1 команда (in rr, sreg) не велика цена за универсальность.
Go to the top of the page
 
+Quote Post
Serjio
сообщение Apr 21 2007, 20:16
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 137
Регистрация: 3-09-04
Пользователь №: 594



Еще можно добавить, что переменные, которые модифицируются в прерываниях положено объявлять как volatile - чтобы процессор правильно произвел оптимизацию обращения к этим переменным (не в регистры)
Go to the top of the page
 
+Quote Post

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

 


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


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