Mikrokontrolery STM32 - Obsługa kart SD i FatFs.pdf

(767 KB) Pobierz
652389792 UNPDF
PODZESPOŁY
Mikrokontrolery STM32
Obsługa kart SD
i modułu FatFs
Dodatkowe
materiały na CD
Ilości przechowywanych
i przetwarzanych informacji
nieustannie rosną. Coraz
częściej systemy wbudowane
są zmuszane do zarządzania
dużą ilością danych. W artykule
omówiono sposób wykorzystania
kart pamięci SD i modułu FatFs
w połączeniu z mikrokontrolerami
STM32. Biorąc pod uwagę
nieustanny spadek cen kart
SD warto poważnie zastanowić
się nad wykorzystaniem tego
typu nośnika w aplikacji, która
wymaga administrowania
nieprzeciętną ilością danych.
Przykładowe aplikacje
przygotowano dla płytki
ewaluacyjnej STM3210B-EVAL.
Co to jest? Dzowiesz się na końcu artykułu
lerach sprzętowych sterowników kart SD.
Przedstawiciele najbardziej zaawansowanej
grupy układów z rodziny STM32 mają wbu-
dowany właśnie taki sterownik.
Obecnie na rynku karty SD można spo-
tkać najczęściej w dwóch typach obudów:
zwykłej SD i SDMicro. Obie przedstawiono
na rys. 1 .
W zasadzie wszystkie karty SD dostępne
na rynku obsługują dwa standardy komuni-
kacyjne: dedykowany SDBus oraz SPI. Jak to
zwykle bywa, interfejs natywny (SDBus) ofe-
ruje duże możliwości i dużą szybkość pracy,
ale za cenę wzrostu stopnia skomplikowania
obsługi interfejsu. Z tego powodu w kartach
SD dostępna jest również komunikacja za
pomocą o wiele prostszej w obsłudze magi-
strali SPI, z tym, że tutaj mamy nieco okro-
jone możliwości. Jeśli tylko aplikacja nie
wymaga wyjątkowo dużej szybkości przesy-
łania danych, to nie ma jakiegokolwiek sen-
su implementacja obsługi interfejsu SDBus,
wystarczy praca z magistralą SPI. Przedsta-
wione wyżej podejście znakomicie uprasz-
cza sprawę, ponieważ zdecydowana więk-
szość dostępnych mikrokontrolerów (w tym
oczywiście STM32F103 ) jest wyposażona
w sprzętowy kontroler SPI.
Sposób podłączenia karty SD przez
magistralę SPI do mikrokontrolera został
przedstawiony na rys. 2 . Podobny układ
został wykorzystany na płytce ewaluacyjnej
STM3210B-EVAL.
Komendy kart pamięci SD
Nie będziemy wnikać w budowę re-
jestrów, w jakie wyposażone są karty SD,
ponieważ nie to jest celem niniejszego ar-
tykułu. Do osiągnięcia naszego celu, czyli
uruchomienia obsługi systemu plików FAT
w mikrokontrolerze STM32 z użyciem mo-
dułu FatFs, wystarczy znajomość przede
wszystkim budowy komend oraz ich kilku
typów, jakie obsługują karty SD.
Każda komenda, która ma być wysła-
na do karty SD, składa się z sześciu bajtów.
Pierwszym bajtem jest zawsze kod komendy,
kolejne cztery bajty to jej argument. Na koń-
cu jest przesyłany bajt sumy kontrolnej CRC.
O ile w trybie pracy z interfejsem SDBus
CRC jest sprawdzane, to przy komunikacji
za pomocą magistrali SPI, suma kontrolna
jest przez kartę ignorowana. Tylko w trakcie
przesyłania komendy CMD0, przełączającej
tryb pracy z SDBus na SPI jest wymagany
bajt CRC. Nie trzeba go w żaden sposób obli-
czać, ponieważ jest to stała wartość i wynosi
0x95. W tab. 1 umieszczono kilka komend
Karty SD
Współcześnie najpopularniejsze i najbar-
dziej uniwersalne są karty SD ( Secure Digital
card ). Standard obejmuje karty o pojemności
do 4 GB, a jego rozszerzenie, czyli SDHC ( Se-
cure Digital High Capacity ), aż do 32 GB.
Standard kart SD został pierwotnie
opracowany przez trzy fi rmy: Matsushita,
SanDisk i Toshiba. Pierwsze nośniki danych
tego typu pojawiły się pod koniec 2000 roku.
Początkowo dokumentacja standardu SD
była dosyć trudno dostępna, jednak sytu-
acja uległa zmianie wraz z nadejściem roku
2006, kiedy to stały się dostępne informacje
m. in. na temat interfejsu SDIO, co w efekcie
pozwoliło na implementację w mikrokontro-
Rys. 1.
Rys. 2.
92
ELEKTRONIKA PRAKTYCZNA 6/2009
652389792.031.png 652389792.032.png 652389792.033.png 652389792.034.png 652389792.001.png 652389792.002.png 652389792.003.png 652389792.004.png 652389792.005.png
 
Obsługa kart SD i modułu FatFs
Rys. 3.
wowym źródłem informacji na temat danych
zapisanych na nośniku. Zwykle, oprócz
głównej tablicy alokacji, występuje również
jej kopia. Czwarty obszar to katalog główny,
który jest zakładany automatycznie w trakcie
tworzenia systemu plików. Ostatni, piąty re-
gion, to obszar danych.
Tab. 1.
komenda opis
CMD0 zeruje kartę, pozwala włączyć tryb pracy z magistralą SPI
CMD12
CMD16
CMD17
tworzenia systemu plików. Ostatni, piąty re-
gion, to obszar danych.
Moduł FatFs
System plików w urządzeniach wbudo-
wanych można zaimplementować na dwa
sposoby: pisząc obsługę systemu plików od
podstaw, lub też wykorzystać gotowe rozwią-
zania. W zasadzie nie ma żadnego sensow-
nego uzasadnienia pierwsze wymienione
podejście. System plików FAT jest na tyle do-
brze udokumentowany, a przy tym stosun-
kowo prosty, że powstało wiele darmowych
narzędzi, które radzą sobie bardzo dobrze
z administracją zawartości nośnika danych
z systemem plików FAT. Z reguły otwarty
charakter kodu pozwala na wprowadzenie
koniecznych zmian i poprawek, które mogą
się okazać niezbędne dla stabilności pracy
urządzenia.
Jednym z takich ogólnodostępnych na-
rzędzi jest moduł FatFs, którego zadaniem
jest stanowienie pomostu pomiędzy warstwą
wymuszenie zakończenia transmisji wielu bloków danych
konfi guracja długości bloku danych dla zapisu/odczytu
odczyt bloku pamięci o długości określonej przez CMD16
wanych można zaimplementować na dwa
sposoby: pisząc obsługę systemu plików od
podstaw, lub też wykorzystać gotowe rozwią-
zania. W zasadzie nie ma żadnego sensow-
nego uzasadnienia pierwsze wymienione
podejście. System plików FAT jest na tyle do-
zapis bloku pamięci o długości określonej przez CMD16
w argumencie jest przesyłany adres pierwszego bloku przeznaczonego do skasowania
w argumencie jest przesyłany adres ostatniego bloku przeznaczonego do skasowania
CMD38 kasuje bloki wyznaczone za pomocą CMD32 i CMD33
obsługiwanych w trybie pracy z magistra-
lą SPI wraz z opisem argumentów. Oprócz
standardowych komend CMD karty SD mogą
wykorzystywać jeszcze tak zwane komendy
aplikacji (ACMD). Wysłanie komendy aplika-
cji wymaga uprzedniego wysłania komendy
CMD55, która informuje kartę SD, że następ-
na będzie komenda ACMD.
Nośnik danych w systemie plików FAT
jest podzielony na pięć części, wszystkie
przedstawiono na rys. 3 . Pierwszą logicz-
ną częścią nośnika danych, umieszczoną
w pierwszym sektorze, jest obszar zarezer-
wowany, który zawiera wszystkie podsta-
wowe informacje na temat bieżącej partycji
(nośnika). Do tych informacji zaliczają się m.
in.: typ i rozmiar partycji, rozmiar sektora,
ilość sektorów w klastrze.
Za obszarem zarezerwowanym znajdują
się tablice alokacji plików, które są podsta-
System plików FAT
Z perspektywy systemu plików, każdy
nośnik danych (dysk twardy, karta pamięci)
podzielony jest na sektory i klastery . Sekto-
rem nazywamy najmniejszą liczbę bajtów,
jaką można zapisać lub odczytać. Zwykle
sektor ma rozmiar 512 bajtów. Pliki zapisy-
wane są w numerowanych klastrach. Roz-
miar klastra jest zależny od systemu plików
i nośnika danych. Każdy klaster jest w cało-
ści przydzielony do danego pliku, co ozna-
cza, że nawet jeśli plik jest dużo mniejszy od
rozmiarów klastra, to i tak na dysku zajmuje
tyle, co pojedynczy klaster.
Kluczowym elementem systemu plików
FAT ( File Allocation Table ) jest, zgodnie z je-
go nazwą, tablica alokacji plików. System
plików FAT występuje w sumie w czterech
odmianach, przy czym w systemach wbu-
dowanych zazwyczaj wykorzystuje się dwie,
w zależności od rozmiarów nośnika i wyma-
gań aplikacji będzie to FAT16 lub FAT32.
List. 1.
static
void SELECT (void) // CS w stan niski
{
GPIO_ResetBits(GPIOC, GPIO_Pin_12);
}
static
void DESELECT (void)
// CS w stan wysoki
{
GPIO_SetBits(GPIOC, GPIO_Pin_12);
}
static
void xmit_spi (BYTE Data)
// Wyslanie bajtu do SD
{
// Wyslanie bajtu
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, Data);
}
static
BYTE rcvr_spi (void)
// Odebranie bajtu z SD
Rys. 4.
{
u8 Data = 0;
// Wyslanie 0xFF
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, 0xFF);
// Odebranie bajtu
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
Data = SPI_I2S_ReceiveData(SPI1);
return Data;
}
ELEKTRONIKA PRAKTYCZNA 6/2009
93
Moduł FatFs
CMD24
CMD32
CMD33
652389792.006.png 652389792.007.png 652389792.008.png 652389792.009.png 652389792.010.png 652389792.011.png 652389792.012.png 652389792.013.png 652389792.014.png
PODZESPOŁY
Za konfi gurację kontrolera SPI,
portów wejścia/wyjścia i ich sygna-
łów zegarowych odpowiada funkcja
power_on() , którą zamieszczono na
list. 3 . Po zdefi niowaniu zmiennych,
wykorzystywanych w dalszym ko-
dzie funkcji, następuje włączenie
sygnałów zegarowych dla wyprowa-
dzeń (porty GPIOA i GPIOC) i kon-
trolera SPI. Następnie konfi guro-
wane jest wyprowadzenie PC12 do
sterowania wyborem układu (CS)
oraz piny PA5, PA6, PA7 jako linie
magistrali SPI.
Kontroler SPI jest ustawiany
jako master do pracy w trybie full
List. 2.
static
BYTE wait_ready (void)
{
BYTE res;
Rys. 5.
Timer2 = 50; // Czeka przez 500ms
fi zyczną (nośnikiem pamięci), a aplikacją
uruchomioną na mikrokontrolerze. Szcze-
gółowych informacji na temat FatFs należy
szukać na jego stronie internetowej – http://
elm-chan.org/fsw/ff/00index_e.html . Rola mo-
dułu FatFs w systemie wbudowanym została
zilustrowana na rys. 4 .
Sam moduł FatFs jest napisany w języ-
ku C, a zatem jest całkowicie niezależny od
sprzętu. Pliki, które są niezbędne do popraw-
nej pracy FatFs zostały przedstawione na
rys. 5 w formie drzewa skopiowanego z pro-
jektu wykorzystującego system plików FAT.
Teoretycznie, do poprawnej pracy moduł
FatFs wymaga obecności w systemie wbudo-
wanym zegara czasu rzeczywistego (RTC).
Można ten wymóg bardzo łatwo obejść wpi-
sując stałe wartości w miejsce daty i czasu.
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && Timer2);
}
return res;
List. 3.
static
void power_on (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
u8 i, cmd_arg[6];
u32 Count = 0xFFF;
// Konfi guracja wyprowadzen i kontrolera SPI:
// Wlaczenie sygnalow zegarowych dla peryferiow
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
Implementacja modułu FatFs
w mikrokontrolerach STM32
– warstwa fi zyczna
Do opracowania warstwy sprzętowej zo-
stał wykorzystany przykładowy projekt, za-
mieszczony na stronie internetowej modułu
FatFs. Wszystkie funkcje, których zadaniem
jest sterowanie urządzeniami peryferyjnymi
mikrokontrolera, oraz zapis i odczyt danych
z karty pamięci, zostały umieszczone w jed-
nym pliku sd_stm32.c .
Bezpośrednio ze sprzętem komunikują się
cztery funkcje. Za odbieranie danych z kon-
trolera magistrali SPI odpowiada funkcja
rcvr_spi() , która została przedstawiona, wraz
z pozostałymi trzema na list. 1 . Wysyłaniem
bajtów przez SPI do karty pamięci zajmuje się
funkcja xmit_spi() . Do zadań interfejsu sprzę-
towego należy jeszcze sterowanie sygnałem
wyboru układu CS, co należy do obowiązków
funkcji SELECT() i DESELECT() .
Czasem, gdy mikrokontroler zażąda do-
stępu do zasobów karty pamięci, może się
okazać, że ta ostatnia jest w danym momen-
cie zajęta wykonywaniem innych operacji.
Wtedy istotna jest możliwość sprawdzania
zajętości karty. W tym celu została napisa-
na funkcja wait_ready() , przedstawiona na
list. 2 . Jej zadaniem jest oczekiwanie przez
maksymalny czas 500 ms, aż odebrany bajt
będzie miał wartość 0xFF. Jeżeli w ciągu
500 ms nie zostanie odebrany bajt 0xFF, to
funkcja kończy swoje działanie, zwracając
ostatnią wartość odczytaną z kontrolera SPI.
Mamy już wszystkie niezbędne funkcje
zajmujące się interfejsem sprzętowym, jed-
nak, aby mogły one w ogóle pracować, to
sam sprzęt musi zostać odpowiednio skon-
fi gurowany.
RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO,
ENABLE);
// PA4 jako CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//SCK, MISO and MOSI
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Konfi guracja SPI
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
// Wlacz SPI
SPI_Cmd(SPI1, ENABLE);
// Inicjalizacja karty i przelaczenie w tryb SPI:
DESELECT();
// CS = 1
for (i = 0; i < 10; i++)
xmit_spi(0xFF); // Wyslij 0xFF 10 razy = 80 cykli zegarowych
// (wymaganych co najmniej 74 cykli)
SELECT(); // CS = 0
// Przygotowanie ramki inicjujacej do wyslania
cmd_arg[0] = (CMD0 | 0x40);
cmd_arg[1] = 0; // Argument komendy
cmd_arg[2] = 0; // nawet, gdy komenda go nie ma
cmd_arg[3] = 0; // musi zostac wyslany w postaci zer
cmd_arg[4] = 0;
cmd_arg[5] = 0x95;
// CRC = 0x95
xmit_spi(cmd_arg[i]);
while ((rcvr_spi() != 0x01) && Count) // Czeka na 0x01
Count--;
DESELECT(); // CS = 1
xmit_spi(0XFF); // Wyslij 0xFF
// Wyslanie ramki
PowerFlag = 1;
}
94
ELEKTRONIKA PRAKTYCZNA 6/2009
for (i = 0; i < 6; i++)
652389792.015.png 652389792.016.png
Obsługa kart SD i modułu FatFs
List. 4.
void SysTick_Conf(void)
{
// SysTick bedzie taktowany z f = 72MHz/8 = 9MHz
SysTick_CLKSourceConfi g(SysTick_CLKSource_HCLK_Div8);
// Przerwanie ma byc co 10ms, f = 9MHz czyli liczy od 90000
SysTick_SetReload(90000);
// Odblokowanie przerwania od timera SysTick
SysTick_ITConfi g(ENABLE);
// Wlaczenie timera
SysTick_CounterCmd(SysTick_Counter_Enable);
}
wał funkcję disk_timerproc() , która jest wy-
korzystywana dalej do odmierzania czasu.
Do cyklicznego wywoływania wymienionej
wyżej funkcji został wykorzystany 24 – bito-
wy timer SysTick. Jego konfi guracja została
przedstawiona na list. 4 .
Domyślnie główny zegar systemowy, po
powieleniu przez układ PLL, wynosi 72 MHz
i z taką częstotliwością domyślnie jest takto-
wany SysTick. Aby uzyskać przerwanie co
10 ms zastosowano preskaler, dzielący sygnał
72 MHz przez 8, co w efekcie daje 9 MHz. Je-
śli chcemy, aby funkcja obsługi przerwania
od timera SysTick ( SysTickHandler() ) była
wywoływana z częstotliwością 100 Hz, to
należy sprawić, aby licznik liczył od 90000.
Bardziej szczegółowo timer SysTick został
omówiony w EP12/08, natomiast w tym
przypadku funkcja obsługi jego przerwania
wygląda następująco:
void SysTickHandler(void)
{
disk_timerproc();
}
Omówione funkcje są jedynymi zależny-
mi od sprzętu fragmentami kodu w module
FatFs, zatem teraz zajmiemy się już najwyż-
szą jego warstwą, umożliwiającą operacje na
plikach i katalogach.
Tab. 2.
komenda opis
f_mount „montuje” (rejestruje dysk logiczny w systemie
f_open otwieranie i/lub tworzenie pliku
f_close zamykanie pliku
f_read czytanie zawartości pliku
f_write zapisywanie pliku
f_Iseek 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 wy-
konywać na nim 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, np. plik może być tylko do odczytu
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 nośnika i bezpośrednio przekazuje dalej
Podstawowe operacje na plikach
i katalogach
Gdy mikrokontroler umie się już poro-
zumiewać z kartą SD i system plików jest
należycie obsługiwany, to kolejnym krokiem
są już właściwe operacje na plikach i katalo-
gach, jakie wymaga projektowana aplikacja.
Wszystkie funkcje, jakie oferuje moduł FatFs
zostały omówione na jego stronie interneto-
wej http://elm-chan.org/fsw/ff/00index_e.html ,
a ich spis umieszczono w tab. 2 . Tutaj zaj-
miemy się przykładami aplikacji wykonywu-
jących niezbędne zadania na plikach i kata-
logach.
Przykładowy program, którego zadaniem
są podstawowe operacje na plikach i katalo-
gach pokazano na list. 5 . Przedstawiony kod
dupleks . Ramka danych będzie wynosić 8
bitów, a zatrzaskiwanie stanu linii będzie
następować na zboczu narastającym sygnału
zegarowego. W stanie nieaktywnym na linii
SCK będzie występował stan wysoki.
Preskaler dla zegara kontrolera SPI zo-
stał ustawiony na 4, co oznacza, że dane
będą przesyłane z niebagatelną prędkością
18 Mbit/s. Po ustawieniu wszystkich pa-
rametrów SPI, kontroler zostaje włączony
przez wywołanie funkcji SPI_Cmd() .
Od tego momentu mikrokontroler jest
już prawidłowo skonfi gurowany, natomiast
karta SD domyślnie po włączeniu zasila-
nia pracuje w trybie obsługi dedykowanego
standardu SDBus. Aby komunikacja (odbie-
ranie komend) była w ogóle możliwa, należy
w pierwszej kolejności wysłać co najmniej 74
cykle zegarowe, w celu zainicjowania karty.
Następnie, żeby przejść do trybu pracy z SPI,
należy wysłać komendę CMD0. Jeśli inicja-
lizacja karty do pracy w trybie SPI zostanie
przeprowadzona poprawnie, to karta zwróci
bajt potwierdzenia wynoszący 0x01.
Moduł FatFs wymaga do pracy sygnału
zegarowego, który co 10 ms będzie wywoły-
R
E
K
L
A
M
A
ELEKTRONIKA PRAKTYCZNA 6/2009
95
652389792.017.png
PODZESPOŁY
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 dys-
ku (tutaj 0) oraz, przez referencję, główną
zmienną systemu plików typu FATFS .
Po zamontowaniu dysku można już do-
wolnie 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ścia-
mi 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 pli-
kó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 funk-
cji 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() wszyst-
kie możliwe wartości ostatniego argumentu
pokazano w tab. 3 . Na omawianym list. 5 wi-
dać, że program tworzy nowy plik, niezależ-
nie, czy wcześniej istniał na karcie pamięci
plik o nazwie plik.txt , czy nie.
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 wy-
padku wystąpiły błędy.
Oprócz tworzenia plików warto rów-
nież dysponować mechanizmem pozwala-
jącym na tworzenie katalogów. W module
FatFs takiego mechanizmu dostarcza funkcja
f_mkdir() . W argumencie do funkcji przeka-
zujemy nazwę katalogu. Jeśli katalog nie ma
być utworzony w jakimś innym katalogu to
wystarczy jego nazwa, a jeśli chcemy utwo-
rzyć folder jako podkatalog, to należy podać
całą jego ścieżkę. Ostatni przypadek przed-
stawia poniższa linia kodu:
fresult = f_mkdir(„katalog1/
katalog2”);
List. 5.
int main(void)
{
FRESULT fresult;
FIL plik;
WORD zapisanych_bajtow;
RCC_Conf();
GPIO_Conf();
SysTick_Conf();
fresult = f_mount(0, &g_sFatFs);
// Tworzenie pliku
fresult = f_open (&plik,”plik.txt”, FA_CREATE_ALWAYS);
fresult = f_close (&plik);
fresult = f_mkdir(„katalog1”);
// Zapis pliku
fresult = f_open (&plik,”plik.txt”, FA_WRITE);
fresult = f_write(&plik, „zawartosc pliku”, 15, &zapisanych_bajtow);
fresult = f_close (&plik);
fresult = f_unlink(„plik.txt”);
}
while(1);
Tab. 3.
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
Jeśli można tworzyć pliki i katalogi, to wy-
padałoby również móc je usuwać. Zapewnia
to wywołanie funkcji f_unlink() , w argumencie
należy podajać nazwę pliku lub katalogu prze-
znaczonego do usunięcia. Zapis do pliku, po
jego wcześniejszym otwarciu do zapisu, wy-
konuje 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ła-
nie może wyglądać podobnie poniżej zamiesz-
czonej linii kodu:
fresult = f_truncate(&plik);
Jak widać, jedynym wymaganym do prze-
kazania argumentem jest adres do uchwytu
pliku, czyli zmiennej (struktury) zawierają-
cej wszystkie informacje na temat pliku, nie-
zbędne do jego poprawnego egzystowania
w systemie plików. Funkcja f_truncate() do
skracania długości pliku wykorzystuje aktu-
alny wskaźnik zapisu/odczytu. Mechanizm
zmniejszania rozmiarów pliku przedstawio-
List. 6.
/* File status structure */
typedef struct _FILINFO {
DWORD fsize;
/* Size */
WORD fdate;
/* Date */
WORD ftime;
/* Time */
char fname[13];
/* Name (8.3 format) */
} FILINFO;
List. 7.
fresult = f_opendir(&Dir, „katalog1”);
if(fresult != FR_OK)
return(fresult);
for(;;)
{
fresult = f_readdir(&Dir, &plikInfo);
if(fresult != FR_OK)
return(fresult);
if(!plikInfo.fname[0])
break;
// p jest wkaznikiem na tablice elemetnow typu FILINFO
*p++ = plikInfo;
}
Rys. 6.
96
ELEKTRONIKA PRAKTYCZNA 6/2009
// Tworzenie katalogu
// Usuniecie pliku
652389792.018.png 652389792.019.png 652389792.020.png 652389792.021.png 652389792.022.png 652389792.023.png 652389792.024.png 652389792.025.png 652389792.026.png 652389792.027.png 652389792.028.png 652389792.029.png 652389792.030.png
 
Zgłoś jeśli naruszono regulamin