Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ГЛЮКИ КОМПИЛЯТОРОВ
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Fortune
Открыть эту тему меня подтолкнул тот факт, что используя однажды в IARe функцию SIN, я так и не смог добиться нормальной ее работы. Хотя не утверждаю что мой код не содержал ошибок, но все же может кто-то сталкивался с подобными проблемами?

Исходным текстом поделиться не могу, потому что уже затер его.

Предлагаю также сюда кидать описание глюков (багов, граблей) при работе с компиляторами...
SasaVitebsk
Предыдущие попытки "обвинить" компилятор и уличить его в граблях, заканчивались провалом. (По крайней мере в области языка). Так что не думаю, что данная ветка будет содержать большое колличество постов. Хотя кто знает ...
IgorKossak
Цитата(SasaVitebsk @ Feb 6 2007, 11:12) *
Предыдущие попытки "обвинить" компилятор и уличить его в граблях, заканчивались провалом. (По крайней мере в области языка). Так что не думаю, что данная ветка будет содержать большое колличество постов. Хотя кто знает ...

Подавляющее количество подобных глюков - от недопонимания. Зато как хорошо звучит: "ГЛЮКИ КОМПИЛЯТОРОВ"
Тем не менее, позволю себе указать на один реальный (я уже писал о нём).
Тулчейн от IAR не важно какой версии.
Глюк содержится в файле \avr\src\lib\eeprom.s90 (предкомпилирован во все библиотеки с еепром больше 256 байт) и заключается в неверной записи в еепром чисел типа long long.
Для исправления глюка надо включить в проект исправленный файл.
Исправить надо содержимое функции __eeput64_16:
заменить в ней ?eeput16 на ?eeput16_64 и ?eeput16_inc на ?eeput16_64_inc.
Как это ни странно, но разработчики от версии к версии вносят изменения только в комментарии.
satellite-plus
?eeget16_64_inc:
ADIW R25:R24,1
?eeget16_64:
RCALL ?eewait
OUT EEARL,R24
//***********************************************
OUT EEARH,R25
SBI EECR,EERE
RET

Является ли глюком загрузка адреса без запрета прерывания? Если в прерывании захочется обратится к EEPROM можно сбить EEARL.
Fortune
Цитата(SasaVitebsk @ Feb 6 2007, 13:12) *
Предыдущие попытки "обвинить" компилятор и уличить его в граблях, заканчивались провалом. (По крайней мере в области языка). Так что не думаю, что данная ветка будет содержать большое колличество постов. Хотя кто знает ...


Почему, программы ведь пишутся людьми(компилятор-тоже не ислключение), а люди ошибаются...
_Bill
Цитата(Fortune @ Feb 6 2007, 13:23) *
Цитата(SasaVitebsk @ Feb 6 2007, 13:12) *

Предыдущие попытки "обвинить" компилятор и уличить его в граблях, заканчивались провалом. (По крайней мере в области языка). Так что не думаю, что данная ветка будет содержать большое колличество постов. Хотя кто знает ...


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

Вот и давайте разбираться с этими "ГЛЮКАМИ". Я думаю, лучше всего в одной ветке. Хотя бы здесь.
Sergio66
Согласен с теми, кто предлагает вынести на широкое бсуждение Т.Н. ГЛЮКОВ компиллятора. И не важно, следствием чего они являются, ошибками разработчиков компиллятора, или недопониманием чего - либо нами самими. Вот к примеру:
http://electronix.ru/forum/index.php?showtopic=26578
я создал этот пост, и сам разобрался в чем дело. Только вот не до конца понял, чей это "косяк".
Так, что, вперед... И с песней...
Меньше будет недопонимания, меньше будет "ГЛЮКОВ".
IgorKossak
Цитата(satellite-plus @ Feb 6 2007, 12:18) *
Является ли глюком загрузка адреса без запрета прерывания? Если в прерывании захочется обратится к EEPROM можно сбить EEARL.

Нет, не является.
Но если существует возможность обращения к еепром (или к любому другому подобному ресурсу) из прерываний (или в других процессах в случае применения RTOS), то обрамление критичного ресурса процедурами сохранения/запрета/восстановления прерываний ложится на пользователя.
Но когда это бывает нужно, то это несложно сделать. Я уже выкладывал исправленный файл в этой ветке.
Fortune
Цитата(_Bill @ Feb 6 2007, 14:28) *
Вот и давайте разбираться с этими "ГЛЮКАМИ". Я думаю, лучше всего в одной ветке. Хотя бы здесь.


Ну давайте. Вот код(нашел все-таки, я тогда не разобрался до конца в чем дело):

void sine()
{
unsigned int x;
unsigned char y;
float a;

for (x=0; x<320; x++)
{
a=(float)x/50;
y=(40*sin(a))+100;
point(x,y,0x0a);
delay(250);
}

}

Это для ЖКИ 320x240.
GDI
Может потому что функция имеет следующее объявление
double sin(double);
А вы ей float скормить пытаетесь...
xinod2000
Цитата(Fortune @ Feb 6 2007, 15:04) *
Цитата(_Bill @ Feb 6 2007, 14:28) *

Вот и давайте разбираться с этими "ГЛЮКАМИ". Я думаю, лучше всего в одной ветке. Хотя бы здесь.


Ну давайте. Вот код(нашел все-таки, я тогда не разобрался до конца в чем дело):

void sine()
{
unsigned int x;
unsigned char y;
float a;

for (x=0; x<320; x++)
{
a=(float)x/50;
y=(40*sin(a))+100;
point(x,y,0x0a);
delay(250);
}

}

Это для ЖКИ 320x240.


А как выглядит сей баг\глюк, в чем проявляется?
Насколько я вижу, то более коректным является

y=(char)((40*sin(a))+100);

а так особого криминала не вижу.
ну и аргументы функции sin()
_Bill
Цитата(xinod2000 @ Feb 6 2007, 14:50) *
Цитата(Fortune @ Feb 6 2007, 15:04) *

Цитата(_Bill @ Feb 6 2007, 14:28) *

Вот и давайте разбираться с этими "ГЛЮКАМИ". Я думаю, лучше всего в одной ветке. Хотя бы здесь.


Ну давайте. Вот код(нашел все-таки, я тогда не разобрался до конца в чем дело):

void sine()
{
unsigned int x;
unsigned char y;
float a;

for (x=0; x<320; x++)
{
a=(float)x/50;
y=(40*sin(a))+100;
point(x,y,0x0a);
delay(250);
}

}

Это для ЖКИ 320x240.


А как выглядит сей баг\глюк, в чем проявляется?
Насколько я вижу, то более коректным является

y=(char)((40*sin(a))+100);

а так особого криминала не вижу.
ну и аргументы функции sin()

Вроде, и так все коррктно. Не нужно только забывать включать соотвествующие заголовочные файлы с прототипами функций.
ahulap
мне кажется, что дело здесь в преобразовании типов - результат sin(a) преобразовывается в char, т.е. всегда 0.
может, попробовать что-то вроде y=(40.0*sin(a))+100 или y=(unsigned char)((float)(40.0*sin(a))+100) ...
_Bill
Цитата(ahulap @ Feb 6 2007, 16:19) *
мне кажется, что дело здесь в преобразовании типов - результат sin(a) преобразовывается в char, т.е. всегда 0.
может, попробовать что-то вроде y=(40.0*sin(a))+100 или y=(unsigned char)((float)(40.0*sin(a))+100) ...

Да правильно там все. То, что Вы предлагаете, совершенно излишне. Хотя это и не делает выражение некорректным, но делает менее читабельным. И вообще, "глюк"-то в чем?
Fortune
Цитата(_Bill @ Feb 6 2007, 17:28) *
... И вообще, "глюк"-то в чем?


Ну началось все с того, что я подключил atmega128 к монитору bg320240 через sed1375 и сделал интерфейс связи с писюком через usart.
так вот, если обсчитываю по приведенной выше программе значение функции
в компьютере - получаю на экране чистый синус,
если пытаюсь обсчитать в контроллере, то выводится мусор, точнее та же синусоида,но грязная, и если выводить ее повторно, через некоторое время синус обрисовывается треугольником, случайные точки тоже имеются.Жаль не могу прислать скриншот, потому что девайс пока у меня не работает - надо монитор доставать.
Ну а разобраться тогда с проблемой у меня не хватило терпения, поэтому и жалуюсь
на компилятор, ибо за собой греха "успеть не нашел".
_Bill
Цитата(Fortune @ Feb 7 2007, 11:50) *
Цитата(_Bill @ Feb 6 2007, 17:28) *

... И вообще, "глюк"-то в чем?


Ну началось все с того, что я подключил atmega128 к монитору bg320240 через sed1375 и сделал интерфейс связи с писюком через usart.
так вот, если обсчитываю по приведенной выше программе значение функции
в компьютере - получаю на экране чистый синус,
если пытаюсь обсчитать в контроллере, то выводится мусор, точнее та же синусоида,но грязная, и если выводить ее повторно, через некоторое время синус обрисовывается треугольником, случайные точки тоже имеются.Жаль не могу прислать скриншот, потому что девайс пока у меня не работает - надо монитор доставать.
Ну а разобраться тогда с проблемой у меня не хватило терпения, поэтому и жалуюсь
на компилятор, ибо за собой греха "успеть не нашел".

А как со временем? Вы же пытаетесь формировать сигнал в реальном времени, а вычисления с плавающей точкой времени требуют.
GDI
delay(250) убрать - вот и будет время
Fortune
Цитата(_Bill @ Feb 7 2007, 14:33) *
А как со временем? Вы же пытаетесь формировать сигнал в реальном времени, а вычисления с плавающей точкой времени требуют.

Что значит "времени требуют"? Немного не понимаю. Я вызвал функцию, она посчитала. Функция ведь не в фоне выполняется.
_Bill
Цитата(Fortune @ Feb 7 2007, 15:19) *
Цитата(_Bill @ Feb 7 2007, 14:33) *

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

Что значит "времени требуют"? Немного не понимаю. Я вызвал функцию, она посчитала. Функция ведь не в фоне выполняется.

Сколько времени занимает вычисление sin для одной точки - 100 мкс, 1 мс, 5 мс?
DimG
Почему никто не обратил внимание на вот это
Цитата(GDI @ Feb 6 2007, 17:30) *
Может потому что функция имеет следующее объявление
double sin(double);
А вы ей float скормить пытаетесь...

тогда полная запись выглядела бы так
y=(unsigned char)((40.0*sin((double)a))+100.0),
а еще лучше переменную объявить сразу как
double a;
Хотя, честно говоря совсем не уверен, что это все это поможет.
Но есть еще функция
Цитата
point(x,y,0x0a);

где ее объявление? Может все дело в ней?
ahulap
запись y=(40*sin(a))+100 верна, я проверил на нескольких числах - точно как в виндовом калькуляторе. IAR 4.11A, "Use 64-bit doubles" не установлена.
может опять переполнение стека?
Fortune
Цитата(_Bill @ Feb 7 2007, 17:01) *
Сколько времени занимает вычисление sin для одной точки - 100 мкс, 1 мс, 5 мс?


На этот вопрос ответить не могу, нет возможности запустить девайс,
но разве это так важно? меня по-моему не должно беспокоить время выполнения.


Цитата(ahulap @ Feb 7 2007, 18:26) *
запись y=(40*sin(a))+100 верна, я проверил на нескольких числах - точно как в виндовом калькуляторе. IAR 4.11A, "Use 64-bit doubles" не установлена.
может опять переполнение стека?


Проверил в проекте, Data stack 0x80 bytes, return address stack 0x80 - это немало, вроде

Ну я вообще к тому, может кто-то использовал IAR и функцию SIN в реальных разработках,
считает или нет?
GDI
Цитата
меня по-моему не должно беспокоить время выполнения.

А зачем тогда delay(250) в цикле стоит? чтоб медленнее работало?
Fortune
[quote name='GDI' post='207730' date='Feb 7 2007, 19:38']
А зачем тогда delay(250) в цикле стоит? чтоб медленнее работало?
[/quote]

Ну я сначала думал, что SED1375 не успевает прорисовывать линию, поэтому вставил delay(250),
но оказалось это не так. delay(250)- всего-навсего пустой цикл.


[quote name='DimG' date='Feb 7 2007, 17:06' post='207619']
Но есть еще функция
point(x,y,0x0a);[/quote]
где ее объявление? Может все дело в ней?
[/quote]

Вряд ли. Потому что прямые линии рисуются этой функцией нормально
GDI
Не плохо было бы посмотреть какие данные получаются на выходе функции sin, до и после преобразования типов float -> char

Я думаю, что все дело в типах и преобразованиях типов, где то происходит либо переполнение, либо потеря точности, а посему предлагаю считать данный случай не глюком компилятора, а глюком программиста, не в обиду будет сказано... Где то в инете был перевод хорошей статьи про компиляторы и про т.н. "глюки" компиляторов...
Fortune
Цитата(GDI @ Feb 8 2007, 16:59) *
... предлагаю считать данный случай не глюком компилятора, а глюком программиста, не в обиду будет сказано...


Не факт, если дойдут руки, я еще раз проверю чей глюк...
Сергей Борщ
Цитата(Fortune @ Feb 8 2007, 15:10) *
Цитата(GDI @ Feb 8 2007, 16:59) *

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


Не факт, если дойдут руки, я еще раз проверю чей глюк...
Просмотрел обсуждение и не нашел упоминания - какой именно компилятор использовался. Он имеет симулятор? Вы можете написать простую программу, заполняющую массив из 36(100, 360) чисел типа float значением sin(i * 2 * M_PI / (sizeof(array)/sizeof(array[0])) и таким образом выяснить виновата функция sin или дальнейшая формула? Если функция не виновата, можно медитировать формулу. если виновата функция - будем "разбирать" ее.
ahulap
Цитата(Fortune @ Feb 7 2007, 10:50) *
если пытаюсь обсчитать в контроллере, то выводится мусор, точнее та же синусоида,но грязная, и если выводить ее повторно, через некоторое время синус обрисовывается треугольником, случайные точки тоже имеются.

Не может эта функция давать разные результаты. А 128 байт стека (если не ошибаюсь) может и не хватить, особенно если есть локальные массивы или обработка внутри прерываний...
kolobok0
Цитата(Fortune @ Feb 6 2007, 11:28) *
...
Предлагаю также сюда кидать описание глюков (багов, граблей) при работе с компиляторами...


не знаю глюк или нет..
но и в симуляторе от атмела, и в самих кристаллах - неправильно трактуются ведущие нули, при инициализации регистров (азм). Не проходила (дай бог памяти) инициализация регистров с ведущими нулями в 10сс.

с уважением
(круглый)
ЗЫ
НЕ проходила - это значит что в регистр заносился бред, а не значение которое грузилось. Да, и ышо... Прогон с выводом на ЖК подтвердил - это результат компиляции...
ЗЫ ЗЫ
Ну про баги у кейла под 51 серию - я не буду тут распространяться. smile.gif
ahulap
Цитата(kolobok0 @ Feb 8 2007, 20:02) *
не знаю глюк или нет..
но и в симуляторе от атмела, и в самих кристаллах - неправильно трактуются ведущие нули, при инициализации регистров (азм). Не проходила (дай бог памяти) инициализация регистров с ведущими нулями в 10сс.

Ведущим нулем обозначается восьмиричная сс. Или не все так просто? smile.gif
DimG
Цитата
Вряд ли. Потому что прямые линии рисуются этой функцией нормально

Какая прямая? Y у нее изменяется?(по крайней мере в пределах диапазона Y для функции с SIN). Если это не так, то это ничего не значит.
Вы бы привели все-таки саму функцию здесь.
Цитата
Ну про баги у кейла под 51 серию - я не буду тут распространяться.

Хотя бы один приведите. Можете даже отдельную ветку создать.
Fortune
Цитата(DimG @ Feb 9 2007, 07:06) *
Цитата
Вряд ли. Потому что прямые линии рисуются этой функцией нормально

Какая прямая? Y у нее изменяется?(по крайней мере в пределах диапазона Y для функции с SIN). Если это не так, то это ничего не значит.
Вы бы привели все-таки саму функцию здесь.
Цитата
Ну про баги у кейла под 51 серию - я не буду тут распространяться.

Хотя бы один приведите. Можете даже отдельную ветку создать.


Y меняется естественно, я рисовал линии с наклоном в 0, pi/2, pi/3, pi/4,pi/6.
Потом создал массив, заполнил массив значениями синусоидальной функции(посчитал в компьютере) и через USART передал в контроллер. С массива синусоида вывелась контроллером нормально. Так что у меня нет повода сомневаться в том, что функция вывода точки работала как надо.

Ну текст то мне привести не сложно, но что вам это даст? Это всего лишь особенности работы с контроллером SED.Мне придется обьяснять как работает этот контроллер,и мы уйдем от темы.
Я попробую на днях ввести данные, посчитанные функцией sine на флеш карту(SD-карту через SPI уже подключил), тогда посмотрим, что к чему.Если синус окажется истинным, значит мне придется признать, что глюк был по моей вине unsure.gif



Цитата(Сергей Борщ @ Feb 8 2007, 18:23) *
Просмотрел обсуждение и не нашел упоминания - какой именно компилятор использовался. Он имеет симулятор? Вы можете написать простую программу, заполняющую массив из 36(100, 360) чисел типа float значением sin(i * 2 * M_PI / (sizeof(array)/sizeof(array[0])) и таким образом выяснить виновата функция sin или дальнейшая формула? Если функция не виновата, можно медитировать формулу. если виновата функция - будем "разбирать" ее.


IAR. Попробуем.
tag
...уже около года юзаю IAR и столкнулся с интересной особенностью (признаться компилятор у меня крякнутый), компилятор не любит глобальные переменные, в коде есть строчки типа:

unsigned int x;

.....

x = y;


...


sprintf(str, "x = %d", x);

...программа зацикливается. Посмотрел lst-ники, появились вопросы, стал играть оптимизацией, когда отменил оптимизацию все заработало.
DimG
Fortune
Вообще-то я просто хотел увидеть, как объявлены в функции
point(x,y,0x0a);
первый и второй параметры. Совпадают ли они с объявлениями x и y.

И действительно, если у вас включена оптимизация, то попробуйте выключить ее.
Вообще, я бы предложил отложить дальнейшее обсуждение до момента, когда устройство будет собрано, а после этого продоложить поиски истины.
ahulap
Функция sine() не имеет параметров, так что должна каждый раз давать один и тот же результат. И если синус считался неправильно, то он бы считался одинаково неправильно каждый раз. А автор пишет, что результаты на экране отличатся. ИМХО дело все же в чем-то другом. Или я не прав?
Fortune
Цитата(DimG @ Feb 9 2007, 12:23) *
Вообще, я бы предложил отложить дальнейшее обсуждение до момента, когда устройство будет собрано, а после этого продоложить поиски истины.


Не возражаю.
Fortune
Изменил программу:

volatile u08 iob[512];
void sine();
...
...
int main( void )
{
...
...
sine();
...
...

void sine()
{
unsigned int x;
unsigned char y;
float a;

for (x=0; x<320; x++)
{
a=(float)x/50;
y=(40*sin(a))+100;
iob[x]=y;
}

}
}

Теперь у меня вообще все виснет при вызове функции sine()
_Bill
Цитата(Fortune @ Feb 9 2007, 12:48) *
Изменил программу:

А контроллер какой?
Fortune
Цитата(_Bill @ Feb 9 2007, 15:07) *
А контроллер какой?


Atmega128
_Bill
Цитата(Fortune @ Feb 9 2007, 15:59) *
Цитата(_Bill @ Feb 9 2007, 15:07) *

А контроллер какой?


Atmega128

Модель памяти, значения стека, версия компилятора?
Fortune
Цитата(_Bill @ Feb 9 2007, 17:07) *
Цитата(Fortune @ Feb 9 2007, 15:59) *

Цитата(_Bill @ Feb 9 2007, 15:07) *

А контроллер какой?


Atmega128

Модель памяти, значения стека, версия компилятора?


Small, 0x80, 0x80 , IAR 4 - крякнутый
Andy Great
Аргумент синуса предполагается в радианах.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.