Skocz do zawartości

esp32s3 zabezpieczenie zapisu pamięci USB pendrive


Pomocna odpowiedź

28 minut temu, _LM_ napisał:

Konkluzja jest taka że pliki zapisują się w pamięci po poleceniu fclose(f)

Niezupełnie. stdio zapisuje jakiś fragment po zapełnieniu swojego bufora lub przy zamknięciu pliku albo poleceniu flush().

(edytowany)

Zrobiłem tak:

        ESP_LOGW(TAG,"Start written No: %d\n", bufCount);
      
      for(int i = 0; i < 1000; i++)
      {
        fprintf(f, "%d.\n	%s",bufCount, LoremIpsum);
    }		
    //    vTaskDelay(500);
        fclose(f);

LOG
 

W (1000) example: Start written No: 0
(27)[0m
E (2830) Transfer failed: Status 7
E (2830) USBH: Device 1 gone
E (2830) USB_MSC_SCSI: bot_execute_command(271):
I (2830) example: MSC device disconnected
E (2830) diskio_usb: scsi_cmd_write10 failed (5891)
E (2830) example: Disconnect?

Wynik: Plik został utworzony ale nie zawiera danych. Zrobię teraz jeszcze jeden test aby przynajmniej jeden rekord został zamknięty, podczas zapisu drugiego usunę pamięć

Edytowano przez _LM_

Ok teraz: 
 

W (844) example: Creating file
I (844) temperature_sensor: Range [-10°C ~ 80°C], error < 1°C
I (854) example: Example finished, you can disconnect the USB flash drive
W (864) example: Start written No: 0
(27)[0m
W (13604) example: Start written No: 1
(27)[0m
E (14454) Transfer failed: Status 1
E (14454) USB_MSC_SCSI: bot_execute_command(271):
E (14454) diskio_usb: scsi_cmd_write10 failed (5891)
E (14454) USBH: Device 1 gone
I (14464) example: MSC device disconnected
E (14464) example: Disconnect?

Pierwszy obieg do zamknięcia pliku jest na pendrive, drugi nie został zapisany. 

Przede wszystkim - do prawidłowego działania musisz wiedzieć czy dana paczka zapisała się na nośniku (fclose wcale nie oznacza że się zapisała, bo ktoś może wyjąć nośnik między fwrite a fclose i wtedy fclose zwraca błąd).

Poza tym (bo nie wiem): czy fflush spowoduje zapisanie wszystkiego na nośniku (może zwrócić błąd)? Jeśli tak, to plik mógłby pozostać otwarty cały czas. Jeśli nie - zabawa z fopen(...,'a') i fclose. Tyle że przy większych plikach fopen z 'a' może być dość kosztowny (vfs musi znaleźć koniec pliku).

Ogólnie - bez sprawdzenia czy rekord został rzeczywiście zapisany dość ciężko coś zrobić...

Z tego co wyczytałem, jest jakiś parametr w konfiguracji fatfs który powoduje, że f_sync() jest wywoływany za każdym razem po write() i podobnych. Tyle, że jeśli używasz fwrite to masz jeszcze kolejną warstwę (stdio i jego bufory), a nie znam aż tak implementacji tego na esp32 żeby coś konkretnego powiedzieć.

Tak na czuja: ustawiasz ten parametr autosync w konfigu, robisz jakiś fwrite, potem fflush, i sprawdzasz czy się rzeczywiście zapisało. Przynajmniej ja bym tak zrobił gdybym musiał tworzyć taką apkę 🙂 I zależnie od tego co wyjdzie trza kombinować dalej.

 

 

  • Pomogłeś! 1
6 minut temu, Harnas napisał:

Rozwiązaniem problemu może być po prostu użycie systemu plików z Journalingiem np: EXT3, EXT3, Btrfs czy nowsze wersje NTFS.

Pokaż mi takie cudo na ESP32 (szczególnie NTFS). Poza tym do odczytania ext3/ext4 potrzebna jest apka (płatna) na windowsie.

 

@_LM_ wydaje mi się, że bez buforowania kilku sekund i kopii zapasowej się nie obędzie. Robiłem niedawno podobny mechanizm dla STM i skończyło się na takim procesie:

  1. zapis serializuje i wrzucam bajty w kolejkę
  2. bajty zbieram aż uzyskam 512B tyle ile zajmuje sektor lub do zdarzenia flush, np przy zakończeniu wgrywania.
  3. otwieram i dogrywam.

Jeżeli często robisz zapisy to wearleveling szybko zfragmentuje pamięć i spadnie szybkość zapisu. 

Jest coś takiego (przynajmniej w FileX) jak failsafe, mechanizm po powrocie zasilania odtworzy to co zostało niedomknięte, ale kopia zapasowa będzie na pewno bezpieczniejsza.

 

  • Lubię! 1
(edytowany)

@ethanak @Gieneq fflush jeszcze nie sprawdziłem ale widzę w api reference że zwraca result także przy pierwszej okazji przetestuję te opcje. Dzięki za cenne informacje.

Jako bufor tymczasowy można wykorzystać pamięć zegarka który i tak ma podtrzymanie zasilania 

Edytowano przez _LM_
1 godzinę temu, Gieneq napisał:

Jeżeli często robisz zapisy to wearleveling szybko zfragmentuje pamięć i spadnie szybkość zapisu. 

 

Dlatego proponowałem buforowanie w aplikacji (w końcu do czegoś te 8 MB RAM trzeba wykorzystać jak dali) i zapisywać rzadziej. Ja bym w ogóle zapisywał co 10 minut bo na oko częściej nie ma sensu - a dane z ostatnich minut i tak będą w buforze.

  • Lubię! 1

Tak bufor na pewno będzie, a więc zrobię to tak że poza automatycznym ładowaniem na pena co określony czas/ zapełnienie bufora. Dorobię przycisk lub coś że należy dopełnić resztę próbek i zamknąć plik. Póki co niestety wszystko w sferze teorii ale już nie długo wrócę do warsztatu 

Było już wspominane o czymś w stylu zabezpieczenia mechanicznego, także myślę że to w tę stronę pójdzie 

To by było najlepsze, ale mój sposób na sam przycisk: po wciśnięciu zapala się dioda informująca o możliwości wyjęcia pena. Po jakimś czasie dioda gaśnie, ale plik pozostaje zamknięty jeszcze przez ileś tam sekund (to dla takich z refleksem szachisty).

Lepszy by był jakiś porządny solenoid ze szpindlem blokującym pena (to jakby nie dało się klapki zamontować), chociaż kolesie z hurtowni telewizorów poradzą sobie ze szpindlem 😞

(edytowany)

Najlepsze by było jakby wszystkie urządzenia miały taki pendrive (gabarytowo). Realnie nie mogę na to liczyć 

Edytowano przez _LM_

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...