Hallo,
programmiere seit Jahren die Atmel AVRs per AVRStudio in Assembler, habe
aber nun ein Projekt bei dem ich haufenweise 16/32-bit Operationen
ausführen muss und möchte deswegen diesen Teil in C schreiben.
Habe mir daher unter Ubuntu die Eclipse IDE mit den entsprechenden C/C++
und AVR Plugins installiert und mal losgelegt. Einige zeitkritische Subs
und IRQs habe ich schon in Assembler geschrieben und würde diese gerne
einbinden, um sie nicht nochmal schreiben zu müssen. (Außerdem sind sie
schon per Logic Analyzer bis auf einzelne ClkCycles speedoptimiert, was
vlt auch in C möglich wäre, aber sicher nicht so einfach wie in
Assembler)
1. Die Suchfunktion hier und das AVR-GCC Tutorial haben mir zwar einige
Tipps gebracht wie man in WinAVR oder bei selbstgeschriebenen makefiles
vorgeht (ASRC= oder so ähnlich), aber ich wüsste gerne wo ich das bei
Eclipse einstelle.
2. Das der gcc Assembler Compiler wohl eine etwas andere Syntax hat als
der proprietäre Atmel Compiler habe ich auch schon gelesen, aber da kann
ich ja wohl mit entsprechenden Fehlermeldungen rechnen, aufgrund derer
ich dann geziehlt nach Lösungen such kann, oder?!
3. Sicher von Experten schnell nebenher beantwortet: Ich habe in meine
main Funktion eine IO.c per Anführungszeichen eingebunden (#include
"IO.c"), was wie ich gelesen hab bedeutet, dass er die Datei schlicht an
diesem Ort in den Code rundherum rein "kopiert". Allerdings bekomme ich
beim compilern bei allen Zuweisungen der Art "DDRA = 0xFF;" eine
Fehlermeldungen: ">>int<< ist Standardtyp in Deklaration von >>DDRA<<"
und gleichzeitig "data definition has no type or storage class".
"#include <avr/io.h>" steht natürlich in meiner main.c Datei ganz oben,
noch vor der main Funktion. Die Zuweisung von anderen Registern in der
main Funktion bereitet auch keine Probleme.
Vielen Dank für eure Hilfe schon im Voraus!
PUSH
Sind meine Fragen zu dumm (wahrscheinlich) oder zu schwer (kann ich mir
nicht vorstellen), um sie zu beantworten?!
Wär auch schon über einen Tipp aufs richtige Manual/Thread froh.
Mit installiertem Eclipse-plugin und automatischen makefiles gibt es in
den Project-Properties den Bereich C/C++-Build/Settings, in dem sich
alles einstellen lässt. Das makefile erstellt Eclipse dann selber.
Alternativ baust du dir ein makefile von Hand (oder besser mit MFile aus
dem WinAVR-Paket), und nutzt das auch unter Eclipse. Es gibt aber kaum
Gründe, nicht die automatischen makefiles von Eclipse zu verwenden.
Nicht funktionieren Sourcecode bitte anhängen. Das spart dir seitenlange
Beschreibungen, die am Ende doch keiner versteht. Prinzipiell ist das
includieren von .c-Files der falsche Weg.
Oliver
Oliver schrieb:
> Mit installiertem Eclipse-plugin und automatischen makefiles gibt es in> den Project-Properties den Bereich C/C++-Build/Settings, in dem sich> alles einstellen lässt. Das makefile erstellt Eclipse dann selber.
Das hab ich gefunden, allerdings gibts da unter "AVR Assembler"/General
nur "(-Xassembler) options", "Other GCC Flags" oder "Include paths
(-I)".
Wobei man bei letzterem nur ein Verzeichnis angeben kann, keine
einzelnen Dateien. Muss ich nun meine .S Dateien in ein Verzeichnis
legen und das dann dort angeben?! Oder bin ich bei "AVR Assembler"
falsch?
Für meine dritte Frage hier meine main.c:
//boot completed: lis on, red LED off, global interrupts enabled:
36
lis_on();
37
PORTD&=!(LED_RED_MASK);
38
sei();
39
40
while(1){
41
42
}
43
return0;
44
}
Die vier Funktionsaufrufe lis_off(); lis_on(); adis_conf(); und
adis_bias(); sollen aus der Assemblerdatei kommen, werden im Moment noch
als undefined reference bemeckert.
Meine dritte Frage war jedoch, warum er innerhalb der IO.c dann bei
simplen Zuweisungen wie " EICRA = 48; " oder " EIMSK = 0x04; " meckert,
dass der Datentyp nicht stimmt.
Die IO.c ist etwas länger, deswegen hab ich sie mal als Datei angehängt.
>Muss ich nun meine .S Dateien in ein Verzeichnis>legen und das dann dort angeben?!
Assembler-Dateien sind source-Dateien, und werden im source-Ordner des
Projektes links in der Projektansich angegeben, doert, wo auch main.c
und IO.c aufgelistet sind.
>#include </home/florian/eclipse/workspace/Beagle IMU/Sources/IO.h>
Macht man nicht, in <> eingeklammerte Pfade sind Systemdateien
vorbehalten. User-Includes gehören in "". Das macht man nicht nur aus
optischen Gründen, die Suchpfade unterscheiden sich. Daher musstest du
auch den vollen Pfad angeben, damit das file gefunden wurde. Der
Projektordner gehört nicht zu den System-Includepfaden, wohl aber zu den
Projekt-Includepfaden. Deshalb reicht
1
#include"IO.h"
wenn das .h-File im gleichen Ordner wie die .c-Dateien steht.
>Meine dritte Frage war jedoch, warum er innerhalb der IO.c dann bei>simplen Zuweisungen wie " EICRA = 48; " oder " EIMSK = 0x04; " meckert,
Der Compiler compiliert jede Datei einzeln, völlig unabhängig von allen
anderen. Daher muß jede C-Datei eigenständig kompilierbar sein. In
deinem IO.c fehlen aber alle erforderliche includes, in diesem Fall
#include <avr/io.h>. Daß die auch in main.c icludiert ist, ist egal.
Oliver
> Die vier Funktionsaufrufe lis_off(); lis_on(); adis_conf(); und> adis_bias(); sollen aus der Assemblerdatei kommen, werden im Moment noch> als undefined reference bemeckert.
Übergibst du dem Linker die aus der Assemblerfile genererierte
Objektdatei (*.o) ? Falls ja, könnte es sein, dass du für die Funktionen
keine Prototypen deklarierst (diese per Header-File einbinden) ?
Ich halte das für den steinigen Weg.
Denn Assembler schreibt man ja ohne Rücksicht auf Linker, Compiler,
reservierte Register, Parameterübergabe und andere Konventionen.
D.h. für den Mix Assembler + C braucht man schon viel Erfahrung und Du
wirst vieles in den Assemblerroutinen umschreiben müssen.
Hat man jedoch die nötige C-Erfahrung, braucht man aber Assembler nicht
mehr.
Wesentlich einfacher finde ich daher den Sprung ins kalte Wasser (pures
C).
Du darfst Dich auch nicht darin verzetteln, alles auf jeden CPU-Zyklus
hin zu optimieren. Das ist bei C der falsche Weg (bei Assembler
eigentlich auch).
Bevor Du was anfaßt zum Optimieren, stelle erst fest, wieviel CPU-Last
prozentual zum gesamten Programm benötigt das überhaupt.
Bei kleiner 1% lohnt sich Optimieren nur in Ausnahmenfällen.
Laß den Compiler also ruhig mal einige Zyklen mehr brauchen.
Peter
Florian W. schrieb:
> programmiere seit Jahren die Atmel AVRs per AVRStudio in Assembler, habe> aber nun ein Projekt bei dem ich haufenweise 16/32-bit Operationen> ausführen muss und möchte deswegen diesen Teil in C schreiben.
Das ist aber nicht unbedingt ein Grund für C.
Unter Assembler brauchst Du nur ne Lib für die Grundrechenarten zu
nehmen und fertig.
C: a = a * b;
Assembler: rcall umul32
Peter
Erst mal Vielen Dank für die zahlreichen Antworten.
Das heißt bei den Includes unterscheidet <> und "" nur die Suchpfade,
das erklärt dann auch das verhalten. Demnach ist aber folgende Erklärung
falsch:
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/1.7.html#include
Denn die suggeriert, dass bei "" der include Befehl ähnlich einem Makro
einfach die referenzierte Datei an dieser Stelle in den Quellcode rein
kopiert, so als ob es direkt in der Datei stehen würde.
Da das ja offensichtlich nicht der Fall ist, is auch klar, dass die
Header in der IO.c nochmal extra eingebunden werden müssen.
Mit der IO.c als korrekter Funktion und einer Header Datei mit
Deklarationen zu allen Funktionen (auch denen aus der Assemblerdatei)
und allen globalen Variablen sind nun fast alle Fehler behoben. Er
scheint jetzt auch die Assemblerdatei zu futtern, war ja im Nachhinein
doch recht einfach ;).
>Demnach ist aber folgende Erklärung>falsch:>http://www.acm.uiuc.edu/webmonkeys/book/c_guide/1....
Nö. Da steht genau das drin.
#include kopiert IMMER die referenzierte Datei an dieser Stelle in den
Quellcode. Der Unterschied zwischen <> und "" besteht nur darin, in
welchen Pfaden der Compiler die zu inkludierende Datei sucht.
Oliver
Man sollte nicht gleiche Namen verwenden, wie die Standardincludes, also
nicht "io.h". Sonst wird je nach Suchpfadreihenfolge mal das eine, mal
das andere zuerst gefunden.
Auch sollten sich Namen nicht nur in Groß-/Kleinschreibung
unterscheiden.
Unter Linux mag das gehen, unter Windows krachts aber.
Peter