| Author |
Message |
|
|
Posted: Nov 08, 2007 - 02:24 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
Ok to start, YES I have setup avrstudio to be linking to libprintf_flt.a (as well as libm.a) And from my understanding, I should not be needing anything to do with fdev_setup_stream because I'm printing to a buffer, then sending that buffer to a serial port.
and YES my serial port works fine with hyperterminal. I have no problems receiving and echoing characters.
My issue is sprintf with a float (or a double) is not working as I expect it to... whenever I hit the enter key in hyperterminal with this cut down example, I get four spaces and a question mark....
also, sprintf seems to be needing to be calles with a double, rather than a float (if I call it with just a float, it warns me, but I change my datatype to double and it is happy to compile with no warnings...
I guess I'm doing something wrong, but I'm totally stumped here. can anyone help me out, please?
I guess I don't *have* to use a float, and I haven't ever bothered before, but I'm trying to use one here because it makes sense to me for what I'm doing, It *should* be faster to implement just using a float for what I want to do, and well, I want to learn.
(note - if anyone wants to test this, I'm using the pfleurry uart.c and uart.h files)
Code:
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include "uart.h"
// define CPU frequency in Mhz here
#ifndef F_CPU
#define F_CPU 14745600UL
#endif
int main(void)
{
uint8_t uart_baud = 2;
const uint16_t baud_divisor[6] = {383,191,95,47,23,15}; // from ATmega64 datasheet!
double num = 0.0;
unsigned int c;
char character;
char message[48];
uart_init( baud_divisor[uart_baud] );
sei(); //enable interrupts
for(;;)
{
c = uart_getc();
if ( c & UART_NO_DATA )
{
}
else //we have RS232 input
{
if ( c & UART_FRAME_ERROR )
{
uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
uart_puts_P("Buffer overflow error: ");
}
character = (unsigned int)c;
//look for "newline"
if (character == '\r')
{
num = 93.21;
sprintf(message, "%5.2f\r\n", num);
uart_puts(message);
}
} //else (we have rs232 input)
} // for(;;)
}
|
|
|
| |
|
|
|
|
|
Posted: Nov 08, 2007 - 03:06 AM |
|


Joined: Jan 03, 2004
Posts: 1637
Location: Apalachin, NY, USA
|
|
| See the WINAVR avr-libc documentation. From the Library Refernce for <stdio.h>:
Quote:
Since the full implementation of all the mentioned features becomes fairly large, three different flavours of vfprintf() can be selected using linker options. The default vfprintf() implements all the mentioned functionality except floating point conversions. A minimized version of vfprintf() is available that only implements the very basic integer and string conversion facilities, but none of the additional options that can be specified using conversion flags (these flags are parsed correctly from the format specification, but then simply ignored). This version can be requested using the following compiler options:
-Wl,-u,vfprintf -lprintf_min
If the full functionality including the floating point conversions is required, the following options should be used:
-Wl,-u,vfprintf -lprintf_flt -lm
Don |
|
|
| |
|
|
|
|
|
Posted: Nov 08, 2007 - 03:23 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
I'm already linking libprintf_flt.a and libm.a
But can you please tell me what -Wl,-u,vfprintf is for? and where do I put it? just chucking that into the LIBS string in my (avrstudio created) makefile only manages to break compilation. |
|
|
| |
|
|
|
|
|
Posted: Nov 08, 2007 - 03:43 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
Ok, right.....
so I put in that argument in exactly as written, and it works.
Still NO IDEA what the hell -Wl,-u,vfprintf is actually for... but I know that it has to be directly in front of -lprintf_flt, to work....
similarly, having -Wl,-u,vfscanf right before linking libfscanf_flt.a works too.
My next question is why do I need this great big -Wl,-u,vfprintf thing in front of my plain old linkage to what was (I thought!) the library I needed? and how do I get avrstudio to do this automatically when I tell it I want to link the floating point printf and scanf library? |
|
|
| |
|
|
|
|
|
Posted: Nov 08, 2007 - 09:53 AM |
|

Joined: Feb 12, 2005
Posts: 16324
Location: Wormshill, England
|
|
|
JulianHigginson wrote:
Ok, right.....
Still NO IDEA what the hell -Wl,-u,vfprintf is actually for... but I know that it has to be directly in front of -lprintf_flt, to work....
Just follow the instructions. it is a linking thing. When you have several different versions of a named function.
In AvrStudio right-click on the project, select Configure, select the "libraries" button. Add your required libraries.
David. |
|
|
| |
|
|
|
|
|
Posted: Nov 08, 2007 - 10:10 AM |
|


Joined: Dec 20, 2002
Posts: 7277
Location: Dresden, Germany
|
|
> Still NO IDEA what the hell -Wl,-u,vfprintf is actually for...
You could read about it in the linker documentation...
Anyway, it's simple. The linker resolves undefined references out of
the libraries specified. By the time it processes your
libprintf_flt.a library, there is an undefined reference to the symbol
printf, but that library *only* defines vfprintf. As this symbol
doesn't help resolving anything, the library is effectively skipped.
Later on, the standard library (libc.a) is processed, and it
eventually will resolve the symbol printf. This will, in turn, cause
a new undefined reference, now to vfprintf. But oh well!, your old
libprintf_flt.a has already been completely forgotten about now, so
vfprintf will also be resolved from libc.a, thus using the default
implementation.
The -uvfprintf causes the linker to start right from the beginning
with an undefined reference to vfprintf (artificially forced from the
command-line), so this reference will then be resolved from
libprintf_flt.a. When the standard library is then used to resolve
printf, this will reference a symbol vfprintf that is now already
known. |
_________________ Jörg Wunsch
Please don't send me PMs, use email if you want to approach me personally.
Please read the `General information...' article before.
|
| |
|
|
|
|
|
Posted: Nov 09, 2007 - 02:30 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
thankyou, Jörg! It makes a bit more sense now. I can just follow instructions for How to make something work, but it's nice to have a bit more of an understanding as to why they need to be done.
I guess I was a bit frustrated, as I just wanted this (what I thought should be) trivial thing to work, so I could get on with the task of actually writing my code to do what I wanted to do. It seemed a bit confusing to have to do this for the printf and scanf floating point stuff, when floating point maths from libm.a works perfectly well just linked into the linker with -lm.
Anyway - all is good, and I'm very happy with how float reading and writing is working now. thankyou!
 |
|
|
| |
|
|
|
|
|
Posted: Nov 18, 2008 - 05:29 AM |
|

Joined: Feb 20, 2008
Posts: 41
|
|
so how do you add the -WL,-u,vfprint in studio 4?
Do you just type this in the "ADD" box under custom options?
when I look at the makefile after doing this, I find "-WL,-u,vfprint" in the CF flags (common), but it doesn't attach it directly in front of -lprint_flt -lm under "LIBS=" and it doesn't look like it's supposed too. Here is the makefile it generated. I ,too am getting a 63/"?" from my sprintf call.
###############################################################################
# Makefile for the project ADCdisplINTfloat
###############################################################################
## General Flags
PROJECT = ADCdisplINTfloat
MCU = atmega128
TARGET = ADCdisplINTfloat.elf
CC = avr-gcc.exe
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -Wl,-u,vfprint -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=ADCdisplINTfloat.map
## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
## Libraries
LIBS = -lprintf_flt -lm
## Objects that must be built in order to link
OBJECTS = MainADCdispINTfloat.o ADC_float.o LCD_float.o
## Objects explicitly added by the user
LINKONLYOBJECTS =
## Build
all: $(TARGET) ADCdisplINTfloat.hex ADCdisplINTfloat.eep ADCdisplINTfloat.lss size
## Compile
MainADCdispINTfloat.o: ../MainADCdispINTfloat.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
ADC_float.o: ../ADC_float.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
LCD_float.o: ../LCD_float.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
%.eep: $(TARGET)
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: ${TARGET}
@echo
@avr-size -C --mcu=${MCU} ${TARGET}
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) ADCdisplINTfloat.elf dep/* ADCdisplINTfloat.hex ADCdisplINTfloat.eep ADCdisplINTfloat.lss ADCdisplINTfloat.map
## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) |
|
|
| |
|
|
|
|
|
Posted: Apr 09, 2009 - 04:10 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
hmm... sorry - a bit of a slow reply.... I missed the question when it was posted.
Anyway - for completeness of the thread if anyone finds it later, here's the answer...
from memory of what I could work out, there is NO way to do this in avrstudio...
Code:
## Libraries
LIBS = -lprintf_flt -lm
##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
really, you need these extra directives in the LIBS string, because it's a libs directive.... but avrstudio won't put anything you want in the LIBS string, just the library links themselves.
I tried looking about in the custom options section of the project setup, there's a section there for linker commands.... but this goes in the LDFLAGS string, and putting these LIBS directives in there stops the linking.
I also tried doing a bit of a hack, seeing if I could sneak the directives into the LIBDIRS string (done by putting the directives in the directory pane in the libs section of setup) but that didn't work at all - ended up getting absolute directory paths appended to them...
the only working solution I've found is generate the makefile, and then edit the LIBS string to the suggested setting from the avr-libc manual, if you need to printf or scanf with floats.
so in effect even though AVRstudio provides you with access to the floating point savvy libraries as a linking option, if you don't go in and manually fix up your compile options with a makefile, these libraries get thrown away at linking time because it doesn't generate the directives needed to use the functions in the library... |
|
|
| |
|
|
|
|
|
Posted: Apr 09, 2009 - 04:13 AM |
|

Joined: Aug 16, 2005
Posts: 330
|
|
oh.... and also, as has been shown in all the replies - it turned out this is an avrstudio issue, not winavr... so this topic is really in the wrong forum.
 |
|
|
| |
|
|
|
|
|
Posted: Apr 09, 2009 - 04:18 AM |
|

Joined: Feb 20, 2008
Posts: 41
|
|
| ahh! i'm a newb so it's good to know it wasn't all my infinite newbness....thanks for answering the question though!! |
|
|
| |
|
|
|
|
|
Posted: Jul 16, 2009 - 07:41 PM |
|

Joined: Jun 11, 2005
Posts: 44
|
|
It's actually not hard to get this working in avrstudio.
1. Go to Libraries in project config and add libprintf_flt.a
2. Now add libm.a so it appears below libprintf_flt.a.
3. Go to custom options and firstly check that -lprintf_flt is abowe -lm, if not sort em out.
4. Now select linker options and add -uvfprintf (not with commas and such as others want you to.)
Compile and verify the printf response. |
|
|
| |
|
|
|
|
|
Posted: Sep 11, 2009 - 12:19 PM |
|

Joined: Aug 19, 2009
Posts: 16
|
|
Hello, I tryed to display the value that I was measuring from an variable resistance on my lcd.
I use the folowing code:
Code:
int main(){
double i;
lcd_init(LCD_DISP_ON_CURSOR_BLINK);
lcd_clrscr();
lcd_puts("<__>");
_delay_ms(2000);
ADMUX |= (1<<REFS0);
ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADFR);
while(1){
lcd_clrscr();
i = (ADC*5)/1024;
sprintf(a,"%.12f",i);
/* x = i;
itoa(x, a, 10);
j = (i-x)*10000;
x = j;
itoa(x, b, 10);
//lcd_puts(b);
//_delay_ms(1000);
//lcd_puts(b);
strcat(a, ".");
strcat(a, b);*/
lcd_puts(a);
_delay_ms(1000);
}
return 1;
}
ex: 4.0000000000.
On my display appears diggits, but with no zecimal. Why? |
|
|
| |
|
|
|
|
|
Posted: Sep 22, 2009 - 01:53 PM |
|

Joined: Aug 17, 2005
Posts: 1
|
|
|
KreAture wrote:
It's actually not hard to get this working in avrstudio.
1. Go to Libraries in project config and add libprintf_flt.a
2. Now add libm.a so it appears below libprintf_flt.a.
3. Go to custom options and firstly check that -lprintf_flt is abowe -lm, if not sort em out.
4. Now select linker options and add -uvfprintf (not with commas and such as others want you to.)
Compile and verify the printf response.
OMG, thankyou
It just took me over an hour and a half to find out i had the linker options in the wrong order !!! This is up there with the time i typed a "\" instead of a "/" and took me 2 hours of debugging to figure it out. |
|
|
| |
|
|
|
|
|
Posted: Nov 06, 2009 - 03:33 AM |
|


Joined: Nov 10, 2008
Posts: 13
|
|
|
KreAture wrote:
It's actually not hard to get this working in avrstudio.
1. Go to Libraries in project config and add libprintf_flt.a
2. Now add libm.a so it appears below libprintf_flt.a.
3. Go to custom options and firstly check that -lprintf_flt is abowe -lm, if not sort em out.
4. Now select linker options and add -uvfprintf (not with commas and such as others want you to.)
Compile and verify the printf response.
I'm trying to get sprintf working on my box but I'm just using command line make file. It compiles but only shows a 0.0000 for my doubles.
Not sure how to add the libm.a and libprintf_flt.a to the make file. Any help on this? |
|
|
| |
|
|
|
|
|
Posted: Nov 06, 2009 - 06:28 AM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
|
Quote:
Not sure how to add the libm.a and libprintf_flt.a to the make file. Any help on this?
Locate the Mfile utility (comes with WinAVR for Windows users, locatable on the net for non-Windows users). Mfile template makefile has all those goodies, and alot more, for you.
Or locate the post by Don Blake above, where he gives the correct options to the linker.
Or read this: You need to have this
Code:
-Wl,-u,vfprintf -lprintf_flt -lm
in your linker rule in the makefile. |
|
|
| |
|
|
|
|
|
Posted: Nov 06, 2009 - 07:44 AM |
|


Joined: Nov 10, 2008
Posts: 13
|
|
| ok, thats what I had. but it wasn't working out for me. I got it working now though. My make file was overly complicated and was doing some weird things. After I simplified it I got it to work. Thanks! |
|
|
| |
|
|
|
|
|
Posted: Jun 22, 2012 - 09:26 PM |
|

Joined: Jan 16, 2007
Posts: 124
|
|
Hi all,
Can't seem to get sprintf to work in Atmel Studio 6
I have tried the linker options and still do not get a proper response. I tried the same code in an old version of AVR Studio 4 on my system building using the same WinAVR version as my Studio 6 project and I cannot get identical results. The studio 4 version works and the studio 6 version does not.
Here are my linker flags from my makefile:
Quote:
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(SCANF_LIB) $(MATH_LIB)
LFFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm
Here is the code I am running
Code:
char buf[20];
double voltage = 3.14;
sprintf(buf, "5.2f", voltage);
bt_usb_txPacket[3] = buf[1]; // Should be 3
bt_usb_txPacket[4] = buf[3]; // Should be 1
bt_usb_txPacket[5] = buf[4]; // Should be 4
By the way there is a percent in from of the 5.2 in the above code but it will not let me post with the percent in the text
Any help would be very appreciated.
Thank you! |
|
|
| |
|
|
|
|
|
Posted: Jun 23, 2012 - 12:03 AM |
|


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA
|
|
I matched your linker settings* in AS6 with a small test program and it worked correctly. Export your project, if it's not proprietary, and post it here. We can take a look at it and try to help you with the problem.
This is an old thread that you posted in. It might have been better to start a new thread for this. Perhaps a nice Moderator will split this off.
* except the patsubst line, it generated an error, some thing about not being able to parse bla bla, and I had to exit AS6 without saving. I will look into this as a separate bug/feature? |
_________________ Larry
Those afraid to embrace the future will quickly fade into the past. - larryvc
|
| |
|
|
|
|
|
Posted: Jun 23, 2012 - 10:10 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Here are my linker flags from my makefile:
How have you confirmed that this is actually the Makefile being used? |
_________________
|
| |
|
|
|
|
|
Posted: Jun 23, 2012 - 10:15 AM |
|


Joined: Jul 23, 2001
Posts: 2439
Location: Osnabrueck, Germany
|
|
|
Code:
LDFLAGS += ...
LFFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm
^
???
|
_________________ Stefan Ernst
|
| |
|
|
|
|
|
Posted: Jun 23, 2012 - 05:08 PM |
|

Joined: Jan 16, 2007
Posts: 124
|
|
Thanks Stefan! That was the problem. I must have looked at that line for hours and not seen it. Must be working too hard lol
Thanks for the help!
Hope you all have a nice weekend! |
|
|
| |
|
|
|
|
|