Hallo zusammen,
bisher habe ich nur mit dem Atmel Studio gearbeitet.
Jetzt beschäftige ich mich mit IAR. Es wird demnächst beides parallel
zum Einnsatz kommen.
Ich hatte mir nun vorgestellt, die zukünftigen Projekte so anzulegen,
dass sie mit beiden Entwicklungsumgebungen bearbeitet werden können.
Um erst einmal zu unterscheiden, welcher Compiler zum Einsatz kommt,
wollte ich folgendes verwenden:
1
#if defined (__GNUC__) && defined (__AVR__)
2
/* Mache was speziell fuer avr-gcc */
3
# include <avr/io.h>
4
#elif defined (__ICCAVR__)
5
/* IAR Compile is used */
6
# inclide <avrio.h>
7
#else
8
# error "Unknown compiler"
9
#endif /* aiccavr */
Für die anderen Unterschiede der Compiler wollte ich dann entsprechend
Makros über die obige Weiche erstellen.
Bevor ich jetzt direkt an die Umsetzung einer solchen Compiler-Weiche
gehe, wollte ich mich erst einmal noch etwas schlau machen, ob das in
der Art, wie ich es vor habe, sonnvoll ist? Ob es andere/bessere
Möglichkeiten gibt?
Hat hier jemand schon etwas ähnliches umgesetzt oder sollte man das
besser sein lassen und das Projekt dann nicht für beide Compiler
erstellen?
Vielleicht hat der ein oder andere ja schon Erfahrung damit und teilt
sie mit uns.
Beste Grüße
Swen
Swen schrieb:> Bevor ich jetzt direkt an die Umsetzung einer solchen Compiler-Weiche> gehe, wollte ich mich erst einmal noch etwas schlau machen, ob das in> der Art, wie ich es vor habe, sonnvoll ist?
Ja, ist sinnvoll, dies genau so zu machen. Aber bevor Du diese #ifdefs
nun quer über den Quellcode verstreust, kann es sinnvoll sein, ganz oben
(oder in include-Dateien) gleichnamige Makros für jeden Fall zu
definieren, die Du dann im Quellcode nutzt. Dadurch bleibt der
eigentliche Code dann lesbar.
Also:
Ob das überhaupt sinnvoll ist, sei mal dahingestellt. Da gibt es schon
an einige Ecken Unterschiede, die sich nicht mit ein paar globalen
defines erschlagen lassen. Das wird einen arg vermurksten Quelltext
ergeben, oder du schreibst einiges vom Code in zwei Versionen.
Oliver
Hallo,
vielen Dank für die Antwort bis hierher.
Ich werde mich einmal in das Thema einarbeiten und mal versuchen ein
Projekt so aufzubauen, dass es eben in beiden Entwicklungsumgebungen
nutzbar ist.
Im Laufe der Arbeit werden sich dann sicher noch mehr Unterschiede
heraustellen. Dann wird sich zeigen, wie praktikabel das sein wird.
Vielen Dank.
Beste Grüße
Swen
Im AutoSAR wird eine ganze Reihe an Macros definiert um Quellcode so
weit wie es geht Compilerunabhängig zu machen. Das liefert dann aber
schon Code, der ziemlich vom "gewöhnten" C abweicht . Sieht etwa so aus:
Hallo,
ich habe einmal kurz drüber geschaut, sieht ja schon wild aus.
Mal sehen, wo wir landen werden.
Einige Sachen sind schienbar nicht ganz so einfach weitestgehend
compilerunabhängig zu machen.
Beim EEPROM Schreiben/Lesen schient es schon größere Unterschiede zu
geben, auf den ersten Blick. Mal schauen, wie wir es umsetzen.
Vielen Dank.
Beste Grüße
Swen
Oliver S. schrieb:> Da gibt es schon an einige Ecken Unterschiede, die sich nicht mit ein> paar globalen defines erschlagen lassen.
Wir haben beruflich 10 Jahre lang Code geschrieben, der für IAR und
GCC funktioniert (anfangs AVR, später auch ARM). Kann man alles
über Makros abdecken, allerdings sind diese teilweise dann etwas
komplexer. Zwischenzeitlich kam sogar noch die Anforderung für
MSP430 mit rein, was die Komplexität weiter gesteigert hat (far
functions und noch ein weiterer Compiler).
Hallo,
wir sind gerade dabei, das ein oder Makro dafür zu erstellen, indem wir
eines unserer kleineren Projekte einmal so umschreiben möchten, dass es
eben mit beiden Compilern läuft.
Im Moment schauen wir uns das Thema eeprom an, da in dem Projekt einige
Daten im EEPROM abgelegt werden. Mal schauen, wie komplex das ist.
Beste Grüße
Swen
Hallo,
vielleicht noch eine Frage zur Protierung der EEPROM-Funktionen auf IAR.
Lassen sich auch die EEPROM Funktionen wie eeprom_write_byte,
eeprom_write_word,...usw. auch alle so per Makro definieren, man dieses
in beiden Umgebungen verwenden kann?
Im Moment fehlt mir der Ansatz, wie man dieses einfach in Makros
umsetzen kann, da es diese ganzen oben genannten Funktionen im IAR nicht
gibt, dort kann ja direkt auf eine mit __eeprom definierte Variable
zugegriffen werden, wie auf jede andere Variable auch, wenn ich das
richtig verstanden habe.
Ich sehs noch nicht....
Beste Grüße
Swen
Swen schrieb:> Lassen sich auch die EEPROM Funktionen wie eeprom_write_byte,> eeprom_write_word,...usw. auch alle so per Makro definieren, man dieses> in beiden Umgebungen verwenden kann?
Der IAR hat meines Wissens nur Funktionen auf Byteniveau (__EEGET()
und __EEPUT()). Diese kannst du einfach so abstrahieren, dass du
auch ein GCC-Pendant dafür hast. Wenn du mehr willst, kannst du
natürlich aber auch beim IAR das Assemblieren / Disassemblieren der
Bytes (über Maskierung und Bitschiebeoperation) innerhalb einer
Makro-Ersetzung realisieren.
IAR ist ungetestet. Bin auch noch nicht sicher, ob das so richtig ist im
IAR. Ganz so weit bin ich da noch nicht durchgestiegen.
>Der IAR hat meines Wissens nur Funktionen auf Byteniveau (__EEGET()>und __EEPUT()).
Das hatte ich auch so verstanden. Wobei man doch auch ohne Funtionen auf
diee EEPROM Variablen zugreifen kann, wie auf jede andere Variable auch,
wie oben dargestellt?
Das würde dann weiter heißen, dass ich für eeprom_read_word usw. Makros
oder Funktionen im IAR erstellen müsste, die eben durch
Bitschiebeoperationen z.B. 32 Bit in 4 Schritten ins EEPROM schreibt
oder liest?
Beste Grüße
Swen
Das sollte so von beiden Compilern genommen werden.
P.S. Du hattest oben eeprom_read_word() statt eeprom_read_byte()
geschrieben, Vorsicht.
> Das würde dann weiter heißen, dass ich für eeprom_read_word usw. Makros> oder Funktionen im IAR erstellen müsste, die eben durch> Bitschiebeoperationen z.B. 32 Bit in 4 Schritten ins EEPROM schreibt> oder liest?
Es gibt auch eeprom_read_block(), damit kannst Du auch 32bit-Variablen
lesen bzw. wegschreiben. Einfach den Adressoperator wie gehabt benutzen.
Erweitere die Makros für eeprom16_t und eeprom32_t. Bei 16_t dann
eeprom_read_word() und bei 32_t dann eeprom_read_block() verwenden. Die
Makros würde ich dann EEPROM_READ_WORD() und EEPROM_READ_LONG() oder
EEPROM_READ_DWORD() benennen.
Hallo,
>P.S. Du hattest oben eeprom_read_word() statt eeprom_read_byte()>geschrieben, Vorsicht.
Ah ja... hatte erst uint16_T stehen.
Warum das do while Konstrukt?
Write würde dann wie folgt aussehen:
1
AVR-GCC:
2
#define EEPROM_WRITE_BYTE(add, val) do { val = eeprom_write_byte(add, val); } while (0);
3
4
#define EEPROM_WRITE_BYTE(add, val) do { eeval = val; } while (0);
Swen schrieb:> Warum das do while Konstrukt?
Damit wird das Statement so geklammert, dass solche Konstrtukte wie
1
if(irgendwas)
2
MAKROAUFRUF();
3
else
4
ANDERERMAKROAUFRUF();
ohne explizite Klammerung mit { ... } noch korrekt umgesetzt werden.
Gerade dann, wenn im Makro selbst eine if-Abfrage steht, wirds hässlich
mit einem darunterstehenden else-Statement. Viel Spaß dann noch bei der
Zuordnung, wo das else denn hingehört ;-)
> Write würde dann wie folgt aussehen:AVR-GCC:> #define EEPROM_WRITE_BYTE(add, val) do { val = eeprom_write_byte(add,> val); } while (0);>> #define EEPROM_WRITE_BYTE(add, val) do { eeval = val; } while (0);
Pardon, ich hatte meinen Beitrag nochmals nachträglich editiert. Das
Semikolon hinter "while (0)" muss weg. Ebenso sollte man eeval nochmal
im Makro klammern, damit der Adressoperator auch auf den kompletten
Ausdruck wirkt. Schau Dir bitte nochmal meine bearbeitete Fassung von
oben an.
Swen schrieb:> Nun aber:AVR-GCC:> #define EEPROM_WRITE_BYTE(val, eeval) do { eeprom_write_byte(eeval,> val); } while (0);
Ja, aber auch hier das Semikolon am Zeilenende weg.
>> IAR:> #define EEPROM_WRITE_BYTE(val, eeval) do { eeval = val; } while (0);>> eeprom8_t ValueOneEEPROMAddress;> uint8_t ValueOneFromEEPROM = 0;> uint8_t ValueOneToEEPROM = 23;> EEPROM_WRITE_BYTE (ValueOneToEEPROM, ValueOneEEPROMAddress);>> So sollte es stimmen!?
Sieht fast gut aus! Du hast beim Aufruf nur die Argumente vertauscht:
EEPROM_WRITE_BYTE (ValueOneEEPROMAddress, ValueOneToEEPROM);
Frank M. schrieb:> Sieht fast gut aus! Du hast beim Aufruf nur die Argumente vertauscht:>> EEPROM_WRITE_BYTE (ValueOneEEPROMAddress, ValueOneToEEPROM);
Jedenfalls würde ich eher
#define EEPROM_WRITE_BYTE(eeval, val) .....
schreiben, also das Target links - wie es nicht nur bei einer Zuweisung,
sondern auch bei Standardfunktionen wie strcpy() oder memcpy() der Fall
ist.
Hallo,
ich bin gerade dabei, mir die Sachen noch einmal anzuschauen.
Warum ist der Aufruf hier falsch herum?
>>>> IAR:>> #define EEPROM_WRITE_BYTE(val, eeval) do { eeval = val; } while (0);>>>> eeprom8_t ValueOneEEPROMAddress;>> uint8_t ValueOneFromEEPROM = 0;>> uint8_t ValueOneToEEPROM = 23;>> EEPROM_WRITE_BYTE (ValueOneToEEPROM, ValueOneEEPROMAddress);>>>> So sollte es stimmen!?>Sieht fast gut aus! Du hast beim Aufruf nur die Argumente vertauscht:>EEPROM_WRITE_BYTE (ValueOneEEPROMAddress, ValueOneToEEPROM);
Ich übergebe den Wert, der ins EEPROM geschrieben werden soll (val ->
ValueOneToEEPROM) und die Adresse, bzw. die EEPROM-Variable (eeval ->
ValueOneEEPROMAddress).
Mit eeval = val schiebe ich doch dann den Wert von ValueOneToEEPROM in
ValueOneEEPROMAddress, also ins EEPROM.
Zumindest ist das bisher so, da die Reihenfolge der Argumente im Makro
und in den Funktionen wie eeprom_read_byte usw. gedreht sind.
Oder habe ich da jetzt einen Denkfehler drin?
Vielen Dank!
Beste Grüße
Swen
Swen schrieb:> Warum ist der Aufruf hier falsch herum?
Sorry, ich hatte "falsch herum" gelesen. Ich konnte meinen Beitrag aber
nicht mehr korrigieren und hatte es dann in einem nachfolgenden Beitrag
versucht zu erklären, was ich meinte.
>>> #define EEPROM_WRITE_BYTE(val, eeval) do { eeval = val; } while (0);
Eben genau das: Bei Zuweisungen, strcpy(), memcpy und anderen ähnlichen
Funktionen (auch eeprom_write_xxxx()) steht das Target immer links.
Daher würde ich das auch so herum schreiben, also:
1
#define EEPROM_WRITE_BYTE(eeval, val) do { eeval = val; } while (0);
Hallo,
kein Problem,
vielen Dank. Ich hatte den letzten Post auch gelesen, aber irgendwie
dann noch nicht mit der Reihenfolge der Argumente in Verbindung gesetzt.
Nur der vollständigkeithalber. Bei dem Beispiel müssen die Semikolon am
Ende dann wieder weggelassen werden!?
>Entschuldige bitte die Verwirrung.
So denkt man wenigstens mit und schreibt nicht nur ab!
Beste Grüße
Swen