Hallo zusammen,
ich hab' merkwürdige Probleme mit dem MSPGCC-Compiler. Ich bin
eigentlich dabei, die EFSL (Embedded file system library) für den MSP430
umzuschreiben. Im grossen und ganzen ja kein Problem, aber es scheint
auf dieser Welt keinen MSP430-Compiler zu geben, der das Ding
kompilieren kann. IAR hat so seine Probleme, gemäss CCE ist so ziemlich
jede Zeile falsch und der MSPGCC liefert Fehler, die irgendwie einfach
net logisch sind. Beispiel:
""tmp" undeclared" Code:
1
FAT_File*tmp;
Hallo? tmp wird ja in eben dieser Zeile deklariert!
Allerdings ist das nur die Spitze des Eisbergs. Die Probleme scheinen
alle in den Dateien "helper.h" und "helper.c" (im nächsten Post
angehängt) zu sein.
Hier mal die Fehlermeldungen und Warnungen:
----------------------------------
Severity and Description Path Resource Location Creation Time Id
`f' undeclared (first use in this function) efsl_msp430/src/interfaces
helper.c line 50 1161634750093 19563
warning: implicit declaration of function `fclose'
efsl_msp430/src/interfaces helper.c line 68 1161634750093 19570
`FAT_File' undeclared (first use in this function)
efsl_msp430/src/interfaces helper.c line 59 1161634750093 19566
`file' undeclared (first use in this function)
efsl_msp430/src/interfaces helper.c line 75 1161634750093 19573
`filename' undeclared (first use in this function)
efsl_msp430/src/interfaces helper.c line 50 1161634750093 19565
`SEEK_END' undeclared (first use in this function)
efsl_msp430/src/interfaces helper.c line 75 1161634750093 19574
`tmp' undeclared (first use in this function)
efsl_msp430/src/interfaces helper.c line 59 1161634750093 19567
syntax error before '*' token efsl_msp430/inc/interfaces helper.h
line 45 1161634750093 19559
syntax error before '*' token efsl_msp430/inc/interfaces helper.h
line 47 1161634750093 19560
syntax error before '*' token efsl_msp430/src/interfaces helper.c
line 48 1161634750093 19562
syntax error before '*' token efsl_msp430/src/interfaces helper.c
line 71 1161634750093 19571
warning: implicit declaration of function `fgetc'
efsl_msp430/src/interfaces helper.c line 66 1161634750093 19569
warning: implicit declaration of function `fopen'
efsl_msp430/src/interfaces helper.c line 50 1161634750093 19564
warning: implicit declaration of function `fseek'
efsl_msp430/src/interfaces helper.c line 75 1161634750093 19572
warning: implicit declaration of function `ftell'
efsl_msp430/src/interfaces helper.c line 76 1161634750093 19575
warning: implicit declaration of function `perror'
efsl_msp430/src/interfaces helper.c line 42 1161634750093 19561
warning: ISO C89 forbids mixed declarations and code
efsl_msp430/src/interfaces helper.c line 60 1161634750093 19568
-------------------------------
Anscheinend hat er Probleme mit den Deklarationen der folgenden beiden
Funktionen und ihren Prototypen:
1
voidFopen(FAT_File**f,eint8*filename)
2
{
3
*f=fopen(filename,"r+");
4
if(*f==NULL){
5
perror("Fopen: ");
6
exit(-1);
7
}
8
}
und
1
intgetFileSize(FAT_File*file)
2
{
3
eint32c=0;
4
5
fseek(file,0,SEEK_END);
6
c=ftell(file);
7
return(c);
8
}
Auch in den anderen Funktionen in diesen Dateien wirft er Fehler, die
hängen aber möglicherweise mit diesen beiden Funktionen zusammen...
Ich wäre sehr froh, wenn mir jemand sagen könnte, was an dem Code denn
angeblich falsch ist, bzw. wie ich es hinkriege, dass der MSPGCC diese
Lib kompilieren kann. Bin net so der C-Hai, daher fallen mir
Ungereimtheiten auch net wirklich auf. Wär' ja alles verständlich, wenn
es nicht etwas wäre, was bestimmt schon viele Male von anderen Compilern
erfolgreich kompiliert wurde...
Ich hoffe mir kann jemand helfen und danke im Voraus
Philipp
> (...) und der MSPGCC liefert Fehler, die irgendwie einfach> net logisch sind. Beispiel:> ""tmp" undeclared" Code:>> FAT_File *tmp;>> Hallo? tmp wird ja in eben dieser Zeile deklariert!
Ja, tmp wird da deklariert. Aber was ist "FAT_File"? Wo ist das
deklariert?
Im übrigen solltest Du Fehlermeldungen/Warnungen immer von "oben herab"
betrachten, der erste Fehler ist oft der entscheidende und der Rest sind
nur Folgefehler.
Ohne debug.h und types.h zu sehen, kann man aber nur wenig Schützenhilfe
geben.
Oh sorry, hier sind mal alle Dateien. Geändert habe ich eigentlich nix,
das ganze Ding ist der Code von der EFSL bei SourceForge. Ausser
FAT_File, das hab' ich so beannt, davor hiess es einfach "File". Ich
hab' den Namen geändert, um Probleme mit evtl. gleichheissenden
Bezeichnern zu vermeiden. Hat leider auch nix geholfen, der Fehler ist
der gleiche wie davor.
Zwar bindet helper.c die Datei helper.h ein, aber die wiederum bindet
keine Headerdatei ein, in der der Typ "FAT_File" deklariert wird.
Deklariert wird der zweimal in efs.h und in file.h
Du solltest Dir das mit dem wer-bindet-wann-wo-welche-Headerdatei-ein
nochmal genauer ansehen bzw. sinnvoll überarbeiten.
Warum bindest Du "helper.h" nur in "helper.c" und sonst nirgends ein?
Warum bindest Du die Headerdateien, die Du in "helper.h" einbindest,
nicht gleich in "helper.c" ein, wo sie auch hingehören?
Sorry wegen dem kurzen Post gestern, war etwas im Stress.
Also:
Du meinst also, dass er FAT_File nicht findet und als Fehler angibt,
"tmp" sei nicht deklariert? Ist das ein Fehler des Compilers oder sowas?
Allerdings ist der Fehler, dass FAT_File nicht deklariert ist ja etwas
weiter unten...
Das "wer-bindet-wann-wo-welche-Headerdatei-ein" werde ich mir noch
ansehn, scheint so als wäre das irgendwie etwas verkehrt. Was wäre denn
eine gute Variante, damit sicher überall alles eingebunden wird? Macht
es Sinn, alle Dateien von einer Datei aus einzubinden (Includes.h oder
sowas) und die einfach überall einzubinden, oder ist das nicht so
geschickt?
Jedenfalls schonmal danke für deine Hilfe, ich weiss jetzt jedenfalls
schonmal, was ich mir genauer anschauen muss.
> Was wäre denn eine gute Variante, damit sicher überall alles eingebunden> wird?
Ganz einfach. Jede Einheit, egal ob Header oder C-File bindet
die Header mit ein, die sie selber braucht.
Wenn also in einem helper.h eine struct FAT_file benutzt
wird, und diese struct FAT_file in einem anderen Header
File file.h deklariert ist, dann bindet helper.h die file.h
mit ein.
Dadurch ist sichergestellt, dass derjenige, der seinerseits
helper.h einbindet sich nicht darum kümmern muss, welcher
Rattenschwanz an includes noch nötig ist um helper.h includen
zu können.
Dabei kann es natürlich zu dem Fall kommen, dass ein und dieselbe
Header-Datei bei der Compilierung eines *.c Files mehrfach
includiert wird. Die dabei entsehenden Schwierigkeiten kann
man mit Include-Guards umgehen:
Jede Header-Datei beginnt und endet so (am Beispiel einer
helper.h)
helper.h:
*********
#ifndef HELPER_H_INCLUDED
#define HELPER_H_INCLUDED
#include "file.h"
// Hier kommt dann der Inhalt der helper.h
#endif
file.h:
*******
#ifndef FILE_H_INCLUDED
#define FILE_H_INCLUDED
struct FAT_file {
// bla bla
};
#endif
Damit ist sichergestellt, dass der Compiler bei der Compilierung
eines *.c Files:
helper.c:
*********
#include "helper.h"
#include "file.h"
void FAT_file was_weis_ich()
{
}
den Inhalt von file.h nur ein einziges mal zu Gesicht kriegt,
auch dann wenn helper.c die file.h inkludiert und über den
Umweg über helper.h nochmal.
Aber das Grundprinzip ist: Jeder bindet das ein, was er braucht.
Nicht mehr und nicht weniger.
Solche Alles-inkludieren-Rundumschlag-Header haben sich auf
lange Sicht nicht bewährt.
Zu deinem Fehlermeldungen:
Interessant ist im Regelfall nur die erste Fehlermeldung.
Wird die korrigiert, so fallen oft eine ganze Menge anderer
Fehler weg. Wenn der Compiler durch einen Fehler 'den Faden verloren'
hat, dann kommen oft ne Menge Folgefehler.
> FAT_File *tmp;> Hallo? tmp wird ja in eben dieser Zeile deklariert!
Die erste Fehlermeldung war:
>efsl_msp430/src/interfaces helper.c line 68 1161634750093 19570> `FAT_File' undeclared (first use in this function)
Der Compiler konnte also mit FAT_File nichts anfangen. Er weis
nicht was das ist. Folgerichtig kann er auch keine Variablen
vom Typ FAT_File anlegen, da er ja nicht weis wieviele Bytes
dafür zu reservieren sind. Noch nicht mal einen Pointer. FAT_File
könnte ja auch ein Funktionstyp sein und niemand garantiert, dass
Funktionspointer und Datenpointer dieselbe Länge haben.
Da er also die Variable tmp nicht erzeugen kann, sind daher alle
Verwendungen von tmp ebenfalls illegal. Siehst du wie Eins zum
Anderen führt? Wie gesagt:
Konzentrier dich auf den ersten Fehler oder zumindest: frage
dich bei weiteren Fehlermeldungen ob das nicht ein Folgefehler
sein könnte, der durch Behebung eines früheren Fehlers ebenfalls
verschwindet.
Und schrecke nicht vor vielen Fehlermeldungen zurück: 90%
davon sind meist Folgefehler. Korrigiert man den ersten Fehler
so verschwinden 100 von den 120 Fehlermeldungen ganz von alleine.
> warning: implicit declaration of function `fclose'
Diese Warnung (und alle anderen in weiterer Folge) allerdings
solltest du ernst nehmen.
Entweder hat da wer vergessen stdio.h zu inkludieren (in dem
Fall sollte man ihm das Compilermanual mal um die Ohren hauen,
dass er solche Warnungen ignoriert), oder mit deinem Compiler-
Setup stimmt was nicht.
Also, hab' jetzt nochmal bissle rumprobiert. Ich hab' den Code nun
soweit, dass ich bei einem Fehler angelangt wird (Lag wirklich an den
Includes...). Allerdings wird's langsam relativ strub. Je nachdem wie
fest ich optimieren lasse (O0 - O3) hat er andere "internal error"s. Bei
O0 und O1 (Das erste Zeichen ist ein grosses o):
make: *** [src/debug.o] Error 1 efsl_msp430 line 0
Bei O2:
internal error: Segmentation fault efsl_msp430/src fs.c line 179
make: *** [src/debug.o] Error 1 efsl_msp430 line 0
Und schliesslich bei O3:
Internal compiler error in verify_local_live_at_start, at flow.c:586
efsl_msp430/src fs.c line 60
make: *** [src/debug.o] Error 1 efsl_msp430 line 0
Wenn ich ihn mit der gleichen Einstellung nochmal aufrufe gibt's auch
noch folgende Warnung:
Error launching external scanner info generator (gcc -E -P -v -dD
C:/Programme/eclipse/workspaces/.metadata/.plugins/org.eclipse.cdt.make.
core/specs.c) efsl_msp430 Unknown
In fs.c (Im Anhang) besteht Zeile 60 sowie 179 aus
1
}
Nix weiter, bei beiden ist es das Ende einer Funktion. Allerdings nicht
der gleichen...
Die beiden "internal error"s könnten ein Bug des Compilers sein, muss
ich dessen Erbauern wohl mal schreiben. Aber der andere Fehler "Error 1"
ist eigenartig. In der Konsole steht da sowas:
--------------------
'Building file: ../src/debug.c'
'Invoking: mspgcc GCC C Compiler'
msp430-gcc -I"C:\Programme\mspgcc\msp430\include" -O0 -g3 -Wall -c
-fmessage-length=0 -mmcu=msp430x169 -o"src/debug.o" "../src/debug.c" &&
\
echo -n 'src/debug.d' src/ > 'src/debug.d' && \
msp430-gcc -MM -MG -P -w -I"C:\Programme\mspgcc\msp430\include" -O0
-g3 -Wall -c -fmessage-length=0 -mmcu=msp430x169 "../src/debug.c" >>
'src/debug.d'
Das System kann den angegebenen Pfad nicht finden.
make: *** [src/debug.o] Error 1
--------------------
Und das mehr oder weniger für alle Dateien. Manchmal für ein paar mehr,
manchmal weniger...
Ich blick's echt nicht mehr... Was kann das sein? Und WELCHEN Pfad kann
er denn nicht finden? Ich weiss ja nicht was er mit 'src/debug.xy'
anstellt, aber ich nehme schon an, dass er da im richtigen Verzeichnis
sucht. Ansonsten existieren die Verzeichnisse ja...
Kann mir da auch jemand helfen?
Weiss denn niemand was zu den Fehlermeldungen? Ich komm' echt nimmer
nach. Ich hab' das ganze Ding jetzt mal mit IAR kompiliert und DAMIT
GEHT'S! Aber warum? Das heisst ja, dass der Code jetzt in Ordnung ist,
was hat der mspgcc also für komische Probleme damit?!
Im Anhang mal die gesamte Ausgabe der Konsole.
> -o"src/plibc.o" "../src/plibc.c"
Das sieht seltsam aus. Das die *.c Files auf einem Verzeichnis
namens src liegen, ist noch logisch. Aber dass die Object-Files
auf ein anderes src Verzeichnis gehen, ist schon seltsam:
Zum einen ist es nicht dasselbe Verzeichnis, zum anderen heist
es ebenfalls src. Und das ist schon eher ungewöhnlich. Selbiges
mit den *.d files.
Deine Verzeichnis-Struktur muesste also so aussehen:
was_weis_ich
/ \
src (1) Projekt (3)
\
src (2)
(1) hier muessten die *.c Files zu finden sein
(2) hier enstehen die *.o und *.d Files
(3) hier liegt das makefile
Hast du die Struktur? Ich könnte mir vorstellen, dass
es das Verzeichnis src (2) nicht gibt und sich der Compiler
beschwert, dass er die Ausgabefiles nicht erzeugen kann.
Zu den internal Compiler-Errors:
Sowas ist immer blöd. Da hilft nur mit dem Code etwas spielen.
Dinge umstellen und hoffen, dass du das richtige erwischt.
Also, die Verzeichnisstruktur sieht so aus:
Projekt-Ordner
/ | \
/ | \
src inc Debug
*.c *.h / \
/ \
src makefiles
*.o *.mk
So gesehen eigentlich durchaus existierend, aber ob der da wirklich
immer am richtigen Ort sucht? Und wie könnte man sowas denn umstellen?
>Zu den internal Compiler-Errors:>Sowas ist immer blöd. Da hilft nur mit dem Code etwas spielen.>Dinge umstellen und hoffen, dass du das richtige erwischt.
Na du machst mir Mut ;)
Philipp Burch wrote:
> *f=fopen(filename,"r+");
Das was du da kompilierst macht auf einem MSP430 keinen Sinn, das ist
das "Hardwarelayer" für einen PC wo fopen & Co. zur Verfügung stehen.
Meine Meinung: EFSL ist unübersichtlich, unnötig komplex, schlecht
dokumentiert, und hat ein zweifelhaftes API. Nimm lieber
http://elm-chan.org/fsw/ff/00index_e.html.
Hui, danke für den Link Andreas! Das sieht schonmal sehr gut aus!
Irgendwann hatte ich das schonmal gesehen, hab's aber dann leider wieder
vergessen. Hätte mir womöglich einiges an Arbeit erspart, mal sehn...
PS: Sorry wegen dem falschen Forum.
So, hab's jetzt mit dem Code vom Elm-Chan gemacht. Sieht gut aus! War
noch ein ordentlicher Kampf, bis ich den Debugger zum Laufen gekriegt
hab'. Vielleicht sollte man im Artikel noch erwähnen, dass der u.U.
nicht funktioniert, wenn die Pfade zu lang sind und/oder Leerzeichen
beinhalten. Auf einem "neuen" Laufwerk ohne langen Pfad ging's dann
plötzlich.