Hallo zusammen,
ich bin dabei eine 2,5" Festplatte mit meine AT32UC3C zu verbinden.
Das funktioniert auch schon, aber wenn ich versuche die FAT Daten zu
bekommen hängt die Geschichte.
Ich habe einen fertigen Code gefunden, der für einen ATMega geschrieben
ist. Ist auch schon einige Jahre alt. Den habe ich auf meinen Controller
portiert.
Der Zugriff über das ATA-Interface funktioniert soweit, ist aber noch
nicht alles getestet.
In der fat.c liegt die Funktion unsigned char fatInit(void). Und da
fangen die Probleme an.
Die Fat Daten sollen in einer globalen Struktur abgelegt werden. Konkret
geht es um diese beiden Ausdrücke:
Die erzeugen eine Exception und ich hänge in einer Endlosschleife.
Wenn ich ehrlich bin verstehe ich diese Ausdrücke nicht, was da
passieren soll.
Kann mir da jemand auf die Sprünge helfen?
Danke euch!
Grüße, Jens
Ich verstehe nicht, was es an den beiden Code Zeilen NICHT zu verstehen
gibt?
Es gibt Strukturen für Sector Buffer, den Partition Sector und den Boot
Block.
Sektor ist die kleinste Einheit die man auf der Festplatte schreiben
kann.
Im Partition Sector steht die Info, wie die Festplatte partitioniert
ist.
Im Boot Sector steht der Lieder Code des OS.
Die Anweisungen setzen nur Pointer auf die Stelle wo der Sektor
eingelesen wurde.
Damit man bequem die Daten auslesen kann.
Das Exception Problem, ...
Es riecht förmlich nach Problemen mit der Interpretation der struct.
Da stimmen wahrscheinlich die Längen der einzelnen Felder nicht.
Compiler haben unterschiedliche Auffassungen über die Größe von
Variablen.
Und manchmal machen Compiler das aligning so, daß es Probleme gibt.
Google Mail nach packed structure ...
Hallo Thomas W,
das hat geholfen!
Die structs habe ich mit "__attribute__ ((packed))" ausgestattet und
schon geht es.
Das ist wohl bei der Portierung notwendig von einem 8bit System auf
eines mit 32bit.
Danke dir!
Grüße, Jens
Hallo zusammen,
also da ist noch ein Problem. Aber ein anderes.
Das Thema von oben ist erledigt. Läuft!
Ich kann die Festplatte richtig initialisieren und die Statusregister
auslesen. Und ich kann die eigenen Werte wie Größe uns Hersteller und so
weiter auslesen.
Bei der Größe fängt es aber schon an.
Die Daten werden beim Lesen in einen Buffer geschrieben, der als char
definiert ist.
Also ein Byte nach dem anderen. Die Byteorder ist auch richtig.
Bei der Portierung wechselte ich aber auf einen 16bit Bus, was bei einem
32bit Prozessor Sinn macht. Und ich schreibe die Daten auch der Reihe
nach in den Buffer.
Die Größe der Festplatte wird als 32bit Wert gespeichert. Und da ist nun
das Low-Word und das High-Word getauscht.
Also konkret: Die Byteorder (der 16bit Zugriffe) ist richtig, aber im
Speicher landen die 16bit Werte getauscht.
Ich habe nun für die Größe ein Macro erstellt, das dies behebt. Keine
große Sache, aber die Fat-Daten kann ich so nicht lesen, wenn da noch
Werte getauscht sind.
Meine Frage ist nun, wie so ein Verhalten zustande kommen kann.
Hat das auch noch mit der Portierung zu tun? Oder liegt es daran, wie
das bei Festplatten gemacht wird?
Ich würde mir den Umweg über das Macro gerne ersparen, da dies nur
Symptome lindert, aber das Problem nicht löst.
Wo sollte ich denn nochmal genau hin schauen, um hier weiter zu kommen?
Ich bin grad etwas ratlos. Oder wer kennt ein ähnliches Verhalten?
Danke euch!
Grüße, Jens
Ein passendes Stichwort wäre "Endianness".
Wenn du ein Little-Endian-System hast (wie die meisten Architekturen,
vermutlich auch dein AVR32), dann liegen die Bytes anders im Speicher
als ihre Interpretation (d.h. als in den Registern). Das heißt, uint32_t
und uint8_t[4] sehen unterschiedlich aus, was man so erstmal nicht
erwarten würde.
Beheben kann man das mit Makros oder kleinen Funktionen, aber man muss
sich immer bewusst sein, welche Endianness jeder Wert hat, der ins
System reinkommt oder aus dem System raus soll. Ich tippe mal spontan,
dass dein Code da nicht explizit ist und dein Kopf auch nicht. :-)
Nun, das Phänomen kennst Du jetzt schon. Fehlt nur noch der Name:
Endianess.
Vielleicht liest Du mal den Wikipedia-Artikel zur Einstimmung.
Was geschieht ist eigentlich recht einfach: Die Bytes werden von
unterschiedlichen Systemen und Operationen in gewissen Fällen in
unterschiedlicher Reihenfolge abgelegt.
So einfach das ist, so wichtig ist, genau zu verfolgen, an welchen
Übergängen zwischen Systemen, bei welchen Operationen welche Reihenfolge
verwendet wird.
Dazu wird in Deinem Fall, die Spezifikation der FAT, des Busses, der
Ports, deren Deklaration in der verwendeten Programmiersprache sowie die
Prozessorbeschreibung und die Compilerbeschreibung benötigt.
Inzwischen gibt es auch noch Portabilitätsmakros für die Endianess. Kann
man auch anschauen, wenn man portablen Code schreiben will.
Wenn man es gründlich machen will. :-) Willst Du?
Es ist etwas mühsam, aber nicht kompliziert. Am besten eine Skizze
machen.