|
WinAVR 200701.., Не могу понять где глюк |
|
|
|
Apr 18 2007, 22:54
|

кекс
     
Группа: Свой
Сообщений: 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(); Оставлю на ночь с этим изменением, завтра отпишу рез-тат. Большое спасибо за помощь  Цитата(singlskv @ Apr 18 2007, 19:52)  А по-моему зря Вы убрали U32 переменную. Как Вы теперь узнаете что прога близка к перезагрузке ? Дык и раньше эти два события были мало взаимосвязаны. Т.е. программа могла продолжать работать с неверным K, а это для меня гораздо хуже чем перезагрузка..
|
|
|
|
|
Apr 19 2007, 21:40
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Apr 18 2007, 23:54)  Дык и раньше эти два события были мало взаимосвязаны. Т.е. программа могла продолжать работать с неверным K, а это для меня гораздо хуже чем перезагрузка.. Ну наверное это все-таки как-то связанные события учитывая то что Вы заполнили перед этим стек константой 0xA5, ну да ладно. не суть... Лучше раскажите, удалось победить глюк, и если удалось то как победили и в чем он был ? ilock ? или что-то другое
|
|
|
|
|
Apr 19 2007, 22:40
|

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

|
Да, проблема-таки была связана с ILock! С изменением приведенным выше девайс уже проработал 24 часа без ребутов. Причина банальна - дребезг... Счетчик секунд который чуть-чуть опережал показание RTC это подтвердил. Прерывание, которое должно происходить строго раз в секунду - иногда (очень редко) происходило едва ли не сразу после предыдущего. Если в момент запуска callback'а происходило повторное прерывание с повторной установкой этого же callback'a, то старый еще не запущенный но уже проверенный на NULL удалялся из очереди (у меня не допускается держать в очереди дубликаты событий) - ну а потом уже NULL() - и ребут.... Подправил расположение ILock и сместил время выполнения события на 20ms. SetCallback( ..., 20, ...); Теперь работает все как надо. Еще раз спасибо всем кто принимал участие в обсуждении!
|
|
|
|
|
Apr 19 2007, 22:54
|
дятел
    
Группа: Свой
Сообщений: 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, ...); Теперь работает все как надо. Еще раз спасибо всем кто принимал участие в обсуждении!  А стек при этом таки переполнялся или нет ? прошу прощения за навязчивость, просто вопрос возникновения таких ошибок меня сейчас очень интересует, точнее интересуют способы борьбы с такими ошибками... вобщем вопрос в том как можно програмно конролировать выполнение собственной программы типа статистику собираю, а Ваш случай интересный...
|
|
|
|
|
Apr 19 2007, 23:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Apr 20 2007, 00:25)  Стек не переполнялся это 100%, и объяснить появление 0xA5A5xxxx я не могу, кроме как предположить, что GCC при оптимизации держит константу 0, где-то в памяти, а при моем вмешательстве с заполнием стека паттерном "заполнило" и ее. (у меня там была довольно существенная прослойка "гуляющей" памяти - байт в 200 между стеком и переменными).
Сейчас я затрудняюсь сказать память портилась до перезагрузки или после.. Скорее всего после - тогда это многое объясняет, т.к инициализация проходила при разрешенных прерываниях. GCC держит константу 0 в регистре R1 кажись, вроде бы были сообщения от userов что при определенных условиях там может оказатся не 0. но это бабушка на двое сказала... Вобщем если Вы пнете в меня своим hexом хотябы то мне будет очень интересно посмотреть чего там протсходит, а если елфом то тады ваще очень интересно, обесчаю перед прочтением Вашего кода его съесть...
|
|
|
|
|
Apr 20 2007, 00:13
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Apr 20 2007, 01:03)  При умножении! (mul/fmul используют R0, R1). А у меня там как раз и было умножение.. типа того, к сожалению точно не помню(не пользуюсь умножением/делением на авр без особой нужды) но если не етот глюк, то hex все таки пните... если этот то тогда не надо
|
|
|
|
|
Apr 20 2007, 02:34
|

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

|
Цитата(_artem_ @ Apr 20 2007, 00:32)  Я бы блокировал прерывания прежде чем проверять очередь на наличие задачи, а не проверять результат после того как фунцкия выбрана из очереди Резонно. Цитата , а дребезг подавлял бы до того как он сгенерирует событие. имхо. Дребезг теперь сам-собой подавляется, из-за этих условий: - два одинаковых события в очереди находиться не могут, - время до запуска события - 20ms с момента попадания в очередь. тобиш если приходит неожидаемое второе событие вызванное дребезгом - старое удалится - новое добавится, в очереди останется только одно такое событие. Цитата Один вопрос - а Вы используете Ilock из прерывания ? Если нет то зачем статус регистр запоминать? Вроде бы Set_Callback для того чтобы запускать тасковые функции после прерывания. Некоторые функции, например запись в eeprom, могут выполняться как в обработчиках прерываний так и вне, в них требуется запрещать прерывания. ILock/Unlock у меня сделаны так чтобы не задумываться где я сейчас нахожусь. Думаю они себя оправдывают, 1 команда (in rr, sreg) не велика цена за универсальность.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|