Hallo, ich hab jetzt mal versucht in WINAVR einzusteigen. Folgende Fragen: 1. ich hab den Typ direkt im C-File definiert, da ich nicht immer das make ändern will: #define _AVR_AT90S2313_ Scheint zu gehen oder ist das falsch ? 2. ich hab erstmal mit -S übersetzt, um mir den Code anzusehen. Die Funktion SIGNAL (SIG_OVERFLOW0) sichert aber kein SREG und Register und schließt nur mit RET ab. 3. Beim Keil kann ich mit #pragma disable eine Funktion unter Interruptsperre laufen lassen. Im AVR-Code ist davon aber nichts zu sehen, gibt aber auch keinen Fehler. Gibt es da eine Möglichkeit den kompletten Code zu sehen ? 4. Kann man globale Variablen, die man besonders schnell und häufig braucht, als register declarieren ? Peter
zu 4. bin da grad drübergestolpert. mal in der history schauen. How to permanently bind a variable to a register? This can be done with register unsigned char counter asm("r3");
Hier die Antworten: 1. geht fast alles, nur der Stack zeigt ins Nirwana. Schade, muß man doch ständig das eklige make anfassen :-( 2. #include <avr\interrupt.h> #include <avr\signal.h> wird benötigt, dann kommt das RETI. Bischen sehr sparsam mit Fehlermeldungen der WINAVR. 3. kann der WINAVR nicht. Work-around: cli(); und sei(); 4. geht, wie Milchknilch es beschreibt. Wenn aber der WINAVR das Register auch haben will nimmt er es einfach, rücksichtslos. Peter
zu 2: mit -Wall als compiler option sollten evtl. n paar mehr meldungen kommen. zu 4: ich würd nicht rumoptimieren. überlass das gcc (mit der option -O2 z.B.), der sollte das eigentlich selber optimieren...
1. Nein, es geht noch mehr nicht. Beispielsweise wird dann ständig nur Code für eine avr2-Architektur erzeugt. Das geht also eher zufällig, weil es hier sowieso ein 2313 und damit ein Exemplar von avr2 ist, bei größeren Controllern verschenkt man mit dieser Methode einiges. Grundregel #1: Sachen, die mit _ beginnen, sind tabu. (Der Standard formuliert das ein bißchen anders, aber verkürzt kann man es auf diese Formel bringen.) 2. Der Compiler kann das nicht/kaum warnen. Leider gleicht der Aufruf des SIGNAL() bzw. INTERRUPT() Macros zu sehr einer normalen Funktionsdeklaration, als daß man bei Nichtdeklaration des Macros einen Fehler sehen würde. Aus ähnlichen Gründen werden auch Tipfehler in den Namen der Interruptvektoren nicht erkannt. <avr\irgendwas> ist übrigens Quatsch, weil es eine nicht definierte escape sequence (\i) ergibt. Wenn schon, dann also <avr\\irgendwas>, aber der Zinnober ist gar nicht nötig. DOS und Windows verstehen in den internen Systemaufrufen seit einem Jahrzehnt den Vorwärtsstrich als Trennzeichen für Verzeichnisse; es ist lediglich der Kommandoprozessor (command.com bzw. cmd.exe), der damit ein Problem hat, weil man mal aus CP/M den Vorwärtsstrich als Options-Trenner übernommen hat... Also besser gleich überall <avr/irgendwas> schreiben. 3. #pragma ist per definitionem implementation-defined. Der Standard definiert nur ein paar #pragma STDC Sachen, ansonsten sagt er: »Any such pragma that is not recognized by the implementation is ignored.« Das ist also eine ziemlich explizite Vorschrift an den Compilerbauer, daß er sich über unbekannte pragmas nicht beklagen darf... 4. Vorsicht, die Definition muß natürlich allen translation units eines Projektes gleichermaßen bekannt sein, ansonsten geht das in die Hose. Ich würde es (außer bei einem sehr kleinen Prozessor mit wenig Code, bei dem es einem substantiell z. B. Einsparungen in einer ISR bringen kann) wohl auch eher sein lassen.
@Jörg, vielen Dank für die tiefen Einblicke in die GCC-Interna. 1. Ich hab make noch nicht verwendet und alle Aufrufe in einer Batch gemacht. Beim 8051 war mit z.B.: #include <reg51.h> eben schon alles geregelt, was den Typ betrifft. Beim AVR muß ich dann also nicht nur *.c, *.h sondern auch die *.bat für jedes Projekt sichern. 2a) Da sollte man wohl diese beiden Includes standardmäßig einbinden, da Interrupts fast immer gebraucht werden. 2b) Es hat aber auch so funktioniert (mit einfachem "\"). Liegt vielleicht daran, daß ich noch den guten alten Norton Commander verwende. Was mich etwas wundert, warum ein extra Unterverzeichnis "AVR" für die Includedateien angelegt wurde. Ich werde mal alles nach "Include" zurückverschieben, dann braucht man ja die extra Pfade nicht mehr. Was mich noch wundert, wieso dieser Pfad überhaupt gefunden wird ? Ich habe PATH ja nur auf: path c:\avr\winavr\bin;c:\avr\winavr\utils\bin;%path% gesetzt. Noch ne Frage: Bei mir werden standardmäßig alle *.C mit BC und alle *.C51 mit Keil übersetzt. Nur der GCC weigert sich standhaft *.CA zu übersetzen. Da führt wohl kein Weg rein oder ? Ich finde das unter dem Norton Commander so ungemein praktisch: Auf eine Datei klicken und fertig ist die EXE oder HEX. Aber dazu muß man eben unterschiedliche Endungen vergeben können. Peter
1) Nun, ein Makefile gehört eigentlich ohnehin zum Projekt dazu... 2b) Zufall. Solange Du unbekannte Escape-Folgen benutzt, nimmt der Präprozessor wohl wirklich eine Backslash und das nachfolgende Zeichen getrennt. Spätestens bei <avr\timer.h> geht's aber schief, denke ich (\t -> TAB). OK, vielleicht wird dort auch wirklich keine Verarbeitung von Escape-Folgen gemacht, müßte ich im Standard nochmal nachlesen. Es gibt aber keinen Grund, auf diese Weise künstlich unportabel zu werden. Wie geschrieben, mit <avr/io.h> bist Du prima portabel. Mit Norton-Commander etc. hat das überhaupt nichts zu tun. Innerhalb des Unterverzeichnisses avr/ liegen die AVR-spezifischen Headerdateien. Im Basisverzeichnis liegen nur solche Headerdateien, die im C-Standard geregelt sind. Das Dilemma wurde spätestens mit <avr/signal.h> deutlich, da es ein allgemeines <signal.h> mit einem völlig anderen Verwendungszweck gibt. Initial hieß diese Datei dann aus diesem Grunde <avr-signal.h>. Da ist das Unterverzeichnis die schönere Lösung (auch wenn die kommerziellen Compiler leider nicht diesen Weg gehen). Geplant ist außerdem noch ein weiteres Verzeichnis compat/. Dort soll anfangs <compat/ina90.h> rein (Kompatibilität zum IAR-Compiler), weitere sollen folgen. Der Pfad zu den Include-Dateien (und zu den Libraries) hat mit $PATH (bzw. %PATH%) überhaupt nichts zu tun. Ein Default ist eincompiliert, der Rest wird über -I (bzw. -L) angegeben. Ich denke nicht, daß man dem gcc auf einfachem Wege (also ohne Recompilieren) einen neuen Suffix beibringt. Es gibt bereits folgende Endungen: .s -> Assembler ohne Präprozessor .S -> Assembler mit Präprozessor .c -> C .C, .cxx, .cc -> C++ .m -> Objective C (beim AVR normalerweise nicht implementiert) .i -> C ohne Präprozessor .ii -> C++ ohne Präprozessor Das mit dem Übersetzen einer Quelle anhand der Endung funktioniert doch sowieso nur sehr eingeschränkt: normalerweise hat man eine Reihe anderer Optionen, die man dem Compiler noch mitgeben kann/möchte, und außerdem willst Du ja am Ende auch noch ein ladbares File rausbekommen und ggf. programmieren. Da ist ein Makefile eigentlich die sinnvollere Wahl.
Nochmal vielen Dank. Beim 8051 bin ich bisher ohne make ausgekommen, da der das automatisch kann (amake). Beim AVR werde ich erstmal alles zusammen in ein Objekt packen, dann braucht man kein make. Erst mal sehen wie bei größeren Projekten die Compilezeit ansteigt, d.h. ob mehrere Objekte überhaupt was bringen. Peter
Nun, sie bringen Modularisierung. Compilezeit? Weiß nicht, ob das nun 200 oder 250 ms dauert, ist mir dabei eher egal...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.