Forum: Mikrocontroller und Digitale Elektronik FatFS Bibliothek Fehler bei Beispielcode


von Clara E. (clara97)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich nutze einen atmega328p microcontroller und brauchte ein SD Modul zum 
speichern von Daten. Da habe ich die FatFs Bibliothek gefunden. Ich habe 
Sie direkt meinem Projekt hinzugefügt und dann das Beispielprogramm auf 
folgender Seite einkopiert: http://elm-chan.org/fsw/ff/doc/open.html
Natürlich habe ich nicht vergessen die ff.h und diskio.h einzubinden. 
Jedoch bekomme ich beim Ausführen eine Reihe von Fehlern, die Ihr dem 
folgenden Screenshot entnehmen könnt.
Weiß einer mir zu helfen und kann mir helfen diese Probleme zu lösen?

von M. Н. (Gast)


Lesenswert?

Er findet die ganzen Referenzen auf die Low-Level Funktionen nicht, die 
mit deinem Medium sprechen (SD Karte, USB etc.) Diese werden in der 
diskio.c benötigt. Du musst darin die Treiber für deinen Controller 
hinterlegen. Ich nehme an, diese hast du noch nicht. Da musst du mal 
googlen. Für die AVRs + SD Karte gibt es die low-level Treiber bzw. 
schon fertig zusammengeschnürte Beispielprojekte.

Hier ist besipielsweise schon ein Treiber für MMC/SD an AVR SPI drin:
https://community.atmel.com/projects/fatfs-sd-card-atmega328p

Den kannst du theoretisch auch herauslösen und bei dir in deine eigene 
FatFS implementierung stecken.

FatFS ist komplett HW unabhängig programmiert und erfordert, dass man 
einen Satz an low-Level funktionen implementiert:
Bspw die disk_read Funktion: http://elm-chan.org/fsw/ff/doc/dread.html

von Clara E. (clara97)


Lesenswert?

Vielen Dank! hab die Datei heruntergeladen und statt meiner Version der 
Dateien ausgetauscht. Die main.c aus der heruntergeladenen Datei habe 
ich gelöscht und die Fehler sind nicht mehr da. Jetzt bringt es mich 
aber auf ein neues Problem. Funktioniert mein code mit f_write etc. oder 
muss ich disk.write verwenden?

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

M. H. schrieb:
> Er findet die ganzen Referenzen auf die Low-Level Funktionen nicht, die
> mit deinem Medium sprechen (SD Karte, USB etc.) Diese werden in der
> diskio.c benötigt. Du musst darin die Treiber für deinen Controller
> hinterlegen. Ich nehme an, diese hast du noch nicht. Da musst du mal
> googlen. Für die AVRs + SD Karte gibt es die low-level Treiber bzw.
> schon fertig zusammengeschnürte Beispielprojekte.

Ja, eben! Und den hat der OP! Also muss man "nur" das richtige 
Beispielprojekt kompilieren, da ist ALLES drin!

von Falk B. (falk)


Lesenswert?

Clara E. schrieb:
> Vielen Dank! hab die Datei heruntergeladen und statt meiner Version der
> Dateien ausgetauscht. Die main.c aus der heruntergeladenen Datei habe
> ich gelöscht und die Fehler sind nicht mehr da. Jetzt bringt es mich
> aber auf ein neues Problem. Funktioniert mein code mit f_write etc.

Ja.

> oder
> muss ich disk.write verwenden?

Nein, die nutzt nur FATfs!

von Clara E. (clara97)


Lesenswert?

Leider haben sich weitere Probleme eingeschlichen. Ich habe das ganze 
auf Microchip Studio versucht und komme nun auf 2 Fehler
1. undefined reference to `disk_ioctl'  in ff.c
2. undefined reference to `f_gets` in main.c

Weiß jemand woran das liegen kann?
Der erste Fehler verschwindet, sobald ich die f_close() Funktion lösche.

von Malte _. (malte) Benutzerseite


Lesenswert?

Dann hast du 1.
disk_ioctl nicht eingebaut. Ein Beispiel aus der Nutzung meines Codes:
1
DRESULT disk_ioctl (
2
  BYTE pdrv,    /* Physical drive nmuber (0..) */
3
  BYTE cmd,    /* Control code */
4
  void *buff    /* Buffer to send/receive control data */
5
)
6
{
7
  switch (pdrv) {
8
  case DEV_EXTFLASH:
9
    if ((cmd == CTRL_SYNC) || (cmd == CTRL_TRIM)) {
10
      return RES_OK;
11
    }
12
    if (cmd == GET_SECTOR_COUNT) {
13
      uint32_t sectors = (FlashSizeGet() - RESERVEDOFFSET) / BLOCKSIZE;
14
      *((LBA_t*)buff) = sectors;
15
      return RES_OK;
16
    }
17
    if (cmd == GET_SECTOR_SIZE) {
18
      *((WORD*)buff) = BLOCKSIZE;
19
      return RES_OK;
20
    }
21
    if (cmd == GET_BLOCK_SIZE) {
22
      *(DWORD*)buff = BLOCKSIZE;
23
      return RES_OK;
24
    }
25
  }
26
  return RES_PARERR;
27
}

Da musst du natürlich jetzt an deine Fat Implementierung anpassen. In 
der Doku ist das alles beschrieben.

Zu f_gets: Die verwendest du in der main.c - das wird nicht umbedingt 
gebraucht. Also kann man die bei FatFs weg optimieren. Das ist also eine 
Option in deiner Config Datei.

von Clara E. (clara97)


Lesenswert?

disk_ioctl wurde aber in der diskio.c Datei eingebunden.
1
DRESULT disk_ioctl (
2
  BYTE pdrv,    /* Physical drive nmuber (0..) */
3
  BYTE cmd,    /* Control code */
4
  void *buff    /* Buffer to send/receive control data */
5
)
6
{
7
  switch (pdrv) {
8
#ifdef DRV_CFC
9
  case DRV_CFC :
10
    return cf_disk_ioctl(cmd, buff);
11
#endif
12
#ifdef DRV_MMC
13
  case DRV_MMC :
14
    return mmc_disk_ioctl(cmd, buff);
15
#endif
16
  }
17
  return RES_PARERR;
18
}

von Malte _. (malte) Benutzerseite


Lesenswert?

Hmm, wird die Datei auch compiliert? Der einfachste Test ist manchmal 
bewusst einen Syntaxfehler in eine Datei zu tun und dann zu schauen ob 
es nicht compiliert. Wenn doch, wird sie offensichtlich nicht vom 
Compiler beachtet.

von Clara E. (clara97)


Lesenswert?

Anscheinend liegt das Problem an microchip studio, denn ich habe das 
ganze über platformio probiert und da läuft es problemlos. Allerdings 
wird auf meiner SD Karte keine Datei erstellt. Folgenden Code habe ich 
verwendet:
1
#include "ff14a/source/ff.h"
2
#include "ff14a/source/diskio.h"
3
#include <stdio.h>
4
5
6
FATFS FatFs;   /* Work area (filesystem object) for logical drive */
7
8
int main (void)
9
{ 
10
 
11
 
12
    FIL fil;        /* File object */
13
    char line[100]; /* Line buffer */
14
    FRESULT fr;     /* FatFs return code */
15
16
17
    /* Give a work area to the default drive */
18
    f_mount(&FatFs, "0:", 1);
19
20
    /* Open a text file */
21
    fr = f_open(&fil, "0:FatFs test.txt", FA_WRITE | FA_CREATE_ALWAYS);
22
    if (fr) return (int)fr;
23
24
  
25
26
    /* Close the file */
27
    f_close(&fil);
28
29
    return 0;
30
}

Leider weiß ich nicht wie ich die Ausgabe auslese, daher weiß ich nicht 
genau woran es liegt.

: Bearbeitet durch User
von Malte _. (malte) Benutzerseite


Lesenswert?

Aber du kannst doch irgendwas ausgeben, oder? Sei es eine serielle 
Ausgabe, oder eine blinkende LED. In deinem Beispielcode sind ja mehrere 
Abbruchbedingungen. Da könntest du also code einbauen, der den 
Fehlercode ausgibt, oder zumindest im Fehlerfall eine LED einschaltet.

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.