Hallo,
ich habe FatFs mit einem eigenem SDIO Treiber auf dem STM32F407.
Der SDIO Treiber tut soweit auch. Allerdings kann FatFs kein Dateisystem
finden. f_mount() liefert immer 13 zurück.
Ich habe mich mit dem Debugger in die disk_read Funktion gehängt. Es
wird der erste Sektor der SD-Karte angefragt. Mein Treiber schreibt
diesen auch einwandfrei in den Puffer. Ebenfalls mit Debugger überprüft.
Im Anhang seht ihr den Dump der ersten 512 Bytes der SD-Karte (Als Bild
und als bin-File). Diesen habe ich mittels dd am PC erstellt. Die vom
Mikrocontroller eingelesenen Daten sind absolut identisch.
Hatte jemand schonmal dieses Problem? Das beschäftigt mich jetzt bereits
einige Stunden. Da die Daten vom Controller gleich eingelesen werden und
mein Treiber soweit tut, fällt mir nicht ein, wo der Fehler sein könnte.
Habe den kompletten MBR und die Partition + das FAT-System mit einem
Windowsrechner bereits mehrfach neu erstellt. Ebenso habe ich andere
Karten versucht. Der PC kann die Karte einwandfrei lesen und
beschreiben.
Ich hoffe ihr könnt mir helfen. Kenne mich mit Dateisystemen nicht aus
und kann nur im Nebel stochern.
EDIT:
FatFS liest nur den ersten Sektor und meldet dann sofort, dass es kein
gültiges FAT-System sei. Deswegen habe ich auch nur die ersten 512 Byte
angehängt.
Danke
Was ist es denn für eine SD-Karte? FATfs kann nur SD und SD HC. Bist du
sicher, daß dein SDIO Treiber WIRKLICH funktioniert? Keine Bytes
verdreht? Sicher, daß dir die Zwischenpufferung nicht irgendwie
dazwischenfunkt?
99% aller Probleme liegen dort, denn FATfs ist tausendfach erprobt.
Falk B. schrieb:> Was ist es denn für eine SD-Karte? FATfs kann nur SD und SD HC.
Die Art der KArte hat nichts mit FatFs zu tun. Man könnte genau so gut
eine VHS Kasette benutzen...
Falk B. schrieb:> Bist du> sicher, daß dein SDIO Treiber WIRKLICH funktioniert? Keine Bytes> verdreht? Sicher, daß dir die Zwischenpufferung nicht irgendwie> dazwischenfunkt?
Ja. Ich bin mir sicher. Im Anhang sind Bilder vom Dump mit dem PC und
vom Speicher im uC.
Es sind alle Bytes da und auch in der richtigen Reihenfolge.
Mir fehlt leider das Wissen, um mit dem ersten Block etwas anzufangen.
Für mich sieht das aber noch nach MBR/Partitionstabelle aus und noch
nicht mal nach FAT. Eigentlich müsste er doch weitere Sektoren lesen,
oder?
M. H. schrieb:> Allerdings kann FatFs kein Dateisystem> finden. f_mount() liefert immer 13 zurück.
Jetzt mal ein ganz ketzerischer Vorschlag... Steppe per Debugger in
f_mount rein und finde die Stelle an der "return 13;" steht, und
schlussfolgere rückwärts was schief läuft. Alles andere ist doch
Kaffeesatz lesen und Stochern im Nebel. Trotz oft hier kundgegebener
andersartiger Meinungen, ist es keine Schande einen Debugger zu benutzen
und Probleme nicht nur durch pures Grübeln zu lösen.
M. H. schrieb:> Mir fehlt leider das Wissen, um mit dem ersten Block etwas anzufangen.
Lies dich mal 30 Minuten auf Wikipedia in die Artikel zu MBR und FAT32
ein, das ist wirklich nicht kompliziert. Das erspart viel Rätseln.
@M. H. (bambel2)
>> Was ist es denn für eine SD-Karte? FATfs kann nur SD und SD HC.>Die Art der KArte hat nichts mit FatFs zu tun. Man könnte genau so gut>eine VHS Kasette benutzen...
Jaja, immer schön schwätzen. Dumm nur, daß sich SD XC Karten auch im
Protokoll unterscheiden.
>Ja. Ich bin mir sicher. Im Anhang sind Bilder vom Dump mit dem PC und>vom Speicher im uC.
Hab ich jetzt nicht im Detail geprüft.
>Mir fehlt leider das Wissen, um mit dem ersten Block etwas anzufangen.
Das musst du auch nicht haben. FATfs weiß was es tut.
>Für mich sieht das aber noch nach MBR/Partitionstabelle aus und noch>nicht mal nach FAT. Eigentlich müsste er doch weitere Sektoren lesen,>oder?
Formatier deine SD-Karte ganz normal mit Windows und gut. Keine
Hackertricks und manuelles Manipulieren der Sektoren. Das brauchst du
nicht.
Falk B. schrieb:> Formatier deine SD-Karte ganz normal mit Windows und gut.
Das ist aber auch verkehrt. Die SD Spezifikation sieht ein ganz
bestimmtes Layout vor, auf welches sich der Controller ggf. verlässt,
welches Windows aber so nicht produziert. Es kann sein dass manche
Karten trotzdem optimal funktionieren, aber es ist Betrieb außerhalb der
Spezifikation. Die einzige von der SD Group vorgesehene Methode zum
Formatieren besteht in dem von sdcard.org herunterladbaren Tool, welches
das Layout korrekt produziert.
M. H. schrieb:> Ich hoffe ihr könnt mir helfen. Kenne mich mit Dateisystemen nicht aus> und kann nur im Nebel stochern.
Ist es eine 4GB SD Card ?
Falls ja, lese mal die Sectors 1166, 8775 und 16384 (Dezimal) und
schaue dir die Dumps an (und/oder als Dump anhängen).
Bambel2,
der Sektor, den Du präsentiert hast, sieht aus wie ein Bootsektor einer
Partition und nicht wie ein MBR (master boot record
[Partitionstabelle]).
Es gibt wohl zwei Möglichkeiten, ein Medium zu strukturieren, einmal
MBR-basiert und das andere heißt wohl "Superfloppy" oder so ähnlich.
Eventuell kommt Dein System mit der MBR-freien Struktur nicht klar.
Neuformatieren bringt nichts, Du müsstest mal probieren, das Ding zu
partitionieren, dann wird ein MBR erzeugt.
Dann hast Du am Ende des ersten Sektors (Sektor 0) die
Partitionsinformation etwa da, wo Deine Fehlermeldungstexte im Moment
stehen.
@Dr. Sommer (Gast)
>> Formatier deine SD-Karte ganz normal mit Windows und gut.>Das ist aber auch verkehrt.
Erzähl doch keinen Quark. Du weißt was ich meine! Das normale
Windows-Format macht KEIN Low Level Format und läßt die Grundstruktur in
Ruhe!
Es schreibt aber gültige MBR, Bootsektor und FAT.
>Spezifikation. Die einzige von der SD Group vorgesehene Methode zum>Formatieren besteht in dem von sdcard.org herunterladbaren Tool, welches>das Layout korrekt produziert.
Das kann man auch machen. Aber selbst eine einfache Karte direkt aus dem
Laden wird funktionieren.
Falk B. schrieb:> Erzähl doch keinen Quark.
Verbreite du kein Halbwissen. Lies die Spezifikation. Es steht alles da.
Falk B. schrieb:> Das normale Windows-Format macht KEIN Low Level Format
Darum geht's nicht.
Falk B. schrieb:> und läßt die Grundstruktur in Ruhe!
Falsch. Es schreibt zB keine leeren Sektoren nach dem FAT Header, und
lässt die Partition ganz am Anfang beginnen. Laut SD Spezifikation
müssen aber bestimmte Abstände da sein. (Wimre müssen die Daten ab
Sektor 8192 beginnen. Das macht aber Windows nicht so).
Falk B. schrieb:> Es schreibt aber gültige MBR, Bootsektor und FAT.
Gültig nach dem FAT Standard, ungültig nach der SD Spezifikation.
Falk B. schrieb:> Formatier deine SD-Karte ganz normal mit Windows und gut. Keine> Hackertricks und manuelles Manipulieren der Sektoren. Das brauchst du> nicht.
Das hab ich gemacht. Hab extra n Windows installiert :P. Da kam dann die
SD Karte ohne Partition raus, wo das FAT System direkt auf die Karte
geschrieben war.
Falk B. schrieb:> Es schreibt aber gültige MBR, Bootsektor und FAT.
Das wage ich zu bezweifeln. ich habe die KArte mit dd if=/dev/urandom
of=/dev/sdx bs=1M count=30 gelöscht und dann mit Windoof ein System
generiert. Da war keine Partition drauf. Siehe erster dump.
ich bin momentan noch dran das ganze zum Laufen zu bringen. Mal schauen,
ob das was wird.
Dr. Sommer schrieb:> Das ist aber auch verkehrt. Die SD Spezifikation sieht ein ganz> bestimmtes Layout vor, auf welches sich der Controller ggf. verlässt,> welches Windows aber so nicht produziert.
Zumindest bei Sandisk ist das nicht essentiell, da hat vor einiger Zeit
extra jemand bei denen angefragt, und die Antwort hier ins Forum
gestellt.
Deren Wear-Leveling verlässt sich nicht auf Eigenheiten von FAT generell
oder gar der mitgelieferten Formatierung, man kann deren Karten ohne
Einschränkung als "transparenten Datenblockspeicher" verwenden.
-> War hier: Beitrag "Re: SDXC 128GB Karte richtig mit EXT4 formatieren"
Εrnst B. schrieb:> Zumindest bei Sandisk ist das nicht essentiell, da hat vor einiger Zeit> extra jemand bei denen angefragt, und die Antwort hier ins Forum> gestellt.
In der Tat, in dem Thread hab ich ja auch geschrieben...
Nichtsdestoweniger verstehe ich nicht, warum man anscheinend auf Biegen
und Brechen sich nicht an die Spezifikation halten möchte und damit
potentielles Nicht-Funktionieren bei anderen Karten, oder neuren
SanDisk-Karten, riskieren möchte, anstelle von einfach das Tool von
sdcard.org zu benutzen und in 3 Minuten alle potentiellen Fehler bei
diesem Aspekt auszuschließen. Wenn ich mich recht erinnere legt das Tool
auch automatisch die korrekte Partitionstabelle/MBR an, sodass dort auch
Fehler ausgeschlossen sind.
Ich habe das Problem jetzt gefunden.
Der SDIO Zugriff funktionier doch nicht richtig. Allerdings weiß ich
nicht, woran es liegt.
Ich schreibe die Daten mittels DMA in den Puffer. Allerdings ist das
letzte 32bit Wort falsch. Es steht 0x00000000 im Speicher statt
0x000055AA (big endian). Ich habe allerdings keine Ahnung, woran das
liegen könnte, da sowohl das SDIO Interface, als auch der DMA keinen
Fehler werfen. DMA sagt, dass der Transfer abgeschlossen sei. SDIO setzt
ebenfalls das Complete flag.
Hatte jemand schonmal dieses Phänomen?
Mein Code, der den Block liest sieht so aus:
Mit dem debugger triggere ich auf das ende der Funktion im Puffer fehlt
dann das letzte 32bit wort.
EDIT: Ich habe den Block mal mit einem Muster gefüllt. Das Modul liest
sogar 12 bytes zu wenig aus. SDIO->DLEN steht auf 512 (geprüft mit
Debugger) und SDIO->DCOUNT steht nach dem Transfer auf 0. => Alle Bytes
empfangen.
Wohin verschwinden die letzten 12 Bytes?
M. H. schrieb:> while (!(SDIO->STA & SDIO_STA_DBCKEND));
Versuch's mal mit SDIO_STA_DATAEND statt DBCKEND.
Setze außerdem am Schluss DMASTREAM->CR auf 0 und lese es aus und warte
darauf bis es tatsächlich zu 0 wird.
Packe mal auf Verdacht ein asm volatile ("dsb"); ans Ende, glaube aber
nicht dass es daran liegt
Pack mal testweise ein Delay ans Ende
Dr. Sommer schrieb:> M. H. schrieb:>> while (!(SDIO->STA & SDIO_STA_DBCKEND));> Versuch's mal mit SDIO_STA_DATAEND statt DBCKEND.> Setze außerdem am Schluss DMASTREAM->CR auf 0 und lese es aus und warte> darauf bis es tatsächlich zu 0 wird.> Packe mal auf Verdacht ein asm volatile ("dsb"); ans Ende, glaube aber> nicht dass es daran liegt> Pack mal testweise ein Delay ans Ende
Das werde ich versuchen.
Der DMA setzt aber das Complete Flag.
Ebenso ist das SDIO-FIFO leer.
Habe mal alles, was du geschrieben hast eingefügt.
Der Code macht aber immernoch den selben Fehler. Die letzten 12 Bytes
fehlen.
Im Anhang mal ein Bild vom dump, der so auf der Karte ist.
Das zweite Bild zeigt, was der Controller liest. Das letzte Byte, das
stimmt ist markiert. Der Rest ist 0
Alle Module sagen, dass der Datentransfer abgeschlossen ist. Kann es
sein, dass die Karte tatsächlich Nullen sendet? Eigentlich sollte dass
doch nicht passieren, oder?
EDIT: Habe jetzt noch weitere Karten ausprobiert. Es ist immer das
gleiche. Die letzten 12 Byte fehlen. Aber die CRC und alles stimmt.
Ich habe jetzt noch etwas herausgefunden:
Nach dem flaschen Lesezugriff springt FatFs wieder in die Main zurück.
Da habe ich mir das Status register des SDIO's nochmal angeschaut.
Folgende flags sind gesetzt:
Wert: 0x202540
RXDAVL (Data available in receive FIFO)
RXACT (Data receive in progress)
DBCKEND (Data block sent/received -- CRC passed)
DATAEND (Data end)
Das verstehe ich nicht. aus der einen Seite sagt das Modul, dass die
Daten empfangen wurden, auf der anderen, dass ein receive gerade im
Gange ist.
Dr. Sommer schrieb:> Öh, du löschst das STA vor dem Kommando aber schon oder?SDIO->ICR> =SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | SDIO_ICR_CTIMEOUTC |> SDIO_ICR_DTIMEOUTC | SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC |> SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | SDIO_ICR_DATAENDC |> SDIO_ICR_STBITERRC | SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC |> SDIO_ICR_CEATAENDC;
Nein mache ich nicht. Ändert aber nichts. Selbst mit deinem Code, zeigt
das Modul an, dass es fertig ist und das FIFO leer ist. Aber man kann
die Fehlenden Daten von Hand aus dem FIFO auslesen.
Der FIFO Count wert steht auf null (= FIFO leer). M;an kann aber
trotzdem noch dei fehlenden Daten rausholen. Ich habe keine Ahnung, was
ich diesem Modul getan habe, dass es sowas macht.
@M. H. (bambel2)
>Das verstehe ich nicht. aus der einen Seite sagt das Modul, dass die>Daten empfangen wurden, auf der anderen, dass ein receive gerade im>Gange ist.
Mit den FIFOs hab ich mir beim ATXmega auch mal ins Knie geschossen 8-0
Wie auch immer man das bei deiner CPU machen muss, man muss sicher
stellen, daß WIRKLCICH alle Daten im Speicher gelandet sind und nicht
noch in irgendwelchen FIFOs rumliegen.
Das ganze funktioniert jetzt. Das FIFOCNT Register ist übrigens
immernoch durchgehend auf 0.
FatFs leißt nun 2 Sketoren. Das ganze funktioniert immernoch nicht.
Weiß jemand, wie die Adresse, die FatFS übergibt zu interpretieren ist?
ist die Sektor Variable die Sektornummer, oder die Byteadresse?
FatFs fragt zuerst nach 0 und dann nach 2048.
Falk B. schrieb:> Mit den FIFOs hab ich mir beim ATXmega auch mal ins Knie geschossen 8-0> Wie auch immer man das bei deiner CPU machen muss, man muss sicher> stellen, daß WIRKLCICH alle Daten im Speicher gelandet sind und nicht> noch in irgendwelchen FIFOs rumliegen.
Das Problem ist: Die FIFOs sagen, dass sie leer sind. Auch nach einiger
Wartezeit. Man kann aber trotzdem noch blind herauslesen. Ist nur
schwierig, weil man nicht weiß, ob noch was valides drin ist...
@M. H. (bambel2)
>Der FIFO Count wert steht auf null (= FIFO leer). M;an kann aber>trotzdem noch dei fehlenden Daten rausholen. Ich habe keine Ahnung, was>ich diesem Modul getan habe, dass es sowas macht.
Falsche Anzahl von Transferworten eingestellt?
Im RM0090 findet sich in Abschnitt 31.3.1 unter "Data FIFO" unter Flags:
RXFIFOHF : Set to high when 8 or more receive FIFO words contain valid
data. This flag can be used as a DMA request.
Bei den anderen Flags kein Hinweis auf DMA. Offenbar ist es also "by
design" so, dass der Transfer u. U. nicht komplett per DMA abgewickelt
werden kann(!) und ggf. ein verbleibender Rest zu Fuß zu bewältigen ist.
A. B. schrieb:> Bei den anderen Flags kein Hinweis auf DMA. Offenbar ist es also "by> design" so, dass der Transfer u. U. nicht komplett per DMA abgewickelt> werden kann(!) und ggf. ein verbleibender Rest zu Fuß zu bewältigen ist.
Nein, definitiv nicht. Ich benutze in einer Anwendung auch das SDIO mit
DMA und da werden immer alle Bytes kopiert. Ich verwende allerdings
Interrupts und keine Busy-Wait-Loops. Für das Problem vom OP weiß ich
aber auch keine Lösung :-/
A. B. schrieb:> Im RM0090 findet sich in Abschnitt 31.3.1 unter "Data FIFO" unter> Flags:>> RXFIFOHF : Set to high when 8 or more receive FIFO words contain valid> data. This flag can be used as a DMA request.>> Bei den anderen Flags kein Hinweis auf DMA. Offenbar ist es also "by> design" so, dass der Transfer u. U. nicht komplett per DMA abgewickelt> werden kann(!) und ggf. ein verbleibender Rest zu Fuß zu bewältigen ist.
Das wäre interessant. Klingt aber nach ST. Die Controller sind zwar gut,
haben Speicher und sind schnell, aber ihre Peripherie ist mir sowas von
unsympathisch :)
Der Code, den ich gepostet habe, hat noch einen Fehler: Es muss
heißen.
Aber ansonsten tut das ganze soweit erstmal. FatFS erkennt die
Partition. :D
Ich melde mich, sobald es wieder Probleme gibt. Der 4bit Mode tut
nämlich noch nicht. Da empfängt er immer Müll und wirft dann einen CRC
Fehler.
M. H. schrieb:> Der Code, den ich gepostet habe, hat noch einen Fehler:
Hier list du "STA" 2x hintereinander aus. Ich würde "STA" 1x auslesen,
in eine temp. Variable speichern, und dann die Flags abfragen.
M. H. schrieb:> Der 4bit Mode tut> nämlich noch nicht. Da empfängt er immer Müll
Das kann auch ein elektrisches Problem sein. Was für ein Board nutzt du?
M. H. schrieb:> wirft dann einen CRC> Fehler.
Es gibt da ein paar Errata bzgl. Clock und Sampling, siehe Errata Sheet.
Insb. kann man die 48 MHz nicht erreichen. Das ist beim STM32F7
repariert.
Dr. Sommer schrieb:>> Der 4bit Mode tut>> nämlich noch nicht. Da empfängt er immer Müll> Das kann auch ein elektrisches Problem sein. Was für ein Board nutzt du?
Ein STM32F4 discovery. Da ist eine Datenleitung auch noch an dem Audio
DAC, aber als Eingang. keine Ahnung, ob es daran liegt. Das werde ich
wohl noch debuggen müssen.
Jetzt muss erstmal der 1bit mode richtig laufen. Auf den DMA werde ich
verzichten. Dann muss ich mich auch nicht darum kümmern, ob der Puffer
Word aligned ist.
M. H. schrieb:> Ein STM32F4 discovery. Da ist eine Datenleitung auch noch an dem Audio> DAC, aber als Eingang. keine Ahnung, ob es daran liegt.
Nö, das passt. Habe ich auch auf einem Discovery gemacht. Allerdings
konnte ich damit nicht die max. Frequenz erreichen (wilde Verdrahtung).
M. H. schrieb:> Dann muss ich mich auch nicht darum kümmern, ob der Puffer> Word aligned ist.
Er müsste sogar 16-Byte-Aligned sein, denn ein "Burst" (4x4 Bytes) darf
keine 1kB-Grenze überschreiten.
Dr. Sommer schrieb:> Marc V. schrieb:>> Ja.> Danke für diesen hilfreichen Beitrag, der die Diskussion enorm> voranbringt.
Das hat sich zum Glück erledigt. Habe es selbst herausgefunden. War nur
irritiert, weil ich eine Implementierung im Internet für einen LPCxxxx
gefunden habe, die davon ausgegangen ist, dass das eine Byte Adresse
ist.
Hallo,
ich habe nun zum probieren mit CubeMX (oder wie das Ding heißt) das
FatFS versucht in Gang zu bringen. Das geht genau so wenig, wenn man es
debuggt. Die letzten Bytes bleiben auch hier im FIFO stehen und alle
Flags sagen: FIFO leer, alles kopiert. Ich verstehe diesen Controller
nicht mehr...
Ich habe nun folgenden Code gefunden:
https://github.com/yigiter/Sample-STM32F4-codes/blob/master/SDIOLib/src/SDIO.c
Hier wird der DMA aktiviert und solange gewartet, bis das CR Register
des Streams vom SDIO auf 0 gesetzt wird. Das passiert bei mir auch.
Dannach wartet das Programm darauf, dass RXACT beim Lesen inaktiv wird.
Das passiert bei mir jedoch nie. Der Controller hängt sich weg. Die
letzten paar Wörter fehlen.
Ich habe außerdem das Problem, dass das DATAEND flag des SDIO teilweise
schon nach dem halben Block gesetzt wird. Ich muss, wenn ich manuell das
FIFO lese, darauf warten, bis mein Zähler auf 512 Bytes ist, oder ein
Fehlerflag gesetzt wird. Die Flags vom SDIO kommen, wann sie wollen.
Da auch dieser Code nicht funktioniert, bestärkt sich mein verdacht,
dass mein STM einen Fehler hat. Das wäre aber irgendwie total
unwahrscheinlich, dass ein Fehler genau in dem Modul auftritt.
Ich habe das Problem nun gelöst und will euch die Lösung nicht
vorenthalten.
Meiner Meinung nach steht im Reference Manual nicht, dass man das machen
muss, aber es hat das Problem für mich gelöst:
Beim Konfigurieren des DMA Streams das FIFO Control Register
folgendermaßen konfigurieren:
DMASTREAM->FCR = DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1 | DMA_SxFCR_DMDIS;
Das setzt die Threshold des FIFOs des DMA und deaktiviert den "direct
mode"
Warum es ohne nicht geht, weiß ich nicht. Auf jedenfall repariert es
mein Problem :)