Forum: Mikrocontroller und Digitale Elektronik FAT16 Sektoren im Cluster Reihenfolge der Belegung


von David L. (davidl)


Lesenswert?

Hi,

kurze Frage an die FAT Experten. In nem Cluster 4 (ab Sektor 711) sind 
bei mir 36 Sektoren. Dort ist der Inhalt einer TXT Datei laut FAT. Wenn 
ich ab Cluster 4 den ersten Sektor ausgebe, kommt erst jede Menge 
Quatsch und dann der richtige Inhalt.

Ist es nicht festgelegt das die Daten immer im 1ten Sektor des Clusters 
anfangen muss ? Oder kann das dort abgelegt sein wie es will ?


MfG
David

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In einem Cluster sind mit Sicherheit NIE 36 Sektoren enthalten. Das sind 
immer glatte Zweierpotenzen.

Dein Algorithmus zur Clustergrößenberechnung scheint daher fehlerhaft zu 
sein, und damit auch die Bestimmung der zu einem Cluster gehörenden 
Sektoren.

von David L. (davidl)


Lesenswert?

sorry tippfehler sind 64
kein algo. ist einfach aus dem VBR ausgelesen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und wie erklärst Du dann, daß der erste Sektor in einem 64 Sektoren 
(also 32 kiByte) großen Cluster die Nummer 711 haben soll?

von David L. (davidl)


Lesenswert?

das interessiert mich nicht, die nummern sind fiktiv, ich wollte eig. 
nur wissen ob daten im cluster immer bei sektor 1 beginnen.

aber hier: mein cluster offset ist sektor 647 da fängt der erste cluster 
an, und 711 ist der zweite cluster usw.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Alle Sektoren, aus denen ein Cluster besteht, sind linear hintereinander 
angeordnet, der erste Sektor ist der erste Sektor.

Wenn Du eine bekannte Datei liest, aber der erwartete Inhalt nicht an 
der erwarteten Stelle steht, hast Du einen Positionierungsfehler.

Um wieviele Sektoren (512-Byte-Schritte) ist denn Dein Dateianfang 
verschoben?

Dein "cluster offset" ist vermutlich um genau diesen Wert zu klein.

von David L. (davidl)


Lesenswert?

hey rufus,

des problem war tat. das meine clustergröße falsch war, ich habe mit 
einer Funktion init die clustergröße rausgelesen

unsigned char cluster_size;
1
init()
2
{
3
cluster_size = Buffer[13];  // ist 64
4
fat_root_dir();
5
// nach rückkehren der funktion // plötzlich 36
6
}
7
8
unsigned int fat_root_dir (unsigned char *Buffer) 
9
{
10
unsigned int FirstRootDirSecNum;
11
unsigned char NumFATs;
12
unsigned short FATSz16;
13
14
mmc_read_sector (volume_boot_record_addr,Buffer);
15
NumFATs = Buffer[16];
16
FATSz16 = Buffer[22] + (Buffer[23] << 8);
17
18
//berechnet den ersten Sector des Root Directory --> VBR_ADR + reservierte Sektoren + (NumFATs * Sektoren per FAT)
19
FirstRootDirSecNum = ( fat_offset + (NumFATs * FATSz16));
20
FirstRootDirSecNum+= volume_boot_record_addr;
21
22
return(FirstRootDirSecNum);
23
}
Ich ändere in der Funktion nichts!
wenn ich cluster_size static mache dann merkt er sich den Inhalt.

Komisch oder ?

von oszi40 (Gast)


Lesenswert?

Schreib einfach was Markantes rein und prüfe dann wo es steht.

http://de.wikipedia.org/wiki/File_Allocation_Table

von David L. (davidl)


Lesenswert?

jo, wie gesagt passt schon, das problem ist das meine variable geändert 
wird ohne dass ich was dran mache. Es gibt auch keine Referenz darauf, 
hmm...
wenn ich die variable mit const deklariere und den 1ten zugriff 
rausmache, dann meckert der compiler nicht, also kann ich davon 
ausgehen, dass mir die niemand mit der original referenz ändert

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ohne Deinen Quelltext zu sehen, ist es natürlich schwierig, 
herauszufinden, warum Dein Variablenzugriff fehlschlägt bzw. welcher 
Effekt da auftritt.

von David L. (davidl)


Lesenswert?

im prinzip sinds zwei funktionen, ich ruf die init auf, und in der init 
die fat_root_dir, und wenn ich von der fat_root_dir zurückkehre ist 
meine variable ansatt 64, 36 außer ich mach se static
1
unsigned char cluster_size;  // 64 Blöcke je 512 Byte
2
unsigned int fat_offset;  // reservierte sektoren
3
unsigned int cluster_offset; // erste cluster
4
unsigned int volume_boot_record_addr; //sek root verzeichnis
5
6
unsigned char TEMP_Buffer[BlockSize];
7
8
9
void fat_init (void)
10
{
11
  int i;
12
  int tmp_size_sek;
13
        unsigned short byte_per_sekor;
14
15
  unsigned char Buffer[BlockSize];
16
17
  mmc_read_sector (MASTER_BOOT_RECORD,Buffer); //Read Master Boot Record 
18
     
19
    if (Buffer[510] == 0x55 && Buffer[511] == 0xAA)
20
    {
21
         FAT_DEBUG("\r\nMBR Signatur found!\r\n");
22
  tmp_size_sek = Buffer[458] + (Buffer[458] << 8);
23
  FAT_DEBUG("Part 1 groessee : %d \n", tmp_size_sek );
24
    }
25
    else
26
    {
27
       FAT_DEBUG("\r\nMBR Signatur not found!\r\n"); 
28
       while(1);
29
    }
30
31
    volume_boot_record_addr = Buffer[VBR_ADDR] + (Buffer[VBR_ADDR+1] << 8);
32
    mmc_read_sector (volume_boot_record_addr,Buffer);
33
  
34
    if (Buffer[510] == 0x55 && Buffer[511] == 0xAA) FAT_DEBUG("\r\nVBR Signatur found!\r\n");
35
   
36
    cluster_size = Buffer[13];
37
    fat_offset = Buffer[14] + (Buffer[15] << 8);
38
    byte_per_sekor = Buffer[11] + (Buffer[12] << 8);
39
    cluster_offset = ((byte_per_sekor * 32)/BlockSize);  
40
FAT_DEBUG("cluser size :%d \n",cluster_size);  // ist 64 !!!
41
    cluster_offset += fat_root_dir_addr(Buffer);
42
43
FAT_DEBUG("cluser size :%d \n",cluster_size);  // ist 36 !!!
44
45
46
}
47
48
49
//Auslesen der Adresse des Root Directory von Volume Boot Record
50
unsigned int fat_root_dir_addr (unsigned char *Buffer) 
51
{
52
53
unsigned int FirstRootDirSecNum;
54
unsigned char NumFATs;
55
unsigned short FATSz16;
56
   
57
//auslesen des Volume Boot Record von der MMC/SD Karte 
58
mmc_read_sector (volume_boot_record_addr,Buffer);
59
NumFATs = Buffer[16];
60
FATSz16 = Buffer[22] + (Buffer[23] << 8);
61
62
63
//berechnet den ersten Sector des Root Directory --> VBR_ADR + reservierte Sektoren + (NumFATs * Sektoren per FAT)
64
FirstRootDirSecNum = ( fat_offset + (NumFATs * FATSz16));
65
FirstRootDirSecNum+= volume_boot_record_addr;
66
67
return(FirstRootDirSecNum);
68
}

von holger (Gast)


Lesenswert?

>FAT_DEBUG("cluser size :%d \n",cluster_size);  // ist 36 !!!

Ob das wirklich so ist?

Du verrechnest dich dauernd! Und das an mehreren Stellen.

    fat_offset = Buffer[14] + (Buffer[15] << 8);

Was ist ein unsigned char wert << 8? Genau, Null.

    fat_offset = Buffer[14] + ((uint16_t)Buffer[15] << 8);

von David L. (davidl)


Lesenswert?

holger schrieb:
> Was ist ein unsigned char wert << 8? Genau, Null.
ne, wie kommst du da drauf ?

Habs grad getestet:
1
unsigned char Buffer[]={0x01, 0x11};
2
unsigned short fat_offset;
3
fat_offset = Buffer[0] + (Buffer[1] << 8);
4
printf("ausgabe: %x\n", fat_offset);

ausgabe: 0x1101

>> so rum is null , also 0

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann ist Dein Compiler gutmütig eingestellt und macht bei 
Schiebeoperationen eine automatische Typerweiterung.

von David L. (davidl)


Lesenswert?

jo , ich werds auf jeden fall ändern

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.