logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

FAT32[SD] + AVR[MEGA8] ??

maly_elektronik 20 Lip 2008 23:31 4131 13
REKLAMA
  • #1 5361802
    maly_elektronik
    Poziom 23  
    Witam :!:
    Dogaduje się z kartą SD ale zamierzam odczytywać z niej także pliki (oczywiście w formacie FAT) Ale tu zaczynają się schody :| Rozumie zasadę działania FAT ale nie bardzo wiem jak zaimplementować niektóre rzeczy :( Mianowicie chodzi mi tu o nazwę pliku i sposób jego otwarcia :D
    Na razie wiem wszystko o odczycie zawartości Boot Sectora ale to tylko dane do odczytu (z nimi sobie daję rade) Ale problem pojawia sie w momencie gdy wrzucę jakiś plik na SD. Obliczając ze wzoru wiem który z sektorów jest tym pierwszym na którym mogę coś zapisać. Ale w jaki sposób znaleźć początek tego pliku i odczytać jego atrybuty i znaleźć go w tablicy FAT i dowiedzieć się gdzie jest początek i koniec tego pliku :?:
    Pomóżcie proszę bo siedzę już trochę nad tym i sam nie potrafię tego zrozumieć :(
  • REKLAMA
  • #3 5361938
    markosik20
    Poziom 33  
    Obliczasz w których sektorach znajduje się katalog główny. W katalogu głównym szukasz sektor po sektorze tego pliku (jego nazwy), jeżeli się tam znajduje. W atrybutach pliku są podane adresy gdzie znajdują się dane tego pliku. Tablica FAT służy do tego żeby znaleźć następny sektor (klaster) tego samego pliku. Musisz wiedzieć jak jest zapisany nagłówek pliku i co na niego się składa.
  • REKLAMA
  • #4 5362196
    maly_elektronik
    Poziom 23  
    Nie bardzo dalej kapuje :( Możesz wkleić te gotowe wzory co umieszcza np. Microsoft bo nie bardzo kapuje z którego mam z korzystać. Ja korzystam w dużym stopniu z tej strony. Czy wystarczy mi jej zawartość i przeczytana specyfikacja Misrocoftu :?:
    A i jeszcze dodatkowo skąd wziąć Partition_LBA_Begin :?:
    P.S Odczyt pliku zmieszczę w MEGA8. Znak kolesia który zmieścił to w 90s2313 :)
  • REKLAMA
  • #6 5362527
    markosik20
    Poziom 33  
    maly_elektronik napisał:
    Czy wystarczy mi jej zawartość i przeczytana specyfikacja Misrocoftu :?:


    W zupełności wystarczy :wink:. Ściągnij sobie program WINHEX, podglądnij nim kartę i wszystko Ci się "rozjaśni".
    Napisałeś że wiesz gdzie jest ten pierwszy sektor w którym możesz coś zapisać, to jest właśnie katalog główny i od tego sektora zaczynasz szukać plików. Wszystkie nagłówki plików mają jednolitą strukturę (opisana jest m.in. w linkach które podałeś) i z nagłówka pliku dowiesz się o jego dacie utworzenia, nazwie pełnej, atrybucie (do odczytu, ukryty itp), rozmiarze i nr. klastra gdzie się znajduje. Trzeba tylko wiedzieć że nr. klastra nie jest taki sam jak numer sektora a dodatkowo nie zawsze 1klaster = 1 sektor (512B).
  • #8 5362580
    maly_elektronik
    Poziom 23  
    Makrosik20 wszystko by było fajnie ale ja właśnie nie łapie jak szukać tych plików :( Ze stronki którą podałem wynika ze mam jakieś 128 tablic bo 32 bity to wychodzi mi z tego że po prostu jest tablica 4bajtyx128 wierszy :?: Ale jak szukać tego pliku to mnie wciąż nurtuje :| przeczytałem już chyba wszystko co krąży po sieci ale nadal nie "kumam". Chce tylko znaleźć plik i ładować go do bufora i ewentualnie czytać jego nazwę ale po prostu nie wiem jak :(
    PS mam WINHEX'a ale tego problemu nie mogę rozwiązać przy jego pomocy bo nie wiem jak :cry:
  • Pomocny post
    #9 5364971
    markosik20
    Poziom 33  
    A więc tak:
    Na nagłówek pliku składa się 32B (pomijamy tutaj długie nazwy).
    Sektor składa się z 512B (czyli mamy 16 plików/katalogów).
    1. Odczytujemy 512B do bufora (sektor Root_directory).
    2. Dzielimy te 512B na 16 paczek po 32B.
    3. W każdej paczce bit po bicie sprawdzamy czy są one równoważne z naszą nazwą pliku/katalogu. Tzn. pierwszy bajt w paczce ma być równy pierwszej literze nazwy pliku (tylko duże litery), drugi bajt ma być równy drugiej literze i tak do końca nazwy pliku.
    3. Jeżeli nazwa się zgadza to z pozostałych bajtów odczytać można wszystkie istotne informacje (FAT 32 Byte Directory Entry Structure).
    4. Jeżeli pliku nie ma to odczytujemy następny sektor (512B).
    5. Operacje powtarzać aż do znalezienia pliku/katalogu lub do końca obszaru Root_directory.

    Jak znajdziesz plik to jego położenie okreslone jest nie w sektorach a w klastrach. Musisz z Boot_Sektor dowiedzieć się ile sektorów przypada na klaster i odpowiednio wyznaczyć adres danych z pliku. Należy pamiętać że katalog główny (pierwszy obszar zapisywalny) znajduje się w klastrze nr.2 :wink:.
  • #10 5365014
    maly_elektronik
    Poziom 23  
    O dzięki tobie makrosik20 powoli zanczyna mi się wszystko układać :D. Ale nasówają mi się kolejne pytania:
    1. Jakiewartości hexadecymalne mają litery (najmniej istotne pytani)
    2 Skąd mam wiedzieć ile klastrów ma dany plik i gdzie pisze w którym klastrze znajduje się ciąg dalszy pliku
    3. Z góry dzięki za pomoc bo dużo zacząłem rozumieć z wiedzy którą nabyłem wcześniej
  • REKLAMA
  • #12 5365083
    markosik20
    Poziom 33  
    Cytat:
    1. Jakiewartości hexadecymalne mają litery (najmniej istotne pytani)


    Pczytaj o znakach ASCII :wink:.

    Cytat:

    2 Skąd mam wiedzieć ile klastrów ma dany plik i gdzie pisze w którym klastrze znajduje się ciąg dalszy pliku


    Rozmiar pliku znajduje się w jego nagłówku (ostatnie 4 bajty).Przed tymi bajtami znajdują się 2B informujące o nr. pierwszego klastra z danymi.
    Ciąg dalszy pliku nalezy odczytywać z Tablicy FAT. W FAT32 na każdy klaster przypada 4bajty w tablicy FAT. Czyli każde kolejne 4B oznaczają następny klaster. W tych czterech bajtach jest informacja dt. numeru kolejnego klastra pliku, jego końca, zajątości klastra (czy pusty czy zajęty) itd. Przed odczytem trzeba sprawdzić ile jest zarezerowanego miejsca w tablicy (dane z Boot_sektora) i wykonać odpowiednie przesunięcie po czym każde kolejne 4B oznaczają kolejne klastry :wink:.
  • #13 5365210
    maly_elektronik
    Poziom 23  
    Aha narazie chyba wszystko rozumię :)
    Podaje jeszcze kod i proszę o jego sprawdzenie (jest to przypianie zmiennym tybu SecPreClus, FATPerClus itp wartości z tablicy BootSectora [pirewszego sektora nośnika danych])
    
    
    uint32_t RootClus = 0;          
    uint32_t FATSz32  = 0;           
    uint32_t Partition_LBA_Begin= 0;
                                     // 
    uint16_t Signatures = 0;         
    uint16_t BytsPerSec = 0;         
    uint16_t RsvdSecCnt = 0;         
    					             		
    uint8_t  SecPerClus = 0;         
    uint8_t  NumFATs = 0;            
    
    ///// RootClus////////
    RootClus |= sd_Buff[47];
    RootClus <<= 8;
    RootClus |= sd_Buff[46];
    RootClus <<= 8;
    RootClus |= sd_Buff[45];
    RootClus <<= 8;
    RootClus |= sd_Buff[44];
    
    ///// FATSz32/////////
    FATSz32 |= sd_Buff[39];
    FATSz32 <<= 8;
    FATSz32 |= sd_Buff[38];
    FATSz32 <<= 8;
    FATSz32 |= sd_Buff[37];
    FATSz32 <<= 8;
    FATSz32 |= sd_Buff[36];
    
    ///// Partition_LBA_BEGIN/////////
    Partition_LBA_Begin |= sd_Buff[444];
    Partition_LBA_Begin <<= 8;
    Partition_LBA_Begin |= sd_Buff[443];
    Partition_LBA_Begin <<= 8;
    Partition_LBA_Begin |= sd_Buff[442];
    Partition_LBA_Begin <<= 8;
    Partition_LBA_Begin |= sd_Buff[441];
    
    
    ///// Signatures/////////
    Signatures |= sd_Buff[511];
    Signatures <<= 8;
    Signatures |= sd_Buff[510];
    
    
    ///// BytsPerSec/////////
    BytsPerSec |= sd_Buff[12];
    BytsPerSec <<= 8;
    BytsPerSec |= sd_Buff[11];    
        
    ///// RsvdSecCnt/////////
    RsvdSecCnt |= sd_Buff[15];
    RsvdSecCnt <<= 8;
    RsvdSecCnt |= sd_Buff[14];   
        
    ///// SecPerClus/////////
    SecPerClus |= sd_Buff[13]; 
    
    ///// NumFATs////////////
    NumFATs    |= sd_Buff[16];  
    
    
    }
    
    unsigned long Cluster_LBA_Begin(void)
    {
      return Partition_LBA_Begin + RsvdSecCnt + (NumFATs * FATSz32);
    }
    
    // adres jakiegoś klastra
    uint32_t cluster_addr(unsigned long number)
    {
      return Cluster_LBA_Begin() + (number - 2) * SecPerClus;
    }
    
    unsigned long FAT_LBA_Begin(void)
    {
      return Partition_LBA_Begin + RsvdSecCnt;
    }
    
    

    Dorzuciłem tam jeszcze proste funkcje z obliczaniem potrzebnych informacji do fata. Jeżeli to możliwe proszę o korektę błędów oraz o sprawdzenie czy dobre odczytuje bajty i ładuje je do dobrej zmiennej :D
REKLAMA