|
|
AVR FAT32
[Bearbeiten] Der Status
[Bearbeiten] FAT 16/32 , die BibliothekSchichtmodell der Lib Dies ist eine freie FAT 16 / 32 Bibliothek. Die Bibliothek ist modular und besteht aus folgenden Modulen:
Es gibt die Möglichkeit über #defines in der config.h den Umfang der Lib zu bestimmen, dies wirkt sich auch extrem auf die Codegröße aus. [Bearbeiten] Code einbindenDie Module werden über die *.h Dateien bekannt gemacht. Zudem müssen noch die dazugehörigen *.c Dateien eingebunden werden. Es gibt mehrere Möglichkeiten dies zu tun. Einmal im Makefile im Bereich der "c source files" oder bei IDEs über einen Dialog der das Gleiche macht. [Bearbeiten] Die FunktionalitätIn der Datei config.h gibt es Möglichkeiten die Bibliothek zu konfigurieren.
[Bearbeiten] Die SchalterHier ein Auszug aus der config.h mit den wichtigsten Parametern:
[Bearbeiten] Bedeutung der SchalterMMC_SMALL_FILE_SYSTEM TRUE, oder FALSE bestimmt den Funktionsumfang der Lib. Es Fallen Folgende Funktionalitäten raus: ffcd(), fat_str(), ffls(), ffcdLower(), ffmkdir() und ffrm() der Teil mit Ordnern rekursiv löschen. (FALSE = Komplette Unterstützung) MMC_WRITE TRUE, oder FALSE bestimmt ob schreib Unterstützung einkompiliert wird oder nicht. (TRUE = Write an) MMC_OVER_WRITE TRUE, oder FALSE bestimmt ob ffwrite() mit Überschreiben Funktionalität Kompiliert wird oder nicht. Überschreiben von Dateien ist nicht so performant. Siehe auch: Interne Technik (TRUE = Dateien überschreiben) MMC_MULTI_BLOCK TRUE, oder FALSE legt fest ob mit MultiBlock Read/Write Unterstützung Kompiliert wird oder nicht. Geht nur wenn OVER_WRITE FALSE ist! (TRUE = MultiBlock Operation) MMC_MAX_SPEED TRUE, oder FALSE legt fest, ob nach der Initialisierung der MMC/SD Karte mit maximalem Speed geschrieben/gelesen wird oder nicht. Zum testen wenn man nicht sicher ist ob die Hardware die maximale Geschwindigkeit mit macht empfiehlt sich FALSE als Wert. MMC_MAX_CLUSTERS_IN_ROW 1-500, gibt an, wie viele Cluster, leer oder Verkettet die zusammenhängen, gesucht werden sollen. Hier muss man den Overhead des Suchens abwägen, gegen die Zeit, die z. B. benötigt wird 500 Cluster in der Fat zu verketten. Siehe auch: Interne Technik MMC_SDHC_SUPPORT TRUE, oder FALSE legt fest, ob mit SDHC Unterstützung Kompiliert wird oder ohne. Der SD Standard 2.0 wird damit unterstützt, also Karten bis 32 GB Größe. MMC_TIME_STAMP TRUE, oder FALSE legt fest, ob die Zeitstempel Unterstützung mit kompiliert wird oder nicht. Wenn TRUE, dann wird das Erstelldatum und die Erstellzeit eingetragen. Bei weiteren Schreibzugriffen auf die Datei wird dann auch das Zugriffsdatum und die Zugriffszeit eingetragen. Es müssen dafür auch 2 Funktionen in der fat.c mit Code gefüllt werden, damit diese das Datum und die Zeit liefern. MMC_SOFT_SPI TRUE, oder FALSE legt fest, ob mit Software SPI Unterstützung kompiliert wird, oder nicht. Wenn TRUE, muss in der mmc.h noch eingetragen werden welche Pins als SPI Interface benutzt werden sollen. Es werden nur Pins des selben Ports unterstützt. Also z. B. nur Pins von Port B. [Bearbeiten] Die C FunktionenDas Modul FILE bietet in der Standard-Konfiguration folgende für den Nutzer interessante Funktionen:
Das Modul MMC/SD bietet für den Nutzer direkt nur eine interessante Funktion:
Das Modul FAT bietet für den Nutzer direkt nur zwei interessante Funktionen:
[Bearbeiten] Interne TechnikIn der Regel wird das Schicht-Modell eingehalten. Das heißt, jedes Modul nutzt nur die Funktionen aus der Schicht darunter, es gibt allerdings Ausnahmen, aus Gründen der Code-Größe. Beispiel : ffwrite nutzt direkt die Funktion mmc_write_sector(sector); aus dem Modul mmc.c. Aufgrund der Namens-Konvention ist aber leicht zu erkennen, woher die Funktion kommt. Es gibt in dem Modul fat, "Daten-Ketten". Die Aufgaben sind atomar aufgeteilt. Zum lesen von Daten sind beispielsweise die Funktionalitäten, lesen eines Sektors, auswerten der Information und weitere Entscheidung (nächsten Sektor laden usw.) nötig. Die Idee dabei ist gewesen, die Funktionen der atomaren Aufgabe nach zu implementieren. Beispielkette:
Diese Kette wird beispielsweise beim Öffnen einer Datei durchlaufen. Um die Datei zu öffnen, muss man wissen ob es die Datei im aktuellen Verzeichnis gibt. Um das herauszufinden, muss man den ersten Sektor des Verzeichnisses laden. Dann muss man die Reihen (immer 32 Byte am Stück), also Datei/Ordner-Einträge des Sektors prüfen. Da ein Cluster aus verschiedenen Sektoren bestehen kann, müssen diese auch geprüft werden. Als letzte logische Einheit müssen jetzt noch die verketteten Cluster geprüft werden, also das ganze Verzeichnis. Ist diese Kette so durchlaufen, weiß man, ob die Datei da ist oder nicht. [Bearbeiten] LesenBeim lesen, einer Datei wird in der FAT nach verketteten Clustern gesucht. Bei einer unfragmentierten FAT liegen im Idealfall alle Cluster in einer Reihe. Dies wird ausgenutzt:
Es wird der erste Cluster der Datei gesucht und solange gesucht, bis MAX_CLUSTERS_IN_ROW am Stück gefunden wurden, oder ein Abbruch der Kette erkannt wird. Wird ein Abbruch erkannt, wird erstmal das bekannte Teilstück der kompletten Kette gelesen, danach wird das nächste Teilstück gesucht. Bis die ganze Kette durchlaufen wurde. [Bearbeiten] SchreibenBeim schreiben, einer Datei wird in der FAT nach leeren Clustern gesucht. Bei einer unfragmentierten FAT liegen diese im Idealfall alle nebeneinander. Das wird ausgenutzt:
Bei beiden Methoden kann es zu größerem Overhead kommen, wenn die FAT fragmentiert ist. Im Extremfall ist immer nur ein Cluster am Stück frei bzw. verkettet. [Bearbeiten] Funktionsübersichts Diagramm(Link) Größe: 2412 x 7946 Pixel, ältere Version der Lib. Viele der Funktionen enden in Schreiboperationen, weil das Diagramm mit der Option "MMC_OVER_WRITE TRUE" erstellt wurde. [Bearbeiten] Die RichtlinienAllgemein: Es ist immer darauf zu achten, dass es sich bei MMC/SD-Karten um Flash-Speicher handelt, dieser ist NICHT unendlich oft beschreibbar. Die Schreiben/Anhängen- und Löschen- Funktionalitäten sollten so selten wie möglich benutzt werden! Richtlinien stable-mmc-0.5.x: Wenn eine Datei zum schreiben geöffnet ist, aber gerade keine Daten zum schreiben vorliegen, bringt es keinen Vorteil (Strom oder Geschwindigkeit) die Datei zu schießen, wenn später noch Daten geschrieben werden sollen. Bei jedem ffclose, wird der Datei Eintrag geupdatet, also dieser Sektor geschrieben (möglicherweise zusätzlich sogar ein FAT Sektor). Oftmaliges anlegen und löschen einer Datei schreibt immer die selben (logischen) Sektoren. Besser nicht löschen und einfach neu anlegen, mit anderem Namen, oder überschreiben, da dabei die schon verketteten FAT Sektoren nicht nochmals beschrieben werden, sondern nur die Daten Sektoren überschrieben werden.
[Bearbeiten] Beispiel Beschaltung[Bearbeiten] SchaltplanMMC/SD-Karten brauchen 3,3 Volt. Wenn der Controller mit 5 Volt arbeitet, muss man die Spannungspegel anpassen. Arbeitet der Controller auch mit 3,3 Volt kann man alle Leitungen direkt mit der Karte verbinden. Benutzt wird der SPI-Port des Controllers (bis auf Slave Select, hier PB1). Es wäre aber auch Software basiertes SPI möglich, siehe hierfür auch Link [Bearbeiten] Pinbelegung MMC/SD/SDHC
[Bearbeiten] Der Code[Bearbeiten] Sourcen
[Bearbeiten] Einfaches Code BeispielEin Beispiel um in eine Datei zu schreiben/anhängen und wieder zu lesen:
[Bearbeiten] FAT 32 GrundlegendesBild 0: Grundlegende FAT32 Struktur Ein Dateisystem des Typs FAT besteht aus mehreren Bereichen.
FAT ist immer little Endian.
Ein Dateisystem wie FAT32 ist ein Verwaltungsinstrument. Der FAT16/32 Standard beschreibt die Art und Weise wie die Daten Verwaltet werden.
FAT bedeutet File Allocation Table ( Dateizuordnungstabelle ). Dateizuordnungstabelle beschreibt schon das Prinzip der FAT.
Kern des Dateisystems ist eine einfach verkettete Liste, in der festgehalten wird wo sich die Daten befinden, die Dateizuordnungstabelle ! [Bearbeiten] Sektor 0 oder LBABild 1: Sektor 0 (512 Byte) bei einer unpartitionierten Karte Um das Dateisystem lesen zu können muss man wissen wo was steht. Die nötigsten Informationen sind:
Aus diesen Daten ergibt sich demnach:
Damit sind alle nötigen Daten vorhanden ! Bei FAT Dateisystemen können mehrere Sektoren (512 Bytes) logisch zu Clustern zusammengeschlossen werden. Ein Cluster ist für eine Datei die kleinste Speichereinheit. Das hat zur Folge, dass eine 100 Byte große Datei eventuell 2048 Bytes im Dateisystem belegt. Die rote Zahl gibt an wieviele Sektoren ein Cluster bilden. Der Daten Bereich wird immer in Clustern angegeben, das macht die Umrechnung von Sektoren zu Clustern nötig. In diesem Fall ist Cluster 2 der absolute Sektor 1003. [Bearbeiten] Die FATFolgendes Bild zeigt den ersten FAT Sektor (512 Bytes) eines FAT32 Dateisystems (nicht den ersten Sektor der Karte!). Eingetragen sind: Root-Dir und zwei darin enthaltene Ordner sowie eine Datei mit 60.000 Bytes Größe. Bild 2: 1. FAT Sektor (hier Sektor 32) Die Einträge 0-7 sind immer reserviert (Quasi Cluster 0 und 1)! Also beginnt die FAT ab 8 (rot, Cluster Nummer 2). Der erste Eintrag (rot) ist 4 Byte groß und zu lesen von Stelle 8 zu Stelle 11 weil little Endian, also umgedrehte Wertigkeit. 8 niedrigste Wertigkeit, dann 9 eins höher, 10 noch eine höher und 11 höchste (dazu später noch ein Beispiel). An den gelben Einträgen wird die einfach verkettete Liste der FAT deutlich. Der erste gelbe Eintrag steht an der Stelle des Clusters Nummer 5 und hat als Inhalt eine 6. Das bedeutet: Cluster 5 und 6 gehören zusammen. Würde an der Stelle des Clusters Nummer 5 ein FFFFFF0F stehen (little Endian) ist nur der Cluster 5 mit Daten belegt (wie bei rot, blau und grün). [Bearbeiten] DatenBild 3: Inhalt eines Ordners/Dirs (hier Cluster 4) Ein Dateieintrag besteht aus 32 Bytes und liegt in einem Ordner/Dir im Datenbereich des Dateisystems ( 32 Bytes = eine Zeile). Dies ist der 1. Cluster eines Ordners. Hier sieht man den "." bzw ".." Eintrag in Zeile 1 bzw. 2. Diese beiden Einträge sind in jedem ersten Cluster eines Ordners vorhanden. Außer im Root-Dir, von dort spannt sich der Verzeichnis Baum ja erst auf. Der "." Eintrag hat als 1. Cluster Eintrag den eigenen Cluster, hier 4. Der ".." Eintrag ist interessanter, weil er den 1. Cluster des Übergeordneten Ordners enthält, hier 3. Ist der Übergeordnete Ordner das Root-Dir, ist der 1. Cluster Eintrag 0. Diese beiden Einträge werden in der Lib genutzt um rekursiv zu löschen. Die dritte Zeile des Bilds zeigt eine Datei namens TEST3.TXT (grün) mit 60.000 Bytes Größe (blau) und dem 1. Cluster 5,damit ist immer der 1. Daten Cluster gemeint (rot, Folgecluster siehe Bild 2). Speziell ist hier, dass die 4 Bytes des ersten Clusters aufgeteilt sind auf 2 unterschiedliche "Orte" im 32 Byte Eintrag (Wertigkeit: 26:27:20:21). Um nun die Daten der Datei lesen zu können, muss man die Daten Cluster kennen. Der erste Daten Cluster steht im Datei Eintrag, hier Cluster 5. Für die Folgenden sieht man in der FAT nach. Dort stehen die Folgecluster der Datei. An der Stelle des ersten Clusters der Datei Cluster 5 steht eine 6, d.h. der nächste Cluster ist 6. In dieser Form ist die FAT verkettet. Wenn in der FAT der letzte Cluster erreicht ist, inhalt des Clusters ist FFFFFFF0, liest man den letzten Sektor bis man insgesammt die Größe der Datei (blau) gelesen hat und ist fertig. [Bearbeiten] Root DirBild 4: Root des Dateisystems (hier Cluster 2) Die Sektor Nummer des Root-Dirs, bei FAT32, wird aus Sektor 0 oder dem LBA ausgelesen (siehe Bild 1). Zu Sehen ist hier in der ersten Zeile ein 32 Byte Eintrag eines Ordners. Zu erkennen ist dieser am Datei Attribut 0x10 an Stelle 11 (rot). Für den Ordner Namen ist das Gleiche Feld da wie für einen Dateinamen (grün). Der 1. Cluster des Ordners ist 3 (blau, Inhalt des Ordners ist Bild 3). Bei Ordnern werden die Felder für die Größe genullt (orange). Das Root-Dir hat keinen "." bzw. ".." Eintrag. Der erste Cluster des Dirs ist ja über Sektor 0 bekannt und ab dem Root-Dir spannt sich der Verzeichnisbaum erst auf. Das Root-Dir bei FAT32 kann beliebig groß werden. [Bearbeiten] ZusammenfassungFür Dateien und Ordner sind nur zwei Bereiche eines FAT32 Dateisystems wichtig, nämlich die FAT selbst und der Daten Bereich. Eine Datei wird aufgesplittet, in einen Datei Eintrag und in die Nutzdaten der Datei (alles im Daten Bereich). Ein Ordner ist vom Eintrag im Dateisystem einer Datei sehr ähnlich. Wo bei einer Datei über den 1.Cluster eine Cluster-Chain für die eigentlichen Daten der Datei beginnt, wird bei einem Ordner so eine Cluster-Chain für weitere Datei/Ordner Einträge verkettet. Ein Ordner bietet pro Sektor maximal 16 Einträge (16*32=512).
[Bearbeiten] Siehe auch
[Bearbeiten] WeblinksWeitere Projekte mit FAT MMC/SD Karten: |