This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: Problem with ARM port and pow() function
- From: Fau Marz <faumarz at libero dot it>
- To: newlib at sourceware dot org
- Cc: Nick Clifton <nickc at redhat dot com>
- Date: Tue, 16 Oct 2007 15:37:47 +0200
- Subject: Re: Problem with ARM port and pow() function
- References: <4714A5CB.6050600@redhat.com>
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