Forum: Mikrocontroller und Digitale Elektronik sd-Karten, Sektoren, Cluster


von Grundschüler (Gast)


Lesenswert?

noch einige Fragen zu Elm chans Fat:

Ich habe eine Datei mit 300k Byte angelegt.
Anfangssektor ist 339792

Die link-table sagt 74 Cluster hintereinander + Startcluster 38669.

Ich gehe davon aus, dass der Sektor ohne Offset von Beginn der Karte 
zählt?

Wie ist das mit den Clustern? Ich nehme an, 8 Sektoren ergeben einen 
Cluster. Woher kommt dann der Offset von den Clustern gegenüber den 
Sektoren? Woher weiß man bei fragmentierten Dateien, mit welchem Sektor 
eines Clusters anzufangen ist?

sector ist bei Chan ein 32bit-Wert. Wie wird der 33bit-Bereich der Karte 
angesprochen?

von holger (Gast)


Lesenswert?

Such nach fatgen103.pdf. Da steht alles drin was du wissen musst.

von c-hater (Gast)


Lesenswert?

Grundschüler schrieb:

> noch einige Fragen zu Elm chans Fat:

Das ist schon das erste grundlegende Problem, was du hast: Es ist nicht 
Elm chans FAT. Sondern das von Microsoft. Elm hat's bloß implementiert. 
Zum tausendsten(?) Mal.

> Ich gehe davon aus, dass der Sektor ohne Offset von Beginn der Karte
> zählt?

Schon falsch. Gerechnet wird vom Beginn der Partition (sofern es eine 
gibt, was der Normalfall ist). Nur wenn die Karte als "Superfloppy" 
formatiert ist, stimmt der Nullpunkt der Kartenadresse mit dem Nullpunkt 
des Filesystems überein.

> Wie ist das mit den Clustern? Ich nehme an, 8 Sektoren ergeben einen
> Cluster.

Nur dann, wenn das entsprechende Feld des Headers das so sagt. Das ist 
ein variabler Wert. Nichtmal für eine Karte konstanter Größe zwingend 
konstant. Man kann es durch Neu"formatieren" ändern.

> Woher kommt dann der Offset von den Clustern gegenüber den
> Sektoren?

Partitionierung. Das Filesystem beginnt einfach nicht am physikalischen 
Beginn des Mediums.

> Woher weiß man bei fragmentierten Dateien, mit welchem Sektor
> eines Clusters anzufangen ist?

Immer beim ersten. Genau das ist doch die Idee des Clustering: 
Verwaltungseinheiten vergrößern, um Verwaltungsinformationen kleiner 
halten zu können.

Wie wäre es, wenn du erstmal lernst, wie FAT funktioniert, bevor du dich 
mit Code auseinandersetzt, der FAT implementiert?

von Grundschüler (Gast)


Lesenswert?

Danke für die konstruktiven Antworten. Das Problem ist, dass ich einen 
großen Teil des Grundlagenwissens außen vor lassen muss, weil ich sonst 
mit meinem Code nicht weiterkomme. Es läuft viel über Versuch und 
Irrtum, aber es läuft dann meist auch irgendwie. Mein Programm schreibt 
inzwischen mittels DMA Blöcke an die richtige Stelle einer Datei, so 
dass man die Datei anschließend mit MS-Chan-Fat-Implementierung - oder 
wie auch immer das richtig bezeichnet wird - auslesen kann.

Damit ist meine Aufgabenstellung bzgl. SD+DMA im Prinzip gelöst, es muss 
nur noch in das Hauptprogramm eingebunden werden.

letzte dumme Frage hierzu: Ist die Anzahl der 512Byte-Blöcke, die mit 
einem cmd25 geschrieben werden können nach oben begrenzt?

von Falk B. (falk)


Lesenswert?

@Grundschüler (Gast)

>Danke für die konstruktiven Antworten. Das Problem ist, dass ich einen
>großen Teil des Grundlagenwissens außen vor lassen muss, weil ich sonst
>mit meinem Code nicht weiterkomme.

:-)
Das ist der Brüller des Tages.

> Es läuft viel über Versuch und
>Irrtum, aber es läuft dann meist auch irgendwie.

Aber nie solide und stabil. Eben WEIL dein Grundlagenwissen viel zu dünn 
ist.

>Damit ist meine Aufgabenstellung bzgl. SD+DMA im Prinzip gelöst,

Nö. Deine Zielstellung war ja, parallel zum laufenden Programm die Daten 
per DMA und INterruptsteuerung zu schreiben. Das macht dein Programm 
Afaik NICHT. Was man tun muss habe ich mehrfach gesagt.

>es muss nur noch in das Hauptprogramm eingebunden werden.

Wo ist dann das Problem?

>letzte dumme Frage hierzu: Ist die Anzahl der 512Byte-Blöcke, die mit
>einem cmd25 geschrieben werden können nach oben begrenzt?

Keine Ahnung, AFAIK setzt FatFs eine Grenze bei 128 Sektoren. OB die 
SD-Karten mehr können weiß ich nicht.

von Grundschüler (Gast)


Lesenswert?

Falk Brunner schrieb:
> Nö. Deine Zielstellung war ja, parallel zum laufenden Programm die Daten
> per DMA und INterruptsteuerung zu schreiben. Das macht dein Programm
> Afaik NICHT. Was man tun muss habe ich mehrfach gesagt.

???????
1
v u32 DMATCCount=0,DMAErrCount,DMA_STATUS,zl_bsy_rpt, blocks, cmd_token,speedtest;
2
3
void DMA_IRQHandler(void)
4
{
5
  uint32_t regVal, x=0,tmp;
6
  regVal = LPC_GPDMA->DMACIntStat;
7
  if ( regVal ){//not error
8
   DMATCCount++;
9
  LPC_GPDMA->DMACIntTCClear = regVal;
10
11
  switch(DMA_STATUS){
12
  case 0://ready abfrage
13
//    buf_rx[0]=xchg_spi(0xFF);        // Receive data resp 0xe5
14
/*    do
15
    {tmp=xchg_spi(0xFf);
16
    buf_rx[10+x]=tmp;
17
    x++;
18
    }
19
      while(tmp!=255);
20
    if(buf_rx[0]!=255){
21
      DMA3_transfer_from_SSP0_to_buffer(16);
22
      return;
23
    }else{//512 Databytes
24
      zl_bsy_rpt=DMATCCount;
25
//      xchg_spi(0xfc);//token_cmd25
26
      DMA_STATUS = 1;
27
      xchg_spi(cmd_token);//token_cmd24
28
      DMA0_512bytes_transfer_to_SSP0(0,512); //buffer_offset,Anzahl_bytes
29
//    }
30
*/  break;
31
  case 1://2xcrc
32
    DMA_STATUS = 2;
33
    DMA2_transfer_from_buffer_to_SSP0(3);//ohne 2 x crc keine response
34
    break;
35
  case 2://"fifo leeren + response"
36
    DMA_STATUS = 3;// Receive data resp (0xe5&0x1F)==0x05
37
    DMA3_transfer_from_SSP0_to_buffer(9);//8x rxfifo leeren + 1x Response abfragen
38
    break;
39
  case 3://busy-abfrage 8xtx
40
  tmp=buf_rx[8];
41
42
  do
43
  {tmp=xchg_spi(0xFf);
44
  buf_rx[10+x]=tmp;
45
  x++;
46
  }
47
    while(tmp!=255);
48
 /* DMA_STATUS = 4;
49
    DMA2_transfer_from_buffer_to_SSP0(8);
50
  case 4://busy-abfrage 8xRx
51
    DMA_STATUS = 5;
52
    DMA3_transfer_from_SSP0_to_buffer(8);
53
    break;
54
  case 5://busy-abfrage auswertung
55
    if(buf_rx[7]=!255){
56
    DMA_STATUS = 4;
57
    DMA2_transfer_from_buffer_to_SSP0(8);
58
    break;
59
    }else{
60
    DMA_STATUS = 6;
61
    }
62
  case 6://next
63
*/    if(cmd_token==0xfe)break;
64
    if(blocks--){
65
    DMA_STATUS = 1;
66
    xchg_spi(cmd_token);//token_cmd24
67
    DMA0_512bytes_transfer_to_SSP0(0,512); //buffer_offset,Anzahl_bytes
68
    }else{
69
    xchg_spi(0xFd);  //cmd25 stoptoken
70
    speedtest = TimeTick;
71
    }
72
73
    break;
74
75
  }//switch
76
  }else{
77
78
  regVal = LPC_GPDMA->DMACIntErrStat;
79
  if ( regVal )
80
  {
81
  DMAErrCount++;
82
  LPC_GPDMA->DMACIntErrClr = regVal;
83
  }
84
  }
85
  return;
86
}

macht es doch, Schreibvorgang läuft im Hintergrund, nur per DMA + 
Interrupt. Getestet mit 20k Daten. Problemlos und fehlerfrei. Ziel sind 
600k Daten.
  do
  {tmp=xchg_spi(0xFf);
  buf_rx[10+x]=tmp;
  x++;
  }
  while(tmp!=255);

Diesen Teil habe ich noch nicht auf DMA umgestellt, weil nennenswerte 
Wartezeiten bislang nicht aufgetreten sind.
Ein einzelner Aufruf von tmp=xchg_spi(0xFf) ist kürzer als der Aufruf 
der DMA

Sollte es hier zu mehreren Schleifendurchläufen kommen, wird auch dies 
durch per DMA ausgelagert.

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.