LDFLAGS+=-lm -Wl,-u,vfprintf -lprintf_flt
Since the avr are so tiny on rom and ram the developers made a version without float support
to reduce resources usage when possible.
Best Marcelo.
2011/1/14 Thomas D. Dean
<address@hidden>
I am attempting to compare the uM-FPU and avr-libc floating point times.
I think I am missing something, but, what?
See the code at the bottom.
The code is compiled with:
avr-gcc -Os -mmcu=atmega128 -c -o main.o main.c
avr-gcc -Os -mmcu=atmega128 main.o -o main.elf -lc
avr-objcopy --only-section .text --only-section .data \
--output-target=ihex main.elf main.hex
The output on the sio is:
AVR Floating Point Tests
AVR Floating Point Tests
ssprintf ? 58
Fporta ? 6
Fmul ? 18
Fadd ? 16
Fdiv ? 0
Fsin ? 0
Llint -235875775 0
All the floating point numbers are converted to '?' It appears the
floating point conversion is not done???
If I link with
avr-gcc -Os -mmcu=atmega128 main.o -o main.elf \
-L/usr/lib/avr/lib/avr51 -lc -lm
I get the same code, looking at the output of avr-objdump. It appears
that avr-gcc either uses the intrinsic code or always uses libm.a.
Which?
What am I doing wrong?
tomdean
=== Code =============================================================
// main.c - part of atmega float test
//
// 20110113 tomdean - initial version
// This code is GPL
//
// $Id$
////////////////////////////////////////////////////////
// includes
#include <avr/io.h> // port definitions
#include <math.h> // math functions
#include <string.h> // string functions
#include <avr/interrupt.h> // interrupt
#include <stdio.h> // sprintf
// need two defines before setbaud
#define F_CPU 16000000L
#define BAUD 38400
#include <util/setbaud.h>
////////////////////////////////////////////////////////
// defines
#define TRACE_PORT PORTB
#define TRACE_DDR DDRB
#define TRACE_ON(n) TRACE_PORT |= _BV((n))
#define TRACE_OFF(n) TRACE_PORT &= ~_BV((n))
////////////////////////////////////////////////////////
// globals
uint16_t ovfl;
uint16_t tcnt;
uint16_t tmp;
uint16_t start, delta[10];
uint8_t sio_buf[64];
////////////////////////////////////////////////////////
// serial init
void serial_init() {
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
UCSR0B = _BV(RXEN0) | _BV(TXEN0);
// UCSR0C = _BV(USBS) | _BV(UCSZ1) | _BV(UCSZ0);
return;
}
////////////////////////////////////////////////////////
// counter1 init
void counter1_init() {
TCCR1B = _BV(CS11); // clk/8 = 1/2 usec ticks
TIMSK |= _BV(TOIE1); // counter1 overflow interrupt
return;
}
////////////////////////////////////////////////////////
// counter 1 ISR
ISR(SIG_OVERFLOW1) {
ovfl++;
}
////////////////////////////////////////////////////////
// usec - return the number of usec since we started.
uint32_t usec() {
tcnt = TCNT1;
tmp = ovfl;
return (uint32_t)tcnt + (uint32_t)65536*(uint32_t)tmp;
}
/////////////////////////////////////////////////////////////
// serial_recv
uint8_t serial_recv() {
while (!(UCSR0A & _BV(RXC0)));
/* return the char */
return UDR0;
}
/////////////////////////////////////////////////////////////
// serial_send
void serial_send(uint8_t c) {
while (!(UCSR0A & _BV(UDRE0)));
/* send the char */
UDR0 = c;
return;
}
/////////////////////////////////////////////////////////////
// serial_print
void serial_print(uint8_t *msg) {
while (*msg != 0)
serial_send (*msg++);
return;
}
////////////////////////////////////////////////////////
// initialize
void initialize(void) {
TRACE_DDR = 0xff; // all output
serial_init();
counter1_init();
}
////////////////////////////////////////////////////////
// main
int main() {
float pi, fmul, fadd, fdiv, fsin;
float ftcnt1;
long long ltcnt1, ltcnt2, llint;
char ch;
initialize();
ch = serial_recv();
serial_print("AVR Floating Point Tests\n");
while(1) {
ch = serial_recv();
serial_print("AVR Floating Point Tests\n");
// Start
TRACE_PORT ^= _BV(0);
//
TRACE_ON(1);
start = usec();
ftcnt1 = (float)TCNT1; // sort of like a random number
delta[0] = usec() - start;
TRACE_OFF(1);
TRACE_ON(2);
start = usec();
sprintf(sio_buf,"%f",M_PI);
delta[1] = usec() - start;
TRACE_OFF(2);
TRACE_ON(3);
start = usec();
fmul = ftcnt1 * M_PI;
delta[2] = usec() - start;
TRACE_OFF(3);
TRACE_ON(4);
start = usec();
fadd = fmul + ftcnt1;
delta[3] = usec() - start;
TRACE_OFF(4);
TRACE_ON(5);
start = usec();
fdiv = fmul/fadd;
delta[4] = usec() - start;
TRACE_OFF(5);
TRACE_ON(6);
start = usec();
fsin = sin(fadd);
delta[5] = usec() - start;
TRACE_OFF(6);
ltcnt1 = (long long)TCNT1;
ltcnt2 = (long long)TCNT1;
TRACE_OFF(7);
start = usec();
llint = ltcnt1 * ltcnt2;
delta[6] = usec() - start;
TRACE_OFF(7);
serial_print("sprintf ");
serial_print(sio_buf);
sprintf(sio_buf," %d\n",delta[1]);
serial_print(sio_buf);
sprintf(sio_buf,"Ftcnt1 %f %d\n",ftcnt1, delta[0]);
serial_print(sio_buf);
sprintf(sio_buf,"Fmul %f %d\n",fmul,delta[2]);
serial_print(sio_buf);
sprintf(sio_buf,"Fadd %f %d\n",fadd, delta[3]);
serial_print(sio_buf);
sprintf(sio_buf,"Fdiv %f %d\n",fdiv,delta[4]);
serial_print(sio_buf);
sprintf(sio_buf,"Fsin %f %d\n",fsin,delta[5]);
serial_print(sio_buf);
sprintf(sio_buf,"Llint %ld %d\n",llint,delta[6]);
serial_print(sio_buf);
// reset the clock
ovfl = 0;
}
// never get here ...
return 0;
}
_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
--
[]s,
Marcelo