Útfærsla mín á hringabuffi í NOR flash

Forsaga

Það eru sjálfsalar af okkar eigin hönnun. Inni í Raspberry Pi og nokkrar raflögn á sérstakt borð. Mynttökutæki, víxlaviðtaka, bankaútstöð eru tengdir... Öllu er stjórnað af sjálfskrifuðu forriti. Allur vinnuferillinn er skrifaður í log á flash-drifi (MicroSD), sem síðan er sendur í gegnum netið (með USB mótaldi) á netþjóninn þar sem hann er geymdur í gagnagrunni. Söluupplýsingum er hlaðið inn í 1c, einnig er einfalt vefviðmót fyrir eftirlit o.fl.

Það er, blaðið er mikilvægt - fyrir bókhald (tekjur, sölu osfrv.), eftirlit (alls konar bilanir og aðrar óviðráðanlegar aðstæður); Þetta, má segja, eru allar upplýsingarnar sem við höfum um þessa vél.

vandamálið

Flash drif sýna sig vera mjög óáreiðanleg tæki. Þeir mistakast með öfundsverðri reglusemi. Þetta leiðir bæði til stöðvunar á vélinni og (ef af einhverjum ástæðum var ekki hægt að flytja skráninguna á netinu) til taps gagna.

Þetta er ekki fyrsta reynslan af notkun flash-drifa, áður en þetta var annað verkefni með meira en hundrað tæki, þar sem tímaritið var geymt á USB-drifum, það voru líka vandamál með áreiðanleika, stundum fjöldi þeirra sem biluðu í mánuður var í tugum. Við reyndum mismunandi glampi drif, þar á meðal vörumerki með SLC minni, og sumar gerðir eru áreiðanlegri en aðrar, en að skipta um glampi drif leysti ekki vandamálið á róttækan hátt.

Attention! Langlestur! Ef þú hefur ekki áhuga á „af hverju“, heldur aðeins „hvernig“, geturðu farið beint Á endanum greinar.

ákvörðun

Það fyrsta sem kemur upp í hugann er: yfirgefa MicroSD, settu upp til dæmis SSD og ræstu úr því. Fræðilega mögulegt, líklega, en tiltölulega dýrt og ekki svo áreiðanlegt (USB-SATA millistykki er bætt við; bilanatölfræði fyrir fjárhagsáætlun SSDs er heldur ekki uppörvandi).

USB HDD lítur heldur ekki út eins og sérlega aðlaðandi lausn.

Þess vegna komumst við að þessum valmöguleika: slepptu ræsingu frá MicroSD, en notaðu þá í skrifvarið ham, og geymdu aðgerðaskrána (og aðrar upplýsingar sem eru einstakar fyrir tiltekinn vélbúnað - raðnúmer, kvörðun skynjara osfrv.) einhvers staðar annars staðar .

Efnið um skrifvarið FS fyrir hindber hefur þegar verið rannsakað að innan sem utan, ég mun ekki dvelja við útfærsluupplýsingar í þessari grein (en ef áhugi er fyrir hendi þá skrifa ég kannski smágrein um þetta efni). Eina atriðið sem ég vil taka fram er að bæði af persónulegri reynslu og af umsögnum þeirra sem þegar hafa innleitt það er áreiðanleiki ávinningur. Já, það er ómögulegt að losna alveg við bilanir, en það er alveg mögulegt að draga verulega úr tíðni þeirra. Og kortin eru að verða sameinuð, sem gerir þjónustufólki mun auðveldara að skipta út.

Vélbúnaður

Það var enginn sérstakur vafi á vali á minnistegund - NOR Flash.
Rök:

  • einföld tenging (oftast SPI strætó, sem þú hefur þegar reynslu af að nota, svo engin vélbúnaðarvandamál eru fyrirséð);
  • fáránlegt verð;
  • staðlaða rekstrarsamskiptareglur (útfærslan er nú þegar í Linux kjarnanum, ef þú vilt geturðu tekið þriðja aðila, sem er líka til staðar, eða jafnvel skrifað þitt eigið, sem betur fer er allt einfalt);
  • áreiðanleiki og úrræði:
    úr dæmigerðu gagnablaði: gögn eru geymd í 20 ár, 100000 eyðingarlotur fyrir hverja blokk;
    frá þriðju aðilum: mjög lágt BER, staðhæft að engin þörf sé á villuleiðréttingarkóðum (sum verk telja ECC fyrir NOR, en venjulega þýða þau samt MLC NOR; þetta gerist líka).

Við skulum áætla kröfur um magn og auðlind.

Ég vil að tryggt sé að gögnin séu vistuð í nokkra daga. Þetta er nauðsynlegt svo að sölusaga glatist ekki ef upp koma samskiptavandamál. Við munum leggja áherslu á 5 daga, á þessu tímabili (jafnvel að teknu tilliti til helgar og frídaga) vandamálið er hægt að leysa.

Núna söfnum við um 100kb af annálum á dag (3-4 þúsund færslur), en smám saman eykst þessi tala - smáatriðin aukast, nýjum viðburðum er bætt við. Auk þess eru stundum springur (sum skynjari byrjar að senda ruslpóst með fölskum jákvæðum, til dæmis). Við munum reikna fyrir 10 þúsund færslur 100 bæti hver - megabæti á dag.

Alls koma 5MB af hreinum (vel þjöppuðum) gögnum út. Meira til þeirra (gróft mat) 1MB af þjónustugögnum.

Það er, við þurfum 8MB flís ef við notum ekki þjöppun, eða 4MB ef við notum það. Nokkuð raunhæfar tölur fyrir þessa tegund af minni.

Hvað auðlindina varðar: ef við áætlum að allt minnið verði endurskrifað ekki oftar en einu sinni á 5 daga fresti, þá fáum við yfir 10 ára þjónustu innan við þúsund endurskrifunarlotur.
Ég minni á að framleiðandinn lofar hundrað þúsund.

Smá um NOR vs NAND

Í dag er NAND-minni auðvitað miklu vinsælli, en ég myndi ekki nota það fyrir þetta verkefni: NAND, ólíkt NOR, þarf endilega að nota villuleiðréttingarkóða, töflu yfir slæmar blokkir o.s.frv., og einnig fætur á NAND franskar venjulega miklu meira.

Ókostir NOR eru:

  • lítið magn (og, í samræmi við það, hátt verð á megabæti);
  • lítill samskiptahraði (að mestu leyti vegna þess að raðviðmót er notað, venjulega SPI eða I2C);
  • hægt eyðsla (fer eftir stærð blokkarinnar, það tekur frá broti úr sekúndu til nokkrar sekúndur).

Það virðist sem það sé ekkert mikilvægt fyrir okkur, svo við höldum áfram.

Ef smáatriðin eru áhugaverð hefur örrásin verið valin á25df321a (þetta skiptir hins vegar ekki máli, það eru margar hliðstæður á markaðnum sem eru samhæfar í pinout og stjórnkerfi; jafnvel þótt við viljum setja upp örrás frá öðrum framleiðanda og/eða annarri stærð, mun allt virka án þess að breyta kóða).

Ég nota ökumanninn sem er innbyggður í Linux kjarnann; á Raspberry, þökk sé stuðningi við tré yfirlögn tækis, er allt mjög einfalt - þú þarft að setja samansettu yfirborðið í /boot/overlays og breyta /boot/config.txt örlítið.

Dæmi um dts skrá

Til að vera heiðarlegur er ég ekki viss um að það sé skrifað án villna, en það virkar.

/*
 * Device tree overlay for at25 at spi0.1
 */

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; 

    /* disable spi-dev for spi0.1 */
    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            status = "okay";
            spidev@1{
                status = "disabled";
            };
        };
    };

    /* the spi config of the at25 */
    fragment@1 {
        target = <&spi0>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            flash: m25p80@1 {
                    compatible = "atmel,at25df321a";
                    reg = <1>;
                    spi-max-frequency = <50000000>;

                    /* default to false:
                    m25p,fast-read ;
                    */
            };
        };
    };

    __overrides__ {
        spimaxfrequency = <&flash>,"spi-max-frequency:0";
        fastread = <&flash>,"m25p,fast-read?";
    };
};

Og önnur lína í config.txt

dtoverlay=at25:spimaxfrequency=50000000

Ég mun sleppa lýsingunni á því að tengja flísina við Raspberry Pi. Annars vegar er ég ekki sérfræðingur í rafeindatækni, hins vegar er allt hér banalt jafnvel fyrir mig: örrásin hefur aðeins 8 fætur, þar af þurfum við jörð, kraft, SPI (CS, SI, SO, SCK ); stigin eru þau sömu og í Raspberry Pi, ekki þarf frekari raflögn - tengdu bara tilgreinda 6 pinna.

Samsetning vandans

Eins og venjulega gengur vandamálayfirlýsingin í gegnum nokkrar endurtekningar og mér sýnist að það sé kominn tími á þá næstu. Svo skulum við staldra við, setja saman það sem þegar hefur verið skrifað og skýra smáatriðin sem eru eftir í skugganum.

Þannig að við höfum ákveðið að skráin verði geymd í SPI NOR Flash.

Hvað er NOR Flash fyrir þá sem ekki vita?

Þetta er óstöðugt minni sem þú getur gert þrjár aðgerðir með:

  1. Lestur:
    Algengasta lesturinn: við sendum heimilisfangið og lesum eins mörg bæti og við þurfum;
  2. Met:
    Að skrifa í NOR flash lítur út eins og venjulegt, en það hefur einn sérkenni: þú getur aðeins breytt 1 í 0, en ekki öfugt. Til dæmis, ef við hefðum 0x55 í minnishólfi, þá eftir að hafa skrifað 0x0f í það, verður 0x05 þegar geymt þar (sjá töflu rétt fyrir neðan);
  3. Eyða:
    Auðvitað þurfum við að geta gert þveröfuga aðgerð - breyta 0 í 1, þetta er nákvæmlega það sem eyðingaraðgerðin er til. Ólíkt fyrstu tveimur, þá starfar það ekki með bætum, heldur með blokkum (lágmarks eyðingarblokk í völdum flís er 4kb). Eyða eyðileggur allan reitinn og er eina leiðin til að breyta 0 í 1. Þess vegna, þegar unnið er með flassminni, þarf oft að samræma gagnastrúktúra við eyðingarblokkamörkin.
    Upptaka í NOR Flash:

Tvöfaldur gögn

Var
01010101

Skráð
00001111

Hefur orðið
00000101

Loginn sjálfur táknar röð skráa af breytilegri lengd. Dæmigerð lengd færslu er um 30 bæti (þó færslur sem eru nokkur kílóbæt að lengd komi stundum fyrir). Í þessu tilfelli vinnum við með þau einfaldlega sem sett af bætum, en ef þú hefur áhuga þá er CBOR notað í færslunum

Til viðbótar við skráninguna þurfum við að geyma einhverjar „stillingar“ upplýsingar, bæði uppfærðar og ekki: ákveðið auðkenni tækis, kvörðun skynjara, fána „tæki er tímabundið óvirkt“ o.s.frv.
Þessar upplýsingar eru sett af lykilgildaskrám, einnig geymdar í CBOR. Við höfum ekki mikið af þessum upplýsingum (fáein kílóbæti að hámarki) og þær eru uppfærðar sjaldan.
Í því sem hér fer á eftir munum við kalla það samhengi.

Ef við munum hvar þessi grein byrjaði er mjög mikilvægt að tryggja áreiðanlega gagnageymslu og, ef mögulegt er, stöðugan rekstur, jafnvel ef um vélbúnaðarbilun/gagnaspillingu er að ræða.

Hvaða uppsprettur vandamála geta komið til greina?

  • Slökkvið á meðan á ritun/eyðingu stendur. Þetta er úr flokki „það er ekkert bragð gegn kúbein“.
    Upplýsingar frá umræður á stackexchange: þegar slökkt er á straumnum meðan unnið er með flash, leiða bæði eyðsla (stillt á 1) og skrifa (stillt á 0) til óskilgreindrar hegðunar: hægt er að skrifa gögn, skrifa að hluta (segjum við fluttum 10 bæti/80 bita , en enn er ekki hægt að skrifa aðeins 45 bita), það er líka mögulegt að sumir bitanna verði í „millistigi“ (lestur getur framleitt bæði 0 og 1);
  • Villur í sjálfu flassminninu.
    BER, þó mjög lágt, getur ekki verið jafnt og núll;
  • Strætóvillur
    Gögn sem send eru um SPI eru ekki vernduð á neinn hátt; bæði staka bita villur og samstillingarvillur geta komið fram - tap eða innsetning bita (sem leiðir til mikillar röskunar á gögnum);
  • Aðrar villur/gallar
    Villur í kóðanum, hindberjagallar, truflun á geimverum...

Ég hef mótað þær kröfur sem að mínu mati er nauðsynlegt að uppfylla til að tryggja áreiðanleika:

  • færslur verða að fara strax í flassminni, seinkun á skrifum er ekki tekin til greina; - ef villa kemur upp verður að greina hana og vinna úr henni eins fljótt og auðið er; - kerfið verður, ef mögulegt er, að jafna sig eftir villur.
    (dæmi úr lífinu „hvernig það ætti ekki að vera“, sem ég held að allir hafi lent í: eftir neyðarendurræsingu er skráarkerfið „bilað“ og stýrikerfið ræsist ekki)

Hugmyndir, nálgun, hugleiðingar

Þegar ég fór að velta þessu vandamáli fyrir mér komu margar hugmyndir í gegnum hausinn á mér, til dæmis:

  • nota gagnaþjöppun;
  • notaðu sniðug gagnastrúktúr, til dæmis, geymdu færsluhausa aðskilda frá færslunum sjálfum, þannig að ef það er villa í einhverri færslu geturðu lesið afganginn án vandræða;
  • nota bitareiti til að stjórna því að upptöku sé lokið þegar slökkt er á rafmagninu;
  • geyma ávísanir fyrir allt;
  • nota einhverja tegund af hávaðaþolinni kóðun.

Sumar af þessum hugmyndum voru notaðar en aðrar voru teknar upp. Förum í röð.

Gagnaþjöppun

Atburðir sjálfir sem við skráum í dagbókina eru nokkuð svipaðir og endurteknir ("kastaði 5 rúblum", "ýtti á hnappinn til að gefa skipti", ...). Þess vegna ætti þjöppun að vera nokkuð áhrifarík.

Þjöppunarkostnaðurinn er óverulegur (örgjörvinn okkar er frekar öflugur, meira að segja fyrsti Pi var með einn kjarna með tíðni 700 MHz, núverandi gerðir eru með nokkra kjarna með tíðni yfir gígahertz), gengi með geymslunni er lágt (nokkrar megabæti á sekúndu), er stærð færslunnar lítil. Almennt séð, ef þjöppun hefur áhrif á frammistöðu, mun hún aðeins vera jákvæð. (alveg gagnrýnislaust, bara að taka fram). Auk þess erum við ekki með raunverulegt innbyggt, heldur venjulegan Linux - svo útfærslan ætti ekki að krefjast mikillar fyrirhafnar (það er nóg að tengja bara bókasafnið og nota nokkrar aðgerðir úr því).

Hluti af annálnum var tekinn úr virku tæki (1.7 MB, 70 þúsund færslur) og fyrst athugað með þjöppunarhæfni með því að nota gzip, lz4, lzop, bzip2, xz, zstd í tölvunni.

  • gzip, xz, zstd sýndu svipaðar niðurstöður (40Kb).
    Ég var hissa á því að smart xz sýndi sig hér á stigi gzip eða zstd;
  • lzip með sjálfgefnum stillingum gaf aðeins verri niðurstöður;
  • lz4 og lzop sýndu ekki mjög góðan árangur (150Kb);
  • bzip2 sýndi furðu góðan árangur (18Kb).

Svo eru gögnin þjappað mjög vel.
Svo (ef við finnum ekki banvæna galla) verður þjöppun! Einfaldlega vegna þess að fleiri gögn geta passað á sama flash-drifi.

Við skulum hugsa um ókostina.

Fyrsta vandamálið: Við höfum nú þegar samþykkt að allar skrár verða strax að fara að blikka. Venjulega safnar skjalavörðurinn gögnum úr inntaksstraumnum þar til hann ákveður að það sé kominn tími til að skrifa um helgina. Við þurfum strax að taka á móti þjappuðum gagnablokk og geyma hana í óstöðugu minni.

Ég sé þrjár leiðir:

  1. Þjappaðu hverja skrá með því að nota orðabókarþjöppun í stað reikniritanna sem fjallað er um hér að ofan.
    Það er algjörlega virkur valkostur, en mér líkar það ekki. Til að tryggja meira og minna viðeigandi þjöppunarstig verður orðabókin að vera „sníða“ að sérstökum gögnum; allar breytingar munu leiða til þess að þjöppunarstigið lækkar skelfilega. Já, vandamálið er hægt að leysa með því að búa til nýja útgáfu af orðabókinni, en þetta er höfuðverkur - við þurfum að geyma allar útgáfur af orðabókinni; í hverri færslu þurfum við að gefa til kynna með hvaða útgáfu af orðabókinni það var þjappað...
  2. Þjappaðu hverri skrá með „klassískum“ reikniritum, en óháð hinum.
    Þjöppunaralgrímin sem eru til skoðunar eru ekki hönnuð til að vinna með færslur af þessari stærð (tugir bæta), þjöppunarhlutfallið verður greinilega minna en 1 (þ.e. auka gagnamagnið í stað þess að þjappa);
  3. Skolaðu eftir hverja upptöku.
    Mörg þjöppunarsöfn hafa stuðning fyrir FLUSH. Þetta er skipun (eða færibreyta í þjöppunarferlinu), við móttöku myndar skjalavörðurinn þjappaðan straum svo hægt sé að nota hann til að endurheimta allt óþjöppuð gögn sem þegar hafa borist. Þvílík hliðstæða sync í skráarkerfum eða commit í sql.
    Það sem er mikilvægt er að síðari þjöppunaraðgerðir munu geta notað uppsafnaða orðabók og þjöppunarhlutfallið mun ekki þjást eins mikið og í fyrri útgáfu.

Ég held að það sé augljóst að ég valdi þriðja valkostinn, við skulum skoða það nánar.

Fundið frábær grein um FLUSH í zlib.

Ég gerði hnépróf út frá greininni, tók 70 þúsund skráningar úr alvöru tæki, með síðustærð 60Kb (við komum aftur í síðustærð síðar) fékk:

Upphafleg gögn
Þjöppun gzip -9 (engin FLÚSH)
zlib með Z_PARTIAL_FLUSH
zlib með Z_SYNC_FLUSH

Bindi, KB
1692
40
352
604

Við fyrstu sýn er verðið sem FLUSH leggur til of hátt, en í raun höfum við lítið val - annað hvort að þjappa alls ekki eða að þjappa (og mjög áhrifaríkan hátt) með FLUSH. Við megum ekki gleyma því að við erum með 70 þúsund færslur, offramboðið sem Z_PARTIAL_FLUSH kynnti er aðeins 4-5 bæti á hverja færslu. Og þjöppunarhlutfallið reyndist vera næstum 5:1, sem er meira en frábær niðurstaða.

Það gæti komið á óvart, en Z_SYNC_FLUSH er í raun skilvirkari leið til að gera FLUSH

Þegar Z_SYNC_FLUSH er notað, verða síðustu 4 bætin í hverri færslu alltaf 0x00, 0x00, 0xff, 0xff. Og ef við þekkjum þá, þá þurfum við ekki að geyma þá, svo endanleg stærð er aðeins 324Kb.

Greinin sem ég tengdi á hefur skýringu:

Ný tegund 0 blokk með tómu innihaldi er bætt við.

Kubbur af tegund 0 með tómu innihaldi samanstendur af:

  • þriggja bita blokkarhausinn;
  • 0 til 7 bitar jafnt og núlli, til að ná bætajöfnun;
  • fjögurra bæta röðin 00 00 FF FF.

Eins og þú getur auðveldlega séð, í síðasta blokkinni á undan þessum 4 bætum eru frá 3 til 10 núllbitar. Hins vegar hefur æfingin sýnt að það eru í raun að minnsta kosti 10 núllbitar.

Það kemur í ljós að svona stuttir gagnablokkir eru venjulega (alltaf?) kóðaðir með blokk af gerð 1 (fastur blokk), sem endar endilega með 7 núllbitum, sem gefur samtals 10-17 tryggða núllbita (og restin mun vera núll með um það bil 50% líkur.

Þannig að í prófunargögnum er í 100% tilvika eitt núllbæti á undan 0x00, 0x00, 0xff, 0xff, og í meira en þriðjungi tilvika eru tvö núllbæt (kannski er staðreyndin sú að ég nota tvöfaldur CBOR, og þegar ég nota texta JSON, myndu blokkir af tegund 2 - dynamic blokk vera algengari, hver um sig, blokkir án viðbótar núllbæta fyrir 0x00, 0x00, 0xff, 0xff myndu hittast).

Alls, með því að nota fyrirliggjandi prófunargögn, er hægt að passa inn í minna en 250Kb af þjöppuðum gögnum.

Þú getur sparað aðeins meira með því að gera smá juggling: eins og er hunsum við tilvist nokkurra núllbita í lok blokkarinnar, nokkrir bitar í upphafi blokkarinnar breytast heldur ekki...
En svo tók ég eindregna ákvörðun um að hætta, annars gæti ég á þessum hraða endað á því að þróa minn eigin skjalavörð.

Alls, úr prófunargögnunum mínum, fékk ég 3-4 bæti á hverja skrif, þjöppunarhlutfallið reyndist vera meira en 6:1. Ég skal vera heiðarlegur: Ég bjóst ekki við slíkri niðurstöðu; að mínu mati er allt betra en 2:1 nú þegar niðurstaða sem réttlætir notkun þjöppunar.

Allt er í lagi, en zlib (deflate) er samt archaic, verðskuldað og örlítið gamaldags þjöppunaralgrím. Eina staðreyndin að síðustu 32Kb af óþjappaða gagnastraumnum er notað sem orðabók lítur undarlega út í dag (þ.e. ef einhver gagnablokk er mjög svipuð því sem var í inntaksstraumnum fyrir 40Kb síðan, þá byrjar að geyma það aftur, og mun ekki vísa til fyrri atviks). Í nútímalegum skjalavörðum er orðabókarstærðin oft mæld í megabæti frekar en kílóbætum.

Svo við höldum áfram smárannsókn okkar á skjalavörðum.

Næst prófuðum við bzip2 (mundu að án FLUSH sýndi það frábært þjöppunarhlutfall næstum 100:1). Því miður gekk það mjög illa með FLUSH; stærð þjöppuðu gagna reyndist vera stærri en óþjöppuð gögn.

Forsendur mínar um ástæður bilunarinnar

Libbz2 býður aðeins upp á einn skolunarmöguleika, sem virðist hreinsa orðabókina (líkt og Z_FULL_FLUSH í zlib); það er ekki talað um neina skilvirka þjöppun eftir þetta.

Og sá síðasti sem var prófaður var zstd. Það fer eftir breytum, það þjappar annað hvort á gzip stigi, en mun hraðar eða betur en gzip.

Því miður, með FLUSH gekk það ekki mjög vel: stærð þjöppuðu gagna var um 700Kb.

Я spurði spurningu á github síðu verkefnisins fékk ég svar um að þú ættir að treysta á allt að 10 bæti af þjónustugögnum fyrir hvern blokk af þjöppuðum gögnum, sem er nálægt þeim niðurstöðum sem fengust; það er engin leið að ná tæmingu.

Ég ákvað að hætta á þessum tímapunkti í tilraunum mínum með skjalavörslu (minni þig á að xz, lzip, lzo, lz4 sýndu sig ekki jafnvel á prófunarstigi án FLUSH, og ég tók ekki framandi samþjöppunaralgrím).

Snúum okkur aftur að skjalavörsluvandamálum.

Annað vandamálið (eins og þeir segja í röð, ekki í gildi) er að þjöppuðu gögnin eru einn straumur, þar sem stöðugt er vísað til fyrri hluta. Þannig, ef hluti af þjöppuðum gögnum skemmist, týnum við ekki aðeins tilheyrandi blokkinni af óþjöppuðum gögnum, heldur einnig öllum síðari.

Það er aðferð til að leysa þetta vandamál:

  1. Komdu í veg fyrir að vandamálið komi upp - bættu offramboði við þjöppuð gögn, sem gerir þér kleift að bera kennsl á og leiðrétta villur; við tölum um þetta síðar;
  2. Lágmarka afleiðingar ef vandamál koma upp
    Við höfum þegar sagt áður að þú getur þjappað hverri gagnablokk sjálfstætt og vandamálið hverfur af sjálfu sér (skemmdir á gögnum einnar blokkar mun aðeins leiða til taps á gögnum fyrir þessa blokk). Hins vegar er þetta öfgatilvik þar sem gagnaþjöppun mun vera árangurslaus. Hið gagnstæða öfga: notaðu alla 4MB af flísinni okkar sem eitt skjalasafn, sem mun gefa okkur framúrskarandi þjöppun, en skelfilegar afleiðingar ef gagnaspilling er til staðar.
    Já, það þarf málamiðlun hvað varðar áreiðanleika. En við verðum að muna að við erum að þróa gagnageymslusnið fyrir óstöðugt minni með mjög lágu BER og yfirlýstum gagnageymslutíma upp á 20 ár.

Meðan á tilraununum stóð komst ég að því að meira eða minna áberandi tap í þjöppunarstiginu byrjar á blokkum af þjöppuðum gögnum sem eru minni en 10 KB að stærð.
Það var áður nefnt að minnið sem notað er er blaðsíðu; ég sé enga ástæðu fyrir því að ekki ætti að nota „ein síða - ein blokk af þjöppuðum gögnum“ samsvörun.

Það er að segja að lágmarks hæfileg síðustærð er 16Kb (með varasjóði fyrir þjónustuupplýsingar). Hins vegar, svo lítil síðustærð setur verulegar takmarkanir á hámarks færslustærð.

Þó að ég búist ekki enn við færslum sem eru stærri en nokkur kílóbæti í þjöppuðu formi ákvað ég að nota 32Kb síður (fyrir samtals 128 síður á hverja flís).

Yfirlit:

  • Við geymum gögn þjöppuð með zlib (deflate);
  • Fyrir hverja færslu setjum við Z_SYNC_FLUSH;
  • Fyrir hverja þjappaða færslu klippum við slóðbætin (td 0x00, 0x00, 0xff, 0xff); í hausnum tilgreinum við hversu mörg bæti við skerum af;
  • Við geymum gögn á 32Kb síðum; það er einn straumur af þjöppuðum gögnum inni á síðunni; Á hverri síðu byrjum við aftur þjöppun.

Og áður en ég lýkur við þjöppun vil ég vekja athygli á því að við höfum aðeins nokkur bæti af þjöppuðum gögnum á hverja skrá, svo það er afar mikilvægt að blása ekki upp þjónustuupplýsingarnar, hvert bæti telur hér.

Geymsla gagnahausa

Þar sem við höfum færslur af breytilegri lengd, þurfum við einhvern veginn að ákvarða staðsetningu/mörk færslur.

Ég þekki þrjár leiðir:

  1. Allar færslur eru geymdar í samfelldum straumi, fyrst er færsluhaus sem inniheldur lengdina og síðan skráin sjálf.
    Í þessari útfærslu geta bæði hausar og gögn verið af breytilegri lengd.
    Í meginatriðum fáum við einn tengdan lista sem er notaður allan tímann;
  2. Hausar og færslurnar sjálfar eru geymdar í aðskildum straumum.
    Með því að nota hausa með stöðugri lengd tryggjum við að skemmdir á einum haus hafi ekki áhrif á hina.
    Svipuð nálgun er til dæmis notuð í mörgum skráarkerfum;
  3. Færslur eru geymdar í samfelldum straumi, færslumörkin eru ákvörðuð af ákveðnu merki (stafur/röð stafa sem er bönnuð innan gagnablokka). Ef það er merki inni í skránni, þá skiptum við því út fyrir einhverja röð (sleppum því).
    Svipuð nálgun er notuð, til dæmis í PPP-samskiptareglunum.

Ég skal lýsa.

Valkostur 1:
Útfærsla mín á hringabuffi í NOR flash
Allt er mjög einfalt hér: með því að vita lengd færslunnar getum við reiknað út heimilisfang næsta haus. Þannig að við förum í gegnum fyrirsagnirnar þar til við rekumst á svæði fyllt með 0xff (laust svæði) eða enda síðunnar.

Valkostur 2:
Útfærsla mín á hringabuffi í NOR flash
Vegna breytilegrar færslulengdar getum við ekki sagt fyrirfram hversu margar færslur (og þar með hausa) við þurfum á síðu. Þú getur dreift hausunum og gögnunum sjálfum á mismunandi síður, en ég vil frekar aðra nálgun: við setjum bæði hausana og gögnin á eina síðu, en hausarnir (í stöðugri stærð) koma frá upphafi síðunnar, og gögn (af breytilegri lengd) koma frá endanum. Um leið og þeir „hittast“ (það er ekki nóg pláss fyrir nýja færslu) teljum við þessa síðu lokið.

Valkostur 3:
Útfærsla mín á hringabuffi í NOR flash
Það er engin þörf á að geyma lengd eða aðrar upplýsingar um staðsetningu gagnanna í hausnum; merki sem gefa til kynna mörk skráanna eru nóg. Hins vegar þarf að vinna úr gögnunum við ritun/lestur.
Ég myndi nota 0xff sem merki (sem fyllir síðuna eftir stroku), þannig að lausa svæðið verður örugglega ekki meðhöndlað sem gögn.

Samanburðartafla:

Valkostur 1
Valkostur 2
Valkostur 3

Villuþol
-
+
+

Samkvæmni
+
-
+

Flækjustig í framkvæmd
*
**
**

Valkostur 1 hefur banvænan galla: ef einhver hausinn er skemmdur eyðileggst öll síðari keðjan. Valkostirnir sem eftir eru gera þér kleift að endurheimta nokkur gögn, jafnvel ef um stórtjón er að ræða.
En hér er rétt að muna að við ákváðum að geyma gögnin í þjöppuðu formi og því týnum við öllum gögnum á síðunni eftir „brotið“ met, svo þó að það sé mínus í töflunni, þá gerum við það ekki taka tillit til þess.

Þéttleiki:

  • í fyrsta valmöguleikanum þurfum við aðeins að geyma lengdina í hausnum, ef við notum heiltölur með breytilegri lengd, þá getum við í flestum tilfellum komist af með eitt bæti;
  • í seinni valkostinum þurfum við að geyma upphafs heimilisfang og lengd; færslan verður að vera stöðug stærð, ég áætla 4 bæti á hverja skrá (tvö bæti fyrir offsetið og tvö bæti fyrir lengdina);
  • þriðji valkosturinn þarf aðeins einn staf til að gefa til kynna upphaf upptöku, auk þess sem upptakan sjálf eykst um 1-2% vegna hlífðar. Almennt um það bil jöfnuður við fyrsta valkostinn.

Upphaflega leit ég á seinni valkostinn sem aðal (og skrifaði jafnvel útfærsluna). Ég yfirgaf það aðeins þegar ég loksins ákvað að nota þjöppun.

Kannski mun ég einhvern tíma samt nota svipaðan valmöguleika. Til dæmis, ef ég þarf að takast á við gagnageymslu fyrir skip sem ferðast á milli jarðar og Mars, verða allt aðrar kröfur um áreiðanleika, geimgeislun, ...

Hvað varðar þriðja valmöguleikann: Ég gaf honum tvær stjörnur vegna erfiðleika við útfærslu einfaldlega vegna þess að mér líkar ekki að skipta mér af hlífum, breyta lengd í ferlinu osfrv. Já, kannski er ég hlutdræg, en ég verð að skrifa kóðann - af hverju að neyða þig til að gera eitthvað sem þér líkar ekki.

Yfirlit: Við veljum geymsluvalkostinn í formi keðja „haus með lengd - gögn af breytilegri lengd“ vegna skilvirkni og auðveldrar framkvæmdar.

Notkun bitasviða til að fylgjast með árangri skrifaðgerða

Ég man nú ekki hvar ég fékk hugmyndina, en hún lítur svona út:
Fyrir hverja færslu úthlutum við nokkrum bitum til að geyma fána.
Eins og við sögðum áðan, eftir eyðingu eru allir bitar fylltir með 1s, og við getum breytt 1 í 0, en ekki öfugt. Þannig að fyrir „fáninn er ekki stilltur“ notum við 1, fyrir „fáninn er stilltur“ notum við 0.

Svona gæti það litið út að setja færslu með breytilegri lengd í flash:

  1. Stilltu fánann „lengdarupptaka er hafin“;
  2. Skráðu lengdina;
  3. Stilltu „gagnaupptöku er hafin“ fána;
  4. Við skráum gögnin;
  5. Stilltu fána „upptöku lokið“.

Að auki munum við hafa fána „villa kom upp“, fyrir samtals 4 bita fána.

Í þessu tilfelli höfum við tvö stöðug ríki „1111“ - upptaka er ekki hafin og „1000“ - upptaka tókst; ef óvænt truflun verður á upptökuferlinu fáum við millistig sem við getum síðan greint og unnið úr.

Aðferðin er áhugaverð, en hún verndar aðeins gegn skyndilegum rafmagnsleysi og álíka bilunum, sem er auðvitað mikilvægt, en þetta er langt frá því að vera eina (eða jafnvel helsta) ástæðan fyrir hugsanlegum bilunum.

Yfirlit: Höldum áfram í leit að góðri lausn.

Tékkafjárhæðir

Tékkatölur gera það einnig mögulegt að ganga úr skugga um (með hæfilegum líkum) að við séum að lesa nákvæmlega það sem hefði átt að vera skrifað. Og ólíkt bitasviðunum sem fjallað er um hér að ofan, virka þeir alltaf.

Ef við skoðum listann yfir hugsanlegar uppsprettur vandamála sem við ræddum hér að ofan, þá getur athugasumman greint villu óháð uppruna hennar (nema kannski illgjarn geimverur - þær geta falsað tékksumman líka).

Svo ef markmið okkar er að sannreyna að gögnin séu ósnortin, þá eru eftirlitssummur frábær hugmynd.

Val á reiknirit til að reikna út eftirlitssumman vakti engar spurningar - CRC. Annars vegar gera stærðfræðilegir eiginleikar það mögulegt að ná ákveðnum tegundum villna 100%; hins vegar sýnir þetta reiknirit á tilviljunarkenndum gögnum venjulega líkurnar á árekstrum sem eru ekki miklu meiri en fræðileg mörk. Útfærsla mín á hringabuffi í NOR flash. Það er kannski ekki hraðvirkasta reikniritið, né heldur alltaf lágmarkið hvað varðar fjölda árekstra, en það hefur mjög mikilvægan eiginleika: í prófunum sem ég lenti í voru engin mynstur þar sem það mistókst greinilega. Stöðugleiki er aðal gæðin í þessu tilfelli.

Dæmi um rúmmálsrannsókn: Part 1, Part 2 (tenglar á narod.ru, því miður).

Hins vegar er verkefninu að velja tékksummu ekki lokið; CRC er heil fjölskylda tékksumma. Þú þarft að ákveða lengdina og velja síðan margliðu.

Að velja lengd athugunarsummans er ekki eins einföld spurning og það virðist við fyrstu sýn.

Leyfðu mér að útskýra:
Við skulum hafa líkurnar á villu í hverju bæti Útfærsla mín á hringabuffi í NOR flash og tilvalin athugunarsumma, við skulum reikna út meðalfjölda villna á hverja milljón færslur:

Gögn, bæti
Athugunarsumma, bæti
Óuppgötvaðar villur
Rangar villuuppgötvun
Algjör rangar jákvæðar

1
0
1000
0
1000

1
1
4
999
1003

1
2
0
1997
1997

1
4
0
3990
3990

10
0
9955
0
9955

10
1
39
990
1029

10
2
0
1979
1979

10
4
0
3954
3954

1000
0
632305
0
632305

1000
1
2470
368
2838

1000
2
10
735
745

1000
4
0
1469
1469

Það virðist sem allt sé einfalt - fer eftir lengd gagna sem verið er að vernda, veldu lengd eftirlitssummans með að lágmarki rangar jákvæðar - og bragðið er í pokanum.

Hins vegar kemur upp vandamál með stuttar eftirlitssummur: þó þær séu góðar í að greina staka bita villur geta þær með nokkuð miklum líkindum samþykkt algjörlega tilviljunarkennd gögn sem rétt. Það var þegar grein á Habré sem lýsir vandamál í raunveruleikanum.

Þess vegna, til að gera slembitölusamsvar næstum ómögulegt, þarftu að nota tékksummur sem eru 32 bitar eða lengri. (fyrir lengdir sem eru lengri en 64 bita eru dulmáls kjötkássaaðgerðir venjulega notaðar).

Þrátt fyrir þá staðreynd að ég skrifaði áðan að við þurfum að spara pláss fyrir alla muni, munum við samt nota 32 bita eftirlitsummu (16 bitar eru ekki nóg, líkurnar á árekstri eru meira en 0.01%; og 24 bita, þar sem þeir segja, eru hvorki hér né þar).

Hér gæti komið upp andmæli: vistuðum við hvert bæti þegar við völdum þjöppun til að gefa núna 4 bæti í einu? Væri ekki betra að þjappa ekki eða bæta við tékksummu? Auðvitað ekki, engin þjöppun þýðir ekki, að við þurfum ekki á heilindum að halda.

Þegar við veljum margliðu munum við ekki finna upp hjólið aftur, heldur taka CRC-32C sem nú er vinsæll.
Þessi kóði greinir 6 bita villur á pökkum allt að 22 bæti (kannski algengasta tilfellið fyrir okkur), 4 bita villur á pökkum allt að 655 bæti (einnig algengt tilfelli fyrir okkur), 2 eða hvaða staka fjölda bita villu sem er á pökkum af hvaða hæfilegri lengd sem er.

Ef einhver hefur áhuga á smáatriðum

Wikipedia grein um CRC.

Kóða breytur crc-32c á Heimasíða Koopman - kannski fremsti CRC sérfræðingur á jörðinni.

В grein hans есть annar áhugaverður kóða, sem gefur aðeins betri færibreytur fyrir pakkalengdirnar sem eiga við okkur, en ég taldi muninn ekki marktækan og ég var nógu hæfur til að velja sérsniðinn kóða í staðinn fyrir staðlaða og vel rannsakaða kóðann.

Einnig, þar sem gögnin okkar eru þjöppuð, vaknar spurningin: eigum við að reikna út eftirlitssummu þjappaðra eða óþjappaðra gagna?

Rök fyrir því að reikna út eftirlitsummu óþjappaðra gagna:

  • Við þurfum á endanum að athuga öryggi gagnageymslu - svo við athugum það beint (á sama tíma verða hugsanlegar villur í útfærslu þjöppunar/þjöppunar, skemmdir af völdum bilaðs minnis o.s.frv. skoðaðar);
  • Deflate algrímið í zlib er með nokkuð þroskaða útfærslu og ætti ekki falla með „skökkum“ inntaksgögnum; þar að auki er það oft hægt að greina villur í inntaksstraumnum sjálfstætt, sem dregur úr heildarlíkum á að villu finnist ekki (framkvæmdi próf með því að snúa við einum bita í stuttri skráningu, zlib fann villu í um þriðjungi tilfella).

Rök gegn því að reikna út eftirlitsummu óþjappaðra gagna:

  • CRC er „sérsniðið“ sérstaklega fyrir þær örfáu bitavillur sem eru einkennandi fyrir flassminni (bitvilla í þjöppuðum straumi getur valdið gríðarlegri breytingu á úttaksstraumnum, sem við getum, eingöngu fræðilega séð, „skilið“ árekstur);
  • Mér líkar ekki hugmyndin um að senda hugsanlega biluð gögn til afþjöppunnar, Hver veithvernig hann mun bregðast við.

Í þessu verkefni ákvað ég að víkja frá almennt viðurkenndri venju að geyma eftirlitsummu óþjappaðra gagna.

Yfirlit: Við notum CRC-32C, við reiknum út eftirlitssumman úr gögnunum á því formi sem þau eru skrifuð til að blikka (eftir þjöppun).

Offramboð

Notkun óþarfa kóðun útilokar að sjálfsögðu ekki gagnatapi, hins vegar getur hún verulega (oft í mörgum stærðargráðum) dregið úr líkum á óafturkræfum gagnatapi.

Við getum notað mismunandi gerðir af offramboði til að leiðrétta villur.
Hamming kóðar geta leiðrétt staka bita villur, Reed-Solomon stafakóða, mörg afrit af gögnum ásamt eftirlitsumtölum eða kóðun eins og RAID-6 geta hjálpað til við að endurheimta gögn jafnvel ef um stórfellda spillingu er að ræða.
Upphaflega var ég staðráðinn í víðtækri notkun villuþolinnar kóðun, en svo áttaði ég mig á því að við þurfum fyrst að hafa hugmynd um hvaða villur við viljum vernda okkur fyrir og velja síðan kóðun.

Við sögðum áðan að það þarf að grípa villur eins fljótt og auðið er. Á hvaða stöðum getum við lent í villum?

  1. Ókláruð upptaka (einhverra hluta vegna var slökkt á straumnum á þeim tíma sem upptakan var gerð, hindberjum fraus, ...)
    Því miður, ef slík villa verður, er allt sem eftir er að hunsa ógildar skrár og telja gögnin glatuð;
  2. Skrifvillur (af einhverjum ástæðum var það sem var skrifað í flassminnið ekki það sem var skrifað)
    Við getum strax greint slíkar villur ef við gerum próflestur strax eftir upptöku;
  3. Bjögun gagna í minni við geymslu;
  4. Lestrarvillur
    Til að leiðrétta það, ef athugunarsumman passar ekki, er nóg að endurtaka lesturinn nokkrum sinnum.

Það er að segja að aðeins villur af þriðju gerðinni (sjálfráða spilling gagna við geymslu) er ekki hægt að leiðrétta án villuþolinnar kóðun. Svo virðist sem slíkar villur séu enn afar ólíklegar.

Yfirlit: það var ákveðið að hætta við óþarfa kóðun, en ef aðgerð sýnir villu þessarar ákvörðunar, farðu aftur til umfjöllunar um málið (með þegar safnað tölfræði um bilanir, sem gerir kleift að velja ákjósanlegasta tegund kóðunar).

Annað

Auðvitað leyfir snið greinarinnar okkur ekki að rökstyðja hvern einasta bita í sniðinu (og styrkur minn er þegar búinn), svo ég mun í stuttu máli fara yfir nokkur atriði sem ekki hafa verið rakin áðan.

  • Ákveðið var að gera allar síður „jafnar“
    Það er að segja að það verða engar sérstakar síður með lýsigögnum, aðskildum þráðum o.s.frv., heldur einn þráður sem endurskrifar allar síður í röð.
    Þetta tryggir jafnt slit á síðunum, enginn bilunarpunktur, og mér líkar það bara;
  • Nauðsynlegt er að gefa upp útgáfu sniðsins.
    Snið án útgáfunúmers í hausnum er illt!
    Það er nóg að bæta við reit með ákveðnu Töfranúmeri (undirskrift) við síðuhausinn, sem gefur til kynna útgáfu sniðsins sem notað er (Ég held að í reynd verði þeir ekki einu sinni tugir þeirra);
  • Notaðu haus með breytilegri lengd fyrir færslur (sem það eru margar), reyndu að gera hann 1 bæti langan í flestum tilfellum;
  • Til að umrita lengd haussins og lengd klippta hluta þjöppuðu færslunnar skaltu nota tvíundarkóða með breytilegum lengd.

Hjálpaði mikið rafall á netinu Huffman kóðar. Á örfáum mínútum gátum við valið nauðsynlega kóða með breytilegri lengd.

Lýsing á gagnageymslusniði

Byte röð

Reitir sem eru stærri en eitt bæti eru geymdir á big-endian sniði (netbæta röð), það er að segja 0x1234 er skrifað sem 0x12, 0x34.

Síðuskipting

Öllu flassminni er skipt í jafnstórar síður.

Sjálfgefin síðustærð er 32Kb, en ekki meira en 1/4 af heildarstærð minniskubbsins (fyrir 4MB flís fást 128 síður).

Hver síða geymir gögn óháð öðrum (þ.e. gögn á einni síðu vísa ekki til gagna á annarri síðu).

Allar síður eru númeraðar í náttúrulegri röð (í hækkandi röð heimilisfönga), byrjað á númerinu 0 (síða núll byrjar á heimilisfangi 0, fyrsta síða byrjar á 32Kb, önnur síða byrjar á 64Kb o.s.frv.)

Minniskubburinn er notaður sem hringlaga biðminni (hringbuffi), það er að skrifa fyrst á síðunúmer 0, síðan númer 1, ..., þegar við fyllum síðustu síðuna hefst ný hringrás og upptaka heldur áfram frá síðu núll .

Inni á síðunni

Útfærsla mín á hringabuffi í NOR flash
Í upphafi síðunnar er 4-bæta síðuhaus geymdur, síðan hausathugunarsumma (CRC-32C), síðan eru færslur geymdar á „haus, gögn, eftirlitsummu“ sniði.

Titill síðunnar (skítugrænn á skýringarmyndinni) samanstendur af:

  • tveggja bæta töfranúmerareit (einnig merki um sniðútgáfuna)
    fyrir núverandi útgáfu af sniðinu sem það er reiknað sem 0xed00 ⊕ номер страницы;
  • tveggja bæta teljari „Síðuútgáfa“ (númer endurskrifaðs hringrásar).

Færslur á síðunni eru geymdar í þjöppuðu formi (deflate algrímið er notað). Öllum færslum á einni síðu er þjappað saman í einn þráð (notuð er sameiginleg orðabók) og á hverri nýrri síðu hefst þjöppun upp á nýtt. Það er að segja að til að þjappa hvaða færslu sem er, þarf allar fyrri færslur frá þessari síðu (og aðeins þessari).

Hver skrá verður þjappuð með Z_SYNC_FLUSH fánanum og í lok þjappaðs straums verða 4 bæti 0x00, 0x00, 0xff, 0xff, hugsanlega á undan einum eða tveimur núllbætum til viðbótar.
Við fleygum þessari röð (4, 5 eða 6 bæti að lengd) þegar við skrifum í flassminni.

Skráarhausinn er 1, 2 eða 3 bæti sem geymir:

  • einn biti (T) sem gefur til kynna tegund færslu: 0 - samhengi, 1 - log;
  • reit með breytilegri lengd (S) frá 1 til 7 bita, sem skilgreinir lengd haussins og „halans“ sem þarf að bæta við færsluna fyrir þjöppun;
  • met lengd (L).

S gildi tafla:

S
Lengd haus, bæti
Fargað á skrifa, bæti

0
1
5 (00 00 00 ff ff)

10
1
6 (00 00 00 00 ff ff)

110
2
4 (00 00 ff ff)

1110
2
5 (00 00 00 ff ff)

11110
2
6 (00 00 00 00 ff ff)

1111100
3
4 (00 00 ff ff)

1111101
3
5 (00 00 00 ff ff)

1111110
3
6 (00 00 00 00 ff ff)

Ég reyndi að sýna, ég veit ekki hversu skýrt það kom út:
Útfærsla mín á hringabuffi í NOR flash
Gulur hér gefur til kynna T-reitinn, hvítur S-reiturinn, grænn L (lengd þjappaðra gagna í bætum), blár þjöppuðu gögnin, rautt lokabæt þjappaðra gagna sem eru ekki skrifuð í flassminni.

Þannig getum við skrifað færsluhausa af algengustu lengd (allt að 63+5 bæti í þjöppuðu formi) í einu bæti.

Eftir hverja skráningu er CRC-32C eftirlitssumman geymd, þar sem öfugt gildi fyrri eftirlitssummans er notað sem upphafsgildi (init).

CRC hefur eiginleikann „tímalengd“, eftirfarandi formúla virkar (plús eða mínus bitabreyting í ferlinu): Útfærsla mín á hringabuffi í NOR flash.
Það er í raun, við reiknum út CRC allra fyrri bæta af hausum og gögnum á þessari síðu.

Beint á eftir eftirlitssummanum er hausinn á næstu skrá.

Hausinn er hannaður á þann hátt að fyrsta bæti hans er alltaf frábrugðið 0x00 og 0xff (ef í staðinn fyrir fyrsta bæti haussins rekumst við á 0xff, þá þýðir það að þetta er ónotað svæði; 0x00 gefur til kynna villu).

Dæmi reiknirit

Að lesa úr Flash minni

Öllum lestri fylgir ávísun.
Ef athugunarsumman passar ekki er lesturinn endurtekinn nokkrum sinnum í von um að lesa rétt gögn.

(þetta er skynsamlegt, Linux vistar ekki skyndiminni lestur frá NOR Flash, prófaður)

Skrifaðu í flash minni

Við skráum gögnin.
Við skulum lesa þær.

Ef lesin gögn passa ekki við skrifuð gögn fyllum við svæðið með núllum og merkjum villu.

Að undirbúa nýja örrás fyrir notkun

Til frumstillingar er haus með útgáfu 1 skrifaður á fyrstu (eða réttara sagt núll) síðuna.
Eftir það er upphafssamhengið skrifað á þessa síðu (inniheldur UUID vélarinnar og sjálfgefnar stillingar).

Það er það, flassminnið er tilbúið til notkunar.

Að hlaða vélina

Við hleðslu eru fyrstu 8 bætin á hverri síðu (haus + CRC) lesin, síður með óþekkt töfranúmer eða röng CRC eru hunsuð.
Af „réttum“ síðum eru síður með hámarksútgáfu valdar og síðan með hæsta númerið tekin af þeim.
Fyrsta skráningin er lesin, réttmæti CRC og tilvist „samhengis“ fánans er athugað. Ef allt er í lagi telst þessi síða núverandi. Ef ekki, snúum við aftur til fyrri þar til við finnum „lifandi“ síðu.
og á fundnum síðu lesum við allar skrárnar, þær sem við notum með „samhengi“ fánanum.
Vistaðu zlib orðabókina (það þarf að bæta henni við þessa síðu).

Það er það, niðurhalinu er lokið, samhengið er endurheimt, þú getur unnið.

Bæta við dagbókarfærslu

Við þjöppum færslunni með réttri orðabók, tilgreinum Z_SYNC_FLUSH. Við sjáum hvort þjappaða skráin passar á núverandi síðu.
Ef það passar ekki (eða það voru CRC villur á síðunni), byrjaðu nýja síðu (sjá hér að neðan).
Við skrifum niður skrána og CRC. Ef villa kemur upp, byrjaðu nýja síðu.

Ný síða

Við veljum ókeypis síðu með lágmarksfjölda (við teljum ókeypis síðu vera síðu með rangri eftirlitsummu í hausnum eða með minni útgáfu en núverandi). Ef það eru engar slíkar síður skaltu velja síðuna með lágmarksfjölda af þeim sem eru með útgáfu sem er jöfn þeirri sem er í gildi.
Við eyðum völdu síðunni. Við athugum innihaldið með 0xff. Ef eitthvað er að, taktu þá næstu ókeypis síðu o.s.frv.
Við skrifum haus á eyddu síðuna, fyrsta færslan er núverandi ástand samhengisins, sú næsta er óskrifaða annálsfærslan (ef það er einhver).

Nothæfi sniðs

Að mínu mati reyndist það vera gott snið til að geyma meira eða minna þjappanlegt upplýsingastreymi (venjulegur texti, JSON, MessagePack, CBOR, hugsanlega protobuf) í NOR Flash.

Auðvitað er sniðið „sniðið“ fyrir SLC NOR Flash.

Það ætti ekki að nota með háum BER miðlum eins og NAND eða MLC NOR (er svona minni jafnvel til sölu? Ég hef aðeins séð það nefnt í verkum um leiðréttingarkóða).

Þar að auki ætti ekki að nota það með tækjum sem hafa sitt eigið FTL: USB flass, SD, MicroSD osfrv (fyrir slíkt minni bjó ég til snið með síðustærð 512 bæti, undirskrift í upphafi hverrar síðu og einstök skráanúmer - stundum var hægt að endurheimta öll gögnin úr „biluðu“ glampi drifi með einföldum raðlestri).

Það fer eftir verkefnum, sniðið er hægt að nota án breytinga á flash-drifum úr 128Kbit (16Kb) í 1Gbit (128MB). Ef þess er óskað geturðu notað það á stærri flís, en þú þarft líklega að stilla síðustærðina (En hér vaknar nú þegar spurningin um hagkvæmni; verðið fyrir NOR Flash í miklu magni er ekki uppörvandi).

Ef einhverjum finnst sniðið áhugavert og vill nota það í opnu verkefni, skrifaðu, ég skal reyna að finna tíma, pússa kóðann og setja hann á github.

Ályktun

Eins og þú sérð reyndist sniðið á endanum vera einfalt og jafnvel leiðinlegt.

Það er erfitt að endurspegla þróun sjónarhorns míns í grein, en trúðu mér: upphaflega vildi ég búa til eitthvað fágað, óslítandi, sem gæti lifað af jafnvel kjarnorkusprengingu í nálægð. Hins vegar vann skynsemin (vona ég) enn og smám saman færðust forgangsröðunin í átt að einfaldleika og þéttleika.

Getur verið að ég hafi rangt fyrir mér? Já að sjálfsögðu. Það gæti til dæmis komið í ljós að við keyptum slatta af lággæða örrásum. Eða af einhverjum öðrum ástæðum mun búnaðurinn ekki standast væntingar um áreiðanleika.

Er ég með áætlun um þetta? Ég held að eftir að hafa lesið greinina efast þú ekki um að það sé til áætlun. Og ekki einu sinni einn.

Á örlítið alvarlegri nótum var sniðið þróað bæði sem vinnuvalkostur og sem „prufublaðra“.

Í augnablikinu er allt á borðinu að virka fínt, bókstaflega um daginn verður lausnin send inn (u.þ.b.) á hundruðum tækja, við skulum sjá hvað gerist í „bardaga“ aðgerðum (sem betur fer vona ég að sniðið leyfi þér að greina bilanir á áreiðanlegan hátt; svo þú getir safnað fullri tölfræði). Eftir nokkra mánuði verður hægt að draga ályktanir (og ef þú ert óheppinn, jafnvel fyrr).

Ef, byggt á niðurstöðum notkunar, uppgötvast alvarleg vandamál og úrbóta er þörf, þá mun ég örugglega skrifa um það.

Bókmenntir

Ég vildi ekki gera langan leiðinlegan lista yfir notuð verk; þegar allt kemur til alls eru allir með Google.

Hér ákvað ég að skilja eftir lista yfir niðurstöður sem mér þóttu sérstaklega áhugaverðar, en smám saman fluttust þær beint inn í texta greinarinnar og eitt atriði varð eftir á listanum:

  1. Gagnsemi infgen frá höfundinum zlib. Getur greinilega sýnt innihald deflate/zlib/gzip skjalasafna. Ef þú þarft að takast á við innri uppbyggingu deflate (eða gzip) sniðsins, mæli ég eindregið með því.

Heimild: www.habr.com

Bæta við athugasemd