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?
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
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
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!
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!
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.
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.
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 | }
|
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.