Forum: Mikrocontroller und Digitale Elektronik Adressierung der Daten auf einer SD-Karte?


von Andre Z. (andrez)


Lesenswert?

Hallo zusammen,

ich habe für einen ATmega644 ein Programm zum auslesen einer SD-Karte 
(Fat16, 512MB) geschrieben. (3,3v-Regler und Levelshifter verwendet).

Das klappt auch wunderbar, die Karte antwortet auf die CMD0 und 
CMD1-Kommandos wie sie soll!

Lese ich jetzt per CMD17 mit Argument "00 00 00 00" den ersten Block 
aus, empfange ich auch 512 Bytes Daten, soweit so gut!

Allerdings unterscheidet dich dieser erste Block, vom Sektor 0 der 
Karte!
Über den PC ausgelesen, sieht der Sektor (=Bootsektor) so aus, wie er 
soll (FAT16), Sprunganweisung am Anfang, "55 AA" am Schluss, und so 
weiter.

Die Antwort auf mein CMD17 zum auslesen des Blocks sieht allerdings 
etwas anders aus:

   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 03
   33 00 0F 04 D3 CD EF 00 00 00 1F 04 0E 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 55 AA

Wie kommt das? Immerhin ist das ausgelesene auch ein Bootsektor (55 AA 
am Schluss).

Habe ich den falschen Sektor/Block gelesen?
Wie setzt sich das Adress-Argument im CMD17-Command zusammen? Startbyte? 
Oder Startblock? Und was habe ich dann ausgelesen?

Danke schonmal für Eure Hilfe!!

: Gesperrt durch Moderator
von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Hast Du am Datenasgang der Karte einen PullUp nach 3.3V? Falls nicht, 
kannst Du die Antworten der Karte gar nicht richtg auswerten, da diese 
den SPI-Bus erst dann korrekt bedient, wenn die ersten Init-Kommandos 
erfolgrech angekommen sind . Eine erfolgreiche Init ist auch die 
Grundvoraussetzung für plausible Daten beim Leseversuch.

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

du liest den Masterbootrecord
mit der partiionstabelle

33 00 0F 04 D3 CD EF

dort steht wo der bootsector liegt etc

von Andre Z. (andrez)


Lesenswert?

@Travel Rec.

ich verwende das Evaluationsboard nach 
http://heldt-intern.dyndns.org/index.php?page=atmega32-644-experimentierboard, 
da sollte mit der Beschaltung alles stimmen, und das init funktinoiert 
ja auch korrekt (CMD0 und CMD1)!

@Bereits Fort:
Das ist interessant, ich werde mal googeln wie ich daraus den Sektor des 
Bootsektors errechne!

Interessant auch, das das PC-Tool den mbr-Sektor ignoriert, und die 
Anzeige erst mit dem Bootsektor beginnt - obwohl, so abwegig ist das 
auch nicht...

Was ich jetzt allerdings noch wissen müsste ist, wie ich den Parameter 
berechnen muss, den ich der Karte im CMD17 zum Block-read übergeben 
muss, weis das jemand?

Viele Grüße
  André

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

wenn ich heute abend zeit habe such ich dir raus was ich schon raus 
gefunden habe.

Leider gibt es SD mit und ohne partitionstabelle und das lässt sich 
nicht so leicht unterscheiden.

im MBR ist lauffähiger 86er-Code enthalten der entweder Teil des 
Bootrecords selbst ist oder die Partitionstabelle auswertet welche auf 
den Bootrecord der Bootpartition verweist. und an diese übergibt.

Leider habe ich noch kein eindeutiges Merkmal zur Unterscheidung von 
Bootrecord und MBR gefunden ohne den 86er-Code auszuwerten.

von Jean P. (fubu1000)


Lesenswert?

Hi,

Master Boot Record
=0
Volume Boot Record
=1C6h(4Byte) in Master Boot Record
FAT-Einträge
= Volume Boot Record + 0Eh(2Byte) in Volume Boot Record
Verzeichniseinträge
= FAT-Einträge + (16h(2Byte) * 10h(1Byte)) in Volume Boot Record
Datenbereich (Cluster 0)
= Verzeichniseinträge + (11h(2Byte) * 32 / 512 )in Volume Boot Record


Viel Spaß

von Jean P. (fubu1000)


Lesenswert?

Achso und Vorsicht, Fat benutzt little Endian.

von Andre Z. (andrez)


Lesenswert?

@ Fabian Ostner

Hmm, leider habe ich Dein posting nicht so ganz verstanden...

Also den Karteninhalt der mir am PC angezeigt wird, also 
VolumeBootRecord, FAT, Stammverzeichnis, Datenbereich, das hab' ich 
alles verstanden.

Die Partitionstabelle im mbr hab ich inzwischen auch durchstiegen, 
allerdings nicht in meinem konkreten Fall, da machen die Angaben 
irgendwie keinen Sinn, vor allem die periodischen "0F 04" irritieren 
mich!

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

die 0f 04 irritieren mich auch sieht nach nem systematischen Fehler aus
nimm mal ne andere SD  und /oder nen andern Sector/Block

und Kontrolliere deine Routine da scheint mir auch was faul.

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

1
XX    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
2
00   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
3
01   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
4
02   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
5
03   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
6
04   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
7
05   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
8
06   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
9
07   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
10
08   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
11
09   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
12
0A   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
13
0B   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
14
0C   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
15
0D   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
16
0E   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
17
0F   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
18
10   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
19
11   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
20
12   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
21
13   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
22
14   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
23
15   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
24
16   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
25
17   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
26
18   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
27
19   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
28
1A   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
29
1B   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 03
30
1C   33 00 0F 04 D3 CD EF 00 00 00 1F 04 0E 00 00 00
31
1D   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
32
1E   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 00 00
33
1F   00 00 0F 04 00 00 00 00 00 00 0F 04 00 00 55 AA

von Andre Z. (andrez)


Lesenswert?

@ Bereits Fort

> die 0f 04 irritieren mich auch sieht nach nem systematischen Fehler aus
> nimm mal ne andere SD  und /oder nen andern Sector/Block

eine andere SD muss ich erst besorgen, und einen anderen Sektor/Block zu 
lesen klappt nicht, denn andere Argumente beim CMD17 als "00 00 00 00" 
liefern eine ungültige Antwort von der Karte, daher auch die Frage nachd 
er korrekten Adressierung der Sektoren....

> und Kontrolliere deine Routine da scheint mir auch was faul.

Hmm, okay, ich schaus mir nochmal an, aber die Routine mach im Prinzip 
nix anderes als nach Senden des Kommandos und Erhalt der Antwort 512 
Bytes über SPI einzulesen...

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

dein Volume Bootrecord sollte in sector

00 00 00 EF

beginnen

von Andre Z. (andrez)


Lesenswert?

Bereits Fort wrote:
> dein Volume Bootrecord sollte in sector
> 00 00 00 EF
> beginnen

Danke schonmal! das deckt sich lustigerweise auch mit der Angabe der 239 
(=EF) "versteckten" Sektoren aus dem VolumeBootRecord, den ich mit 
Windows auslesen konnte ;)

Jetzt muss ich nur noch die Angabe "EF" in eine Adresse umrechnen, die 
ich der SD-Karte übergeben kann....

von Jean P. (fubu1000)


Lesenswert?

Hallo Andre,
also die Addressierung erfolgt Sektorweise. Das heisst du kannst immer 
nur mit einem vielfachen von 512 addressieren.
Z.B 0x00000000 = MBR , oder 0x00000200 , oder 0x00000400 , usw....

Gruß

von nullahn (Gast)


Lesenswert?

Die vielen 0F 04 Gruppen sehen auf jeden fall nach schrott aus.

Dein PC Programm arbeitet mit dem Logischem und nicht mit dem 
Physikalischem Laufwerk.

von Andre Z. (andrez)


Lesenswert?

Okay, habs grad ausprobiert.

Die Adressierung mit vielfachen von 512 funktioniert, und der 
VolumeBootRecord liegt auch an EF, so wie ich ihn vom PC her kenne!

Allerdings wird jeder Sektor beim Auslesen von Diesen 8 
Byte-periodischen 0F 04 überlagert, wenn auch nicht immer mit dem 
gleichen Offset! Woher kann das kommen??

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

auch bei ner anderen SD?


wenn ja dann stimmt was an deinem programm (leseroutine ?) 
(anzeigeroutine ?) nicht.

sonst könnte es ein kommunikationsfehler sein.

von Jean P. (fubu1000)


Lesenswert?

Hallo,
lade dir mal WINHEX runter und schau mal nach ob die 0F 04 wirklich da 
stehen. Falls nicht dann poste doch mal deine SD_lese Routine.
Bzw. ich rate einfach mal du speicherst den gelesenen #Sektor im EEPROM, 
also auch die Routine mal posten.

Gruß

von Andre Z. (andrez)


Angehängte Dateien:

Lesenswert?

Hmm, mit einer anderen Speicherkarte funktionierts einwandfrei, kein 
Byte das da nicht hingehört!

Am PC wird der Inhalt der fehlerhaft dargestellten Karte aber korrekt 
angezeigt, ohne die "0F 04"...

Anbei der Code, leider schlecht kommentiert, aber die relevanten Sachen 
laufen am Ende vom Programm bzw. in den SUBs und Funktionen ab...

Ach ja, hab' ich schon erwähnt das ich das ganze in Bascom mache? ;)

hier noch schnell die Lese-Routine auf einen Blick:

unmittelbar nach Sendendes Kommandos und Erhalt der R1-.Antwort (0x00) 
folgt:
1
Do
2
   Spiin Tmp , 1
3
Loop Until Tmp = &HFE
4
5
For J = 0 To 511
6
   Spiin Buffer(j) , 1
7
Next J
8
9
Spiin Tmp , 1
10
Spiin Tmp , 1

Hätt ich also doch nicht die günstigste Karte bei ebay kaufen sollen, 
wenn die SanDisk geht? ;)

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

>Hmm, mit einer anderen Speicherkarte funktionierts einwandfrei, kein
>Byte das da nicht hingehört!

>Am PC wird der Inhalt der fehlerhaft dargestellten Karte aber korrekt
>angezeigt, ohne die "0F 04"...


Das spricht für einen zyklischen Kommunikationsfehler.

etwas langsamer takten?

von Andre Z. (andrez)


Lesenswert?

Bereits Fort wrote:

> Das spricht für einen zyklischen Kommunikationsfehler.
>
> etwas langsamer takten?

Habe den identischen Fehler bei minimaler (/128) und maximaler(/4) 
Geschwindigkeit! (Zwischenwerte nicht getestet...).

Der Mega644 läuft auf 16 MHz...

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

Zeig mal die spiin oder machst du mit HW SPI

Laufen noch irgendwelche Timer oder andere Interrupts?

wo liegt Buffer.

von Andre Z. (andrez)


Lesenswert?

Bereits Fort wrote:
> Zeig mal die spiin oder machst du mit HW SPI

spiin ist die Bascom-Interne Routine. Benutze HW-SPI.

> Laufen noch irgendwelche Timer oder andere Interrupts?

keine Timer, keine Interrupts... einzige weitere Peripherie ist ein 
LCD-Display, aber das tut eigentlich nichts während dem Einlesen der 
Daten

> wo liegt Buffer.

Äh, denke mal im SRAM?
-> Dim Buffer(512) As Byte

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

? mist!


wenn das bei anderen SD funktioniert kanns der buffer nicht sein sind 
die 3V stabil ?
nen Blockkondensator direkt an der SDkarte ?

ich hatte damal eine da ist die spannung  beim lesen periodisch 
eingebrochen gab nen ähnliches Bild. Bis hin zum absturz(aufhängen der 
SPI)

ach ja dan gabs da noch verschiedene SPI modi an der HW-SPI  das timing 
bezüglich der Flankenfolge betreffend.

von holger (Gast)


Lesenswert?

@ Travel Rec.

>Hast Du am Datenasgang der Karte einen PullUp nach 3.3V? Falls nicht,
>kannst Du die Antworten der Karte gar nicht richtg auswerten,

Das ist mir neu. Pullup braucht man nicht. Es sei denn man
möchte ein 0xFF falls die Karte nicht drin ist und der Eingang
demzufolge floaten würde.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der Ausgang der SD-Karte floatet so lange, bis der SPI-Modus angewählt 
ist. Eine Reaktion der Karte auf das erfolgreiche Auswählen des 
SPI-Modus kann man nur dann abfragen, wenn man in der Init solange 
weiterclockt, bis die Karte mit einem Wert ungleich $FF antwortet. Ohne 
PullUp ist dieser anfängliche Status undefiniert und die Init kann in 
eine Sackgasse laufen.

von holger (Gast)


Lesenswert?

>The SD Card is powered up in the SD mode. It will enter SPI mode if the CS 
>signal is asserted
>(negative) during the reception of the reset command (CMD0).

Eigentlich muss man doch nur CS auf low ziehen wenn CMD0
gesendet wird. Dann ist sie im SPI Mode. Pullup nicht mehr nötig.
Oder habe ich das falsch verstanden?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Das hast Du schon korrekt verstanden, aber die Karte zieht den DataOut 
erst dann auf einen definierten Pegel, wenn der SPI-Mode aktiviert wurde 
und das ist erst nach erfolgreicher Ausführung des CMD0 der Fall. Vorher 
floatet der Pin. Du bekommst bei der Response R1, die dem CMD0 folgen 
muß also möglicherweise zu früh eine vermeintlich korrekte Antwort, weil 
der Pin gerade auf 0 geht, obwohl die Karte noch gar nicht bereit ist. 
Du versuchst dann weiter zu initialisieren und bekommst nur noch Müll 
oder gar nichts zu lesen. Mit PullUp ist die Leitung definiert logisch 
1, solange die Karte benötigt, um den Ausgang zu aktivieren.

von holger (Gast)


Lesenswert?

>Mit PullUp ist die Leitung definiert logisch
>1, solange die Karte benötigt, um den Ausgang zu aktivieren.

Ja ok. Dann frag ich mich nur noch warum ich noch nie
einen Pullup brauchte? Mit zwölf unterschiedlichen Karten
geht es ohne. Bei einigen muss man nur CMD0 bis zu drei mal senden.
Vieleicht versuch ichs mal irgendwann mit Pullup ;)

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

Mir erklärt das, warum ich anfänglich erhebliche Schwierigkeiten mit der 
Initialisierung hatte.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ich sende CMD0 exakt ein einziges Mal, bei allen der 10 bisher 
probierten Karten.

von Andre Z. (andrez)


Lesenswert?

Hmm, also ich habe zwischenzeitlich sowohl einen extra 100nF Kondensator 
an der Versorgungsspannung, als auch einen 10k Pullup an Do der Karte 
gehängt.

Trotzdem werden Die Daten der billigen SC-Karte von den periodischen 
Störungen überlagert, die SanDisk-Karte funktiniert einwandfrei...

Werde dann wohl gezwungenermaßen die billige Karte aussortieren (Oder 
möchte sie einer von Euch in seiner Schaltung ausprobieren?) Oder ich 
teste Sie mal in der Digicam, vielleicht kommt die ja damit zurecht!

Danke trotzdem für Eure Unterstützung, und wenn noch jemandem was 
einfällt... :)

Viele Grüße
  André

von Armin J. (arminj)


Lesenswert?

Da es ja verschiedene Aussagen zur Notwendigkeit eines Pullups gibt, 
hier meine Erfahrung.
Eine SanDisk Karte hing sich ohne Pullup nur beim Power up des 
Gesamtsystems (STM32F3-Discovery) auf. Nach Entnahme und wieder 
Einsetzen lief sie dann.
Mit 10kOhm Pullup an DataOut lief sie aber auch direkt beim Power up.
Ich werde ihn jedenfalls immer einbauen!
Gruß
Armin

von Markus H. (traumflug)


Lesenswert?

Weil dieser Thread im Wiki erwähnt wird: bei meiner Karte, einer Samsung 
2GB, brauchte es einen Pullup an DO, um dort überhaupt ein Signal zu 
bekommen. Ohne den Pullup war dieses Signal konstant auf Low.

von Falk B. (falk)


Lesenswert?

@Markus H. (traumflug)

>Weil dieser Thread im Wiki erwähnt wird: bei meiner Karte, einer Samsung
>2GB, brauchte es einen Pullup an DO, um dort überhaupt ein Signal zu
>bekommen. Ohne den Pullup war dieses Signal konstant auf Low.

So will es auch die Spezifikation. Dass einige Karten scheinbar 
zusätzlich einen Pull-Up eingebaut haben, sollte einen nicht dazu 
veranlassen, diesen Widerstand einzusparen. Das lohnt sich nicht.

von Xaver (Gast)


Lesenswert?

gab es nun eine vernünftige Lösung?
gleichs Problem hier bei verschiedenen Karten
mit und ohne Pull-Up
scheint ein Timing Problem zu sein, denn verändere ich den Speed der 
SPI, kommen die fehlerhaften Bytes eine Byte versetzt

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

@Xaver: Dieser Thread ist bereits 7 Jahre alt. Schildere bitte Dein 
Problem detailliert in einem neuen Thread.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.