avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Avr-libc Floating Point Problem


From: Thomas D. Dean
Subject: [avr-gcc-list] Avr-libc Floating Point Problem
Date: Fri, 14 Jan 2011 14:29:18 -0800

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;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]