Obsługa FAT w mikrokontrolerach STM32 – obsługa kart

Podstawowe operacje na plikach i katalogach

Gdy mikrokontroler umie się już porozumiewać z kartą SD i system plików jest należycie obsługiwany, to kolejnym krokiem są już właściwe operacje na plikach i katalogach, jakie wymaga projektowana aplikacja. Wszystkie funkcje, jakie oferuje moduł FatFs zostały omówione na jego stronie internetowej http://elm-chan.org/fsw/ff/00index_e.html , a ich spis umieszczono w tab. 2. Tutaj zajmiemy się przykładami aplikacji wykonywujących niezbędne zadania na plikach i katalogach.  

 

Tab. 2. Funkcje udostępnione przez moduł FatFs 

Funkcja  Opis
f_mount „montuje” (rejestruje) dysk logiczny w systemie
f_open otwieranie lub/i tworzenie pliku
f_close zamykanie pliku
f_read czytanie zawartości pliku
f_write zapisywanie pliku
f_lseek przesuwa wskaźnik zapisu/odczytu pliku
f_truncate skraca długość pliku
f_sync działanie podobne do f_close, z tym, że plik pozostaje otwarty, więc dalej można na nim wykonywać operacje
f_opendir otwiera katalog
f_readdir czyta zawartość katalogu
f_getfree pozwala odczytać liczbę wolnych klastrów
f_stat odczytuje informacje o pliku/katalogu
f_mkdir tworzy katalog
f_unlink usuwa katalog lub plik
f_chmod zmienia atrybuty pliku lub katalogu
f_utime zmienia datę i czas dla określonego pliku lub katalogu
f_rename zmiana nazwy lub przeniesienie pliku/katalogu
f_mkfs tworzy system plików na nośniku
f_forward czyta dane z nosnika i bezpośrednio przekazuje dalej

Przykładowy program, którego zadaniem jest wykonywanie podstawowych operacji na plikach i katalogach pokazano na list. 5. Przedstawiony kod najpierw montuje dysk logiczny za pomocą funkcji f_mount() , dzięki czemu moduł FatFs będzie mógł wykonywać operacje dyskowe. W argumentach przesyłamy numer dysku (tutaj 0) oraz, przez referencję, główną zmienną systemu plików typu FATFS .

List. 5. Przykładowy program wykonujący podstawowe operacje na plikach i katalogach

Po zamontowaniu dysku można już dowolnie zarządzać zawartością karty pamięci. W omawianym programie w pierwszej kolejności następuje utworzenie nowego pliku tekstowego w katalogu głównym karty. Wykorzystano do tego celu funkcję f_open() , która z pozoru (nazwy) nie ma z czynnościami tworzenia plików wiele wspólnego. Mimo tego, że nazwa funkcji na to nie wskazuje, to służy ona również do tworzenia nowych plików.
Jako pierwszy argument przekazujemy (prze referencję) adres do uchwytu pliku. Warto na to zwrócić uwagę, ponieważ, jak się przy okazji omawiania pozostałych funkcji okaże, jeśli operacje są wykonywane na pliku, to zawsze przekazujemy jego uchwyt w ten sposób. Drugim argumentem jest łańcuch znaków, który będzie stanowił nazwę pliku, w przedstawionym przykładzie będzie to plik tekstowy o plik.txt . Jako trzeci argument przesyłamy żądanie akcji, jaka ma być wykonana. Dla funkcji f_open() wszystkie możliwe wartości ostatniego argumentu pokazano w tab. 3. Na omawianym list. 5 widać, że program tworzy nowy plik, niezależnie, czy wcześniej istniał na karcie pamięci plik o nazwie plik.txt czy nie.  

Tab. 3. Możliwe wartości ostatniego argumentu funkcji f_open()

Sposób otwarcia Opis
FA_READ plik otwierany do odczytu
FA_WRITE plik otwierany do zapisu
FA_OPEN_EXISTING otwarcie pliku, jeśli plik nie istnieje, to zostanie zgłoszony błąd
FA_OPEN_ALWAYS otwarcie pliku, jeśli nie istnieje, to zostanie stworzony nowy plik
FA_CREATE_NEW utworzenie nowego pliku, jeżeli plik istnieje, to zostanie zgłoszony błąd
FA_CREATE_ALWAYS utworzenie nowego pliku, jeżeli już istnieje, to nadpisanie na stary plik

Każda funkcja z modułu FatFs zwraca wartość typu FRESULT. Generalnie, jeśli zwracana wartość wynosi 0, to wszystko przebiegło prawidłowo, w przeciwnym wypadku wystąpiły błędy.
Oprócz tworzenia plików warto również dysponować mechanizmem pozwalającym na tworzenie katalogów. W module FatFs takiego mechanizmu dostarcza funkcja f_mkdir() . W argumencie do funkcji przekazujemy nazwę katalogu. Jeśli katalog nie ma być utworzony w jakimś innym katalogu to wystarczy jego nazwa, a jeśli chcemy utworzyć folder jako podkatalog, to należy podać całą jego ścieżkę. Ostatni przypadek przedstawia poniższa linia kodu:

Jeśli można tworzyć pliki i katalogi, to wypadałoby również móc je usuwać. Zapewnia to wywołanie funkcji f_unlink() , w argumencie należy podajać nazwę pliku lub katalogu przeznaczonego do usunięcia. Zapis do pliku, po jego wcześniejszym otwarciu do zapisu, wykonuje się przez wywołanie funkcji f_write() . Oprócz uchwytu do pliku przekazujemy tablice z bajtami przeznaczonymi do zapisu oraz liczbę zapisywanych bajtów. Ostatnim argumentem jest przekazanie przez referencję zmiennej typu DWORD , do której zostanie wpisana faktyczna ilość zapisanych do pliku bajtów.
Administrowanie zawartością karty pamięci może niekiedy wymagać skracania długości pliku, czyli innymi słowy zmniejszenia jego rozmiarów. Można tego dokonać dzięki funkcji f_truncate() ( truncate – skracać), której wywołanie może wyglądać podobnie poniżej zamieszczonej linii kodu:

Jak widać, jedynym wymaganym do przekazania argumentem jest adres do uchwytu pliku, czyli zmiennej (struktury) zawierającej wszystkie informacje na temat pliku, niezbędne do jego poprawnego egzystowania w systemie plików. Funkcja f_truncate() do skracania długości pliku wykorzystuje aktualny wskaźnik zapisu/odczytu. Mechanizm zmniejszania rozmiarów pliku przedstawiono na rys. 5. Mechanizm skracania długości pliku może znaleźć zastosowanie na przykład w systemach akwizycji dużej ilości danych, gdzie niekiedy zachodzi potrzeba odrzucenia części zebranych informacji.

Rys. 5. Mechanizm zmniejszania rozmiarów pliku

Rys. 5. Mechanizm zmniejszania rozmiarów pliku

Przeglądanie zawartości karty pamięci, informacje o plikach i katalogach

Informacje na temat plików w module FatFs można uzyskać poprzez wywołanie funkcji f_stat() , wystarczy w programie umieścić następującą linię kodu:

Jako pierwszy argument należy podać łańcuch znaków zawierający nazwę pliku, ściślej wskaźnik na początek tablicy z nazwą pliku.
Informacje zostają zapisane do struktury typu FILINFO , której budowa pokazano na list. 6, a jej adres jest przekazywany jako drugi argument w wywołaniu funkcji f_stat() . Dane na temat pliku, jakie otrzymujemy to: rozmiar, data ostatniej modyfikacji, czas modyfikacji, atrybuty pliku, nazwa w tablicy 13-elementowej (format 8 + 3).

List. 6. Budowa struktury FILINFO

Przeglądu zawartości całego katalogu można dokonać z wykorzystaniem funkcji f_readdir() . Przykładowy program, który zbiera informację na temat tego, co znajduję się w folderze katalog1 został przedstawiony na list. 7.

List. 7. Program testowy gromadzący informacje na temat zawartości folderu katalog1

Po otwarciu katalogu za pomocą funkcji f_opendir() w nieskończonej pętli następuje odczytywanie informacji o kolejnych plikach i folderach przez skopiowanie struktury wyżej omówionego typu ( FILINFO ). Kolejne wywołania funkcji f_readdir() powodują samoczynne czytanie informacji o następujących po sobie elementach katalogu. Jeśli pole nazwy elementu będzie puste, to oznacza wtedy, że nie ma już w danym folderze elementów i wykonywanie pętli zostaje przerwane.

O autorze