|
Не могу преобразовать double в строку, Преобразование типов в WinAVR |
|
|
|
Mar 9 2007, 00:55
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 26-02-07
Пользователь №: 25 691

|
Возникла такая проблема: для вывода на индикатор требуется строчная переменная (*char) вида Х.ХХХ, а имеется полученная в результате вычислений переменная типа double (т.е. с плавающей запятой). Как я понял, в компиляторе WinAVR не имеется встроенных средств для преобразования чисел с плавающей запятой в строку. Пожалуйста, дайте ссылку или приведите пример такого преобразования.
|
|
|
|
|
Mar 11 2007, 16:16
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 26-02-07
Пользователь №: 25 691

|
Цитата(vooon @ Mar 9 2007, 00:59)  просмотрите stdlib.h внимательно, я там например нашел ф-цию extern char *dtostrf(double __val, char __width, char __prec, char *__s); Спасибо. Действительно, проглядел)) Однако, при использовании этой функции возникают некоторые проблемы. При создании пустого проекта с подключением <stdlib.h> и использовании функции dtostrf() никаких проблем не возникает. Но при использовании в готовом проекте перестает создаваться файл MyProj.elf, а следовательно и MyProj.hex и появляются ошибки: - окно Build: avr-gcc.exe -mmcu=atmega8 MyProj.o -o MyProj.elf c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/../../../../avr/lib/avr4\libc.a(fixsfsi.o): In function `__fixunssfsi': (.text.fplib+0x0): multiple definition of `__fixsfsi' c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/avr4\libgcc.a(_sf_to_si.o):(.text+0x0): first defined here c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/../../../../avr/lib/avr4\libc.a(fixsfsi.o): In function `__fixunssfsi': (.text.fplib+0x0): multiple definition of `__fixunssfsi' c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/avr4\libgcc.a(_fixunssfsi.o):(.text+0x0): first defined here make: *** [MyProj.elf] Error 1
- окно Message: gcc plug-in: Error: Object file not found on expected location Disk:\path\MyProj\default\MyProj.elf
Наличие этих ошибок связано непосредственно с включением функции dtostrf().
|
|
|
|
|
Mar 13 2007, 00:14
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 26-02-07
Пользователь №: 25 691

|
Цитата(beer_warrior @ Mar 11 2007, 15:23)  Похоже на двойное включение одной и той же библиотеки в процесс линковки. Проверьте makefile и прочие установки проекта. Под студией работаете? Сообщения действительно говорят о множественном обьявлении функций. В стуктуре makefile я не очень разбираюсь, но содержимое файла до и после появления ошибки ничем не отличается. До использования функции dtostrf() никаких проблем не возникало, поэтому я думаю, что с установками все нормально. Использую AVR Studio 4.13 (релиз) + WinAVR за 2007 год. У меня возникло чувство, что я неправильно вызываю функцию. Функция объявлена в файле stdlib.h следующим образом: extern char *dtostrf(double __val, char __width, char __prec, char *__s); Откуда она импортируется, мне не очень понятно. Поэтому вызов я строил следующим образом: dtostrf (MyFloatNumber, 16, 3, MyStringPointer);Если это неправильно, подскажите пожалуйста, как оформить правильно вызов функций, обьявленных как extern.
|
|
|
|
|
Mar 13 2007, 08:17
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Цитата Сообщения действительно говорят о множественном обьявлении функций. Не о множественном объявлении (тогда ругнулось бы со словом declared), а о множественном линковании. Цитата c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/../../../../avr/lib/avr4\libc.a(fixsfsi.o): In function `__fixunssfsi':(.text.fplib+0x0): multiple definition of `__fixsfsi'c:/program files/avr/winavr/bin/../lib/gcc/avr/4.1.1/avr4\libgcc.a(_sf_to_si.o)  .text+0x0): first defined here В первый раз - libc.a, во второй libgcc.a. Тут надо смотреть, как именно подключаются библиотеки. С winavr на такое не нарывался, поэтому в глубину не копал. А вот с MinGW многократно - именно из-за дублирующего использования библиотек. Могу посоветовать скомпилировать просто в командной строке - если получится - искать грабли в мэйкфайле.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Mar 13 2007, 22:35
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 26-02-07
Пользователь №: 25 691

|
Пардон, оговорился, я имел в виду конечно определение.
Makefile используется тот, что автоматически генерит Studio.
Для компиляции в командной строке требуется все равно файл makefile. Созданный оболочкой Studio файл не подходит, а с файлом, созданным с помощью программы MFile от WinAVR, проект не компилится (любой проект, не только этот - проверял) с ошибкой
> "make.exe" all Makefile:531: *** target pattern contains no `%'. Stop.
В самом файле текст
# Create library from object files. .SECONDARY : $(TARGET).a .PRECIOUS : $(OBJ) %.a: $(OBJ) @echo @echo $(MSG_CREATING_LIBRARY) $@ $(AR) $@ $(OBJ)
на который указывает ошибка, на мой взгляд никаких подозрений не вызывает.
Файл makefile, созданный Studio, реально в 10 раз меньше по размеру MFile -овского. Короче, одна беда) Уже и не знаю, чего делать...
|
|
|
|
|
Mar 13 2007, 23:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Ну что тут можно сказать. Оба мэйкфайла к осмотру. А скомпилить можно и без них типа Цитата avr-gcc -c -mmcu=atmega162 -Os -std=c99 main.c -o main.o А потом слинковать. Цитата avr-gcc -mmcu=atmega162 -adhlns=main.o -std=c99 -main.o --output main.elf -lm В ключиках не уверен, вырезал лишнее, мог переборщить, но в любом случае их можно глянуть в доке. И еще - я не зря спросил про студию - в ней путь к либам, может быть указан дважды.Типа в системных установках и установках проекта (Точно не знаю, секс со старыми версиями в корне отбил желание работать с этой связкой)
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Mar 14 2007, 00:10
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Sminder @ Mar 13 2007, 22:35)  Makefile используется тот, что автоматически генерит Studio. Для того чтобы избежать ошибки нужно подлинковать баблиотеку libm.lib. Для этого линкеру нужно добавить ключик -lm, но желательно в конец командной строки. Давайте попробуем обмануть AVRStudio. 1. В директории вашего проекта создайте файл с именем libm.lib, с любым содержимым. 2. В AVRStudio меню Project/Configuration Option/Libraries жмете кнопку 'Add Object' и выбираете файл 'libm.lib'. Open ... Ok итд итп... 3. удалите файл libm.lib. 4. Попробуйте пересобрать проект. Clean, Rebuld All. Для контроля: в makefile должны появиться строки: ## Libraries LIBS = -lm и при создании проекта в командной строке линкера должна быть опция -lm: avr-gcc -mmcu=atmega162 -main.o --output main.elf -lmУ меня сейчас нет WinAVR так что я не могу проверить. Если не заработает пишите будем думать. Анатолий.
|
|
|
|
|
Mar 14 2007, 01:08
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
2 aesok Анатолий, там ИМХО проблема с libc/libgcc. К сожалению слабо представляю как они коррелируют между собой, но libm здесь ИМХО непричем. В этом случае ругнулось бы на undefined function.
Тут два варианта - либо это очередная кривизна winavr2007, либо IDE подсовывает либу линкеру дважды. Исключить второе поможет билд из командной строки. Если при этом линкер заругается опять, то тогда откатыватся на старую версию (2006). Я так понял, вы ей активно пользуетесь, она надежна и очищена от старья?
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Mar 14 2007, 02:31
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(beer_warrior @ Mar 14 2007, 01:08)  2 aesok Анатолий, там ИМХО проблема с libc/libgcc. К сожалению слабо представляю как они коррелируют между собой, но libm здесь ИМХО непричем. В этом случае ругнулось бы на undefined function.
Тут два варианта - либо это очередная кривизна winavr2007, либо IDE подсовывает либу линкеру дважды. Исключить второе поможет билд из командной строки. Если при этом линкер заругается опять, то тогда откатыватся на старую версию (2006). Я так понял, вы ей активно пользуетесь, она надежна и очищена от старья? Дело в том что в GCC две версии библиотеки для чисел с плавающей точкой (я говорю только про сложение, вычитание, ..., сравнение, преобразование типов). Одна находиться в стандартной библиотеке компилятора в libgcc.а. Недостаток этой версии в том что эти функции написаны на C, и имеют большой размер кода и время выполнения. Но GCC должен иметь эти функции в стандартной библиотеке. float - это стандартный 'С' тип, и компилятор должен всегда быть готовым сгенерировать код для умножения двух float переменных. Есть еще один набор тех же самых функций, но написанных на ассемблере, тоесть оптимизированных по скорости и размеру. Эти функции находятся в avr-libc, а физически в библиотеке libm.a. Для того чтобы использовались оптимизированные функции и нужно прилинковать библиотеку libm.a с помощью опции линкера -lm. (кстати в вашем примере этот ключ есть). Код avr-gcc -mmcu=atmega162 -adhlns=main.o -std=c99 -main.o --output main.elf [b]-lm[/b] У Sminder-а возникла следующая проблема: он собирает проект без опции -lm и некоторые модули функцию `__fixsfsi' из libgcc.а. Что эта версия функции не эффективна это только пол проблемы. А основная проблема в том что 'dtostrf' функция из avr-libc и использует `__fixsfsi' из libm.a. Ну и компоновщик не может добавить в проект две функции с одним именем. К сожалению я не понял как в AVRStudio как по-человечески добавить libm, и поэтому предложил такой способ. Анатолий. PS: Мое мнение такое: если у вас меньше 64 кб кода то торопиться переходить на winavr2007 смысла нет.
Сообщение отредактировал aesok - Mar 14 2007, 02:35
|
|
|
|
|
Mar 14 2007, 03:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Цитата У Sminder-а возникла следующая проблема: он собирает проект без опции -lm и некоторые модули функцию `__fixsfsi' из libgcc.а. Что эта версия функции не эффективна это только пол проблемы. А основная проблема в том что 'dtostrf' функция из avr-libc и использует `__fixsfsi' из libm.a. Ну и компоновщик не может добавить в проект две функции с одним именем.К сожалению я не понял как в AVRStudio как по-человечески добавить libm, и поэтому предложил такой способ. Посмотрите внимательно на ошибки - libm там не упоминается. Если бы она отсутствовала, линкер бы ругнулся на ненайденное имя. Вот убрал из мэйкфала -lm: Цитата Linking: main.elf C:/_tools/gcc_avr/bin/avr-gcc -mmcu=atmega162 -I. -gstabs - -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o -std=c99 -MD -MP -MF .dep/main.elf.d main.o --output main.elf -Wl,-Map=main.map,--cref main.o(.text+0x28): In function `main': : undefined reference to `dtostrf' В данном случае имеется дубль. Я очень слабо верю, что в стандартном компиляторе можно иметь одинаковое имя функции, в двух разных либах, которые могут линковаться в один проект. Слишком очевидный баг. Цитата Мое мнение такое: если у вас меньше 64 кб кода то торопиться переходить на winavr2007 смысла нет. Судя по тому, как Йорг и Эрик отбиваются от вопросов на avrfreaks, еще долго не захочется переходить. Я интересуюсь сборкой 2006. (сам работаю под 2005)
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Mar 14 2007, 12:20
|
Участник

Группа: Новичок
Сообщений: 27
Регистрация: 24-02-07
Пользователь №: 25 639

|
На данный момент WinAVR 2007 не пригоден для использования , вот допустим у меня он выдавал постоянно ошибку если в еепром ничего не писать + у него был глюк с размером кода (код всегда был толще байт на 30) , и ко всему были проблемы с компиляцие некоторых сторонних библиотек. Поэтому я вернул WinAVR 2005 , но вскоре сменил его на более новую версию winAVR 2006 - пока доволен , ошибок незамечал.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|