Beágyazott rendszerhez file-rendszert keresek

Sziasztok!

Ismertek olyan file-rendszert, amelyik a háttér tárolón nem tárol struktúra adatokat? Nagyon kis program/adat lábnyommal rendelkező háttértárolót (pl SD kártyát) szeretnék használni kicsi programmemóriával rendelkező rendszerben adat loggolásra.

Kb ez lenne a file-rendszer követelmény rendszere:

- előre megadott file struktúra (tároló mérettől függhet) - pl 1 file az egész tároló, vagy 1GB-os file-ok index névvel (pl. 00000000, 00000001, ...)

- asztali gépen is egyszerűen olvasható / írható (windows is jó lenne, de nem ko kritérium)

- a tároló majd összes többször írható bitje egyszerűen írható / olvasható legyen és használható legyen adat tárolásra

- a tárolón nem kell statikus (struktúra) adatokat tárolni (esetleg egy blokkban, hogy az automatikus felismerés detektálhassa)

Röviden: data flash-ként szeretnék használni SD kártyát.

Előre is kösz:

Gábor

Hozzászólások

Én ilyet csináltam loggolásra:

 * SD kártyát az SPI protokollján keresztül érem el mikrovezérlőről

 * sorszám szerint haladok előre a blokkokkal, és minden blokkot megjelölök egy futtatásra jellemző számmal, hogy már írtam egyszer

 * Bináris kereséssel lehet megtalálni, hogy melyik blokknál járunk éppen.

 * Egy blokknyi adatot RAM-ban gyűjtök össze és csak akkor írom ki amikor teljes blokk áll rendelkezésre

 * Így minden blokk pontosan egyszer van írva: a wear a lehető legkisebb

 * Linuxon sima blokk-eszközként olvasható - ugyanúgy működik a bináris keresés, hogy hol a vége, vagy ki lehet dumpolni is az adatot

 * Windowson sajnos nem elérhető - szerintem drivert kellene csinálni hozzá, hogy az legyen.

Csatlakoznék a hülyeségen vitatkozók táborához. :-D

A protokoll jelentése megegyezés. Példaként állíthatjuk pl. az OSI modellt, ahol a protokollokat fizikai és funkcionális rétegenkét sorolják be. Így aztán minden is protokoll, vagy egy megvalósított protokoll eleme.

Kezdetként, amikor két kütyüt összekötsz, akkor meg kell egyezni az átviteli közegben. Pl. rádiófrekvenciás, hidraulikus, pneumatikus, elektromos, mechanikus vagy optikai összeköttetést alkalmazunk. A továbbiakban - SPI esetében - 2, 3 vagy 4 huzalt alkalmazunk az elektromos összekötésre, ami az SPI protokoll szerint dolgozik, miközben az adattartalom lehet túrósrétes is. ;) Hasonló protokollok pl. az I2C, az RS232, CAN stb. Természetesen a fizikai implemetáció kitér a feszülségszintekre és polaritásra is. A protokoll ugyanaz marad, ha más hardverre ülteted, bár az alap specifikáció másképp írja le. Erre egyik legjobb példa a 2 huzalos I2C 4 huzalos RS485 hardveren.

Ezek után, ha bármilyen további kommunikációt is egyeztetünk, akkor eljutunk a protokoll a protokollon esetig. (Lásd fent: túrósrétes.) Tehát pontosan úgy, ahogyan írtad: az SPI buszon (SPI protokollal) továbítjuk azt a beszélgetést - amiben megegyeztünk (szabvány) - az SD kártya protokollját. Ebben a pillanatban az egészet átrakhatom RS485 (hardver) protokollra, vagy TCP/IP protokollra. Az utóbbi már protokoll hegyeket jelent az SPI-hez képest. ;)

A zavart az erőben egy-egy kifejezés több szintű használata okozza. Ebben az esetben érdemes deklarálni, hogy melyik szintről beszélsz. Nagyon jó példa erre a CDROM szabvány. A protokollhoz hasnonlóan ott a "frame" a kisördög, amely 3 szinten is megjelenik. A szabványról beszélgetve gyakran nem elég a frame kifejezés, hanem pontosan meg kell mondani melyik szintű frame a tárgy.  Bizony, ilyen ez a műszaki élet: A nyelvben kevés a szakkifejezés, ezért néha magyarázkodni kell.

Ugy nez ki nem olvastad el az ASZF-et ... oda mar akkor csatlakoztal, amikor ide regisztraltal! Azert mentem ebbe bele mert a kollega epp, hogy pontosan fogalmazott...

Tok jol leirtad, csak kiegeszitenem 2 gondolattal:

A protokoll jelentése megegyezés. 

Igen, de informatikaban/telekommunikacioban mindig kommunikacios megegyezes.

Ha RS485-rol beszelunk az csak jelatviteli szabvany, nem protocol, azaz a peldaval elve ez csak a teszta nincs benne semmi turo :D

Amikor azt mondjuk, hogy SPI/I2C protocol, akkor az adott kommunikacios megegyezesre gondolunk, amit ott hasznalnak (pl. master-slave viszony, kuldes elott cimezni kell / enable labat kell hasnzalni stb.), de a mi szempontukbol ugye ez is csak teszta.

mindig kommunikacios megegyezes

vs

Ha RS485-rol beszelunk az csak jelatviteli szabvany, nem protocol,

Pontosan erről van szó. Így fogalmazva az I2C szabvány egy protokoll (héj és opcionális feature gyűjtemény) ÉS jelátviteli szabvány is. Az előbbi mondat nem teljesen igaz, ha konkrét implementációval találkozol, és/vagy RS485 driverek felhasználásával továbbítod a jelet. Azt már csak félve említem, hogy számos implementáció egyszer-kétszer eltér a szabványtól, aztán a serial_write() nem működik. :) Ez a túró és tészta közötti határfelület. Az előbbiek igazak SPI esetén is, csak ott kevesebb a feature.

Tehát ez egy protokoll.

Az SD kártya esetén az SPI módban az SPI adatain keresztül küldött, olvasott dolgok meg a másik (az SD szempontjából egyik lehetséges) protokoll. Ha úgy tetszik "SD over SPI".

Olyat mondani, hogy a "HTTP over TCP/IP" esetén a TCP/IP fizikai réteg, mivel

Amikor azt mondjuk, hogy SPI/I2C protocol, akkor az adott kommunikacios megegyezesre gondolunk,

de a HTTP az magasabb layer - és mint ilyen, felülről szemléljük - nos az marhaság.

A fizikai réteg ebben az esetben a 3,3V-os SPI (mint jelátviteli szabvány) és az SD protokoll az SPI protokollba van "csomagolva" (SPI, mint protokoll).

Kristálycukorral és szalonnával.

 Pontosan erről van szó. Így fogalmazva az I2C szabvány egy protokoll (héj és opcionális feature gyűjtemény) ÉS jelátviteli szabvány is. Az előbbi mondat nem teljesen igaz, ha konkrét implementációval találkozol, és/vagy RS485 driverek felhasználásával továbbítod a jelet.

Pl. a modbus az protocol de az RS485 nem az. Olyan, hogy RS485 driver nincs. Esetleg egy UART+transciever piszkalast valami gyarto igy hivja, szvsz tevesen.

I2C bus "szabvany" != protocol, hanem az tartalmaz egy protocol leirast is. Ahogy te is irtad, amikor azt mondjuk, hogy I2C protocol, akkor kb. erre gondolunk.

Olyat mondani, hogy a "HTTP over TCP/IP" esetén a TCP/IP fizikai réteg, ...  nos az marhaság.

Persze, a TCP/IP nem fizikai reteg hanem Protocol, barhogyan/barhonnan is nezzuk, hisz a TCP/IP nem ter ki arra, hogy hogyan kell eljuttatni a jelet. Ezt nem is ertem miert irtad :)

A fizikai réteg ebben az esetben a 3,3V-os SPI (mint jelátviteli szabvány) és az SD protokoll az SPI protokollba van "csomagolva" (SPI, mint protokoll).

Ez pontosan igy van.

Az RS485 tényleg nem protokoll, csak - alapesetben - az RS232 differenciális half duplex fizikai megvalósítása. Felette a protokoll általában szoftver alapú.

Az RS485 driver meg nem más, mint a szabvány/specifikáció (részhalmazára) alkalmas áramkör. Pl. a 10Mbaud/10km-es driver egy olyan áramkör, ami ezt képes meghajtani, és az bizony nem két tranzisztorból áll. ;)

Az I2C esetén egészen másra gondolok, mert az leírja a teljes specifikációt. Amit linkeltél, az csak a serial_write() és serial_read() függvényt írja le. ;) A teljes protokollt lehet tanulmányozni akár egy PIC18 adatlapon is, mert ott hardveresen is megcsinálták.

A "HTTP over TCP/IP"-t azért írtam, hogy a kiinduló "SPI nem protokoll" állítás hibájához hasonlót mutassak be.

Az egyik lehetséges meg azért szerepelt, mert ugye van SD protokoll SPI nélkül is.

"Windowson sajnos nem elérhető - szerintem drivert kellene csinálni hozzá, hogy az legyen."

Az alábbi link alapján nem kell hozzá driver. CreateFile() -lal lehet drive -ot megnyitni: https://support.microsoft.com/en-ie/help/100027/info-direct-drive-acces…

Amúgy a mingw -ben is van dd, sajár driver meg nincsen.

Szerkesztve: 2019. 12. 26., cs – 15:55

előre megadott file struktúra (tároló mérettől függhet) - pl 1 file az egész tároló, vagy 1GB-os file-ok index névvel (pl. 00000000, 00000001, ...)

Egy otlet: az adott meretu hattertarolora csinalsz egy fix strukturaju FAT32-es filerendszert es linux/windoz alatt letrehozod az index fileokat adott merettel, kozvetlenul a root directory ala. Ha nincs fragmentalas (marpedig FATxx-en nem lesz, ha sorban hozod letre ezeket a fileokat), akkor eleg csak a root dir-t vegigolvasnod hogy megtudd hogy mi hol helyezkedik el az sd-kartya cimtartomanyaban, es maris tudod irni/olvasni beagyazott rendszerben is.

Kesobb ha lesz kedved, idod es kapacitasod, akkor a backward compatibility megtartasa mellett tudod tovabb fejleszteni :) (fragmentalas, subdirectory-k, uj file-ok letrehozasa, stb).

Letrehozni egyszeru: a/ csinalsz egy ures filerendszert b/ a gyoker konyvtarban valamivel (pl dd-vel) csinalsz annyi szamu es akkora meretu file-t amit szeretnel. Ha 8+3 fileneveket hasznalsz akkor meg egyszerubb lesz a dolog!

Ha ez a folyamat lezarult, akkor mar fix helyen lesznek azok az adatok amik megmondjak hogy melyik file hol talalhato, mind a gyokerkonyvaron belul mind pedig a diszken. Szoval nem kell beleirni ezt kulon, hanem a sztenderdeket kovetve, 1-2 olvasasi muvelettel ez mar kitalalhato! Lasd peldaul: itten. Ezzel a programmal azt is meg tudod nezni hogy mennyire fragmentalt a filerendszer (es/vagy a fat32-nel a root directory), csak ide-oda bele kell tenned egy-ket printf()-et :) De erre biztos vannak ezutobbi problemara mas kesz tool-ok is linux alatt. 

Kérdés, hogy a PC -n egyszerűen olvasható mit jelent. Kb azt döntheted el, a hordozhatóságra vagy a beágyazott rendszer igényeire fókuszálsz.

Hordozhatóság alatt azt értem, mennyire nehéz PC -n hozzáférni az adataidhoz. A beágyazott rendszer igényei a kis erőforrás igényt, illetve a hibatűőrséget jelentik.

A leghordozhatóbb, ha a FAT FS család tagjait használod (FAT12, FAT16, FAT32, EXFAT). Ez kb. bármivel menni fog ami tudja az adathordozódat olvasni. Léteznek rá ingyenes implementációk a netek mikrokontrollerekre, de némileg erőforrás igényes, és a hibatűrőség mint olyan kb 0. 

Ha speciális megkötéssekkel használsz FAT -et, akkor spórolhatsz az erőforrásokkal, viszont a PC -re kell spéci program az olvasáshoz.

Ha beágyazott rendszerekhez tervezett FS -t használsz, akkor lehetsz hibatűrő, és jó lehet az erőforrás kihasználásod, de a PC -n spéci progi kell, ami képes blokk szinten kezelni az adathordozót. Ehhez jó eséllyel root vagy admin jog kell. (Pl a LitteFS: https://os.mbed.com/docs/mbed-os/v5.15/apis/littlefilesystem.html, https://os.mbed.com/blog/entry/littlefs-high-integrity-embedded-fs/).

Hogy neked a fentiek közül melyik megoldás kell azt e körülmények határozzák meg, melyeket mi nem ismerünk.

 

Az is kérdés, hogy az adatmegosztáshoz egyáltalán kell e a PC -nek olvasni az adathordozót, vagy megosztható az adat pl. USB -n.

Atmelhez/Arduinohoz van faek egyszeruseggel hasznalhato SD kartya driver+FAT32 implementacio. Az ATMEGA328P-nek (Uno/Nano/Mini) 2kB memoriaja van, ez eleg neki, a peldaprogramok kozt is van ilyen. Ha mas/sajat FS-t akarsz, osszekotheted PC-vel USB-n (ahogy mar ajanlottak), innentol mindegy mi van a kutyun beluli SD kartyadon.

Ha sima UARTon jovo adatot akarsz eltenni kesobbre (pl. GPS-rol jovo NMEA mondatokat, vagy egyszeruen nem akarsz ezzel foglalkozni), van egy $2 koruli, koromnyi meretu kutyu (Openlog), aminek az egyik oldalan mikro SD foglalat van, a masikon meg egy elore felprogramozott ATMEGA328P. Csak foldet-tapot adsz neki, es TX-RX-en tudsz kommunikalni vele, es alapbol amit kuldesz neki, azt elteszi egy file-ba.

A strange game. The only winning move is not to play. How about a nice game of chess?

Köszönöm mindenkinek a fáradozást.

Röviden összefoglalom a válaszokat, hogy ki tudjatok javítani:

1., némi extra költség vállalása esetén az Openlog lehet alternatíva (kb 2,5$)

2., ha a cél HW-ben elfér, akkor kész FAT implementációt lehet használni

3., ha Linux alatt elégséges az adatok feldolgozása, akkor mehet ömlesztve az adat, mivel linux alatt könnyen lehet a nyers adattárolót olvasni (pl dd)

4., előre létrehozott statikus filerendszer (1 vagy több file) is nagyon jól használható lenne, csak a filerendszer létrehozása nem triviális / nincs rá kész megoldás

Ugye nem hagytam ki semmit?

Gábor

A FAT a metaadatokat mindig ugyanoda írja, az SD kártyákban meg többnyire nincs wear levelling. Ezért senki nem ajánlja logok írására a FAT fájlrendszert SD kártyán. Ha kicsit is fontos, hogy ne legyen hiba, akkor én nem csinálnék ilyet.

Plusz ha FAT-ot használsz, akkor elég rendesen meg kell nézned, hogy mekkora fájlokat kezel hibátlanul, illetve nem lehetséges-e valami tömb overflow a megvalósításban, ha valami túl sokáig fut, vagy ilyesmi. Szóval, hogy megbízhatóan használható-e a te felhasználási esetedre. Ezeket a libeket ugyanis többnyire nem ilyen célra írták AFAIK.

A 4. pontot meg lehet így csinálni:

 * Létrehozod a partíciós táblát és a partíciót

 * Létrehozod a FATXX fájlrendszert.

 * Egy slukkra csinálsz rá egy fájlt (programmal vagy szkriptből), amit pl determinisztikus álvéletlenekkel megtöltesz.

 * Könnyen ki tudod elemezni a fájlrendszer ismerete nélkül, hogy hova tette a fájl darabjait. Pl. A device fájlt blokkonként hexdumppal kiíratva, vagy szintén programmal elemezve. A legvalószínűbb, hogy egymás utáni blokkokba került az adat.

 * Az első és utolsó blokk indexét megjegyzed, és ezt a részt innentől úgy kezeled, ahogy az első hozzászólásban javasoltam.

(Mindezt loopback device-szal valószínűleg meg lehet csinálni valódi SD kártya nélkül is. Mivel egy SD-t végigírni elég hosszú idő, érdemes lehet így spórolni az idővel.)

Így Windowson is kezelhető lesz a kártya, és mégis jó lesz a wear levelling, és egyszerű lesz a programkód is.

(A fájlt előre teljes mérettel kell lefoglalni, így a metaadatokhoz sosem kell többé hozzányúlni, viszont a valódi tartalom hosszát meg kell jelölni valahogy magában a kontentben.)

A partíciós táblát és az üres fájlrendszert bináris formában tömörítve el is rakhatod, amit aztán DD-vel fel tudsz tenni SD kártyákra, ha sorozatgyártani kell esetleg. Az is lehet, hogy egyszerű futamhossz-kódolással az MCU programmemóriájába is be lehet tenni az SD tartalmát, így az MCU is képes léhet a kártya újrainicializálására.

ha mar egyszer letrehozta a bazinagy fajlt, akkor azt ugyanugy tudja olvasni/irni mint a block devicet. raadasul _elvileg_ szekvencialisan lesz rajta a fajl reszek, de ez korant sem torvenyszeru, es ha blockdevice random iraskent belebarom akkor majd jon a kov topic hogyan tudja helyrehozni....

A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

Kicsit vitatkoznék (is) :)

" SD kártyákban meg többnyire nincs wear levelling"

Többnyire van, és kártya minőség függő, hogy milyen. Pl. a legtöbb kártya első szektorai lassabbak mert az SD szabvány előírja a FAT használatát, és erre optimalizálják a kártyákat. Próbáld ki, hogy a DD -vel írod az SD kártya elejét, vagy a közepét más értékeket kapsz. Pendrájvok is hasonlóan viselkednek. (Teszem hozzá legutóbb több mint 10 éve méregettem ilyesmit.)

Ugyanezért nem szerencsés ezeket pl. ext fájlrendszerekkel használni, mert ezeknél nem arra a területre esik a metaadat tárolás okozta erősebb igénybevétel, mint a FAT -nál.

Továbbá saját wear levellinget használni SD kártyák "felett" szintén szerencsétlen lehet. A dupla wear levellingel jó eséllyel csak extra terhelést (írásokat) okozol. Ha fontos, hogy a rendszer fail-safe legyen, akkor "kopasz" FLASH felett kell rendes wear levellinget implementálni.

"...Egy slukkra csinálsz rá egy fájlt (programmal vagy szkriptből), amit pl determinisztikus álvéletlenekkel megtöltesz...."

Az álvéletlenes vajákolás helyett inkább használd ezt: http://elm-chan.org/fsw/ff/00index_e.html. Egyrészt megnézheted a forrásban hogyan találja ki a fájl kezdő illetve befejező szektorát, másrészt, ha "kibelezed" készíthetsz egy olyan függvényt, ami megmondja neked a fájl első és utolsó szektorát.
Továbbá a lap alján van link a FAT32 speckóra, dolgozhatsz az alapján is.
A linkelt cuccban van f_mkfs(), hogy a beágyazott eszköz képes legyen inicializálni az adathordozót, ezt átdolgozva megcsinálhatod a megfelelő formátumú, egyetlen fájlt tartalmazó "formázást". De pl a "Petit FAT" (link az előző linken) támogat " Single volume and Single file." fícsört. Nem tudom ez pontosan mit takar, de név alapján hasonlít arra amiről beszélünk.

Továbbá a fenti cucc lefordítható Linux/windows alá is, és akkor a PC -n ugyan az a kód tudja formázni a médiádat, mint a beágyazott rendszeren, illetve szénné tesztelheted a munkádat PC -n loopback device -szal.

De, ezzel a sok melóval simán összemérhető, ha eleve egy rendes beágyazott FS -sel kezdesz dolgozni (pl: https://github.com/ARMmbed/littlefs), és a PC -n oldod meg saját programmal az olvasást. Mondjuk, mint említettem SD kártya felett saját wear levellinget futtatni cinkes lehet.

" A partíciós táblát és az üres fájlrendszert bináris formában tömörítve el is rakhatod, amit aztán DD-vel fel tudsz tenni SD kártyákra, ha sorozatgyártani kell esetleg. Az is lehet, hogy egyszerű futamhossz-kódolással az MCU programmemóriájába is be lehet tenni az SD tartalmát, így az MCU is képes léhet a kártya újrainicializálására. "

Sajnos már nem emlékszem a FAT részleteire, de meglepő lenne a a média méretétől teljesen független lenne a tartalma. Mondjuk amíg üres a "lemez", inkább csak a méret, meg egy-két index lesz benne egyedi.

-----------------------------------

(Disclaimer: a szobám független területnek minősül, ahol a magyar helyesírás szabályai eltérőek a megszokottól.)