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?
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?
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?
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.