Forum: Mikrocontroller und Digitale Elektronik Problem mit FAT an ATA Drive


von Jens W. (jensw)


Angehängte Dateien:

Lesenswert?

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:
1
 
2
 //some code....
3
 PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);
4
 //some code....
5
 bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
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

von Jens W. (jensw)


Lesenswert?

Hat keiner eine Idee?

von Thomas W. (diddl)


Lesenswert?

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.

von Thomas W. (diddl)


Lesenswert?

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 ...

von Jens W. (jensw)


Lesenswert?

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

von Dr. Sommer (Gast)


Lesenswert?

Das Problem ist in Serialisierung näher erläutert.

von Jens W. (jensw)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jens W. schrieb:
> aber im Speicher landen die 16bit Werte getauscht.

Das wird dann wohl an Deinem Programm liegen.

von S. R. (svenska)


Lesenswert?

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. :-)

von Theor (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.