Hello all Following my previous thread where I was surprised to not be able to convert float to string via printf(), i m looking to recompile the newib (1.16.0) to add this functionality. My question is: How do that ... I read the web page suggested by Clifford Slocombe (Thanks to him for all his precious informations) http://venus.billgatliff.com/node/3 This compilation must be done under Linux (or maybe on Windows with the use of Cygwin, but i m not comfortable with it... I installed a OpenSUSE 11)... But i have some problem during the configuration / compilation of newlib 1st : I m looking to regenerate a newlib for Arm (STR912, ARM9) and for Yagarto. In this case, the target used for the configuration is : --target=arm-elf Is it Right ? (I used the following line to configure : damien@linux-8urm:~/NewLibBuild> ../newlib-1.16.0/configure --target=arm-elf --prefix=`pwd`) Now, when i try to compile, i receive (after 3-4 page of script dump) -----------------------------------------8<----------------------------- ------ /bin/sh: arm-elf-cc: command not found make[5]: *** [lib_a-dummy.o] Error 127 make[5]: Leaving directory `/home/damien/NewLibBuild/arm-elf/newlib/libc/argz' make[4]: *** [all-recursive] Error 1 make[4]: Leaving directory `/home/damien/NewLibBuild/arm-elf/newlib/libc' make[3]: *** [all-recursive] Error 1 make[3]: Leaving directory `/home/damien/NewLibBuild/arm-elf/newlib' make[2]: *** [all] Error 2 make[2]: Leaving directory `/home/damien/NewLibBuild/arm-elf/newlib' make[1]: *** [all-target-newlib] Error 2 make[1]: Leaving directory `/home/damien/NewLibBuild' make: *** [all] Error 2 --------------Look attached file for more details------------------------ I m little bit surprised, for 2 reasons : 1) I was fairly sure the GCC version (i mean the linux `default` version) was able to compile for a huge range of target (including ARM)), in this case, why it's necessary to look for another toolchain (arm-elf-*) ? If this toolchain is required, where i could find a binary (I found a arm-elf-gcc binary, but seems not be able to be executed on my x86 station -> maybe an ARM exec)? 2) What is arm-elf-cc, this arm-elf-cc file seems never included in toolchain Thanks in Advance. Regards. Damien
First try to find you if your toolchain's newlib is configured eith float-io disabled. If it is not the problem might be somehwere else and there is no need to rebuild the newlib. > 1) I was fairly sure the GCC version (i mean the linux `default` > version) was able to compile for a huge range of target (including > ARM)), in this case, why it's necessary to look for another toolchain > (arm-elf-*) ? The "default" toolchain should be a "native" (not cross) toolchain to build software for the same system it is running on. So far I have not seen a Linux distribution where a default toolchain package is "multi-target". > If this toolchain is required, where i could find a binary > (I found a arm-elf-gcc binary, but seems not be able to be executed on > my x86 station -> maybe an ARM exec)? It's not very difficult to build a complete toolchain yourself on Linux systems. See for example: - http://openhardware.net/Embedded_ARM/Toolchain/ (remove the newlib-config-option --disable-newlib-io-float to keep floating-point support for printf et al.) - http://www.gnuarm.org/support.html - search for crosstool - IRC there is an instruction to build an ARM toolchain from a user Bingo on avrfreaks.net He has also published instructions to build an AVR toolchain, so take care to get the right instructions. Ready made binaries of an arm-eabi cross-toolchain for Linux hosts is available from codesourcery.com: http://www.codesourcery.com/gnu_toolchains/arm/portal/package2553?@template=release You may search the distribution's package repository for a ready made cross toolchain. Maybe someone already prepared a cross-toolchain. > 2) What is arm-elf-cc, this arm-elf-cc file seems never included in > toolchain arm-elf-cc is not found anyway. Just follow the steps given in the instructions above or use a ready made cross-toolchain.
I have sucessfully compiled newlib on Windows. You do not need Cygwin or Linux to do that. I cannot remember exactly how I did it, but I may have used MinGW's MSYS shell. This is a minimal bash-like shell that is often sufficient to run a configure script. Once the make file was genereated I was able to perform the build from the normal Windows command line. However, in my case I think I did not even to that. I only needed one configuration - for VFP support - and that was not part of the standard build in any case, so I simply took te source and generated a suitable makefile (probably using Dev-C++ to generate the basic make, then modifying it by hand). It is not a complex build. If you run it on Windows, you will ensure that the library is built with the same compiler (Yagarto in your case) you are ultimately going to be using (unless you are so enamoured with Linux you are going to stick with it!). I think perhaps you might have come here first, installing Linux just for that seems somewhat dreastic. And even on Linux, you still need a cross-compiler - its not magic! Bill Gatliff shows you how to do that too: http://venus.billgatliff.com/node/18 All that said, I think you are doing this the (very) hard way. I am not sure why you are rebuilding newlib for floating point support rather than using an existing build that already supports it. As I said previously WinARM's build of Newlib already supports it. Even if you continue to use Yagarto, I am pretty sure that Martin's Newlib build will work with it directly. Also since it is likely that you only need floating point display in a few, why could you not simply implement a float to string function that does just what you need, and then use %s to output it? That would probably end up smaller that burdoning stdio with floating point support - unless you made it as flexible as printf, which you probably don't need. For example: char* ftostr( char* buffer, float value, int places ) { int whole ; int fraction ; char sign[2] = "" ; if( value < 0 ) { value = -value ; sign[0] = '-' ; sign[1] = '\0' ; } whole = (int)value ; fraction = (int)((value - whole) * pow(10.0f,places) + 0.5f) ; sprintf( buffer, "%s%d.%*.*d", sign, whole, places, places, fraction ) ; return buffer ; } Usage example: float as = 80.027f; char buf[23] ; printf( "%s", ftostr( buf, as, 2 ) ) ; diaplays: 80.03 If you application is single threaded, you can make the buffer static to reduce the stack requirement, but you need to make the buffer large enough for all possible values (not a bad idea in any case, the above is by no means 'safe' code. That's 10 digits for each int, plus the decimal, a possible -ve sign, and the nul termionator. E.g: char* ftostr( float value, int places ) { static buffer[23] ; int whole ; int fraction ; char sign[2] = "" ; if( value < 0 ) { value = -value ; sign[0] = '-' ; sign[1] = '\0' ; } whole = (int)value ; fraction = (int)((value - whole) * pow(10.0f,places) + 0.5f) ; sprintf( buffer, "%s%d.%*.*d", sign, whole, places, places, fraction ) ; return buffer ; }
Clifford Slocombe wrote:
> fraction = (int)((value - whole) * pow(10.0f,places) + 0.5f) ;
A minor correction:
fraction = (int)((value - whole) * powf(10.0f,places) + 0.5f) ;
To force the use of the float rather than double version of pow() which
is a little faster. If you use C++ compilatin and include <cmath> it
does not matter since pow() is overloaded for all fp types in any case.
I implemented it for float rather than double because %f was the format
specifier you were using in your original post, and because double
precision manipulation is significantly slower on a 32bit integer
processor than float. Not the use of the f suffix on all the constants
to enforce single procision. You should do that in your own code to
ensure maximum efficiency.
Also even if you are using double precision for calculations, it is
unlikely that you will want to display so many decimal places that you
need it for display, so casting a double to a float when calling this
function may be adequate.
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.