PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : stdout Umleitung mit GCC



Janvi
28-10-2009, 15:29
probiere mit einem (hitex) GCC für Cortex M3 die printf Ausgabe auf die serielle Schnittstelle umzulenken. Dazu habe ich einen putchar geschrieben, welcher die serielle anspricht. Wenn ich nun printf ("A") mache, funktioniert das wie erwartet korrekt. Sobalb ein Formatzeichen wie etwa %3d auftaucht wird die Laufzeitbibliothek angesprochen und es kracht mit folgenden Fehlermeldungen:

GnuToolPackageCortex/bin/../arm-hitex-elf/lib/libc.a(lib_a-printf.o) uses hardware FP, whereas .\objects\out.elf uses software FP

was ist ein FP bzw. was ist da zu tun ? Ich bin mir auch nicht sicher, ob ich
ein include stdio.h benötige oder nicht. Mit stdio.h geht gar nichts, ohne bekomme ich natürlich Warnungen:

arm-hitex-elf-gcc.exe -mcpu=cortex-m3 -c -gdwarf-2 -xc -MD -Wall -O0 -mthumb -mno-thumb-interwork -mno-tpcs-frame -fsigned-char -mlittle-endian -I.\ -o .\objects\main.o .\main.c
.\main.c:106: warning: conflicting types for built-in function 'putchar'
.\main.c: In function 'main':
.\main.c:132: warning: implicit declaration of function 'printf'
.\main.c:132: warning: incompatible implicit declaration of built-in function 'printf'

In den Projekteinstellungen kann man auswählen:
use math lib, libc, libgcc sowie "do not link against shared lib"

was bedeutet das bzw. wie ist die korrekte Vorgehensweise ?

jeebee
28-10-2009, 22:26
FP bezieht sich auf die Floating Point Instruktionen, welche bei ARM wahlweise als Software-Emulation oder als "Real" Instruktionen ausgeführt werden können. Offensichtlich muss FP bei allen Teilen des Projekts mit der gleichen Methode realisiert sein.


http://gcc.gnu.org/onlinedocs/gcc/ARM-options.html[/url]"]-mfpu=name
-mfpe=number
-mfp=number
This specifies what floating point hardware (or hardware emulation) is available on the target. Permissible names are: `fpa', `fpe2', `fpe3', `maverick', `vfp', `vfpv3', `vfpv3-d16', `neon', and `neon-fp16'. -mfp and -mfpe are synonyms for -mfpu=`fpe'number, for compatibility with older versions of GCC.

HTH

jeebee

Janvi
29-10-2009, 12:33
Au weia, die Runtime Bibliothek scheint von einem Cortex A8 mit Neon und anderem Zeugs zu sein was es bei Cortex M3 nicht gibt. Habe schon andere Versionen der Lib probiert (BE=Big Eindian) aber mein Teil ist auf Little Eindian eingestellt und Float Hardware gibt es nicht. Der Interwork Fehler scheint von einer ARM7/9/11 Lib zu sein und tritt auf weil es im Cortex nur noch Thumb2 Befehlssätze gibt. Leider sind die Quellen der Libs nicht dabei und es ist mir auch unklar, was in libc, libgcc oder newlib drinnen ist, bzw. auf was man am besten aufsetzt wenn man selber machen will. Vielleicht steige ich auf den GCC Buildt von Codesourcery um denn damit scheint der Rest der Welt auch zu arbeiten ...

panzi
29-10-2009, 22:52
Also eine Ausgabe leitet man anders um. Schließe den Filedescriptor 1 und öffne (nach 1) die serielle Schnittstelle. Siehe:


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

int main() {
if (close(1) != 0) {
perror("close(1)");
return EXIT_FAILURE;
}

int fd = open("/dev/pts/0", O_WRONLY);

if (fd == -1) {
perror("open(\"/dev/pts/0\", O_WRONLY)");
return EXIT_FAILURE;
}

if (fd != 1) {
fprintf(stderr, "wasn't opened as 1 (stdout) but as %d\n", fd);
}

// now all output to stdout is in fact written to /dev/pts/0
printf("this should be on /dev/pts/%d\n", 0);
puts("this as well");
write(1, "and this", 8);
fputc('\n', stdout);

return EXIT_SUCCESS;
}

Hier habe ich das erste virtuelle Terminal statt der Seriellen Schnittstelle geöffnet (ich hab denk ich gar keine mehr, will nicht hinter den PC kriechen, jedenfalls finde ich nix passendes in /dev und ich könnt so das Prog. auch nicht testen, hab nix das den Output der Schnittstelle ließt).

Janvi
30-10-2009, 14:01
Das Linken der Libraries funktioniert jetzt. Neben der Auswahl der korrekten libc und libgcc mit Soft Float und war der zum Compilieren der Anwedung passende Schalter -mfloat-abi=soft bzw. -msoft-float das Zauberwort weil dies bei GCC offensichtlich kein default ist.

@panzi: das Zielsystem ist kein Linux sondern hat gar nichts drauf. GCC wird also als Crosscompiler genutzt und es gibt kein Filesystem weshalb ich gar nicht auf die Idee gekommen im Verzeichnis /dev nach einer passenden tty zu suchen. Im Endeffekt möchte ich eben die formatierte Ausgabe mit printf nutzen und deshalb war Idee dem Compiler ein eigenes putchar unterzuschieben was weis wie auf die (zuvor initialisierte) Schnittstelle (oder LCD Display) ein Zeichen geschrieben wird.

Momentan sieht es so aus, dass printf das selbst geschriebene putchar leider nicht aufruft, sondern stattdessen in der Lib bei _isatty auf einen Software Breakpoint Befehl aufläuft. Woher soll die Lib auch wissen, wie tty auf diesem System angesprochen wird?

Ein anderer Lösungsansatz wäre wohl sprintf um den Speicher dann mit einer ganz anderen selbstgemachten Funktion an die HW rauszuschreiben. Das mit dem übersetzen einer eigenen Lib scheint wohl eine größere Sache. Wenn ich das richtig verstanden habe, enthält libgcc den Teil der Laufzeitbibliothke welcher unbedingt mit der gleichen Version des GCC übersetzt werden muss, während libc auch mit älteren GCC übersetzt sein darf.