Problem beim Lesen des SD-Kartensektors

Ich verwende FatFS . Nachdem ich das Karteninitialisierungsproblem gelöst habe, versuche ich, Sektor 0 zu lesen, aber die Karte gibt Junk-Daten zurück.

Dies ist mein Lesevorgang: Geben Sie hier die Bildbeschreibung einIch sehe, dass die Karte mit 0x00 geantwortet hat, was bedeutet, dass sie gelesen wird, um Daten zu liefern.

Natürlich sieht mein nullter Sektor, der mit einem USB-Kartenleser ausgegeben wurde, korrekt aus:Geben Sie hier die Bildbeschreibung ein

Dies ist mein Debug-Protokoll (CMD-Nummern sind in Hex):

    388:mmc_disk_initialize: SPI initialized
    366:send_cmd_INTERNAL: call 401 Cmd 00 response 01
    403:mmc_disk_initialize: CMD0 okay
    366:send_cmd_INTERNAL: call 405 Cmd 08 response 01
    406:mmc_disk_initialize: CMD8 okay - this is an SDv2 card
    409:mmc_disk_initialize: CMD8 response 000001AA
    413:mmc_disk_initialize: Waiting for leaving idle state
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
    366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
    366:send_cmd_INTERNAL: call 415 Cmd 29 response 00
    419:mmc_disk_initialize: Checking CCS bit in OCR
    366:send_cmd_INTERNAL: call 420 Cmd 3A response 00
    423:mmc_disk_initialize: CMD58 response 80FF8000
    452:mmc_disk_initialize: Init okay
    40:disk_initialize: status = 0
    58:disk_read_INTERNAL: Call from 27
    366:send_cmd_INTERNAL: call 494 Cmd 11 response 00
    60:disk_read_INTERNAL: buf=20001588 sector=0 count=1
    27:test_task1: Read result 0
    28:test_task1: dump len 512
    FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    FE000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    00000000000000000000000000000000
    0000000000000000001B3DAFBF000080
    0101008311F4FD3E000000C2EF3A0000
    00000000000000000000000000000000
    00000000000000000000000000000000 
  • Meine Debug-Daten stimmen zu 100 % mit dem Datenverkehr des Logikanalysators überein.
  • Die Initialisierung ist die gleiche wie im FatFS-Referenztreiber, nur die SPI-Schicht wird geändert, daher würde ich erwarten, dass die Initialisierung fehlschlägt, wenn etwas mit SPI selbst nicht stimmt
  • Der SPI-Takt liegt bei etwa 150 kHz
  • Die Karte gibt jedes Mal denselben Müll zurück, eine andere Karte gibt zuverlässig einen anderen Müll zurück
  • Ich sende 2 Dummy-Bytes mit CS hoch zwischen den Befehlen

Was sollte ich überprüfen/ändern, damit der Lesebefehl zuverlässig funktioniert?

Wie @TurboJ unten angibt, zeigt die 0x00-Antwort auf Ihren Lesebefehl nur die Annahme des Befehls an. Danach müssen Sie 0xff lesen/überspringen, bis Sie das Datenstarttoken 0xFE sehen; die Daten des angeforderten Blocks folgen diesem Token. Allerdings scheinen Sie immer noch den falschen Block zu entleeren.

Antworten (3)

Was Sie vom µC ablesen, ist der MBR (Master Boot Record) mit der Partitionstabelle. Diese Daten können Sie auf einem Betriebssystem wie Windows ohne Administratorrechte nicht lesen! Die Daten des USB-Kartenlesers zeigen deutlich den ersten Sektor des "Laufwerks" (Partition) - der nicht Sektor 0 (Null) ist.

Einige Hex-Editoren können Ihnen den MBR anzeigen, wenn Sie als Administrator gestartet werden - aber Sie müssen das richtige physische Gerät verwenden, das keinen Laufwerksbuchstaben hat.

Ich habe es mit dd if=/dev/sdb of=my_file bs=512 count=1 ausgegeben, also glaube ich, dass ich Sektor 0 ausgegeben habe. Ich habe überprüft, wie FatFS das richtige Dateisystem erkennt und es sich die Magie bei Byte 510 ansieht (BS_55AA in ff.c). Auch ohne das FatFS in Sicht, denke ich, dass ich beim Lesen von Sektor 0 die gleichen Daten auf meiner MCU erhalten sollte, die ich von einem USB-Kartenleser bekomme.
Bist du dir 100% sicher? Ein FAT12-Dateisystem kann nicht größer als 32 MByte sein, aber Ihre SD ist eine 2.0, die im GB-Bereich liegen sollte.
Ich habe mit dem genauen Befehl wie im obigen Kommentar abgeladen. Die Karte hat 32 GB. Ich habe jetzt ein Dummy-Dateisystem mit mkfs.vfat auf einer Datei (ohne Partitionstabelle) erstellt und obwohl es die Zeichenfolge FAT32 hat, hat es immer noch 0x55AA Magic bei Offset 510 (dezimal). Ich denke, es ist immer noch nicht das Problem des Dateisystems, sondern des zugrunde liegenden Blockzugriffs der SD-Karte.
Haben Sie z. B. mit überprüft, fdiskob Sie den richtigen Gerätenamen verwenden?
Beachten Sie, dass Ihnen auf dem µC einige Bytes zu fehlen scheinen, da der Sektor 0mit dem 0x00Byte nach dem 0xFEToken beginnt.

Schauen wir uns die Dumps an:

  • Ihr SD-Karten-Hex-Dump zeigt die korrekte Befehlsausführung. Daten beginnen mit Datentoken (FE), und wie TurboJ sagte, scheint es eine Partitionstabelle zu sein, aber es gibt einige Artefakte darin (1B3DAFBF0000). Informationen zum ersten Band von MBR:

    80 01 01 00 83 11 F4 FD 3E 00 00 00 C2 EF 3A 00

Aktive Partition, Typ 83 (native Linux-Partition), Volume First LBA ist 0000003E und Größe 003AEFC2 (1.977.582.592 ~ 2 GB Partition).

  • Ihr erster Hex-Dump zeigt wirklich den Bootsektor des FAT12-Dateisystems, der ein weiterer Teil des Dateisystems ist. Seine OEM-ID zeigt MSWIN4.1 (formatiert unter Windows 95/98/ME); Mediendeskriptor ist 0xF8 (Festplatte); Sektoren pro Cluster ist 0x40 (64); Anzahl der Sektoren 0x5545 (11.176.448 Bytes Volumen). Es ist keine Diskette, keine Festplatte. Höchstwahrscheinlich wurde es mit einer Anwendung formatiert, die Bilder für ältere Geräte erstellt, die FAT12 unterstützen, und die OEM-ID fälscht, sodass das Gerät unter Windows/Linux/Mobilgeräten lesbar ist.

Fazit: Es ist schwer, eine Schlussfolgerung zu ziehen. Lesen Sie die gesamte SD-Karte auf Ihrem Windows/Linux-Host (z. B. mit Image Writer) und sehen Sie sie sich mit dem Hex/Binär-Viewer an. Die Struktur der Karte kann durch ein spezielles Werkzeug erstellt werden, daher kann ihr Inhalt unvorhersehbar sein. Aber was ich mit Sicherheit sagen kann, dass der Bootsektor, den Sie im ersten Dump angegeben haben, unter normalen Umständen nicht dem Volumen des Geräts mit MBR im zweiten Dump entsprechen sollte.

Das Problem war, dass ich anfing, Daten, die direkt nach 0x00 von der Karte kamen, als Sektornutzlast zu behandeln. Ich habe das behoben, indem ich nach dem Senden des Befehls zuerst auf 0x00 gewartet habe und dann auf 0xFE (das ist der Beginn des Datenbytes) gewartet habe. Jetzt kann ich das Dateisystem lesen und Dateien auflisten.