Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: CVAVR "повреждене" локальных переменных
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
MKdemiurg
Пишу прожэкт на CоdeVisionAVR 1.25.5 под atmega128A.

Столкнулся с проблемой , что по неопределённым причинам портитятся значения локальных переменных. Т.е. проблема выглядит так :
...................................................
void modem_control(void)
{
unsigned char step;
unsigned char conflict;
unsigned char atc_retry_number;
unsigned char repeat;
// специально присваиваю значения отдельно от инициализации
step=1;
atc_retry_number=3;
repeat=3;
conflict=0;

while (step!=100)
{ OUT_COM0_CHAR(conflcit); // вывод в уарт переменной conflict. Вместо 0x00 приходит 0xC0 - соответственно выполнение кода сбивается...
..............................................................................

эффект периодический, причину возникновения так и не нашёл, НО смена порядка инициализации переменных меняет и переменную , которая "глючит".. Такая же лажа периодически появляется в функции main. Стека всего то 190/1024 использую. Может оптимизатор глючит- но тогда бы проблема была более менее периодичной...

Проект не то чтобы большой( 10К строк и 20К флеша), но переделывать под другой компилятор долго и осваивать нужно, а время поджимает.

Подскажите где могут быть грабли. Может сама версия нестабильна? Слышал что 1.25.5 может генерить неправильный код... Подскажите более менее нормальную и неглючащую...



kovigor
Цитата(MKdemiurg @ Sep 15 2011, 18:01) *
Подскажите где могут быть грабли.


Возможно, переполняется стек и собой затирает переменные. Попробуйте в опциях проекта увеличить размер стека. Ну или вы с указателями где-то накосячили. Я уже не говорю о том, что скорость UART м.б. неправильно выставлена. Например, что будет, если выводить не по UART, а куда-то в другое место ? И еще. OUT_COM0_CHAR ждет окончания передачи предыдущего байта, или ничего не ждет и тупо пишет в UART независимо от его готовности ? Еще возможно переполнение буфера драйвера на стороне PC и как следствие - потеря данных. Что будет, если передавать не переменную, а число ? Оно тоже будет биться ?

P.S. А еще "conflict" может неожиданно меняться в процессе передачи (обработчиком прерывания, о котором вы забыли) ...
MKdemiurg
Цитата(kovigor @ Sep 15 2011, 19:32) *
Возможно, переполняется стек и собой затирает переменные. Попробуйте в опциях проекта увеличить размер стека.
Ну или вы с указателями где-то накосячили.
Я уже не говорю о том, что скорость UART м.б. неправильно выставлена.
Например, что будет, если выводить не по UART, а куда-то в другое место ?
И еще. OUT_COM0_CHAR ждет окончания передачи предыдущего байта, или ничего не ждет и тупо пишет в UART независимо от его готовности ?
Еще возможно переполнение буфера драйвера на стороне PC и как следствие - потеря данных. Что будет, если передавать не переменную, а число ? Оно тоже будет биться ?


Стек выставлен на 1 Кбайт, при компиляции пишет, что используется 190байт.

С указателями возможно, но блин, я даже не знаю как к ним подступить sad.gif , ибо их я наплодил десятки... jtaga нема, да и программу особо не потрассируешь... Растянута по времени на часы... Попробую покопаться в указателях ... Но какая зависимость непонятно. Все массивы и структуры статичны - если бы где то вылезало за предел выделяемой памяти - ошибка была бы постоянной, да и слетают переменные в местах где указатели не меняются

Дело не в UART 100%, т.к. меняется даже ход выполнения программы, который я тоже контролирую через uart икоторый зависит от этих переменных.


ЗЫ - вот так 1 баг где нибудь и всё программирование сводится к танцу с бубном biggrin.gif .

kovigor
Цитата(MKdemiurg @ Sep 15 2011, 19:55) *
Дело не в UART 100%, т.к. меняется даже ход выполнения программы, который я тоже контролирую через uart икоторый зависит от этих переменных.


А тут не может быть какой-то хитрой завязки ? Просто эта фраза очень странно звучит.

Еще идея: попробуйте повыключать некоторые обработчики прерываний, насколько это возможно, и посмотрите, что будет. Вообще, почти наверняка дело в одном из обработчиков.

Да, и еще. Это может быть ошибка в использовании типов. Например, вы по ошибке пишете в unsigned char 16-разрядное число.

Ну и последнее. Как показывает мной многолетний опыт, самые сложные и трудноуловимые ошибки почти всегда имеют до смешного простые причины. Так что ...
MKdemiurg
Цитата(kovigor @ Sep 15 2011, 20:06) *
А тут не может быть какой-то хитрой завязки ? Просто эта фраза очень странно звучит.

Еще идея: попробуйте повыключать некоторые обработчики прерываний, насколько это возможно, и посмотрите, что будет. Вообще, почти наверняка дело в одном из обработчиков.

Да, и еще. Это может быть ошибка в использовании типов. Например, вы по ошибке пишете в unsigned char 16-разрядное число.


Нет, просто вывожу в ключевых точках параметры.

Из прерываний только таймер - работает как таймер с жёсткой фиксацией ( т.е. пока не сработает других действий не выполняется - чтото типа задержки только с программным опросом ноги или флага до окончания тайминга) , сброс по внешнему - срабатывает от RTS раз в час, ну и UART, в котором вообще ничего мудрёного... Выключить можно , но тогда программа вообще вся собьётся...

Я вот какую особенность подметил у меня по тексту порядок следования функций такой

1void modem_control(void)
2void protokol_set(unsigned char KEY)
3void main(void)
{
//здесь объявляется переменная которая идет параметром в функцию 2 и которая кстати и "ломается".
}

Так вот - если ошибка пропадает в 1 - то появляется ниже во 2 или 3й. Очень похоже на указатель...Завтра точно их поковыряю. Может быть даже частично перейду на использование нумерованых массивов, правда придётся тогда передавать данные через глобальные переменные laughing.gif

Цитата
Ну и последнее. Как показывает мной многолетний опыт, самые сложные и трудноуловимые ошибки почти всегда имеют до смешного простые причины. Так что ...


biggrin.gif Дааа, это есть проблема №1 , у меня всегда так... Видать и тут также

Зы Спасибо за наводящую помощь, будем копать...
ЗЗЫ А всё таки не может это быть в компиляторе или оптимизации дело ?
kovigor
Цитата(MKdemiurg @ Sep 15 2011, 20:24) *
Зы Спасибо за наводящую помощь, будем копать...
ЗЗЫ А всё таки не может это быть в компиляторе или оптимизации дело ?

Да, поищите баг в указателях, прежде всего ...

Volatile в нужных местах везде имеется ?

За ~15 лет практики видел собственными глазами одну ошибку компилятора и один случай неработоспособности программы из-за действий оптимизатора. Так что и такое может быть, но вероятность этого ничтожна ...
MKdemiurg
Цитата(kovigor @ Sep 15 2011, 20:29) *
Volatile в нужных местах везде имеется ?


Хм... Я его вообще не использую biggrin.gif НАсколько я понимаю он ставится чтобы отключить оптимизацию для переменной ?Точно...Надо попробовать всем ключевым переменным ( хотя они явно задаются и не меняются в прерываниях - поэтому и не ставил) задать Volatile.
kovigor
Цитата(MKdemiurg @ Sep 15 2011, 20:50) *
Надо попробовать всем ключевым переменным ( хотя они явно задаются и не меняются в прерываниях - поэтому и не ставил) задать Volatile.



Достаточно задать тем, которые меняются
MKdemiurg
А тем которые параметром в функцию передаются?
kovigor
Цитата(MKdemiurg @ Sep 15 2011, 21:02) *
А тем которые параметром в функцию передаются?


Не надо
Marian
Выловил однажды проблему в CV, при декларировании глобальных переменных.
Был декларирован массив и сразу за ним переменные.
(В массиве хранились структуры)
Все работало до момента записи в массив.
Данные, которые должны были быть записанные в массив, оказывались в переменных.
Компилятор неправильно выделял место, адреса переменных налазили на адрес массива.
Решилась проблема так, при декларировании массива принудительным присваиванием всем значениям массива нулевых значений,
это заставило компилятор правильно выделить место для переменных.
-SANYCH-
В CоdeVisionAVR довольно много глюков (по крайней мере я встречал в старых версиях). Эта среда хороша только что нить сделать быстро. Типа что нить измерить АЦПешкой и выкинуть результат в компорт.
Кстати я бы Вам не советовал использовать atmega128A в новом проекте. Уже давно есть процессоры дешевле и намного лучше.
MKdemiurg
Цитата(-SANYCH- @ Sep 16 2011, 00:41) *
В CоdeVisionAVR довольно много глюков (по крайней мере я встречал в старых версиях). Эта среда хороша только что нить сделать быстро. Типа что нить измерить АЦПешкой и выкинуть результат в компорт.
Кстати я бы Вам не советовал использовать atmega128A в новом проекте. Уже давно есть процессоры дешевле и намного лучше.

У мну работа с памятью, часами и модемом - не столь ужасно для CVAVR. К этой среде я привык, и проект был заточен под него. Просто глюки вылезли неожиданно. А описание примерное глюков можете дать, а то незнаю куда копать - сейчас пересмотрел проект, с указателями вроде всё ок...
Какие например?ИЗ аврок... Чтобы на тот же arm перейти( была идея заюзать stm32f107) нужно месяца два времени, а то и три - освоить кеил или iar, освоить контроллер... А с временем напряжёнка...
kovigor
Цитата(MKdemiurg @ Sep 16 2011, 08:38) *
Чтобы на тот же arm перейти( была идея заюзать stm32f107) нужно месяца два времени, а то и три - освоить кеил или iar, освоить контроллер... А с временем напряжёнка...


Понимаете, освоить можно. Но вам это не поможет - ошибка где-то в проекте, и вы ее не нашли. Со сменой версии или компилятора она на время спрячется и потом (или сразу же) вылезет где-то совсем в другом месте. Так что, повторю, придется ее искать ...
Slava2105
Не знаю как в версии 1.25.5 , я про неё давно забыл.
У меня сейчас 2.03.4.
Никаких нареканий на уарт нет, да и на прошлых версиях тоже не было
Работает чётко, без глюков.
у меня был проект, там 30 штук 128 и одна 32 атмеги между собой связь по 485 держат. А каждая из 128 еще и вторым уартом связь на сторону держит.
проект уже полгода работает без проблем.
так что ищите у себя.
MKdemiurg
Вообщем глюк то вроде бы изза того что переменную не объявил volаtilom. В неё как раз считывались данные с порта только при ресете. И видимо компилятор посчитал, что потом с ней можно делать всё что хочешь. laughing.gif

Столнулся с другим, что уже явно указывает на глюк компилятора. (версию сменил уже на 1.25.9)

прога примерно такая :

void main(void)
{

1)If (условие)
{
if (условие)
{
while (1){операции}
};
};
2)while(1)
{
операции
powerdown();
/*
вот тут задокументирован был временно код на переработку
*/
};

}
какимто образом программа вошла во 2й while(метка 2) выполнила операции , заснула , а когда проснулась попала в условие сверху( метка 1). После ресета было 100% повторение. После перекомпиляции и перепрошивки - всё исчезло. НО, перед перекомпиляцией я убрал задокументированный код. Незнаю сейчас гоняю , вроде работает, но к CV как то отношение ухудшилось biggrin.gif

Да ещё может кто встречал - при прошивке через CV если не сделать стирание чипа с проверкой( обязательно с проверкой) - чип не прошивается вбивает туда 0xFFFF( а может просто не шьёться , но стирается). Грешу на комп - часы у меня на компе уходят за час на 5 минут. Может частота не та идёт с компа? И изза этого появляются битые ячейки? Хотя впринципе тогда должно при верификации выводит ошибку.

Цитата
У меня сейчас 2.03.4.


А как насчёт перехода с версии 1.25 сразу на 2.03 - сложностей не вызовет как думаете?
kovigor
Цитата(MKdemiurg @ Sep 24 2011, 00:34) *
Столнулся с другим, что уже явно указывает на глюк компилятора. (версию сменил уже на 1.25.9)


Почти наверняка это такой же глюк компилятора, как и первый, описанный вами неделю назад. Хотя может быть всякое. я бы на вашем месте просто открыл .asm - файл, созданный компилятором, и посмотрел бы, как выглядит ваш фрагмент на асме. Думаю, это прояснило бы ситуацию.
Я уже, кстати, молчу о том, что у вас может, например, портиться стек, что и приводит к таким последствиям. На 99.9 и в этом случае компилятор не виноват ...
MKdemiurg
Цитата(kovigor @ Sep 24 2011, 13:24) *
Почти наверняка это такой же глюк компилятора, как и первый, описанный вами неделю назад. Хотя может быть всякое. я бы на вашем месте просто открыл .asm - файл, созданный компилятором, и посмотрел бы, как выглядит ваш фрагмент на асме. Думаю, это прояснило бы ситуацию.
Я уже, кстати, молчу о том, что у вас может, например, портиться стек, что и приводит к таким последствиям. На 99.9 и в этом случае компилятор не виноват ...


Да вот , недопёр я в asm заглянуть...
Прикол то в том, что после перекомпиляции и перепрошивки - всё заработало - в коде убрал только задокументированный текст( тогда кстати тоже текст рядом в скобках был , много текста) . Я вот думаю а не был ли и в прошлый раз ещё и стек виноват ( потому как в этот раз точно стек был- иначе не объяснишь). Надо будет асм "разобрать" при следующей запаре... Но там врятли явно увидишь... Пересмотрел указатели. Вроде запар нет нигде. Вот тоглько смущает этот кусок:

Код
void at24c256_read(unsigned char chip,unsigned int address, unsigned char count, unsigned char *buffer)
{
unsigned char a,b;
a=(chip<<1)|0b10100000;
i2c_start();
i2c_write(a);
i2c_write(address >> 8);
i2c_write(address);
i2c_start();
i2c_write((chip<<1)|0b10100001);
for (b=0;b<count-1;b++) {*buffer++=i2c_read(1);};
*buffer=i2c_read(0);
i2c_stop();
};

При переполнении страницы памяти( 64 байта) стабильно происходит запара со стеком( делал специально - при работе жётско контролируется НЕпереполнение записываю страницами по 63 байта) - переходит в начало main или вызывающей процедуры. А вот к функциям i2c добраться никак...
Slava2105
Цитата
А как насчёт перехода с версии 1.25 сразу на 2.03 - сложностей не вызовет как думаете?

Абсолютно никаких проблем не было. Мало того, даже программы созданные в 2.03 компилировались в 1.25.9.
По крайней мере с проблемами не сталкивался.
И утверждать про глюки компилятора надо всё же пореже.
Как правило это глюки вашей, да и моей программы тоже. Просто где то не дочитали, не досчитали, не так сделали.
А кодевижен мне больше нравится чем винавр. Попробовал как то перейти на него... Ни грамма не улыбнуло
MKdemiurg
Цитата
И утверждать про глюки компилятора надо всё же пореже.


ТАк я и не утверждаю. Просто с чем может быть связан глюк , который уходит после перекомпиляции? НУ возможно с процессом прошивки... Но маловероятно...

ЗЫ Тож наверно перейду на 2.03 тогда , там библиотека для SD карты реализована.... biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.