This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with ARM port and pow() function


Alle 13:51, martedì 16 ottobre 2007, Nick Clifton ha scritto:

> Please could you supply a full test case that reproduces the problem ?  

Thank you for your answare!

First of all I must say that I'm not sure this is a newlib problem... maybe 
it's my fault in setting the compilation/linking files. Or something else.

So, thank you again for considering me.

I'm finding this problem in two projects: one is the LPC2106 FREErtos port, in 
which I add a pow() function in order to verify how much time it takes. But 
this is a complex project.
After finding the problem with this complex project, I'm trying the pow() 
function in a more simple project, that simply blinks a development board 
LED.
This is a single-file project (ledswitch.c) that initialize the hardware and 
blinks a LED when you push a button. It is the "simple template project" 
given toghether with the development board I have.

Here is the ledswitch.c file source:

-----------------------------------------------------------------------
#include <math.h>
#include "lpc210x_gnuarm.h"

// olimex LPC-P2106: one led on P0.7 (active low)
#define LEDPIN  7
// olimex LPC-P2106: one switch on P0.15 (active low)
#define SWPIN   15

/* Type definitions. */
#define portCHAR        char
#define portFLOAT       float
#define portDOUBLE      double
#define portLONG        long
#define portSHORT       short
#define portSTACK_TYPE  unsigned portLONG
#define portBASE_TYPE   portLONG


/*##############################################################################
## Memory Accelerator Module (MAM)
##############################################################################*/

#define MAM_TIM         (*(REG32 (0xE01FC004)))
#define MAM_CR          (*(REG32 (0xE01FC000)))

/* Constants to setup the PLL. */
#define mainPLL_MUL_4       ( ( unsigned portCHAR ) 0x0003 )
#define mainPLL_DIV_1       ( ( unsigned portCHAR ) 0x0000 )
#define mainPLL_ENABLE      ( ( unsigned portCHAR ) 0x0001 )
#define mainPLL_CONNECT     ( ( unsigned portCHAR ) 0x0003 )
#define mainPLL_FEED_BYTE1  ( ( unsigned portCHAR ) 0xaa )
#define mainPLL_FEED_BYTE2  ( ( unsigned portCHAR ) 0x55 )
#define mainPLL_LOCK        ( ( unsigned portLONG ) 0x0400 )

/* Constants to setup the MAM. */
#define mainMAM_TIM_3       ( ( unsigned portCHAR ) 0x03 )
#define mainMAM_MODE_FULL   ( ( unsigned portCHAR ) 0x02 )

/* Constants to setup the peripheral bus. */
#define mainBUS_CLK_FULL    ( ( unsigned portCHAR ) 0x01 )


static void ledInit(void)
{
    GPIO_IODIR |= (1<<LEDPIN);	// define LED-Pin as output
    GPIO_IODIR &= ~(1<<SWPIN);	// define Switch-Pin as input
    GPIO_IOSET = (1<<LEDPIN);	// set Bit = LED off (active low)
}

static void delay(void)
{
    volatile int i;
    double Pset_calc, K, Fcol_Set, To, Alpha, Pamb;

    K = Fcol_Set = 2.2;

    Alpha = 1666.0;
    To = 2500.0;
    Pamb = 500.0;

    for (i=0;i<10;i++) {
        Alpha = pow((To/100.0), 2.1);
        Pset_calc = 100*sqrt((K*Fcol_Set*Alpha))-(Pamb/100.0);
    }
}


int main(void)
{
    int i;

    // MAM functions fully enabled
    MAM_MAMCR = 0;
    MAM_MAMTIM = 3;
    MAM_MAMCR = 2;

    ledInit();

    i=0;
    while (i<10)
    {
        GPIO_IOCLR=(1<<LEDPIN);	// set all outputs in mask to 0 -> LED on
        delay();
        GPIO_IOSET=(1<<LEDPIN);	// set all outputs in mask to 1 -> LED off
        delay();
        i++;
    }

    while (1)
    {
        if (GPIO_IOPIN & (1<<SWPIN)) // true if button released (active low)
        {
            GPIO_IOCLR=(1<<LEDPIN);  // clear I/O bit -> LED on (active low)
        }
        else
        {
            i=0;
            while (i<10)
            {
                // set all outputs in mask to 0 -> LED on
                GPIO_IOCLR=(1<<LEDPIN);
                delay();
                // set all outputs in mask to 1 -> LED off
                GPIO_IOSET=(1<<LEDPIN);
                delay();
                i++;
            }
        }
    }

    return 0;
}
-----------------------------------------------------------------------

There is also an assembler file for the vector initializaton. If you want I 
can post it, too.
Or if you need the .ld linker script, I can email you.


> Please include the command line(s) you use to compile the test case, and, 

I've tried with the makefile of the template project, which is long and 
complex:
arm-none-eabi-gcc -mthumb -mcpu=arm7tdmi-s -mthumb-interwork -I. -gdwarf-2 -DROM_RUN 
-D NO_MATH_INLINES -D GCC_ARM7 -D__WinARM__  
-O2 -Wall -Wcast-align -Wimplicit  -Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=build/crt0.lst 
-fomit-frame-pointer -mcpu=arm7tdmi-s -msoft-float -march=armv4t -Wcast-qual -MD -MP -MF .dep/ledswitch.elf.d 
build/crt0.o   ledswitch.o --output 
ledswitch.elf -nostartfiles -Wl,-Map=ledswitch.map,--cref -lc -lm -lc -lgcc -T./build/LPC2106-ROM.ld

These options were mostly found in a template project given with the LPC2106 
development board.

But I tried to compile also with only:
arm-none-eabi-gcc -march=armv4t 
ledswitch.c -lm -T./build/LPC2106-ROM.ld build/crt0.o --output ledswitch.elf

and also with some other flags, but the result does not change: with the pow() 
function hangs, without it it works.

I have to say that I don't know if the math results are correct when not using 
the pow() function; for now I only know that it does not hang. I will check  
the results today.


> this is very important, please tell us exactly which toolchain you are using 
> to compile the test case (including how it was configured) and how you are 
> running the test  

I tried the CodeSourcery arm-none-eabi toolchain, configured with:
--------------------------------------
arm-none-eabi-gcc -v
Using built-in specs.
Target: arm-none-eabi
Configured 
with: /scratch/paul/lite-eabi/src/gcc-4.2/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libgomp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --disable-shared --with-newlib --with-pkgversion=CodeSourcery 
Sourcery G++ Lite 
2007q3-53 --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-none-eabi --with-build-sysroot=/scratch/paul/lite-eabi/install/arm-none-eabi --enable-poison-system-directories --with-build-time-tools=/scratch/paul/lite-eabi/install/arm-none-eabi/bin --with-build-time-tools=/scratch/paul/lite-eabi/install/arm-none-eabi/bin
Thread model: single
gcc version 4.2.1 (CodeSourcery Sourcery G++ Lite 2007q3-53)
--------------------------------------

I tried the Ronetix (www.ronetix.at) arm-elf toolchain, but now I dont' have 
it installed so I can't say the configuration. I will re-install it, if you 
need.

Then I tried to compile my own arm-elf toolchain with the following 
configuration:
---------------------------------------------------------------
BINUTILS 2.17
configure --target=arm-elf --prefix=/usr/cross/arm-elf --enable-interwork --enable-multilib --with-float=soft
make all install

GCC 4.2.0
configure --target=arm-elf --prefix=/usr/cross/arm-elf --enable-interwork --enable-multilib --with-float=soft --enable-languages="c,c++" --with-newlib --with-headers=/root/GNU_ARM_Toolchain_420/newlib-1.15.0/newlib/libc/include
make all-gcc install-gcc

NEWLIB 1.15.0
configure --target=arm-elf --prefix=/usr/cross/arm-elf --enable-interwork --enable-multilib --with-float=soft
make all install

back in gcc and run "make all install"

INSIGHT 6.6
configure --target=arm-elf --prefix=/usr/cross/arm-elf --enable-interwork --enable-multilib --with-float=soft
make all install
---------------------------------------------------------------


> case.  (Are you running it on hardware or under a simulator ?)

Hardware: the Olimex P2106-B development board. I can upload the hex file with 
a jtag USB adapter (Amontec) and OpenOCD, or using the LPC2106 serial port 
bootloader.

If you need a simpler test case or something different I can build one for 
you: only tell me to do it and I will do all I can to help finding the 
solution.


Thank you again,

Fausto


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]