Полная версия этой страницы:
ГЛЮКИ КОМПИЛЯТОРОВ
Fortune
Feb 6 2007, 11:28
Открыть эту тему меня подтолкнул тот факт, что используя однажды в IARe функцию SIN, я так и не смог добиться нормальной ее работы. Хотя не утверждаю что мой код не содержал ошибок, но все же может кто-то сталкивался с подобными проблемами?
Исходным текстом поделиться не могу, потому что уже затер его.
Предлагаю также сюда кидать описание глюков (багов, граблей) при работе с компиляторами...
SasaVitebsk
Feb 6 2007, 12:12
Предыдущие попытки "обвинить" компилятор и уличить его в граблях, заканчивались провалом. (По крайней мере в области языка). Так что не думаю, что данная ветка будет содержать большое колличество постов. Хотя кто знает ...
IgorKossak
Feb 6 2007, 12:53
Цитата(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
Feb 6 2007, 13:18
?eeget16_64_inc:
ADIW R25:R24,1
?eeget16_64:
RCALL ?eewait
OUT EEARL,R24
//***********************************************
OUT EEARH,R25
SBI EECR,EERE
RET
Является ли глюком загрузка адреса без запрета прерывания? Если в прерывании захочется обратится к EEPROM можно сбить EEARL.
Fortune
Feb 6 2007, 13:23
Цитата(SasaVitebsk @ Feb 6 2007, 13:12)

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

Цитата(SasaVitebsk @ Feb 6 2007, 13:12)

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

Является ли глюком загрузка адреса без запрета прерывания? Если в прерывании захочется обратится к EEPROM можно сбить EEARL.
Нет, не является.
Но если существует возможность обращения к еепром (или к любому другому подобному ресурсу) из прерываний (или в других процессах в случае применения RTOS), то обрамление критичного ресурса процедурами сохранения/запрета/восстановления прерываний ложится на пользователя.
Но когда это бывает нужно, то это несложно сделать. Я уже выкладывал исправленный файл в
этой ветке.
Fortune
Feb 6 2007, 14: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.
Может потому что функция имеет следующее объявление
double sin(double);
А вы ей float скормить пытаетесь...
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()
Цитата(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()
Вроде, и так все коррктно. Не нужно только забывать включать соотвествующие заголовочные файлы с прототипами функций.
мне кажется, что дело здесь в преобразовании типов - результат sin(a) преобразовывается в char, т.е. всегда 0.
может, попробовать что-то вроде y=(40.0*sin(a))+100 или y=(unsigned char)((float)(40.0*sin(a))+100) ...
Цитата(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
Feb 7 2007, 11:50
Цитата(_Bill @ Feb 6 2007, 17:28)

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

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

... И вообще, "глюк"-то в чем?
Ну началось все с того, что я подключил atmega128 к монитору bg320240 через sed1375 и сделал интерфейс связи с писюком через usart.
так вот, если обсчитываю по приведенной выше программе значение функции
в компьютере - получаю на экране чистый синус,
если пытаюсь обсчитать в контроллере, то выводится мусор, точнее та же синусоида,но грязная, и если выводить ее повторно, через некоторое время синус обрисовывается треугольником, случайные точки тоже имеются.Жаль не могу прислать скриншот, потому что девайс пока у меня не работает - надо монитор доставать.
Ну а разобраться тогда с проблемой у меня не хватило терпения, поэтому и жалуюсь
на компилятор, ибо за собой греха "успеть не нашел".
А как со временем? Вы же пытаетесь формировать сигнал в реальном времени, а вычисления с плавающей точкой времени требуют.
delay(250) убрать - вот и будет время
Fortune
Feb 7 2007, 15:19
Цитата(_Bill @ Feb 7 2007, 14:33)

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

Цитата(_Bill @ Feb 7 2007, 14:33)

А как со временем? Вы же пытаетесь формировать сигнал в реальном времени, а вычисления с плавающей точкой времени требуют.
Что значит "времени требуют"? Немного не понимаю. Я вызвал функцию, она посчитала. Функция ведь не в фоне выполняется.
Сколько времени занимает вычисление sin для одной точки - 100 мкс, 1 мс, 5 мс?
Почему никто не обратил внимание на вот это
Цитата(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);
где ее объявление? Может все дело в ней?
запись y=(40*sin(a))+100 верна, я проверил на нескольких числах - точно как в виндовом калькуляторе. IAR 4.11A, "Use 64-bit doubles" не установлена.
может опять переполнение стека?
Fortune
Feb 7 2007, 18:18
Цитата(_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 в реальных разработках,
считает или нет?
Цитата
меня по-моему не должно беспокоить время выполнения.
А зачем тогда delay(250) в цикле стоит? чтоб медленнее работало?
Fortune
Feb 8 2007, 10:16
[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]
Вряд ли. Потому что прямые линии рисуются этой функцией нормально
Не плохо было бы посмотреть какие данные получаются на выходе функции sin, до и после преобразования типов float -> char
Я думаю, что все дело в типах и преобразованиях типов, где то происходит либо переполнение, либо потеря точности, а посему предлагаю считать данный случай не глюком компилятора, а глюком программиста, не в обиду будет сказано... Где то в инете был перевод хорошей статьи про компиляторы и про т.н. "глюки" компиляторов...
Fortune
Feb 8 2007, 16:10
Цитата(GDI @ Feb 8 2007, 16:59)

... предлагаю считать данный случай не глюком компилятора, а глюком программиста, не в обиду будет сказано...
Не факт, если дойдут руки, я еще раз проверю чей глюк...
Сергей Борщ
Feb 8 2007, 17:23
Цитата(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 или дальнейшая формула? Если функция не виновата, можно медитировать формулу. если виновата функция - будем "разбирать" ее.
Цитата(Fortune @ Feb 7 2007, 10:50)

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

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

не знаю глюк или нет..
но и в симуляторе от атмела, и в самих кристаллах - неправильно трактуются ведущие нули, при инициализации регистров (азм). Не проходила (дай бог памяти) инициализация регистров с ведущими нулями в 10сс.
Ведущим нулем обозначается восьмиричная сс. Или не все так просто?
Цитата
Вряд ли. Потому что прямые линии рисуются этой функцией нормально
Какая прямая? Y у нее изменяется?(по крайней мере в пределах диапазона Y для функции с SIN). Если это не так, то это ничего не значит.
Вы бы привели все-таки саму функцию здесь.
Цитата
Ну про баги у кейла под 51 серию - я не буду тут распространяться.
Хотя бы один приведите. Можете даже отдельную ветку создать.
Fortune
Feb 9 2007, 11:05
Цитата(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 уже подключил), тогда посмотрим, что к чему.Если синус окажется истинным, значит мне придется признать, что глюк был по моей вине
Цитата(Сергей Борщ @ Feb 8 2007, 18:23)

Просмотрел обсуждение и не нашел упоминания - какой именно компилятор использовался. Он имеет симулятор? Вы можете написать простую программу, заполняющую массив из 36(100, 360) чисел типа float значением sin(i * 2 * M_PI / (sizeof(array)/sizeof(array[0])) и таким образом выяснить виновата функция sin или дальнейшая формула? Если функция не виновата, можно медитировать формулу. если виновата функция - будем "разбирать" ее.
IAR. Попробуем.
...уже около года юзаю IAR и столкнулся с интересной особенностью (признаться компилятор у меня крякнутый), компилятор не любит глобальные переменные, в коде есть строчки типа:
unsigned int x;
.....
x = y;
...
sprintf(str, "x = %d", x);
...программа зацикливается. Посмотрел lst-ники, появились вопросы, стал играть оптимизацией, когда отменил оптимизацию все заработало.
Fortune
Вообще-то я просто хотел увидеть, как объявлены в функции
point(x,y,0x0a);
первый и второй параметры. Совпадают ли они с объявлениями x и y.
И действительно, если у вас включена оптимизация, то попробуйте выключить ее.
Вообще, я бы предложил отложить дальнейшее обсуждение до момента, когда устройство будет собрано, а после этого продоложить поиски истины.
Функция sine() не имеет параметров, так что должна каждый раз давать один и тот же результат. И если синус считался неправильно, то он бы считался одинаково неправильно каждый раз. А автор пишет, что результаты на экране отличатся. ИМХО дело все же в чем-то другом. Или я не прав?
Fortune
Feb 9 2007, 12:00
Цитата(DimG @ Feb 9 2007, 12:23)

Вообще, я бы предложил отложить дальнейшее обсуждение до момента, когда устройство будет собрано, а после этого продоложить поиски истины.
Не возражаю.
Fortune
Feb 9 2007, 12:48
Изменил программу:
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()
Цитата(Fortune @ Feb 9 2007, 12:48)

Изменил программу:
А контроллер какой?
Fortune
Feb 9 2007, 15:59
Цитата(_Bill @ Feb 9 2007, 15:07)

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

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

А контроллер какой?
Atmega128
Модель памяти, значения стека, версия компилятора?
Fortune
Feb 9 2007, 16:36
Цитата(_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
Feb 9 2007, 18:50
Аргумент синуса предполагается в радианах.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.