Skocz do zawartości

Zapis danych na karcie micro SD - pytania odnośnie optymalizacji procesu zapisu i systemu plików


hubert27

Pomocna odpowiedź

Witam wszystkich.

Rozwijam projekt którego istotną częścią jest zapis danych z czujników na kartę micro SD. Należy zwrócić uwagę na fakt, że urządzonko będzie w czasie jednej "sesji" pracowało dość długo, po kilkadziesiąt godzin, a odczyty danych częste (rzędu 1000 sampli na sek., chociaż jeszcze nie jestem pewien, może będzie wystarczały rzadsze odczyty). Mamy więc dużą ilość danych do zapisania. Z samą obsługą karty problemu nie mam, jest wiele tutoriali, sam zresztą już robiłem testy z zapisem małej ilości danych 😃 Interesuje mnie natomiast jak zrobić właśnie taki ciągły zapis dużej ilości danych na microSD. O co konkretnie pytam?

Czy ktoś może podzielić się doświadczeniami z zapisu na kartę SD dużej ilości danych np z czujników, używając platform takich jak AVR, Arduino?

Czy jest coś, na co trzeba zwrócić uwagę przy tworzeniu aplikacji "pracujących" na systemie plików w karcie?

Po prostu chcę zobaczyć, jakie problemy mieli inni, żeby może ich uniknąć / szybciej je rozwiązać. Oczywiście jestem sam w stanie zrobić program zapisujący takie dane, ale nie jestem pewny czy zrobiłbym to optymalnie 😃 Za wszelkie odpowiedzi w tym temacie dziękuję 😃

Używam:

Arduino UNO

karty microSD z czytnikiem i konwerterem 3v3/5v z Botlandu

czujników mierzących różne rzeczy xD

Hubert

Link do komentarza
Share on other sites

To zdecyduj się, odczyt czy zapis?

Z odczytem nie ma problemu, możesz to robić dwolną liczbę razy dowolnymi metodami.

Z zapisem problem jest spory, bo każdy zapis niszczy kartę. Do tego jest on robiony całymi blokami (na przykład 512B na raz). Żeby zapisać jeden bajt, komputer musi taki blok 512 bajtów odczytać gdzieś do pamięci, zmienić ten jeden bajt gdzieś w środku, wyzerować na karcie cały blok i zapisać go w to miejsce. Nie tylko jest to wolne, nie tylko niszczy kartę (dany blok można kasować ograniczoną liczbę razy, potem przestaje się nadawać do użytku), to jeszcze jak wyłączysz prąd w złym momencie, to tracisz dane.

Tak więc przy zapisie dużej ilości danych trzeba się trochę zastanowić -- najlepiej nie używać systemu plików (albo użyć takiego specjalnie zaprojektowanego dla kart), zapisywać całe bloki na raz, nie zapisaywać niepotrzebnie danych, które już tam są, etc.

Link do komentarza
Share on other sites

Biorąc pod uwagę prędkości zapisów danych do karty, 1k próbek na sekundę czyli pewnie jakieś 2kbajty/s to nie jest wielki wyczyn. A w samym Arduino problemem może być RAM. Uno ma go 2kbajty a potrzebujesz:

- bufora na dane zbierane z czujników w czasie rzeczywistym,
- drugiego takiego samego na wymianę: jeden zapełniasz a z drugiego - już pełnego - zlecasz zapis danych na kartę,
- system plików na pewno zarezerwuje sobie pamięć o wielkości min. 1 sektora karty (a zwykle więcej) czyli Nx512 bajtów.

I szybko RAM się kończy a w każdym razie będzie panował ciągły głód i wachlowanie uszami by się coś nie przepełniło (stos na przykład).

Na pewno oba procesy (odczyt danych z czujników i operacje na karcie) będą musiały pracować współbieżnie więc ani transfer danych do karty (SPI) ani operacje na czujnikach (I2C? ADC?) nie mogą być blokujące. O ile czujniki sam pewnie oprogramujesz i możesz to zrobić dowolnie dobrze, o tyle system plików jest jaki jest. Transfer SPI musi się wykonywać na przerwaniach a szczerze mówiąc nie wiem jak to jest zrobione w tych najprostszych, implementowanych na Arduino. Mam złe przeczucia. Sprawę pogarsza żałosny prymityw SPI użytego w procesorach AVR: kompletny brak buforowania i "pojemność" tylko 1bajtu. Chcąc zrobić nieblokujący zapis bloku danych musisz obsługiwać przerwanie co 1 bajt i wtedy cała szybkość tego interfejsu idzie.. w krzaki, a procesor co kilka us jest nękany obsługą prostych przerwań.

Kolejna sprawa to transakcyjność. Chyba nie istnieje arduinowy, transakcyjny system plików dla karty SD. A to oznacza, że nie wolno Ci utracić zasilania i przerwać operacji zapisu bez poprawnie zakończonego zamknięcia pliku. Zamknięcie pliku to aktualizacja FATu więc kilka zapisów/odczytów karty. Bez tego dane zapisywane do pliku zostaną stracone. Pomyśl nad podtrzymywaniem zasilania i/lub sygnałem POWER_FAIL ostrzegającym o jego bliskim upadku, ale tak by procesor miał jeszcze czas na dokończenie ostatniego zapisu i zamknięcie pliku. Na większe maszyny transakcyjne systemy plików są standardem. Masz wtedy pewność, że nawet w razie nienormalnego przerwania operacji spójność wszystkich struktur na pamięci FLASH jest zachowana.

Na Twoim miejscu pomyślałbym ciepło o zwykłej, szeregowej pamięci FLASH. Podłączasz ją także przez SPI, ale jej organizacja jest dużo prostsza więc "overhead" programowy jest mniejszy. Sam decydujesz gdzie zapisywać lub odczytywać, ale po inicjalizacji i wysłaniu adresu początkowego możesz robić to ciurkiem przez całą pamięć. Pojemność 8Mbajtów kosztuje niedużo i jest trywialna w użyciu. Może by wystarczyło?

http://www.tme.eu/pl/details/26vf064b-104i_sm/pamieci-flash-szeregowe/microchip-technology/sst26vf064b-104ism/

Są też pamięci ATMELa (obecnie ktoś tę działkę od nich przejął), tzw. DataFLASH z własnymi buforami. Do niej możesz na bieżąco wysyłać dane wczytane z czujnika bez zajmowania sobie RAMu a po zapełnieniu bufora wydajesz komendę "Zapisz bufor do FLASHa" a w tym czasie gdy jest tym zajęta zapełniasz jej drugi bufor:

http://www.tme.eu/pl/details/at45db641e-shn2bt/pamieci-flash-szeregowe/adesto/at45db641e-shn2b-t/

Oczywiście prędkość zapisu "zwykłej" szeregowej pamięci jest taka, że nie musisz danych buforować w RAMie: 2 bajty zapisuje w jakieś 10us więc można wysyłać na bieżąco nawet do 200kbajtów/s 🙂

Link do komentarza
Share on other sites

Kolejna sprawa to transakcyjność. Chyba nie istnieje arduinowy, transakcyjny system plików dla karty SD. A to oznacza, że nie wolno Ci utracić zasilania i przerwać operacji zapisu bez poprawnie zakończonego zamknięcia pliku. Zamknięcie pliku to aktualizacja FATu więc kilka zapisów/odczytów karty. Bez tego dane zapisywane do pliku zostaną stracone. Pomyśl nad podtrzymywaniem zasilania i/lub sygnałem POWER_FAIL ostrzegającym o jego bliskim upadku, ale tak by procesor miał jeszcze czas na dokończenie ostatniego zapisu i zamknięcie pliku. Na większe maszyny transakcyjne systemy plików są standardem. Masz wtedy pewność, że nawet w razie nienormalnego przerwania operacji spójność wszystkich struktur na pamięci FLASH jest zachowana.

Takiej gwarancji z kartą SD nigdy nie masz, choćbyś nie wiem jaki zaawansowany system plików zastosował, właśnie ze względu na to jak wygląda wewnętrznie taki zapis -- skopiowanie bloku do pamięci podręcznej, wykasowanie go, zapisanie na powrót. Robi to kontroler karty, więc nie masz na to wpływu. Jak wyłączysz zasilanie w złym momencie, to masz pusty blok tam, gdzie kiedyś były dane. Jak to akurat trafi w jakiś indeks twojego systemu plików, to w zasadzie możesz zaczynać od nowa.

Zawsze musisz mieć podtrzymywanie zasilania dla karty, jeśli dane są ważne, zapis jest ciągły a prądu może zabraknąć.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Oczywiście, ze masz, bo transkacyjność nie polega na wyborze meganiezawodnego nośnika tylko na sposobie jego traktowania. Chodzi o to, by wykonać żądaną operację "trochę z boku" a potem jednym strzałem zmienić stan np. systemu plików czy bazy danych na nowy. Jeżeli to ostanie się uda, transakcja jest wykonana. Gdy nie, wciąż mamy stary (ale nadal poprawny) stan. To nie jest łatwe, ale tak to właśnie działa - niezależnie czy na ułomnej karcie SD, pamięci FLASH, EEPROMie, HDD czy SSD.

"Zawsze musisz mieć podtrzymywanie zasilania dla karty"

Przecież to właśnie napisałem: Pomyśl nad podtrzymywaniem zasilania i/lub sygnałem POWER_FAIL ostrzegającym o jego bliskim upadku, ale tak by procesor miał jeszcze czas na dokończenie ostatniego zapisu i zamknięcie pliku.

Link do komentarza
Share on other sites

Oczywiście, ze masz, bo transkacyjność nie polega na wyborze meganiezawodnego nośnika tylko na sposobie jego traktowania. Chodzi o to, by wykonać żądaną operację "trochę z boku" a potem jednym strzałem zmienić stan np. systemu plików czy bazy danych na nowy. Jeżeli to ostanie się uda, transakcja jest wykonana. Gdy nie, wciąż mamy stary (ale nadal poprawny) stan. To nie jest łatwe, ale tak to właśnie działa - niezależnie czy na ułomnej karcie SD, pamięci FLASH, EEPROMie, HDD czy SSD.

Zastanów się trochę. Nawet, jeśli swoją operację będziesz robić "z boku", to nadal musisz mieć gdzieś informację o tym gdzie ten "bok" jest. Jasne, możesz zrobić na karcie kopię danego bloku zanim zaczniesz go modyfikować -- wolne, ale możliwe -- ale skąd potem będziesz wiedzieć przy uruchomieniu po upadku zasilania który z nich jest właściwy? Sprawdzisz w dzienniku? A jak zapisujesz ten dziennik, że on się z kolei nie wyzeruje?

Problem z tym, co piszesz, jest właśnie w tym, że nie jesteś w stanie zmienić stanu "jednym strzałem" -- bo wszystkie operacje jakie masz do dyspozycji nie są atomowe. Jedyny sposób, jaki mogę sobie wyobrazić, to trzymanie pomocniczego dziennika na jakimś innym nośniku -- na przykład w EEPROM Arduino -- ale wtedy co jeśli przełożysz kartę do innego urządzenia?

Link do komentarza
Share on other sites

"ale skąd potem będziesz wiedzieć przy uruchomieniu po upadku zasilania który z nich jest właściwy" - właśnie stąd, że nawet jeśli zasilanie zdechnie podczas tej krytycznej operacji przestawiania (np. zapisu ostatniego sektora do karty) to jest to udane albo nie. Nie ma trzeciej możliwości. Po włączeniu widzisz przełącznik: ma stan taki albo taki. Czego tu nie rozumieć? A zapisy sektorów z mojego punktu widzenia są atomowe. Zapisał się poprawnie albo nie. Najpierw weryfikuję wszystkie zapisy "nowego" stanu a na końcu zmieniam "przełącznik".

deshipu, trochę nie rozumiem celu tej dyskusji. Co właściwie próbujesz udowodnić? Przecież rozmawiamy o rzeczach, które ludzie dawno już wymyślili, pracuje to w milionach komputerów i baz danych i nikt nie ma z tym problemu. Jeżeli przewidujesz kłopoty z fizycznym nośnikiem, robisz matrycę RAID. To nie są tanie ani proste rzeczy, ale nikt nie mówił, że takie mają być. Nie pisałem, że to łatwe albo w ogóle możliwe do zrobienia na Arduino, tylko że problemem prostych systemików plików jest właśnie brak transakcyjności. Bo to że ona istnieje i jest realizowalna chyba nie masz wątpliwości? Pierwszy z brzegu:

https://en.wikipedia.org/wiki/Transaction-Safe_FAT_File_System#TexFAT

http://www.qnx.com/developers/docs/660/index.jsp?topic=%2Fcom.qnx.doc.neutrino.sys_arch%2Ftopic%2Ffsys_ETFS.html

Link do komentarza
Share on other sites

"ale skąd potem będziesz wiedzieć przy uruchomieniu po upadku zasilania który z nich jest właściwy" - właśnie stąd, że nawet jeśli zasilanie zdechnie podczas tej krytycznej operacji przestawiania (np. zapisu ostatniego sektora do karty) to jest to udane albo nie. Nie ma trzeciej możliwości. Po włączeniu widzisz przełącznik: ma stan taki albo taki. Czego tu nie rozumieć? A zapisy sektorów z mojego punktu widzenia są atomowe. Zapisał się poprawnie albo nie. Najpierw weryfikuję wszystkie zapisy "nowego" stanu a na końcu zmieniam "przełącznik".

W tym sęk, że nie masz takiego przełącznika, który możesz sobie jednym pstryknięciem zmienić. Operacja zapisu składa się z dwóch pod-operacji: wymazanie bloku i zapisanie nowych danych. Jeśli ci prąd padnie akurat w momencie, kiedy ten swój "przełącznik" przestawiasz, zaraz po skasowaniu bloku, to twój przełącznik, razem z resztą danych, która była w tym bloku, jest wyzerowany. Nie ma ani poprzedniej ani następnej wartości, tylko ma wartość 0xFF.

I nie pisz proszę o macierzach RAID i dyskach, bo to są zupełnie inne urządzenia. Choć dyski SSD działają na podobnej zasadzie na samym dnie jak karty SD, dlatego też mają wewnętrzne źródła zasilania, podtrzymujące prąd w razie awarii na te krytyczne ułamki sekundy. Natomiast karty SD czegoś takiego nie mają, bo zostały zrobione z założeniem, że urządzenie nie wyłączy się nagle w połowie zapisu, a przed odłączeniem karty zostanie poprawnie wyłączone.

Link do komentarza
Share on other sites

deshipu, poczytaj trochę o UBIFS - lubisz linuxa, więc temat powinien być Ci bliski. Ten system plików nie zakłada podtrzymywania bateryjnego, a działa całkiem dobrze. W przypadku karty SD problem polega na tym, że wewnętrzny procesor wykonuje już wear-leveling, więc ciężko ręcznie sterować zapisem. Jednak UBI jest fajnym, bo otwartym przykładem, że bezawaryjny zapis na awaryjnym nośniku da się zrobić.

Link do komentarza
Share on other sites

deshipu, poczytaj trochę o UBIFS - lubisz linuxa, więc temat powinien być Ci bliski. Ten system plików nie zakłada podtrzymywania bateryjnego, a działa całkiem dobrze. W przypadku karty SD problem polega na tym, że wewnętrzny procesor wykonuje już wear-leveling, więc ciężko ręcznie sterować zapisem. Jednak UBI jest fajnym, bo otwartym przykładem, że bezawaryjny zapis na awaryjnym nośniku da się zrobić.

Ja nie piszę, że nie da się zrobić bezawaryjnego zapisu na awaryjnym nośniku. Przecież w zasadzie wszystkie nośniki od początku historii komputerów były awaryjne i rzeczywiście poszło w to dużo wysiłku.

Ja piszę, że nie da się tego zrobić na karcie SD konkretnie. Gdyby się dało, to już wszystkie Raspberry Pi by takiego systemu plików używały. Owszem, da się prawdopodobieństwo "trafienia" w krytyczny moment minimalizować, ale kiedy nie masz żadnych atomowych operacji, to nie zrobisz niezawodnego systemu.

Link do komentarza
Share on other sites

To co z tego, że operacja zapisu sektora pamięci FLASH składa się z kasowania i zapisu nowych danych? Przełącznik może zajmować cały sektor, to żadna strata. Za poprawny zapis system transakcyjny może uważać zakończenie wszystkich operacji wiążących się z szeroko pojętym zapisem: kasowania, zapisu i weryfikacji. To może się udać i cieszymy się, albo nie i wtedy obowiązuje poprzedni stan. Jeżeli chcesz to wykorzystać, poświęcasz np. dwa sektory na dwa przełączniki i po zmianie i weryfikacji stanu "nowego FATu" zapisujesz do obu przełączników jakieś znaczniki następstw. A teraz wstajesz po awarii zasilania: jeśli oba trzymają to samo - super, mamy jasność która kopia FAT jest ważna. Jeżeli jeden jest uszkodzony (np. w sensie CRC czyli np. tylko skasowany, ale nie zapisany lub zapisany śmieciami) stanem obowiązującym jest ten z drugiego przełącznika - trudno, ostatnia operacja nie udała się pod sam koniec. Jeżeli oba dają się odczytać poprawnie, ale są różne, obowiązuje ten z nowszym znacznikiem czasu. Widocznie podczas zmiany przełączników (zmieniamy zawsze oba na raz) udało się zapisać tylko jeden a potem padło zasilanie. Sam widzisz, takich schematów można mnożyć mnóstwo.

Karta SD nie różni się od zwykłych pamięci FLASH niczym oprócz innego interfejsu i wbudowanego kontrolera odpowiedzialnego za wyrównywanie zużycia sektorów i ew. przemapowanie uszkodzonych. Tak jak w normalnym FLASHu masz tam strony, sektory itp obszary, tylko dostajesz się do nich trochę inaczej. System plików siedzi wyłącznie w procesorze więc możesz go zrobić zupełnie dowolny.

A macierz RAID możesz robić z dowolnych nośników. To mogą być HDD, ale także równolegle pracujące karty SD czy SSD, bo to tylko idea polegająca - w jednej z wersji (RAID1) - na zwielokrotnieniu miejsc gdzie trzymasz swoje dane.

Oczywiście, karty SD nie mają żadnego podtrzymania zasilania i dlatego jeszcze raz przypomnę po raz trzeci cytując samego siebie:

"Pomyśl nad podtrzymywaniem zasilania i/lub sygnałem POWER_FAIL ostrzegającym o jego bliskim upadku, ale tak by procesor miał jeszcze czas na dokończenie ostatniego zapisu i zamknięcie pliku."

Czy z tym pomysłem się zgadzasz? Albo więc mamy prosty FAT i podtrzymujemy zasilanie bo inaczej ostatnio dopisane do pliku dane idą w powietrze albo staramy się bardziej. To teraz już tylko niewielki krok myślowy do użycia transakcyjnego systemu plików odpornego na awarie zasilania - nawet jeśli nie wierzysz w jego istnienie lub nie rozumiesz jak on działa.

W urządzeniach, które produkuje moja firma na rynek profesjonalny użycie systemu plików odpornego na nagłe restarty w przypadku systemu trzymanego na szeregowym FLASHu jest koniecznością. Inaczej już dawno mielibyśmy magazyn pełen zwrotów, bo w miejscu gdzie jest to instalowane awarie zasilania są na porządku dziennym.

Link do komentarza
Share on other sites

A teraz wstajesz po awarii zasilania: jeśli oba trzymają to samo - super, mamy jasność która kopia FAT jest ważna. Jeżeli jeden jest uszkodzony (np. w sensie CRC czyli np. tylko skasowany, ale nie zapisany lub zapisany śmieciami) stanem obowiązującym jest ten z drugiego przełącznika - trudno, ostatnia operacja nie udała się pod sam koniec. Jeżeli oba dają się odczytać poprawnie, ale są różne, obowiązuje ten z nowszym znacznikiem czasu.

Przekonałeś mnie, przepraszam za upór. Będzie to wolne, ale będzie działać.

Link do komentarza
Share on other sites

Dziękuję za liczny odzew 😃 Byłem cały dzień w robocie, więc dopiero teraz czytam, a jest co ;D Jak poogarniam, to odpowiem bardziej konstruktywnie. @Deshipu oczywiście zapis 😃 Słowa odczyt użyłem w kontekście odczytu danych z czujników. Czujniki wykorzystują ADC, łącznie 4 kanały.

OK, ogarnąłem. Trochę mnie przeraziliście XD

Jednak chciałbym zaznaczyć parę rzeczy:

Po pierwsze, być może nie będzie konieczna tak duża prędkość zapisu. Być może dane będą rejestrowane co 1 sek., bo 100 odczytów, czyli jakieś 500 B/s.

Pod drugie: Jeśli raz na 50 pomiarów, coś się sypnie, nie spowoduje to katastrofy, istnieje coś takiego jak szumy i metody ich odfiltrowania 😉 Ważne, aby nie posypał się cały system plików, i to mi głównie chodzi, aby z byle powodu nie stracić wszystkich danych, bo jakiś zły program zrobiłem. To że się raz na jakiś czas z powodu braków zasilania coś nie zapisze nie jest jeszcze straszne 😃

deshipu, dzięki za zwrócenie uwagi na pracę na blokach. Czy wbudowana biblioteka Arduino jest jakoś pod tym względem w miarę optymalna? Tzn. czy nie marnotrawi bloków w trakcie zapisu?

marek1707, nie wiem czy Megabajty to nie będzie za mało 😉

Generalnie wniosek nasuwa mi się jeden: poszukać rozwiązania / biblioteki zaprojektowanej tak, by zoptymalizować zapisy na blokach (i niszczenie karty) i uchronić się przed przypadkowym utraceniem danych. Coś w stylu transakcyjny system plików na kartę SD i prosty microchip, czyż tak? Do tego jakieś sprzętowe odciążenie dla Arduino przy obsłudze systemu plików.

Link do komentarza
Share on other sites

To ja bym odróżnił dwie rzeczy. Pierwsza to zakłócanie cyklu pomiarów przez operacje na plikach. Zapewne zorganizujesz to w ten sposób, że będzie jakiś system pomiaru czasu (timer + jego ISR) wyznaczający momenty kiedy musisz odpalić skan kanałów ADC i zebrać pomiary ze wszystkich czujników. Te pomiary będziesz pewnie gromadził w jakimś swoim buforze, opatrując je przy okazji jakimiś informacjami dodatkowymi typu znacznik czasu albo lub numer kolejny. Można też nic dodatkowego nie wrzucać zakładając, że wykonywane są przecież sekwencyjnie co zadany kwant czasu. Gdy bufor się zapełni powinieneś przełączyć sobie jakąś flagę i zacząć zapisywać kolejne paczki danych do drugiego, identycznego bufora a ten właśnie zapełniony wskazać funkcji file_write() jako blok danych do zapisu. No i teraz najciekawsze: na czas operacji zapisu tracisz sterowanie, bo nie wiesz ile będzie to trwało. Wołasz funkcję z biblioteki nie wiedząc na jak długo procesor w niej utknie a ten czas może bardzo się zmieniać. Szczęście, jeśli nie zablokuje ona przerwań globalnych, bo wtedy Twoje pomiary mogą się nadal wykonywać. Proces pomiarowy i zapamiętywania paczek w buforze musi być jednak wykonywany wyłącznie w przerwaniu od timera lub ADC. Natomiast jeśli z jakiegoś powodu system plików blokuje przerwania na czas transmisji SPI do/z karty to leżysz. Nawet jeśli przyjdzie czas na kolejny pomiar i timer sprzętowy zgłosi przerwanie, nic go nie obsłuży. Wtedy będzie dziura w sekwencji pomiarów a Ty jej nie zauważysz. Mając próbki zbierane co stały kwant czasu - a tak działa 99% systemów analogowo-cyfrowych - istnieją metody (interpolacja wielomianem lub filtrowanie low-pass lub sinc) uzupełniania brakujących, ale musisz wiedzieć, gdzie ich brakuje i znać pasmo sygnału. Bez tego nie masz żadnych szans odtworzenia pierwotnych danych. Nie wiem co to za pomiary i co z nich będziesz wyciągał, ale to podstawy DSP.

Druga rzecz to znikanie danych gdy zasilanie pada. Na pewno wiesz jak to działa: plik najpierw "otwierasz", co de facto powoduje wpis jego nazwy do FAT, znalezienie i dopisanie do tej nazwy numeru pierwszego wolnego klastra na nośniku od którego plik się zaczyna. Teraz gdy kolejno wołasz funkcje zapisu danych, w miarę potrzeby zajmowane są kolejne klastry tworzące dłuższe lub krótsze, spójne łańcuchy. Niestety plik od tego nie rośnie i dopóki na zamkniesz pliku odpowiednią funkcją, FAT nie zostanie uaktualniony a długość pliku pozostanie taka jak była przez otwarciem. Nie tracisz tylko nie zapisanych jeszcze danych, ale wszystkie wysłane na nośnik od ostatniego otwarcia. Dlatego gdy pada zasilanie (lub z innego powodu operacja sekwencyjnego zapisu zostanie nienormalnie zakończona) a Twój procesor nie będzie miał szansy dowiedzieć się o tym i poprawnie zareagować wywołaniem file_close(), strata jest dużo większa niż się spodziewamy. Na nośniku pojawiają się za to klastry zajęte, ale nie przypisane do konkretnego pliku i robi się nieciekawie. Nie sądzę by udało Ci się na małym komputerku odpalić jakikolwiek transakcyjny system plików - ta dyskusja była trochę akademicka więc tym bardziej ważne jest byś:

- albo produkował dużo małych plików poprzez file_open → zapis np. kilku sekund danych → file_flush() → file_close() i generowanie wciąż nowych, unikalnych nazw choćby wg stringu czasu utworzenia,
- albo w przypadku zasilania sieciowego miał system podtrzymywania pracy (wystarczy 100ms i duży kondensator) i natychmiastowy sygnał ostrzeżenia o zaniku 230VAC,
- albo w przypadku zasilania bateryjnego tak napisał program by urządzenie miało polecenie/przycisk "shutdown" albo "stop_pomiarów" zamykający wszystkie otwarte pliki i ew. samodzielnie wyłączający sobie zasilanie jak np. telefony.

Oczywiście przedstawiony schemat pracy to tylko jedna z możliwości, ale dostępne implementacje systemów plików FATxx na Arduino są upraszczane do bólu i byłbym miło zaskoczony gdyby ktoś zrobił to inaczej niż opisałem. To kosztuje też dodatkowy czas w czasie zapisów, bo od czasu do czasu - oprócz zapisu samych danych - trzeba grzebać w FAT.

Czego konkretnie używasz?

Moim zdaniem żadna z dostępnych na Arduino bibliotek FATxx_filesystem nie troszczy się o równomierność zużycia sektorów i dlatego np. nie może być użyta do postawienia systemu plików na zwykłej, szeregowej pamięci FLASH czy DataFLASH. Proponując te kostki myślałem o zapisach wprost. Po podłączeniu do kompa program odczytywałby dane binarne z pamięci i wysyłał je przez USB. Niewiele droższe (jeżeli w ogóle) są pamięci 64Mbajty, ale jeśli to nie starcza, jesteś skazany na SD. W nich z kolei nie musisz przejmować się równomiernym zużyciem stron, bo o to dba wbudowany w kartę kontroler. Nie masz z resztą szans tego robić, bo nie wiesz jakie jest mapowanie numerów sektorów których używa system plików na fizyczne miejsca w pamięci FLASH karty.

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.