Forum: Compiler & IDEs GCC, Keil und ARM, WINXP


von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Hallo Leutz,

hab mal wieder ein Problemchen. Bei meinem LPC2378 habe ich mit Bsp. 
Progs angefangen und ganz einfache Sachen mal selbst ausprobiert, wie 
Eingänge ansteuern. Mit dem eingebauten KEIL Compiler funktioniert das 
auch reibungslos. Ich würde aber gern die GNU-Arm Collection verwenden. 
Leider gibt es da beim kompilieren mehrere Fehler. Diese beziehen sich 
jeweils auf die Startupdatei und die Bibliothek für die Hardware. Bei 
der IDE von KEIL ist beides, angeblich für GNU, enthalten, gibt aber wie 
gesagt Fehler. Gibt diese Dateien evtl. irgendwo als Download? Mir würde 
auch ne Seite helfen wo die einzelnen Befehle erklärt sind, so dass ich 
die vorhandenen modifizieren kann. Bzw. wäre es interessant, was die 
Startup genau macht. Würde es vielleicht reichen die "originale" von 
Keil zu nehmen und nur die Kommentare in "@" umzuwandeln?
Aber vielleicht kann mir auch jemand diesen Code erklären, bzw. wo der 
Fehler liegt. Bin leider mit Assembler noch weniger vertraut als in C.
1
.equ Stack_Size,        (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
Fehler zeigt er folgende:
1
..\gnu\lpc2378_demo1\Common\src\Startup.S: Assembler messages:
2
..\gnu\lpc2378_demo1\Common\src\Startup.S(75): error: bad expression
3
..\gnu\lpc2378_demo1\Common\src\Startup.S(75): error: missing ')'
4
..\gnu\lpc2378_demo1\Common\src\Startup.S(75): error: junk at end of line, first unrecognized character is `F'
Ab FIQ kann er also nicht mehr lesen, oder verstehen... Was soll dieses 
"+ \" eigentlich bedeutet, oder ist das ein falsch umgewandelter 
Zeilentrenner? Der Code nach dem \ war vorher auf der nächsten Zeile.
Das würde zumnidest die Fehler erklären.
Wenn ich den \ weg nehme, dann kommt dieser Fehler nicht mehr, dafür 
aber folgende:
1
/cygdrive/c/Programme/GNUARM/Bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ld: ERROR: .\startup.o uses hardware FP, whereas test.elf uses software FP
2
/cygdrive/c/Programme/GNUARM/Bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ld: failed to merge target specific data of file .\startup.o
Steht FP für Floatpoint?
Weiterhin:
1
.\startup.o: In function `SWI_Handler':
2
..\gnu\lpc2378_demo1\Common\src/Startup.S(142): error: undefined reference to `SoftwareInterrupt'
3
.\startup.o: In function `IRQ_Handler':
4
..\gnu\lpc2378_demo1\Common\src/Startup.S(305): error: undefined reference to `TargetResetInit'
Die Codezeilen dazu sind:
1
SWI_Handler:     B       SoftwareInterrupt  @ see swi_handler.S
und
1
            ldmia       sp!, {pc}^
Die Startup Datei scheint von Martin Thomas für GNU angepasst worden zu 
sein. Das wundert mich auch, da er ja, glaub ich, der Mann hinter WInarm 
ist, oder? Also vermutlich Ahnung hat.
Naja, genug erst mal ich hoffe ihr könnt mir Hinweise, Links, etc. zum 
Problem geben.
Soweit schon mal danke, bis bald,

Hendi

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Was soll dieses "+ \" eigentlich bedeutet,
> oder ist das ein falsch umgewandelter
> Zeilentrenner? Der Code nach dem \ war vorher auf der nächsten Zeile.
> Das würde zumnidest die Fehler erklären.

Genau so ist es. \ am Ende einer Zeile ist ein sogenannter "continuation 
character". Wenn Du mehrere Zeilen zusammenfasst, musst Du dies 
entfernen.
Also:
1
.equ Stack_Size, (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)

Schau mal in die Syntax Deines Assemblers - muss nach dem Label von .equ 
ein Komma angegeben werden?

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Ok, hab den Slash nun herausgenommen, jetzt treten halt besagte andere 
Fehler auf.
Als vorher die Zeilen getrennt waren hat es aber mit Slash auch nicht 
funktioniert, warum nicht? Welchen Assembler benutzt denn Winarm? Ist 
das nicht auch der der GNU Tollchain, oder wurden da Änderungen 
vorgenommen?

von mthomas (Gast)


Lesenswert?

> Würde es vielleicht reichen die "originale" von Keil zu nehmen und nur die
> Kommentare in "@" umzuwandeln?
Nein, neben dem Kommentarzeichen sind z.B. sind diverse andere Dinge 
unterschiedlich (z.B. besagtes equ und auch section-defintionen)

>Steht FP für Floatpoint?
Ja. Sieht so aus, also würde der Compiler nicht mit den richtigen 
Parametern aufgerufen. Habe GNUARM mit Keil uVision aber nie 
ausprobiert.
Mein WinARM-Sammlung kann man in uVision einbinden: 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/winarmtests/WinARM_uVision_glue_20070510.zip
Habe es aber nur oberflächlich mit der uVision Evaluierungsversion 
getestet.

>Weiterhin:
>.\startup.o: In function `SWI_Handler':
...
Die Funktionen Softwareinterrupt und TargetResetInit sind in anderen 
Quellcodedateien implementiert, diese muss man ebenfalls 
compilieren/assemblieren und linken.

>Als vorher die Zeilen getrennt waren hat es aber mit Slash auch nicht
>funktioniert, warum nicht?
"Zeilenverlängerung" stellt meines Wissens bei der GNU-Toolhchain der 
Preprocessor um. Der Realview Assembler kann das wohl von sich aus. Ruft 
man den GNU Assembler über das Compiler-Frontend (arm-elf) und nutzt 
grosses S in der Dateierweiterung (oder eine Option die ich grade nicht 
im Kopf habe, irgendwas in der Art --assemblerwithcpp) wird der 
Preprocessor automatische aufgerufen und neben continuation hat man noch 
gleich noch die anderen praktischen Preprocessor-Funktionen zur 
Verfügung (#define, #if etc.).

>Welchen Assembler benutzt denn Winarm?
Den Assembler aus den GNU Binutils hier in der arm-elf "Ausprägung" 
(arm-elf-as). Das ist bei GNUARM, Yagarto etc. aber nicht anders.

> Ist das nicht auch der der GNU Tollchain, oder wurden da Änderungen
> vorgenommen?
WinARM ist im Kern die GNU-Toolchain für arm-elf. Änderungen wurde nur 
für Kompatibilität mit dem Host ("Windows PC") vorgenommen, aber keine 
in Bezug auf das Target (ARM).

Martin Thomas

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Hallo Thomas, danke dir für die ausführliche Antwort. Dachte mir schon, 
dass Winarm genau die gleichen Files verwendet, deswegen kam mir das 
komisch vor, ich werde mal versuchen noch die fehlenden Files 
einzubinden und dann sehen wir weiter, wenn nicht komme ich gern auf 
deinen Download zurück, aber ich muss da noch kurz selber rum frickeln, 
das wurmt mich...
Ich geb dann Bescheid, bis dahin muss es Keil halt alleine tun.

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Fiel mir doch grad auf, dass Thomas dein Nachname ist :D, tschuldige, 
Martin.

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

So, hab mich jetzt noch mal n bissel mit der Materie beschäftigt, werd 
aber immernoch nicht ganz schlau. Ich hab jetzt erst mal grundsätzliche 
Funktionalität eines Demoprogs, von Martin Thomas, hinbekommen. Ich hab 
allerdings immernoch das Problem mit den Software und Hardware Floating 
Points. Hat der 2378 denn Hardwarefloatpoints? Wenn ja wäre es doch am 
günstigsten diese auch zu nutzen, oder? Wie tu ich das denn, ich muss 
doch sicher irgendein Bit setzen, nur wo, das Manual hat mir keine 
dieser Fragen beantwortet.
Dann noch was, der C-Compiler compiliert die C-Sources, der Assembler 
die ASM Sourcen und der Linker verknüpft alles. Warum kann so ein 
Linkerskript so unheimlich aufgebläht sein, kommt das durch die 
Speicherzuteilung? Das Linkerskript ist doch veranwortlich wo was 
gespeichert wird, oder? Dieser bss-Speicher, wo packt man den denn hin? 
oder setzt man den dynamisch nach den Daten an?
Dann wollte ich gern noch wissen, was so eine Startupdatei eigentlich 
genau macht. Ich hatte das so verstanden, dass sie den Code enthält, der 
als Erstes, also nach einem Reset ausgeführt wird. Also ist das Teil so 
etwas wie eine große Konfigurationsdatei, kann man das so sagen? Also, 
alles, was nicht zur Laufzeit umgestellt werden soll kann da rein, oder? 
An welcher Stelle der startup steht eigentlich, dass die main() 
aufgerufen werden soll? Ist ein Prog auch ohne diese Datei lauffähig?
Danke für eure Antworten, auf für den einen oder anderen triviale 
Fragen,

Hendi

von mthomas (Gast)


Lesenswert?

> Hat der 2378 denn Hardwarefloatpoints?
Hätte er sowas wie VFP, wäre es sicher einer der ersten Punkte in der 
Feature-List.

> Dann noch was, der C-Compiler compiliert die C-Sources, der Assembler
> die ASM Sourcen und der Linker verknüpft alles. Warum kann so ein
> Linkerskript so unheimlich aufgebläht sein, kommt das durch die
> Speicherzuteilung?
Was heisst aufgebläht? Was erscheint überflüssig? Schon mal das default 
Linker-Script angeschaut (arm-elf-ld --verbose)? Schon versucht jede 
Zeile eine "aufgeblähten" Linker-Skritps zu versehen und nachzusehen, ob 
die überflüssig ist?

> Das Linkerskript ist doch veranwortlich wo was gespeichert wird, oder?
Im Prinzip ja.

> Dieser bss-Speicher, wo packt man den denn hin?
Ins RAM. Der darin abgelegte Variableninhalt muss zwar beim Start 0 
sein, kann sich aber zur Laufzeit ändern.

> oder setzt man den dynamisch nach den Daten an?
Benötigten Platz errechnet der Linker, Start- und Endaddresse werde 
ebenfalls definiert und später bei der Initialisierung genutzt. in bss 
kommt der Inhalt statischer mit 0 initialisierten Variablen. "Dynamisch" 
ist er üblich für Verwaltung von Speicher auf dem Heap aber das ist 
wieder etwas anderes.

>Dann wollte ich gern noch wissen, was so eine Startupdatei eigentlich
>genau macht.
Üblich: Execpetions-Vectoren einrichten, Stack-Pointer der verschiedenen 
Modi setzten, Betriebsmodus beim start von main() setzen, .data ins RAM 
kopieren, .bss auf null setzten. Funktionalität kann aber in mehreren 
Quellcodedateien implementiert sein (in der Art vectors.s, startup.s, 
lowlevelinit.s/.c), muss nicht unbedingt alles in der "Startupdatei" 
sein.

> Ich hatte das so verstanden, dass sie den Code enthält, der
> als Erstes, also nach einem Reset ausgeführt wird.
Ungefähr. Bei Reset wird von der Hardware eine bestimmte Adresse 
angesprungen (typisch PC auf 0x00000000, erster Execeptions-Vector, kann 
auch "virtuell" sein, vgl. remapping). Üblicherweise steht dort ein 
Sprung zum Reset-Code. Das muss nicht zwangsläufig alles in einer 
"Startupdatei" implementiert sein, ist aber grade bei Projekten nach dem 
"Keil Schema" (alles an "lowlevel" in einer Assembler-Quellcodedatei 
namens startup.s) nicht unüblich.


> An welcher Stelle der startup steht eigentlich, dass die main()
> aufgerufen werden soll?
Uff, die Mühe gemacht, nach der Zeichenkette main zu suchen?
Bei Verwendung der GNU-Toolchain oft in einer Sequenz: .extern main, LDR 
Rx, main, BX R1. Bei Code für Realview werden einige 
Initialisierungsarbeiten (data, bss, stdio(?) u.a.) in einer Funktion 
__main gemacht, die ihrerseits main() ruft, aber genug Realview, dies 
ist ja das GCC-Forum.


Martin Thomas

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Ich danke dir, das hat wieder ne ganze Menge Licht in die Geschichte 
gebracht. Jetzt ist dann auch das mit dem Memoryremapping klar. Ich 
dachte ich hätte nach der Main gesucht, aber scheinbar hab ich die zwei 
kleinen Einträge überlesen....sorry. Das mit dem aufgebläht hab ich nur 
gemeint, weil einem dass gar nicht so bewusst ist, wenn die IDE alles 
übernimmt und man zum dummen Schaf wird, dass nur zwei Adressen eingeben 
muss, da scheint einem diese plötzliche Mehrarbeit doch recht 
unangenehm, das war keine persönliche Kritik! Ich habe mich nur 
ansatzweise damit beschäftigt und bin der Meinung, dass man da ne Weile 
braucht um 100% durchzusteigen. Ich hoffe das wird noch, halt noch n 
"paar" Manuals lesen. Gut, ich danke dir erstmal für deine 
Ausführlichkeit!

Bis bald,

Hendi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.