GLCD und Grafikdisplay EA DOGM128: Compilermeldungen
Liebe Forenteilnehmer !
Ich möchte die GLCD Libraries von Andy Gock kompilieren, um mehrere
Schriftarten auf meinem Grafikdisplay verwenden zu können. Alle von Andy
Gock beschriebenen Einstellungen zu Soft,- und Hardware habe ich meines
Wissens vorgenommen, komme aber nicht weiter.
Der Compiler meldet sich mit Fehlern, die ich nicht nachvollziehen kann.
Ich verwende die Atmel IDE Atmel Stdio 6.1. Die Hardware besteht aus
ATmega328p und dem Display EA DOGM128 mit 128 x 64 Pixeln. Zugehöriger
Displaytreiber ST7565.
So, wie ich es mit den Setupeinstellungen kompiliert habe, hänge ich
alle Dateien an, mit der Bitte um Hilfe.
Die Compilermeldungen lauten:
conflicting types for "glcd_clear"
conflicting types for "glcd_select"
"glcd_buffer" undeclared (first use in this function) ...in
avr8.c
"glcd_bbox" undeclared (first use in this function) ...in
avr8.c
"GLCD_RESET_TIME" undeclared (first use in this function) ...in
avr8.c
Da avr8.h und avr8.c eingebunden sind, dürfte es diese Meldungen gar
nicht geben.
Was fehlt, bzw. was mache ich falsch? Für einen Tip wäre ich dankbar.
MfG Gerry
Gerry schrieb:> Die Compilermeldungen lauten:
Ja die sind doch ganz eindeutig!
Einfach mal lesen, was da steht.
Also ich sehe das so, daß du wie viele Andere ein ärgerliches
Verzeichnis-Gestrüpp aufgebaut oder übernommen hast. Mach das einfach
platt, also alles was du für dein Projekt brauchst, kommt in ein
einziges Verzeichnis.
Nun behaupte bloß nicht, daß dein AVR-Projektlein für sowas zu groß sei.
Der Knackpunkt dürfte sehr leicht auch ohne Compiler zu finden sein: in
\devices\AVR8.c
steht
#include "../glcd.h"
Merkst du was?
Vielleicht kommt deine Toolchain oder deine IDE mit dem
Verzeichniswechsel nicht zurecht. Bei Windows wäre das
#include "..\glcd.h"
Also mein Rat:
Alles Dateien, die du WIRKLICH brauchst, in ein einziges Verzeichnis und
alle .c und .h durchforsten, ob da sowas wie ../ oder ..\ steht.
Selbiges entfernen. Dann sollten auch deine Headerfiles gefunden werden
und die dort vorhandenen Bezeichner dem Compiler bekannt sein.
W.S.
Hallo, Gerald !
Zunächst einmal herzlichen Dank an alle, die mir geantwortet haben.
Bei der Beschreibung der Compilerfehler ist mir ein kleiner Fehler
unterlaufen. Es muss hier heissen "glcd_select_screen". Alle
Compilerfehler beziehen sich auf Funktionen, die im Verzeichnis
glcd.h und avr8.c untergebracht sind.
Sie haben Recht, wenn man die vielen Verzeichnisse sieht, dass alles
kaum überschaubar ist.Ich werde es in den kommenden Tagen versuchen zu
vereinfachen.
Eingebunden werden alle Verzeichnisse aber einwandfrei, sonst beschwerte
sich der Compiler nicht über die Funktionsangaben in glcd.h und avr8.c .
conflicting types for "glcd_clear" ...in glcd.h und avr8.c
conflicting types for "glcd_select_screen" ...in glcd.h und avr8.c
"glcd_buffer" undeclared (first use in this function) ...in avr8.c
"glcd_bbox" undeclared (first use in this function) ...in avr8.c
"GLCD_RESET_TIME" undeclared (first use in this function) ...in avr8.c
Die Compilermeldungen über undeclared functions entzünden sich
hauptsächlich daran, dass in avr8.c die übergebenen Variablen der
Funktion
glcd_select_screen(glcd_buffer,&glcd_bbox);
und die der Funktion in glcd.h
void glcd_select_screen(uint8_t *buffer, glcd_BoundingBox_t *bbox);
differieren. Ein und dieselbe Funktion mit unterschiedlichen
Variablenbezeichnungen will der Compiler nicht verarbeiten.Wie kann
man das Problem beheben? Einmal sind es glcd_buffer und *buffer, zum
anderen sind es glcd_bbox und glcd_BoundingBox_t *bbox.
Die undeclared "GLCD_RESET_TIME", ziemlich am Ende im Verzeichnis
avr8.c, ist sehr wahrscheinlich nicht definiert worden in avr8.h. Das
ist noch mit einer definierten Zeit nachzuholen?
MfG Gerry
Gerald K. schrieb:> Ein und dieselbe Funktion mit unterschiedlichen> Variablenbezeichnungen will der Compiler nicht verarbeiten.Wie kann> man das Problem beheben?
Indem man nicht bloß von irgendwo her sich was zusammenkopiert, sondern
sich zuerst bemüht, die Sache zu verstehen und dann sich seinen eigenen
Senf aufsetzt - und das möglichst systematisch.
Mein Rat wäre da etwa so:
1. schreib dir eine Quelle für das physische Ansteuern des Displays, zum
Beispiel "display.c", worin enthalten ist:
- ein RAM-Block, der als Bildspeicher dient. Das brauchst du, um eine
Trennung zwischen logischer Ebene (Zeichnen von Elementen auf der
Bildfläche) und physischer Ebene (Ansteuerung des konkreten Displays)
herbeizuführen. Dazu gehört dann noch eine einfache bool Variable, die
anzeigen soll, ob seit der letzten Blockübertragung in den Bildspeicher
geschrieben wurde oder nicht.
- die Initialisierung des Displays
- die Blockübertragung vom Bildspeicher ins eigentliche Display
- eine etwaige Helligkeitssteuerung
2. schreib dir eine zweite Quelle für das logische Ansteuern des
Displays, zum Beispiel "gdi.c", worin enthalten ist:
- einzelne Punkte auf der Bildfläche setzen (Farbe: schwarz oder weiß
oder invertiert)
- Linien auf der Bildfläche zeichnen
- Rechtecke auf der Bildfläche mit Farbe (schwarz, weiß, invertiert)
füllen
- Textzeichen auf der Bildfläche zeichnen (x,y,font, farbe)
Die Funkton für die Punkte sollte die o.g. bool Variable setzen, wenn
sie im Bildspeicher was geschrieben hat. Die übrigen Funktionen können
dann auf der Punkte-Funktion aufsetzen.
3. alle höheren Funktionen wie Buttons, Checkboxen, Eingabezeilen,
Listboxen und sowas gehören in andere Quellen.
Zu allererst solltest du erstmal NUR display.c schreiben und zum Laufen
bringen. Dazu den Bildspeicher entweder mit Zufallsmustern füllen oder
mit Mustern, bei denen du dir was dabei denken kannst (ob die
Orientierung so richtig kommt und so). Die Auswertung der o.g. bool
Variablen erfolgt in der Grundschleife in main.c und wenn das erstmal
läuft, dann ist es Zeit sich um Punkt 2 zu kümmern.
Also immer in überschaubaren Schritten vorgehen.
Natürlich kannst du (nach dem Verstehen) die vorhandenen Quellen
benutzen (entweder ganz oder teilweise oder nach etwaigem Editieren).
Nochwas zu den Fonts: probiere aus, ob und wie die funktionieren. Falls
die dir nicht gefallen, dann nimm andere - Hauptsache du verstehst wie
die Fonts zusammen mit dem gdi.c funktionieren. Viele Font-Autoren
machen es sich leicht: sie arbeiten mit festen Rastern in Höhe und
Breite und verplempern damit Platz und Universalität. Als ein Beispiel,
wie ich das mache, guck dir mal das an:
"http://www.mikrocontroller.net/attachment/301321/Fonts-machen-2.zip"
Damit kann man nicht nur verschiedene Schriften machen, sondern auch
monochrome Icons, Bilder usw.
W.S.
Gerald K. schrieb:> Ein und dieselbe Funktion mit unterschiedlichen> Variablenbezeichnungen will der Compiler nicht verarbeiten.
Doch, will er, aber die Datentypen müssen kompatibel sein. Vermutlich
fehlen die richtigen includes irgendwo, deswegen ist der implizite
Datentyp dann int, dann findet er irgendwoher die includes mit den
richtigen Datentypen, und scho paßt es nicht mehr.
@ W.S.: Eine Library nimmt man, um NICHT alles zu Fuß zu implementieren.
Genau wie man seinen Compiler auch nicht selber aus einzelnen Bits
handmeißelt.
Nop schrieb:> @ W.S.: Eine Library nimmt man, um NICHT alles zu Fuß zu implementieren.
Oh ja. Und wenn man dabei auf die Nase gefallen ist, weil man eben
gemeint hat, daß "man ja NICHT alles selber zu Fuß" etc..etc.. - dann
wird hier geklagt.
Natürlich kann man sowas nehmen - aber verstehen muß man es schon
selbst.
Hier hat der TO offenbar einen in sich inkompatiblen Mix aus Quellen, wo
zwei namensgleiche Funktionen in unterschiedlichen Quellen vorkommen.
Was also würdest DU vorschlagen?
Noch lauter jammern?
Hardware wechseln, um möglichst sklavisch dem Vorbild nachzubasteln?
Was ich vorschlage ist klar: Es selber in Ordnung bringen, und zwar
schrittweise, systematisch und von der Pike an. Aber dazu ist das
Grundverständnis vonnöten - und eben nicht bloß eine Library aus
Fremdhand.
Völker dieser Erde, schaut auf dieses Forum!..
Da wird mit allen möglichen Libraries gewurschtelt: Tasten entprellen,
Alpha-LCD ansteuern, dito Grafik-LCD, SD-Asteuerung und so weiter. Und
jedesmal wird herumgejammert, daß es hier und dort eben nicht geht -
weil man eben bloß copy&paste betrieben hat.
Das ist der Punkt.
W.S.
W.S. schrieb:> Oh ja. Und wenn man dabei auf die Nase gefallen ist, weil man eben> gemeint hat, daß "man ja NICHT alles selber zu Fuß" etc..etc.. - dann> wird hier geklagt.
Naja komm, also den ganzen GDI-Kram selber implementieren, wozu? Dann
wird man ja nie fertig. Auf dem PC schreibt man sich ja auch nicht erst
ein OS mit Treibern, wenn man eine Anwendung machen will.
> Natürlich kann man sowas nehmen - aber verstehen muß man es schon> selbst.
Stimmt.
> Was also würdest DU vorschlagen?
Ich hab das eher so gesehen, daß es irgendein Problem mit den includes
gibt und daher irgendwo als Defaulttyp int genommen wird, was dann an
anderer Stelle, wo die includes da sind, nicht mehr paßt.
Aber selbst wenn es so ist, wie Du das verstehst, das ist ja noch
einfacher. Dann macht man eben Namespaces nach guter alter C-Art, indem
man die Funktionen präfixt. Mache ich sowieso, damit ich direkt beim
Aufruf sehe, in welchem Modul (und somit auch, in welcher Schicht) die
Funktion eigentlich ist.
Danach kann man entweder ein Refactoring machen, um den Merge wirklich
durchzuziehen, oder man läßt es bleiben und behält ein etwas zerrissenes
System, weil man dann leichter Updates der Ursprungsquellen einpflegen
kann.
> Was ich vorschlage ist klar: Es selber in Ordnung bringen, und zwar> schrittweise, systematisch und von der Pike an.
Nee, was Du vorschlägst, ist, alles komplett selber zu programmieren,
besonders die Grafikalgorithmen, und das finde ich nicht sinnvoll,
sofern der Zweck der Sache letztlich eine Anwendung ist.
Grundsätzlich sinnvoll ist es, darin stimme ich Dir zu, die Integration
bottom-up zu machen. Aber Integration und keinen kompletten rewrite.
> Da wird mit allen möglichen Libraries gewurschtelt
Das ist doch nicht nur hier im Forum so. Früher(tm) hieß Software
schreiben noch wirklich kreativ sein, während heute embedded eine der
letzten Bastionen ist, wo das noch so ist. Ansonsten existiert bereits
alles, und SW entwickeln heißt bloß noch Klebstoff für existierende
Sachen machen. Den jüngeren Programmierern fällt der Stumpfsinn dabei
nichtmal auf, sie kennen es nicht anders. Ich sag nur Spolskys
Javaschulen-Artikel.
Nop schrieb:> Früher(tm) hieß Software> schreiben noch wirklich kreativ sein,
Ja - heute auch noch, frag z. B. mal C-Hater :-)
Aber - oh Wunder - es gibt auch noch andere, die nicht nur kopieren
sondern ihr Hirn einsetzen - wenn auch nicht unbedingt via Assembler.
Das hat nichts mit der Programmiersprache zu tun (auch Arduino-Nutzer
sind durchaus kreativ) sondern mit "dem Spirit" :-)
Nicht das Werkzeug ist wichtig - wichtig ist der "Geist" dahinter ...
(wem etwas besseres einfällt - bitte artikulieren).
Und natürlich können die Anwendungen dahinter kreativ sein - die
Programmierung ist hingegen stumpfsinnig. Als Profi ist das
Programmieren selber aber etwa so "spannend", als wenn ein geübter
Motorradfahrer mit einem Dreirad fahren soll.
Nop schrieb:> Als Profi ist das> Programmieren selber aber etwa so "spannend", als wenn ein geübter> Motorradfahrer mit einem Dreirad fahren soll.
Schwaller :-)
Zeig doch mal ein paar spannende Beispiele Deiner Programmierung ... (so
nebenbei, als Abfall), damit wir alle etwas lernen können.
Nop schrieb:> Dann macht man eben Namespaces nach guter alter C-Art, indem> man die Funktionen präfixt...>> Danach kann man entweder ein Refactoring machen, um den Merge wirklich> durchzuziehen,
Nur mal zum grundsätzlichen Verständnis:
Wenn man einen Sack voll C-Quellen nebst zugehörigen .h hat und dort
mehrere offensichtlich differierende Deklarationen von Funktionen hat,
(siehe:
conflicting types for "glcd_clear"
conflicting types for "glcd_select"
)
dann hat man ein Kraut+Rüben Potpourri, was man SO überhaupt nicht
verwenden kann. Da hilft auch kein Präfix, weil offenbar hier alles
drunter und drüber geht. Also lies nochmal den Eröffnungspost, dann wird
dir das klar werden.
Da bleibt wirklich nur eines übrig: Mit der Machete reingehen und
allenfalls die vorhandenen Quellen ausweiden. Den richtigen Weg hatte
ich ja skizziert: zuerst die Strecke Bildspeicher bis Display zum Laufen
kriegen, damit man was sieht. Dann Stück für Stück die Grafikroutinen in
Gang bekommen. Zuerst Pixel setzen, dann den Rest. So bleibt das Ganze
einigermaßen übersichtlich.
Nochwas:
Wenn Bildspeicher bis LCD läuft und Pixel setzen auch läuft, dann
könnnte man das gdi.c aus der Lernbetty problemlos draufsetzen. Ich hab
das selber schon bei den unterschiedlichsten Plattformen gemacht. Sowohl
in s/w als auch in 16 Bit Farbe. So geht das, wenn man auf eine gewisse
Hierarchie seiner SW-Schichten achtet.
W.S.
GLCD und Grafikdisplay EA DOGM128: Compilermeldungen
Liebe Forenteilnehmer!
Mittlerweile ist das Problem gelöst. Der Fehler lag beim Compiler, der
die zu definierende Hardware ( AVR8 ) und den zu definierenden Treiber
(ST7565) nicht für alle eingebundenen Dateien einwandfrei erkannte.Mit
dem Eintrag
GLCD_DEVICE_AVR8 und GLCD_CONTROLLER_ST7565 als defined symbols (-D)
in "C Compiler Symbole" des Atmel Studio:"tool chain" compiliert der
gcc fehlerfrei.
Ich bedanke mich für alle Beiträge.
MfG
Gerry