F_Mount /FATFS / STM32F401RE

Gast #5566268
Hallo,

folgendes Problem beschäftigt mich seit kurzem:

Ich bekommen Daten über UART1 und Interrupt des F401RE rein, speichere 
diese in einem Buffer und möchte dessen Inhalt auf eine µSD-Karte 2GB 
Class 4  speichern.
Die HW lass ich mir mittels CubeMX erstellen.

Dazu folgenden Code, der auch funktioniert:
1
while(1)
2
{
3
fresult1=f_mount(&myFATAFS,SDPath,1) ;
4
      
5
 if(fresult1==FR_OK)
6
        {
7
         
8
        char MyPath[]="testfile.TXT";
9
        char MyData[]="Wieder ein Test.";
10
        f_open(&myFILE,MyPath,FA_WRITE|FA_CREATE_ALWAYS);
11
        f_write(&myFILE,MyData,sizeof(MyData),&testByte);
12
        f_close(&myFILE);
13
        f_mount(&myFATAFS,SDPath,0);
14
}
15
}
-> Funktioniert, Datei und Inhalt können z.B. am PC gelesen werden.
1
{
2
if(received)
3
    { fresult1=f_mount(&myFATAFS,SDPath,1) ;
4
       if(fresult1==FR_OK)
5
        {
6
         
7
        char MyPath[]="testfile.TXT";
8
        char MyData[]="Wieder ein Test.";
9
        f_open(&myFILE,MyPath,FA_WRITE|FA_CREATE_ALWAYS);
10
        f_write(&myFILE,MyData,sizeof(MyData),&testByte);
11
        f_close(&myFILE);
12
        f_mount(&myFATAFS,SDPath,0);
13
     }
14
   received=0;
15
}
-> funktioniert nicht. Der Code bleibt bei f_mount stehen. Nichts geht 
mehr.

Was genau übersehe ich? Hat jemand Lösungen für dieses Problem?

[Mod: Fehlendes C-Tag eingefügt]
Warum hast du das Mount in der while(1) Schleife? Das macht man einmal 
am Programmanfang und dann nie wieder. Damit die Daten komplett 
geschrieben werden reicht das f_close(), das schreibt alle Restdaten aus 
dem Puffer in die Datei.
Gast
Danke für die schnelle Antworten.

>Du hast dein f_mount &co aber schon im Haupt-Programm, nicht in der ISR?
>Wird aus deinem Beispiel-Code nicht ersichtlich...


Ja, das ist mein Hauptprogramm, nicht die ISR. In der ISR wird nur die 
globale variable receive = 1  gesetzt.

>Warum hast du das Mount in der while(1) Schleife? Das macht man einmal
>am Programmanfang und dann nie wieder. Damit die Daten komplett
>geschrieben werden reicht das f_close(), das schreibt alle Restdaten aus
>dem Puffer in die Datei.

Danke für den Tipp. Ich habe nun das f_mount vorher initialisiert. Jetzt 
hängt sich das Programm im f_open auf. Also eine Zeile weiter. :(
Gast
Wie ist die SD angeschlossen? Per SDIO hatte ich auch gerade das Problem 
das der HAL Code im Pollingmode zu langsam ist, besonders im debug build 
ohne Optimierungen. Das führte zuverlässig zu Fehlern bei der 
Datenübertragung. Mit DMA sieht es besser aus und es läuft mit 24 MHz 
SDIO Clock.
Gast
>Wie ist die SD angeschlossen? Per SDIO hatte ich auch gerade das Problem
>das der HAL Code im Pollingmode zu langsam ist, besonders im debug build
>ohne Optimierungen. Das führte zuverlässig zu Fehlern bei der
>Datenübertragung. Mit DMA sieht es besser aus und es läuft mit 24 MHz
>SDIO Clock.

Ich nutze SDIO 1Bit. Somit sind CMD, D0 und CLK an der Karte 
angeschlossen + 3,3V und gemeinsame Masse aufgebaut auf einer 
Lochrasterplatine.

Ich habe das Problem, dass das gesamte Programm abschmirrt.
Gast
Hallo,

was heißt genau: abschmirrt

Kannst du mit dem debugger stop machen? Ist der Context dann ok? Wo bist 
du? While schleife oder interrupt? Sind die Variablen die du da hast 
noch ok? Kommen noch irgendwelche interrupts durch? Timer?

Versuche mal den f_mount zu debuggen. Wie lange kommst du noch durch? 
Ist nicht so schwer, ich habe den auch paar mar gedebugt nach paar Tagen 
geht es wie geschmiert.
@ kyrk.5 (Gast)

>Versuche mal den f_mount zu debuggen. Wie lange kommst du noch durch?
>Ist nicht so schwer, ich habe den auch paar mar gedebugt nach paar Tagen
>geht es wie geschmiert.

Genau sooo macht man es bestimmt nicht. FATfs ist sehr gut getestet, da 
muß man nicht in den Innereien rumdebuggen. Man sollte einfach die 
Rückgabewerte auswerten und ernst nehmen. Einzig und allein die Low 
Level Funktionen, die man an die Hardware selber anpassen muß sind 
debugwürdig.
Gast
>Kann es sein, daß die Interruptfunktion für das Timeout fehlt? Dann
>bleibt der Zugriff natürlich stehen . . .

Tut mir leid Falk, aber das habe ich nicht verstanden. Könntest du mir 
das genauer erklären, bzw. eine Quelle nennen wo ich die Hintergründe 
genauer nachlesen könnte?
Gast
Ich habe das genau so gemacht und festgestellt dass es bei mir damals an 
der Low Level Funktion gelegen hat. Wobei bei mir war ein Delay Funktion 
nicht richtig integriert wurde und deswegen nie zu Ende lief. Dadurch 
gab es keinen Rückgabewert. Dann hatte ich noch ewig probleme mit nicht 
laufenden SD Karten, weil der SPI nicht dediziert war und ein MP3 chip 
hing da auch drauf. Die SD Karte nahm das aber über, weil er ja in SDIO 
mode hochstartet und wenn da erst der MP3 chip initializiest wird nehmen 
das manche karten nicht so gut an (sprich denken die werden gerade 
angesprochen)

Aber prinzipiell hast du recht. Erstmal Doku lesen und so machen wie es 
da drin steht. Wenn aber immer noch nicht tut dann muss man einfach 
reindebuggen. Die 2 Dinge helfen in 80% der Fällen.
Gast
in der hsd Struktur ist noch ein Member 'ErrorCode', das ist der letzte 
Fehler vom LL Treiber. Die Bedeutungen sind in stm32f4xx_ll_sdmmc.h zu 
finden.
@ FATHM (Gast)

>>Kann es sein, daß die Interruptfunktion für das Timeout fehlt? Dann
>>bleibt der Zugriff natürlich stehen . . .

>Tut mir leid Falk, aber das habe ich nicht verstanden. Könntest du mir
>das genauer erklären, bzw. eine Quelle nennen wo ich die Hintergründe
>genauer nachlesen könnte?

Für FATfs muss im 10ms Zeitraster eine kleine Funktion aufgerufen 
werden, welche die Timeouts regelt. Die liegt im avr Beispiel in

mmc_avr_spi.c
1
/*-----------------------------------------------------------------------*/
2
/* Device Timer Interrupt Procedure                                      */
3
/*-----------------------------------------------------------------------*/
4
/* This function must be called in period of 10ms                        */
5

6
void mmc_disk_timerproc (void)
7
{
FATHM schrieb:
> eine µSD-Karte 2GB
> Class 4  speichern.

Hast Du mal eine andere SD(HC) Karte probiert? Die billigen 2GB Class 4 
sind mitunter ab Werk defekt beim Kunden angekommen.

Das mit dem Timeout hilft Dir auch kaum weiter, denn wenn der zuschlägt 
kannste die Karte nur durch Unterbrechen der Stromversorgung resetten.

Im Normalbetrieb sollte kein Timeout auftreten - dann ist immer 
irgendwas nicht OK.
Gast
für die Timeouts nutzt die HAL Implementierung den SysTick, das wird 
alles im generierten Code vom Zauberwürfel gemacht.
In main.c ist noch eine leere Fehlerbehandlung:
1
void _Error_Handler(char *file, int line)
2
  /* USER CODE BEGIN Error_Handler_Debug */
3
  /* User can add his own implementation to report the HAL error return state */
4
  while(1)
5
  {
6
  }
7
  /* USER CODE END Error_Handler_Debug */
da wäre ein printf() mit Fehlerausgabe auf Display oder UART hilfreich. 
Oder wenigstens hektisches LED blinken damit man sieht der µC hängt in 
der Fehlerschleife.
Aber wie Uwe schon schrieb, wenn der nahezu gleich Code schon lief 
müssen noch woanders Änderungen sein.
Fehlerträchtig ist auch das Konzept mit den __weak Deklarationen das mit 
HAL viel genutzt wird. Ich hatte Interrupthandler und Callbacks in eine 
C++ Quelle verschoben und schon wurde es wegen C++ name mangling nicht 
mehr aufgerufen, der Compiler kann da aber nichts prüfen und dem Linker 
ist es egal ob eine __weak Funktion überschrieben wird oder nicht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.