Forum: Mikrocontroller und Digitale Elektronik SD Card - Blocklength


von Philipp C. (philippo)


Lesenswert?

Hallo,
ich entwickle gerade einen SD Kartentreiber und habe da ein 
Verständnisproblem. Wie ist die Blocklänge zu verstehen. Bei mir 
funktioniert nämlich das Multiple Block Read nicht.

Den ersten Block kann ich lesen, der 2 Byte CRC kommt auch noch, aber 
dann gibt es nur noch FF´s. Muß die Blocklänge dafür angepasst werden? 
Eigentlich lese ich solange ich Daten benötige und sende dann STOP 
Transmission.

Ich kann die Blocklänge auf 1024, 2048 setzen und wenn ich wieder zurück 
gehe auf 512, dann bekomme ich kein 0x00 sondern 0x01 als Antwort.

Philipp

von gast (Gast)


Lesenswert?

hi,

vielleicht hilft dir der source:
http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en537999&lang=en&ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en537999#

und da File IO System for PIC18 PIC24 dsPIC PIC32

das ist eine sd lib von microchip. ist relativ gut dokumentiert. 
verwende ich auch. vielleicht kannst du dort bisschen abgucken.

unterstuetzt aber kein sdhc. wenn du dabei hilfe brauchst sag bescheid. 
meine mdd version unterstützt sdhc...

lg ;)

von Oliver R. (superberti)


Lesenswert?

Bei den meisten Karten ist die Blocklänge eh auf 512 Bytes gesetzt und 
kann nicht mehr verändert werden. Ich benutzte auch SD-Karten mit 
Multiple Block Read. Nach dem CRC16 bekomme ich allerdings immer noch 
genau 2 Bytes, die NICHT zu dem gespeicherten Datenstrom passen. Werden 
auch die übersprungen, dann klappt alles wunderbar. Komisch, dass Du nur 
noch falsche Daten bekommst (oder hast Du vielleicht dort wirklich "FF" 
gespeichert?).
Vielleicht auch mal ne andere Karte probieren?
Deine Vorgehensweise erscheint mir jedenfalls korrekt.

Gruß,

von Philipp (Gast)


Lesenswert?

So, da ich nun schon etwas zu lange daran sitze, hab ich es mir mal mit 
einem Analyser angesehen. Nach jedem Block (inkl. CRC16) kommt so lange 
0x00 bis er auf busy geht (0xFE). Bei meiner Karte kommt somit nach 
jedem Datenblock einmal 0x00 und einmal 0xFE. Dann kommen die nächsten 
Daten. Das dürfte dann auch mit deinen 2 Bytes stimmen.

Philipp

von Oliver R. (superberti)


Lesenswert?

Hallo nochmal,

dann verhalten sich ja die Karten offenbar immer gleich. Ich konnte dies 
aber nicht den SD-Specs entnehmen oder ich habe es nicht verstanden.
Da kommt dann gleich die nächste Frage auf: Kann ich mich darauf 
verlassen, dass es nach einem Block mit CRC IMMER zwei Bytes sind (00 
und FE) oder wie wäre die angemessene Vorgehensweise nach dem Lesen des 
ersten Blocks?
Auf irgendwelche Werte prüfen halte ich für nicht machbar, die könnten 
ja auch aus dem nächsten Datenblock stammen...

Gruß,

von holger (Gast)


Lesenswert?

>(00 und FE) oder wie wäre die angemessene Vorgehensweise nach dem Lesen
>des ersten Blocks?

Warten auf 0xFE

von Philipp C. (philippo)


Lesenswert?

So mache ich es ...
1
           
2
wTimeout = 0xFF;   
3
while ((rc != 0xFE) && wTimeout--) { rc = bySD_ReadByte(); }
4
wTimeout = 0xFF;   
5
while ((rc == 0xFE) && wTimeout--) { rc = bySD_ReadByte(); }
6
7
// rc contains the first data byte
8
*pbyReadBuffer++ = rc;

Als erstes warte ich auf "0xFE" (busy),
dann auf das erste nicht busy = Daten.


Philipp

von Oliver R. (superberti)


Lesenswert?

OK, aber was mache ich falls in meinem Datenblock die ersten 200 Bytes 
zufällig auch "0xFE" sind?

Gruß,

von Thomas K. (muetze1)


Lesenswert?

Wieso? So lange die Anzahl der empfangenen Bytes kleiner als die 
Blockgröße ist, sind es Daten. Danach kommt dann der hier gezeigte Code.

von holger (Gast)


Lesenswert?

>OK, aber was mache ich falls in meinem Datenblock die ersten 200 Bytes
>zufällig auch "0xFE" sind?

Nur das erste zählt. Das ist das Start Block Token.

von Oliver R. (superberti)


Lesenswert?

holger schrieb:
>>OK, aber was mache ich falls in meinem Datenblock die ersten 200 Bytes
>>zufällig auch "0xFE" sind?
>
> Nur das erste zählt. Das ist das Start Block Token.

Ja, aber dann ist die Vorgehensweise

while ((rc == 0xFE) && wTimeout--) { rc = bySD_ReadByte(); }

falsch, denn hier wird nicht nur auf das erste 0xFE geschaut.
Oder anders gesagt: Die Karte darf tatsächlich immer nur ein Byte 0xFE 
als Busy senden, niemals beliebig viele, da ich das dann evtl. nicht von 
Daten unterscheiden kann...

Gruß,

von Philipp (Gast)


Lesenswert?

Also nach den Daten (Länge ist die Blocklänge) kommt ja das Statusbyte 
und danach FE. Die Anzahl kann variieren (langsame Karte), deshalb ein 
"While". Ich hab es nun mit 16M,256M,512M,1G,2G und 8G ausprobiert und 
:-)

MMC habe ich leider keine, aber wenn die Specs 2.0 auch für die SDXC 
gelten (so steht es auf einer Seite), dann sollte ich bis 2TB ruhe 
haben.

Philipp

von Oliver R. (superberti)


Lesenswert?

Thomas K. schrieb:
> Wieso? So lange die Anzahl der empfangenen Bytes kleiner als die
> Blockgröße ist, sind es Daten. Danach kommt dann der hier gezeigte Code.

Es geht aber um das Finden des Anfangs vom ZWEITEN Block.

Gruß,

von Philipp C. (philippo)


Lesenswert?

Philipp schrieb:
> Also nach den Daten (Länge ist die Blocklänge) kommt ja das Statusbyte
> und danach FE. Die Anzahl kann variieren (langsame Karte)
>
> Philipp

Danke, mein Fehler. Stimmt es gibt nur ein FE, aber es können mehrere FF 
kommen bis zum Status (sollte 0x00 sein). Also letzte "While" streichen.

Philipp

von Oliver R. (superberti)


Lesenswert?

Philipp schrieb:
> Also nach den Daten (Länge ist die Blocklänge) kommt ja das Statusbyte
> und danach FE. Die Anzahl kann variieren (langsame Karte), deshalb ein
> "While". Ich hab es nun mit 16M,256M,512M,1G,2G und 8G ausprobiert und
> :-)
>
Jetzt stell Dir doch mal vor, die ersten 200 Bytes des ZWEITEN 
Datenblocks bestehen aus 0xFE. Mit obigen Code würdest Du die dann in 
die Tonne lesen und dir einen Offset von 200 Bytes einfangen. Damit wäre 
Dein Datenstrom korrupt.

Gruß,

von microchip (Gast)


Lesenswert?

Hallo,
hätte da auch noch eine kleine Frage. Ich benutze auch das MDD von 
Mikrochip und möchte möglichst schnell auf die Karte schreiben.
Das ganze funktioniert soweit auch schon, nur kommt mir alles zu langsam 
vor.
Ist es günstiger (schneller) immer 512Byte auf einmal abzuschicken oder 
kann ich auch einfach immer nur z.B. 32 Byte an das MDD schicken. Das 
MDD "sammelt" anscheinend bis 512Byte voll sind und schickt die dann 
erst an die SD-Karte.
Also macht es Sinn selbst 512Byte anzusammeln und dann an MDD zu 
schicken oder macht es keinen Unterschied wenn ich das MDD sammeln 
lasse?
Hoffe das ist verständlich!?
Es gibt ja auch Geschwindigkeitsunterschied bei den SD- Karten. Wie kann 
ich herausfinden, ohne jede zu testen, welche am schnellsten ist?

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.