Hallo,
ich versuche zur Compile ZEit code für mehrere CPUs fest zu legen.
z.B.
1
#if MCU == atmega328p
2
UDR0 = c;
3
#elif MCU == atmega1284p
4
UDR0 = c;
5
#elif MCU == atmega32
6
UDR = c;
7
#endif
Also nichts besonderes.
Ist MCU = atmega32 greift aber bereits #if MCU == atmega328p
Mache ich hier was falsch ?
So hatte ich das zumindest laut Anleitung verstanden.
Bisher hatte ich für jede CPU ein "#define _CPU2_" und dann nur noch
1
#if _CPU1_
2
UDR0 = c;
3
#elif _CPU2_
4
UDR0 = c;
5
#elif _CPU3_
6
UDR = c;
7
#endif
Aber das ist ja nicht so toll...
Eventuell kann mir einer ja kurz die Erleuchtung geben.
Danke
Juergen
> Ist MCU = atmega32 greift aber bereits #if MCU == atmega328p
Dann haben die Defines atmega32 und atmega328p den selben Wert. Zeig mal
jene Defines her.
würde da auch Klammern setzen: #if (MCU == ...)
bin nicht sicher, ob der Präprozessor sonst nicht schon das #if MCU als
wahr interpretiert (wenn MCU ungleich 0 ist)
... und in der UART-Lib von P. Fleury gibt's das Ganze schon fertig
aufgebaut und getestet:
http://homepage.hispeed.ch/peterfleury/uartlibrary.zip
Und wenn du den Quellcode nur dafür hernimmst, um zu gucken, wie man
sinnvoll mit dem #define für den Prozessortyp umgeht.
Das #define für den AVR-Typ legt der Preprozessor für dich an, je
nachdem welches Target du mit der gcc-Kommadozeilenoption -mmcu=... oder
per Setting in deiner IDE auswählst ( was letztendlich auch auf die
Kommandozeilenoption hinausläuft).
>> etc. erzeugt der AVR-GCC intern selbst aus der übergebenen Option> -mmcu=atmega1284p.
So ganz habe ich das nicht verstanden.......
Wenn ich folgendes machen möchte
genutzt..
Oder gibt es einen define, der das bereits beinhaltet.
Wenn ich der Datei avr/io.h folge, kann ich da nichts entdecken, mit den
jeweiligen includes natürlich.
Der Umbau auf:
hat erst mal den Erfolg gebracht, trotzdem würde ich das noch weiter
Optimieren wollen.
Nur so als Hinweis, es geht nicht nur UART, auch Interrupts un Co.
Trotzdem Danke für den Hinweis auf die UART Library.
Etwas Offtopic...
Kann mir einer sagen, wie ich bei einer Änderung einer bestimmten Datei
einen "make clean" als erstes ausführen kann ?
Ein (Ausschnitt aus meinem Makefile)
Jürgen S. schrieb:> Muss ich doch MCU definieren?
Ja, an einer Stelle schon. Aber diese Variable namens MCU ist nur
innerhalb des Makefiles bekannt. Von da wird er als -mmcu= an den
Compiler weitergereicht, und dieser wiederum baut sich intern dann
die Makros mit den Unterstrichen draus.
> Kann mir einer sagen, wie ich bei einer Änderung einer bestimmten Datei> einen "make clean" als erstes ausführen kann ?> Ein (Ausschnitt aus meinem Makefile)> build: $(GLOBAL_SRC_DIR/typeToBuild.makefile) elf hex bin eep lss sym> size copyHttp finish>> $(GLOBAL_SRC_DIR/typeToBuild.makefile):> echo "type to Build changed, clean up project first"> clean
Probier' es mal mit einer Hilfsdatei, die von der anderen abhängt:
>> etc. erzeugt der AVR-GCC intern selbst aus der übergebenen Option> -mmcu=atmega1284p.
Inzwischen nicht mehr. Während es sich bis avr-gcc v4.9 noch um
Build-in Makros handelte und in entsprechenden Dumps daher steht
1
# 1 "<built-in>"
2
...
3
#define __AVR_ATmega1284P__ 1
ist das ab v5 nicht mehr so. Die Macros werden qua specs File über die
Kommandozeile definiert:
Jörg W. schrieb:> Jürgen S. schrieb:>>> Muss ich doch MCU definieren?>> Ja, an einer Stelle schon. Aber diese Variable namens MCU ist /nur/> innerhalb des Makefiles bekannt. Von da wird er als -mmcu= an den> Compiler weitergereicht, und dieser wiederum baut sich intern dann> die Makros mit den Unterstrichen draus.
Jetzt wo ich es lese...
Klar, MCU war nur im Makefile bekannt...
Gut, jetzt mit dem
Johann L. schrieb:>> erzeugt der AVR-GCC intern selbst aus der übergebenen Option>> -mmcu=atmega1284p.>> Inzwischen nicht mehr.
OK, das war mir jetzt nicht so ganz genau klar.
Anyway, das Interface aus Nutzersicht hat sich ja dadurch nicht
geändert: er kann sich drauf verlassen, dass sein -mmcu= einen
entsprechenden Makro automatisch generiert, und man muss sich nicht
die Mühe machen, etwas vergleichbares „zu Fuß“ nachzubilden.
Jürgen S. schrieb:> Das mit dem>>> build: stamp elf hex bin eep lss sym size copyHttp finish>>>> stamp: $(GLOBAL_SRC_DIR/typeToBuild.makefile)>> $(MAKE) clean>> touch stamp>> hat genau einmal Funktioniert, sieht bei mir so aus.
Erstens:
Dein "make clean" muss das stamp-File auch löschen, sonst funktioniert
das nur genau einmal. Du kannst aber statt auf ein Dummy-File auch auf
"clean" verweisen lassen, und du solltest "clean" als ".PHONY"
deklarieren. Außerdem macht dein Ansatz parallele Builds kaputt, weil
"clean" an fremden Dateien rumspielt.
Zweitens:
Wenn du vor einem Build ein "make clean" brauchst, ist an deinem
Buildsystem etwas kaputt. Erweitere dein Makefile mal lieber um
richtiges Dependency Tracking (der gcc kann dir passende
Makefile-Snippets erzeugen), dann funktioniert der Rebuild auch
zuverlässig, wenn du einen Header änderst.
Beispiel (Auszugsweise):
1
OBJS = bla.o blub.o main.o
2
3
[...]
4
5
DEPS = $(OBJS:.o=.od)
6
.PHONY: all clean run
7
.PRECIOUS: $(OBJS) $(DEPS)
8
9
[...]
10
11
%.o: %.c
12
$(CC) $(CFLAGS) -c -o $@ $<
13
$(CC) $(CFLAGS) -MM -c $< > $@d
14
15
[...]
16
17
clean:
18
rm -f $(MAIN) $(OBJS) $(DEPS)
19
20
-include $(DEPS)
Die beiden Compileraufrufe kann man sicherlich auch vereinigen, aber das
habe ich bisher nicht gebraucht. Vermutlich geht's auch noch besser.
S. R. schrieb:> Wenn du vor einem Build ein "make clean" brauchst, ist an deinem> Buildsystem etwas kaputt.
Naja, wenn man im Makefile (oder einem seiner Includes) irgendwelche
Parameter ändert, die das komplette Compilat beeinflussen, dann
bleibt einem eigentlich nicht viel anderes übrig, als vorher erstmal
alles zu löschen.
Ja gut, das ist klar. Aber dann macht man vorher einmal "make clean" per
Hand und gut ist. Mein Reflex ist in solchen Fällen "make clean run",
weswegen ich clean auch nicht in NOTPARALLEL stehen habe; mit der Race
Condition kann ich leben,
Ich hatte den TO so verstanden, dass es um eine Datei geht, die im
Makefile nicht explizit auftaucht, aber trotzdem gebraucht wird. Das ist
dann ein Fehler im Buildsystem, und implizit "make clean" aufrufen
lassen ist ein hässlicher Workaround, der zudem parallele Builds bricht.
Wenn man ständig an den Makefiles rumspielt, könnte man natürlich auch
Includes bauen, die die einzelnen Makefile.inc-Dateien verfolgen, und im
Zweifelsfall dann "make" neu aufrufen... ;-)
Genau das ist bei mir der Fall.
Dieses File definiert, was erzeugt wird.
Dadurch wird im Makefile Prozessor und Optionen definiert.
Außerdem werden durch das define bestimmt, was im Quellcode compiliert
wird, eventuell die pin Konfiguration geändert usw.
Da hilft nur ein make Clean um sicher zu gehen.
Gruss
Juergen