implementasine sandi ring buffer ing NOR lampu kilat

prasejarah

Ana mesin vending saka desain kita dhewe. Nang Raspberry Pi lan sawetara wiring ing Papan kapisah. A akseptor duwit receh, akseptor tagihan, terminal bank disambungake ... Kabeh wis kontrol dening program poto-ditulis. Kabeh riwayat karya ditulis ing log ing flash drive (MicroSD), sing banjur dikirim liwat Internet (nggunakake modem USB) menyang server, sing disimpen ing database. Informasi sales dimuat menyang 1c, ana uga antarmuka web prasaja kanggo ngawasi, etc.

Yaiku, jurnal kasebut penting - kanggo akuntansi (asil, penjualan, lan liya-liyane), ngawasi (kabeh jinis kegagalan lan kahanan force majeure liyane); Iki, siji bisa ngomong, kabeh informasi sing kita duwe babagan mesin iki.

masalah

Flash drive nuduhake awake minangka piranti sing ora bisa dipercaya. Padha gagal karo reguler enviable. Iki ndadékaké kanggo loro mesin downtime lan (yen sakperangan alesan log ora bisa ditransfer online) kanggo mundhut data.

Iki dudu pengalaman pertama nggunakake flash drive, sadurunge ana proyek liyane kanthi luwih saka satus piranti, ing ngendi majalah kasebut disimpen ing USB flash drive, ana uga masalah linuwih, kadhangkala jumlah sing gagal. sasi ana ing Welasan. Kita nyoba macem-macem flash drive, kalebu merek kanthi memori SLC, lan sawetara model luwih dipercaya tinimbang liyane, nanging ngganti flash drive ora ngrampungake masalah kasebut.

Ati-ati Longread! Yen sampeyan ora kasengsem ing "kok", nanging mung "carane", sampeyan bisa langsung Neng akhir artikel.

kaputusan

Wangsulan: Bab ingkang sapisanan teka ing atine yaiku: ninggalake MicroSD, nginstal, contone, SSD, lan boot saka iku. Secara teoritis, bisa uga, nanging relatif larang, lan ora bisa dipercaya (adaptor USB-SATA ditambahake; statistik kegagalan kanggo SSD anggaran uga ora nyemangati).

USB HDD uga ora katon minangka solusi sing apik banget.

Mulane, kita teka ing pilihan iki: ninggalake booting saka MicroSD, nanging digunakake ing mode maca-mung, lan nyimpen log operasi (lan informasi liyane unik kanggo Piece tartamtu saka hardware - nomer serial, kalibrasi sensor, etc.) nang endi wae liya .

Topik FS mung diwaca kanggo raspberries wis diteliti ing njero lan njaba, aku ora bakal mikir babagan rincian implementasine ing artikel iki (nanging yen ana kapentingan, mungkin aku bakal nulis artikel mini babagan topik iki). Siji-sijine titik sing dakkarepake yaiku saka pengalaman pribadi lan saka review saka wong-wong sing wis ngetrapake, ana gain linuwih. Ya, iku mokal kanggo njaluk nyisihaken saka breakdowns, nanging Ngartekno nyuda frekuensi sing cukup bisa. Lan kertu dadi manunggal, sing nggawe panggantos luwih gampang kanggo personel layanan.

Hardware

Ora ana keraguan khusus babagan pilihan jinis memori - NOR Flash.
Argumentasi:

  • sambungan prasaja (paling asring bis SPI, sing wis pengalaman nggunakake, supaya ora ana masalah hardware sing foreseen);
  • rega konyol;
  • protokol operasi standar (implementasine wis ana ing kernel Linux, yen sampeyan pengin, sampeyan bisa njupuk pihak katelu, sing uga ana, utawa malah nulis dhewe, bok manawa kabeh iku prasaja);
  • linuwih lan sumber daya:
    saka lembar data khas: data disimpen nganti 20 taun, 100000 siklus mbusak kanggo saben blok;
    saka sumber pihak katelu: BER arang banget, postulates ora perlu kanggo kode koreksi kesalahan (sawetara karya nganggep ECC kanggo NOR, nanging biasane tegese MLC NOR; iki uga kedadeyan).

Ayo ngira syarat volume lan sumber daya.

Aku pengin data kasebut dijamin disimpen nganti pirang-pirang dina. Iki perlu supaya yen ana masalah karo komunikasi, riwayat penjualan ora ilang. Kita bakal fokus ing 5 dina, sajrone periode kasebut (malah nganggep akhir minggu lan preian) masalah bisa ditanggulangi.

Saiki kita ngumpulake kira-kira 100kb log saben dina (3-4 ewu entri), nanging mboko sithik angka iki saya tambah - rincian nambah, acara anyar ditambahake. Plus, kadhangkala ana bledosan (sawetara sensor wiwit spamming karo positif palsu, contone). Kita bakal ngetung kanggo 10 ewu cathetan 100 bita saben - megabyte saben dina.

Secara total, 5MB data sing resik (dikompres kanthi apik). More kanggo wong-wong mau (estimasi kasar) 1 MB data layanan.

Yaiku, kita butuh chip 8MB yen ora nggunakake kompresi, utawa 4MB yen digunakake. Nomer sing cukup nyata kanggo jinis memori iki.

Minangka kanggo sumber daya: yen kita rencana sing kabeh memori bakal ditulis maneh ora luwih saka sapisan saben 5 dina, banjur liwat 10 taun layanan kita njaluk kurang saka sewu siklus nulis ulang.
Ayo kula ngelingake yen pabrikan janji satus ewu.

Sithik babagan NOR vs NAND

Dina iki, mesthine, memori NAND luwih populer, nanging aku ora bakal nggunakake kanggo proyek iki: NAND, ora kaya NOR, kudu nggunakake kode koreksi kesalahan, tabel blok sing ala, lan sapiturute, lan uga sikil Kripik NAND biasane luwih akeh.

Kekurangan NOR kalebu:

  • volume cilik (lan, miturut, rega dhuwur saben megabyte);
  • kacepetan komunikasi kurang (umume amarga kasunyatan sing antarmuka serial digunakake, biasane SPI utawa I2C);
  • mbusak alon (gumantung saka ukuran pemblokiran, iku njupuk saka bagian sekedhik saka detik kanggo sawetara detik).

Kayane ora ana sing kritis kanggo kita, mula kita terus.

Yen rincian menarik, microcircuit wis dipilih ing25df321a (Nanging, iki ora penting, ana akeh analog ing pasar sing kompatibel karo sistem pinout lan perintah; sanajan kita pengin nginstal microcircuit saka pabrikan sing beda lan / utawa ukuran sing beda, kabeh bakal bisa digunakake tanpa ngganti kode).

Aku nggunakake driver sing dibangun ing kernel Linux; ing Raspberry, amarga dhukungan overlay wit piranti, kabeh gampang banget - sampeyan kudu nglebokake overlay sing dikompilasi ing /boot/overlays lan rada ngowahi /boot/config.txt.

Tuladha file dts

Kanggo jujur, Aku ora yakin sing ditulis tanpa kasalahan, nanging bisa.

/*
 * 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?";
    };
};

Lan baris liyane ing config.txt

dtoverlay=at25:spimaxfrequency=50000000

Aku bakal ngilangi gambaran nyambungake chip menyang Raspberry Pi. Ing tangan siji, aku ora ahli ing electronics, ing tangan liyane, kabeh kene banal malah kanggo kula: microcircuit mung 8 sikil, kang kita kudu lemah, daya, SPI (CS, SI, SO, SCK). ); tingkat padha karo Raspberry Pi, ora wiring tambahan dibutuhake - mung nyambung dituduhake 6 pin.

Formulasi masalah

Minangka biasanipun, statement masalah dadi liwat sawetara iterasi, lan misale jek kula iku wektu kanggo sabanjure. Mula, ayo padha mandheg, nglumpukake apa sing wis ditulis, lan njlentrehake rincian sing tetep ana ing bayangan.

Dadi, kita wis mutusake manawa log kasebut bakal disimpen ing SPI NOR Flash.

Apa NOR Flash kanggo sing ora ngerti?

Iki minangka memori non-molah malih sing sampeyan bisa nindakake telung operasi:

  1. Waosan:
    Wacan sing paling umum: kita ngirim alamat lan maca akeh bita sing dibutuhake;
  2. Cathetan:
    Nulis kanggo lampu kilat NOR katon kaya biasa, nanging nduweni siji peculiarity: sampeyan mung bisa ngganti 1 kanggo 0, nanging ora kosok balene. Contone, yen kita duwe 0x55 ing sel memori, banjur sawise nulis 0x0f, 0x05 wis disimpen ing kana. (ndeleng tabel ing ngisor iki);
  3. Busak:
    Mesthi, kita kudu bisa nindakake operasi ngelawan - ngganti 0 kanggo 1, iki persis apa operasi mbusak. Boten kados loro pisanan, ora operate karo bait, nanging karo pamblokiran (pamblokiran mbusak minimal ing chip milih 4kb). Mbusak ngrusak kabeh pemblokiran lan mung cara kanggo ngganti 0 kanggo 1. Mulane, nalika nggarap memori lampu kilat, sampeyan kerep kudu nyelarasake struktur data menyang wates blok mbusak.
    Ngrekam ing NOR Flash:

data binar

iku
01010101

Direkam
00001111

Wis dadi
00000101

Log kasebut nggambarake urutan rekaman kanthi dawa variabel. Dawane rekaman sing khas kira-kira 30 bita (sanajan rekaman sing dawane sawetara kilobyte kadhangkala kedadeyan). Ing kasus iki, kita bisa karo wong-wong mau mung minangka sakumpulan bita, nanging, yen sampeyan kasengsem, CBOR digunakake ing rekaman.

Saliyane log, kita kudu nyimpen sawetara informasi "setelan", sing dianyari lan ora: ID piranti tartamtu, kalibrasi sensor, bendera "piranti dipateni sementara", lsp.
Informasi iki minangka set rekaman nilai kunci, uga disimpen ing CBOR. Kita ora duwe akeh informasi iki (paling sawetara kilobyte), lan ora dianyari.
Ing ngisor iki kita bakal nyebat konteks.

Yen kita ngelingi ngendi artikel iki diwiwiti, penting banget kanggo njamin panyimpenan data sing dipercaya lan, yen bisa, operasi terus-terusan sanajan ana kegagalan hardware / korupsi data.

Apa sumber masalah sing bisa dianggep?

  • Mateni nalika operasi nulis/mbusak. Iki saka kategori "ora ana trik nglawan linggis."
    Informasi saka diskusi ing stackexchange: nalika daya dipateni nalika nggarap lampu kilat, loro-lorone mbusak (diset menyang 1) lan nulis (diset menyang 0) mimpin kanggo prilaku undefined: data bisa ditulis, sebagian ditulis (ngomong, kita ditransfer 10 bait / 80 bit , nanging durung mung 45 bit bisa ditulis), iku uga bisa sing sawetara bit bakal ing "penengah" negara (maca bisa gawé loro 0 lan 1);
  • Kasalahan ing memori lampu kilat dhewe.
    BER, sanajan banget kurang, ora bisa padha karo nol;
  • Kesalahan bis
    Data sing dikirim liwat SPI ora dilindhungi kanthi cara apa wae; kesalahan siji bit lan kesalahan sinkronisasi bisa kedadeyan - mundhut utawa nglebokake bit (sing ndadékaké distorsi data sing gedhé);
  • Kesalahan / kesalahan liyane
    Kesalahan ing kode, glitches Raspberry, gangguan alien...

Aku wis ngrumusake syarat-syarat sing, miturut pendapatku, perlu kanggo njamin linuwih:

  • cathetan kudu langsung mlebu ing memori lampu kilat, tundha nulis ora dianggep; - yen ana kesalahan, kudu dideteksi lan diproses sakcepete; - sistem kudu, yen bisa, pulih saka kesalahan.
    (conto saka urip "ora mesthine", sing dakkira saben wong wis nemoni: sawise urip maneh darurat, sistem file "rusak" lan sistem operasi ora boot)

Gagasan, pendekatan, refleksi

Nalika aku wiwit mikir babagan masalah iki, akeh gagasan sing muncul ing sirahku, contone:

  • nggunakake komprèsi data;
  • nggunakake struktur data pinter, contone, nyimpen header rekaman kapisah saka cathetan dhewe, supaya yen ana kesalahan ing cathetan sembarang, sampeyan bisa maca liyane tanpa masalah;
  • nggunakake kolom bit kanggo ngontrol rampung rekaman nalika daya dipateni;
  • nyimpen checksums kanggo kabeh;
  • nggunakake sawetara jinis kode tahan gangguan.

Sawetara gagasan kasebut digunakake, dene liyane diputusake supaya ditinggal. Ayo budhal.

Kompresi data

Acara kasebut dhewe sing direkam ing jurnal kasebut meh padha lan bisa diulang ("mbuwang duwit receh 5 ruble", "dipencet tombol kanggo menehi owah-owahan", ...). Mulane, kompres kudu cukup efektif.

Overhead kompresi ora pati penting (prosesor kita cukup kuat, sanajan Pi pisanan duwe siji inti kanthi frekuensi 700 MHz, model saiki duwe sawetara inti kanthi frekuensi luwih saka gigahertz), kurs kanthi panyimpenan kurang (sawetara). megabyte per detik), ukuran rekaman cilik. Umumé, yen kompresi nduwe pengaruh ing kinerja, mung bakal positif. (pancen ora kritis, mung nyatakake). Kajaba iku, kita ora duwe embedded nyata, nanging Linux biasa - supaya implementasine ora mbutuhake akeh gaweyan (cukup mung nyambungake perpustakaan lan nggunakake sawetara fungsi saka iku).

Sepotong log dijupuk saka piranti sing digunakake (1.7 MB, 70 ewu entri) lan pisanan mriksa kompresibilitas nggunakake gzip, lz4, lzop, bzip2, xz, zstd sing kasedhiya ing komputer.

  • gzip, xz, zstd nuduhake asil sing padha (40Kb).
    Aku kaget yen xz modis nuduhake dhewe ing tingkat gzip utawa zstd;
  • lzip kanthi setelan gawan menehi asil sing rada ala;
  • lz4 lan lzop nuduhake asil sing ora apik banget (150Kb);
  • bzip2 nuduhake asil sing apik banget (18Kb).

Dadi, data kasebut dikompres kanthi apik.
Dadi (yen kita ora nemokake cacat fatal) bakal ana kompresi! Mung amarga luwih akeh data bisa pas ing flash drive sing padha.

Ayo dipikirake babagan kekurangane.

Masalah pisanan: kita wis setuju yen saben rekaman kudu langsung menyang lampu kilat. Biasane, arsip ngumpulake data saka stream input nganti mutusake yen wektune nulis ing akhir minggu. Kita kudu langsung nampa blok data sing dikompres lan simpen ing memori sing ora molah malih.

Aku ndeleng telung cara:

  1. Kompres saben rekaman nggunakake kompresi kamus tinimbang algoritma sing dibahas ing ndhuwur.
    Iki minangka pilihan sing bisa digunakake, nanging aku ora seneng. Kanggo mesthekake tingkat kompresi sing luwih utawa kurang prayoga, kamus kasebut kudu "disesuaiake" kanggo data tartamtu; owah-owahan apa wae bakal nyebabake tingkat kompresi mudhun kanthi catastrophically. Ya, masalah kasebut bisa ditanggulangi kanthi nggawe versi kamus anyar, nanging iki mumet - kita kudu nyimpen kabeh versi kamus; ing saben entri kita kudu nuduhake versi kamus sing dikompres...
  2. Kompres saben rekaman nggunakake algoritma "klasik", nanging kanthi bebas saka liyane.
    Algoritma kompresi sing dipikirake ora dirancang kanggo nggarap cathetan kanthi ukuran iki (puluhan bita), rasio kompresi bakal jelas kurang saka 1 (yaiku, nambah volume data tinimbang ngompres);
  3. Apa FLUSH sawise saben rekaman.
    Akeh perpustakaan kompresi duwe dhukungan kanggo FLUSH. Iki minangka prentah (utawa parameter kanggo prosedur kompresi), nalika nampa arsip kasebut mbentuk stream sing dikompres supaya bisa digunakake kanggo mulihake. kabeh data sing ora dikompres sing wis ditampa. Analog kaya ngono sync ing sistem file utawa commit ing sql.
    Sing penting yaiku operasi kompresi sabanjure bakal bisa nggunakake kamus akumulasi lan rasio kompresi ora bakal nandhang sangsara kaya ing versi sadurunge.

Aku iku ketok yen aku milih pilihan katelu, ayo kang katon ing liyane rinci.

ketemu artikel apik babagan FLUSH ing zlib.

Aku nindakake tes lutut adhedhasar artikel kasebut, njupuk 70 ewu entri log saka piranti nyata, kanthi ukuran kaca 60Kb (kita bakal bali menyang ukuran kaca mengko) ditampa:

Data sumber
Kompresi gzip -9 (tanpa FLUSH)
zlib karo Z_PARTIAL_FLUSH
zlib karo Z_SYNC_FLUSH

Volume, KB
1692
40
352
604

Sepisanan, rega sing disumbang FLUSH dhuwur banget, nanging ing kasunyatan, kita ora duwe pilihan - ora kanggo ngompres, utawa ngompres (lan efektif banget) nganggo FLUSH. Kita kudu ora lali yen kita duwe 70 ewu rekaman, redundansi sing dienalake Z_PARTIAL_FLUSH mung 4-5 bita saben rekaman. Lan rasio kompresi dadi meh 5: 1, sing luwih saka asil sing apik banget.

Bisa uga kaget, nanging Z_SYNC_FLUSH sejatine cara sing luwih efisien kanggo nindakake FLUSH

Nalika nggunakake Z_SYNC_FLUSH, 4 bait pungkasan saben entri bakal tansah 0x00, 0x00, 0xff, 0xff. Lan yen kita ngerti, mula kita ora kudu nyimpen, saengga ukuran pungkasan mung 324Kb.

Artikel sing daksambungake duwe panjelasan:

Blok 0 jinis anyar kanthi isi kosong ditambahake.

Blok tipe 0 kanthi isi kosong kalebu:

  • header blok telung bit;
  • 0 nganti 7 bit padha karo nol, kanggo entuk keselarasan bait;
  • urutan papat bait 00 00 FF FF.

Minangka sampeyan bisa ndeleng kanthi gampang, ing blok pungkasan sadurunge 4 byte iki ana saka 3 nganti 10 nol bit. Nanging, praktik wis nuduhake yen ana paling ora 10 nol bit.

Pranyata metu sing pamblokiran cendhak data biasane (tansah?) Dienkode nggunakake pemblokiran saka jinis 1 (blok tetep), kang kudu rampung karo 7 nul bit, menehi total 10-17 dijamin nul bit (lan liyane bakal dadi nol kanthi kemungkinan kira-kira 50%).

Dadi, ing data tes, ing 100% kasus ana siji bita nol sadurunge 0x00, 0x00, 0xff, 0xff, lan ing luwih saka sapratelone kasus ana rong bita nol (mbok menawa kasunyatane aku nggunakake binar CBOR, lan nalika nggunakake teks JSON, pamblokiran jinis 2 - pamblokiran dinamis bakal luwih umum, saben, pamblokiran tanpa bita nol tambahan sadurunge 0x00, 0x00, 0xff, 0xff bakal ditemoni).

Secara total, nggunakake data tes sing kasedhiya, bisa pas karo data sing dikompres kurang saka 250Kb.

Sampeyan bisa ngirit luwih sithik kanthi nindakake juggling: saiki kita ora nglirwakake sawetara nol bit ing mburi blok, sawetara bit ing wiwitan blok uga ora owah ...
Nanging banjur aku nggawe keputusan sing kuat kanggo mandheg, yen ora ing tingkat iki, aku bisa ngembangake arsipku dhewe.

Secara total, saka data tes, aku nampa 3-4 bita saben nulis, rasio kompresi dadi luwih saka 6: 1. Aku bakal jujur: Aku ora ngarep-arep asil kasebut; miturut pendapatku, apa wae sing luwih apik tinimbang 2: 1 wis dadi asil sing mbenerake panggunaan kompresi.

Kabeh iku apik, nanging zlib (deflate) isih algoritma komprèsi kuna, pantes lan rada lawas-gaya. Kasunyatan manawa 32Kb pungkasan saka aliran data sing ora dikompres digunakake minangka kamus katon aneh saiki (yaiku, yen sawetara blok data meh padha karo apa sing ana ing aliran input 40Kb kepungkur, mula bakal diarsipake maneh. lan ora bakal ngrujuk marang kedadeyan sadurunge). Ing arsip modern sing modis, ukuran kamus asring diukur ing megabyte tinimbang kilobyte.

Supaya kita nerusake sinau mini arsip.

Sabanjure kita nyoba bzip2 (eling, tanpa FLUSH nuduhake rasio kompresi sing apik banget meh 100: 1). Sayange, kinerjane kurang apik karo FLUSH; ukuran data sing dikompres dadi luwih gedhe tinimbang data sing ora dikompres.

Asumsiku babagan alasan kegagalan

Libbz2 nawakake mung siji pilihan flush, sing misale jek mbusak kamus (analog karo Z_FULL_FLUSH ing zlib); ora ana omongan babagan kompresi sing efektif sawise iki.

Lan sing pungkasan dites yaiku zstd. Gumantung ing paramèter, compresses salah siji ing tingkat gzip, nanging luwih cepet, utawa luwih apik tinimbang gzip.

Sayange, kanthi FLUSH ora nindakake kanthi apik: ukuran data sing dikompres kira-kira 700Kb.

Я takon pitakonan ing kaca github proyek, aku nampa jawaban yen sampeyan kudu ngetung nganti 10 bita data layanan kanggo saben blok data sing dikompres, sing cedhak karo asil sing dipikolehi; ora ana cara kanggo nggayuh deflate.

Aku mutusaké kanggo mungkasi ing titik iki ing nyobi karo archivers (ayo kula ngelingake sampeyan sing xz, lzip, lzo, lz4 ora nuduhake piyambak malah ing tataran testing tanpa FLUSH, lan aku ora nimbang algoritma komprèsi liyane endah).

Ayo bali menyang masalah arsip.

Kapindho (minangka padha ngandika ing urutan, ora ing Nilai) masalah iku data teken punika stream siji, kang ana terus-terusan referensi kanggo bagean sadurungé. Mangkono, yen bagean data sing dikompres rusak, kita bakal kelangan ora mung blok data sing ora dikompres, nanging uga kabeh sing sabanjure.

Ana pendekatan kanggo ngatasi masalah iki:

  1. Nyegah masalah saka kedadeyan - nambah redundansi menyang data sing dikompres, sing bakal ngidini sampeyan ngenali lan mbenerake kesalahan; kita bakal ngomong babagan iki mengko;
  2. Nyilikake akibat yen ana masalah
    Kita wis ujar sadurunge sampeyan bisa ngompres saben blok data kanthi mandiri, lan masalah kasebut bakal ilang dhewe (karusakan data siji blok bakal nyebabake ilang data mung kanggo blok iki). Nanging, iki minangka kasus sing ekstrem nalika kompresi data ora efektif. Ekstrem ngelawan: gunakake kabeh 4MB chip kita minangka arsip tunggal, sing bakal menehi kompresi sing apik banget, nanging akibate catastrophic ing kasus korupsi data.
    Ya, kompromi dibutuhake ing babagan linuwih. Nanging kita kudu elinga yen kita ngembangake format panyimpenan data kanggo memori non-molah malih kanthi BER sing sithik banget lan wektu panyimpenan data sing diumumake 20 taun.

Sajrone nyobi, aku katutup sing luwih utawa kurang ngelingke losses ing tingkat komprèsi wiwit ing pamblokiran data teken kurang saka 10 KB ing ukuran.
Sadurunge kasebut, memori sing digunakake yaiku paged; Aku ora weruh alesan kenapa korespondensi "siji kaca - siji blok data sing dikompresi" ora kudu digunakake.

Tegese, ukuran kaca sing cukup minimal yaiku 16Kb (kanthi cadangan kanggo informasi layanan). Nanging, ukuran kaca sing cilik iki ngetrapake watesan sing signifikan kanggo ukuran rekaman maksimal.

Senajan aku durung nyana cathetan luwih gedhe tinimbang sawetara kilobyte ing wangun teken, Aku mutusaké kanggo nggunakake kaca 32Kb (kanggo total 128 kaca saben chip).

Ringkesan:

  • Kita nyimpen data sing dikompres nggunakake zlib (deflate);
  • Kanggo saben entri kita nyetel Z_SYNC_FLUSH;
  • Kanggo saben rekaman sing dikompres, kita motong bita mburine (contone 0x00, 0x00, 0xff, 0xff); ing header kita nuduhake carane akeh bita kita Cut mati;
  • Kita nyimpen data ing kaca 32Kb; ana siji aliran data sing dikompres ing kaca; Ing saben kaca kita miwiti kompresi maneh.

Lan, sadurunge ngrampungake kompresi, aku pengin menehi perhatian marang kasunyatan manawa kita mung duwe sawetara bita data sing dikompresi saben rekaman, mula penting banget supaya ora nambah informasi layanan, saben bait diitung ing kene.

Nyimpen Header Data

Awit kita duwe rekaman dawa variabel, kita kudu nemtokake panggonan / wates rekaman.

Aku ngerti telung pendekatan:

  1. Kabeh cathetan disimpen ing stream terus-terusan, pisanan ana header rekaman ngemot dawa, lan banjur rekaman dhewe.
    Ing pawujudan iki, loro header lan data bisa dawa variabel.
    Ateges, kita entuk dhaptar sing disambung sing digunakake saben wektu;
  2. Header lan cathetan kasebut disimpen ing aliran sing kapisah.
    Kanthi nggunakake header kanthi dawa konstan, kita mesthekake yen karusakan ing siji header ora mengaruhi liyane.
    Pendekatan sing padha digunakake, contone, ing akeh sistem file;
  3. Cathetan disimpen ing stream terus-terusan, wates rekaman ditemtokake dening panandha tartamtu (karakter / urutan karakter sing dilarang ing blok data). Yen ana tandha ing rekaman kasebut, banjur diganti karo sawetara urutan (uwal).
    Pendekatan sing padha digunakake, contone, ing protokol PPP.

Aku bakal ilustrasi.

Opsi 1:
implementasine sandi ring buffer ing NOR lampu kilat
Kabeh iku prasaja banget: ngerti dawa rekaman, kita bisa ngetung alamat header sabanjuré. Dadi, kita pindhah menyang judhul nganti kita nemokake area sing diisi 0xff (area gratis) utawa pungkasan kaca.

Opsi 2:
implementasine sandi ring buffer ing NOR lampu kilat
Amarga dawa rekaman variabel, kita ora bisa ngomong sadurunge jumlah rekaman (lan mulane header) sing dibutuhake saben kaca. Sampeyan bisa nyebar header lan data dhewe ing kaca sing beda-beda, nanging aku luwih seneng pendekatan sing beda: kita nyelehake header lan data ing siji kaca, nanging header (ukuran konstan) teka saka wiwitan kaca, lan data (saka dawa variabel) teka saka mburi. Sanalika padha "ketemu" (ora cukup ruang kosong kanggo entri anyar), kita nganggep kaca iki wis rampung.

Opsi 3:
implementasine sandi ring buffer ing NOR lampu kilat
Ora perlu nyimpen dawa utawa informasi liyane babagan lokasi data ing header; panandha sing nuduhake wates cathetan wis cukup. Nanging, data kasebut kudu diolah nalika nulis / maca.
Aku bakal nggunakake 0xff minangka marker (sing ngisi kaca sawise mbusak), supaya wilayah free mesthi ora bakal dianggep minangka data.

Tabel perbandingan:

Opsi 1
Opsi 2
Opsi 3

Toleransi kesalahan
-
+
+

Compactness
+
-
+

Kompleksitas implementasine
*
**
**

Opsi 1 duwe cacat fatal: yen ana header sing rusak, kabeh chain sakteruse bakal rusak. Opsi sing isih ana ngidini sampeyan mbalekake sawetara data sanajan ana karusakan gedhe.
Nanging ing kene kudu dieling-eling yen kita mutusake kanggo nyimpen data ing wangun sing dikompres, lan kita bakal kelangan kabeh data ing kaca sawise rekaman "rusak", dadi sanajan ana minus ing tabel, kita ora njupuk menyang akun.

Kekompakan:

  • ing pilihan pisanan, kita kudu nyimpen mung dawa ing header, yen kita nggunakake variabel-dawa integer, banjur ing paling kasus kita bisa njaluk dening siji bait;
  • ing pilihan kapindho kita kudu nyimpen alamat wiwitan lan dawa; rekaman kudu ukuran pancet, Aku ngira 4 bait saben rekaman (rong bait kanggo nutup kerugian, lan loro bita kanggo dawa);
  • pilihan katelu mung perlu siji karakter kanggo nunjukaké wiwitan rekaman, plus rekaman dhewe bakal nambah dening 1-2% amarga shielding. Umumé, kira-kira paritas karo pilihan pisanan.

Kaping pisanan, aku nganggep pilihan kapindho minangka sing utama (malah nulis implementasine). Aku nilar mung nalika pungkasanipun mutusaké kanggo nggunakake komprèsi.

Mbok ing sawijining dina aku isih bakal nggunakake opsi sing padha. Contone, yen aku kudu ngatasi panyimpenan data kanggo kapal sing lelungan antarane Bumi lan Mars, bakal ana syarat sing beda banget kanggo linuwih, radiasi kosmik, ...

Minangka kanggo pilihan katelu: Aku menehi lintang loro kanggo kangelan implementasine mung amarga aku ora seneng kekacoan karo shielding, ngganti dawa ing proses, etc. Ya, mbok menawa aku bias, nanging aku kudu nulis kode - kenapa meksa nindakake perkara sing ora disenengi.

Ringkesan: Kita milih opsi panyimpenan ing wangun ranté "header karo dawa - data dawa variabel" amarga efisiensi lan ease saka implementasine.

Nggunakake Bidang Bit kanggo Ngawasi Sukses Operasi Tulis

Aku ora ngelingi saiki aku entuk ide, nanging katon kaya iki:
Kanggo saben entri, kita nyedhiyakake sawetara bit kanggo nyimpen panji.
Kita ngandika sadurungé, sawise mbusak kabeh bit kapenuhan 1s, lan kita bisa ngganti 1 kanggo 0, nanging ora kosok balene. Dadi kanggo "gendera ora disetel" kita nggunakake 1, kanggo "gendera disetel" kita nggunakake 0.

Mangkene carane nggawe rekaman dawa variabel dadi lampu kilat:

  1. Setel gendera "rekaman dawa wis diwiwiti";
  2. Rekam dawa;
  3. Setel gendera "rekaman data wis diwiwiti";
  4. Kita ngrekam data;
  5. Setel gendera "rekaman rampung".

Kajaba iku, kita bakal duwe "kesalahan kedaden" flag, kanggo total 4 panji dicokot.

Ing kasus iki, kita duwe rong negara stabil "1111" - rekaman durung diwiwiti lan "1000" - rekaman sukses; yen ana gangguan sing ora dikarepake ing proses rekaman, kita bakal nampa negara penengah, sing banjur bisa dideteksi lan diproses.

Pendekatan iki menarik, nanging mung ngreksa marang outages daya dadakan lan gagal padha, kang, mesthi, penting, nanging iki adoh saka mung (utawa malah utama) alesan kanggo bisa gagal.

Ringkesan: Ayo pindhah menyang nggoleki solusi sing apik.

Checksums

Checksums uga bisa kanggo mesthekake (kanthi kemungkinan cukup) sing kita maca persis apa sing kudu wis ditulis. Lan, ora kaya lapangan bit sing dibahas ing ndhuwur, mesthine bisa digunakake.

Yen kita nimbang dhaptar sumber potensial masalah sing kita rembugan ing ndhuwur, checksum bisa ngenali kesalahan preduli saka asal. (kajaba, mbok menawa, kanggo alien angkoro - padha uga bisa nggawe checksum).

Dadi yen tujuane kanggo verifikasi manawa data kasebut utuh, checksum minangka ide sing apik.

Pilihan algoritma kanggo ngitung checksum ora nuwuhake pitakonan - CRC. Ing tangan siji, sifat matématika ngidini kanggo nyekel jinis-jinis kesalahan tartamtu 100%; ing tangan liyane, ing data acak algoritma iki biasane nuduhake kemungkinan tabrakan ora luwih saka watesan teoritis. implementasine sandi ring buffer ing NOR lampu kilat. Bisa uga dudu algoritma sing paling cepet, utawa ora mesthi minimal babagan jumlah tabrakan, nanging nduweni kualitas sing penting banget: ing tes sing ditemoni, ora ana pola sing jelas gagal. Stabilitas minangka kualitas utama ing kasus iki.

Tuladha studi volumetrik: bagean 1, bagean 2 (pranala menyang narod.ru, nuwun sewu).

Nanging, tugas milih checksum durung rampung; CRC minangka kulawarga checksum kabeh. Sampeyan kudu mutusake dawane, banjur pilih polinomial.

Milih dawa checksum ora dadi pitakonan sing gampang kaya sing katon sepisanan.

Ayo kula ilustrasi:
Ayo kita duwe kemungkinan kesalahan ing saben bait implementasine sandi ring buffer ing NOR lampu kilat lan checksum becik, ayo ngetung jumlah rata-rata kesalahan saben yuta cathetan:

Data, byte
Checksum, byte
Kesalahan sing ora dideteksi
Deteksi kesalahan palsu
Total positif palsu

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

Kayane kabeh gampang - gumantung saka dawa data sing dilindhungi, pilih dawa checksum kanthi positip sing ora bener - lan trik kasebut ana ing tas.

Nanging, ana masalah karo checksums singkat: sanajan padha apik ing ndeteksi kesalahan bit siji, padha bisa kanthi kemungkinan cukup dhuwur nampa data rampung acak minangka bener. Wis ana artikel babagan Habré sing nerangake masalah ing urip nyata.

Mulane, kanggo nggawe match checksum acak meh mokal, sampeyan kudu nggunakake checksums sing 32 bit utawa luwih dawa. (kanggo dawa luwih saka 64 bit, fungsi hash kriptografi biasane digunakake).

Senadyan kasunyatan sing aku wrote sadurungé kita kudu ngirit papan kanthi cara apa wae, kita isih bakal nggunakake checksum 32-bit (16 bit ora cukup, kemungkinan tabrakan luwih saka 0.01%; lan 24 bit, amarga padha. ngomong, ora ana kene ora ana).

Ana bantahan ing kene: apa kita nyimpen saben bait nalika milih kompresi supaya saiki menehi 4 bait sekaligus? Apa ora luwih becik ora ngompres utawa nambah checksum? Mesthi ora, ora komprèsi ora ateges, sing kita ora perlu mriksa integritas.

Nalika milih polinomial, kita ora bakal reinvent setir, nanging njupuk saiki populer CRC-32C.
Kode iki ndeteksi kesalahan 6 bit ing paket nganti 22 bait (mbok menawa kasus paling umum kanggo kita), kesalahan 4 bit ing paket nganti 655 bait (uga kasus umum kanggo kita), 2 utawa kesalahan bit sing ganjil ing paket. saka sembarang dawa cukup.

Yen ana sing kasengsem ing rincian

Artikel Wikipedia babagan CRC.

Paramèter kode crc-32c ing situs web Koopman - mbok menawa spesialis CRC anjog ing planet.

В artikelipun ana kode liyane menarik, sing nyedhiyakake paramèter sing luwih apik kanggo dawa paket sing cocog karo kita, nanging aku ora nganggep prabédan sing signifikan, lan aku cukup kompeten kanggo milih kode khusus tinimbang sing standar lan diteliti kanthi apik.

Uga, amarga data kita dikompres, pitakonan muncul: apa kita kudu ngetung checksum data sing dikompres utawa ora dikompres?

Argumen kanggo ngitung checksum data sing ora dikompres:

  • We wekasanipun kudu mriksa safety saka panyimpenan data - supaya kita mriksa langsung (ing wektu sing padha, bisa kasalahan ing implementasine saka komprèsi / decompression, karusakan disebabake memori rusak, etc. bakal dicenthang);
  • Algoritma deflate ing zlib nduweni implementasine cukup diwasa lan kudune ora tiba karo data input "bengkong"; Kajaba iku, asring bisa ndeteksi kesalahan ing aliran input kanthi mandiri, nyuda kemungkinan sakabèhé ora bisa dideteksi kesalahan (nglakoni tes kanthi ngowahi siji bit ing rekaman cendhak, zlib ndeteksi kesalahan ing babagan katelu saka kasus).

Argumen nglawan ngitung checksum data sing ora dikompres:

  • CRC wis "ngatur" khusus kanggo sawetara kasalahan dicokot sing karakteristik saka memori lampu kilat (kesalahan dicokot ing stream teken bisa nimbulaké owah-owahan massive ing stream output, kang sejatine sifate teoritis, kita bisa "nyekel" tabrakan);
  • Aku ora seneng ide ngirim data sing bisa rusak menyang decompressor, Sapa ngerticarane dheweke bakal nanggepi.

Ing proyek iki, aku mutusake kanggo nyimpang saka praktik sing ditampa umum kanggo nyimpen checksum data sing ora dikompres.

Ringkesan: Kita nggunakake CRC-32C, kita ngetung checksum saka data ing wangun kang padha ditulis kanggo lampu kilat (sawise komprèsi).

Redundansi

Panggunaan coding keluwih ora, mesthi, ngilangi mundhut data, Nanging, iku bisa Ngartekno (asring dening akeh pesenan saka gedhene) nyuda kamungkinan mundhut data irrecoverable.

Kita bisa nggunakake macem-macem jinis redundansi kanggo mbenerake kesalahan.
Kode Hamming bisa mbenerake kesalahan siji bit, kode karakter Reed-Solomon, sawetara salinan data sing digabungake karo checksums, utawa enkoding kaya RAID-6 bisa mbantu mbalekake data sanajan ana korupsi gedhe.
Kaping pisanan, aku setya nggunakake coding tahan kesalahan sing nyebar, nanging banjur aku ngerti manawa kita kudu duwe ide babagan kesalahan apa sing arep kita lindungi, banjur pilih coding.

Kita ujar sadurunge yen kesalahan kudu dicekel kanthi cepet. Ing titik apa kita bisa nemoni kesalahan?

  1. Rekaman sing durung rampung (mergo sawetara alesan nalika ngrekam daya dipateni, Raspberry beku, ...)
    Sayange, yen ana kesalahan kasebut, kabeh sing isih ana yaiku nglirwakake cathetan sing ora bener lan nimbang data sing ilang;
  2. Kesalahan nulis (saperangan alesan, apa sing ditulis ing memori lampu kilat dudu sing ditulis)
    Kita bisa langsung ndeteksi kesalahan kasebut yen kita nindakake tes maca sanalika sawise ngrekam;
  3. Distorsi data ing memori sajrone panyimpenan;
  4. Kesalahan maca
    Kanggo mbenerake, yen checksum ora cocog, cukup kanggo mbaleni maca kaping pirang-pirang.

Tegese, mung kesalahan saka jinis katelu (korupsi spontan data sajrone panyimpenan) ora bisa didandani tanpa kode tahan kesalahan. Iku misale jek sing kasalahan kuwi isih arang banget kamungkinan.

Ringkesan: diputusake kanggo nglirwakake coding keluwih, nanging yen operasi nuduhake kesalahan keputusan iki, banjur bali menyang pertimbangan masalah kasebut (kanthi statistik akumulasi gagal, sing bakal ngidini milih jinis coding sing optimal).

Liyane

Mesthine, format artikel ora ngidini kita mbenerake saben bit ing format kasebut (lan kekuatanku wis entek), mula aku bakal ngrembug babagan sawetara poin sing durung disentuh sadurunge.

  • Diputusake kanggo nggawe kabeh kaca "padha"
    Tegese, ora bakal ana kaca khusus kanthi metadata, utas sing kapisah, lan liya-liyane, nanging siji-sijine thread sing nulis ulang kabeh kaca.
    Iki njamin malah nyandhang ing kaca, ora titik siji saka Gagal, lan aku mung seneng;
  • Iku penting kanggo nyedhiyani versi format.
    Format tanpa nomer versi ing header iku ala!
    Cukup kanggo nambah lapangan kanthi Nomer Piandel (tandha) tartamtu menyang header kaca, sing bakal nuduhake versi format sing digunakake (Aku ora mikir yen ing praktik bakal ana puluhan wong);
  • Gunakake header variabel-dawa kanggo cathetan (sing ana akeh), nyoba kanggo nggawe 1 byte dawa ing paling kasus;
  • Kanggo ngodhe dawa header lan dawa bagean sing dipotong saka rekaman sing dikompres, gunakake kode binar dawa variabel.

Mbantu banget generator online Kode Huffman. Mung sawetara menit kita bisa milih kode dawa variabel sing dibutuhake.

Katrangan format panyimpenan data

Urutan byte

Bidang sing luwih gedhe saka siji bait disimpen ing format big-endian (urutan byte jaringan), yaiku, 0x1234 ditulis minangka 0x12, 0x34.

Pagination

Kabeh memori lampu kilat dipérang dadi kaca kanthi ukuran sing padha.

Ukuran kaca standar yaiku 32Kb, nanging ora luwih saka 1/4 saka ukuran total chip memori (kanggo chip 4MB, 128 kaca dijupuk).

Saben kaca nyimpen data kanthi bebas saka liyane (yaiku, data ing sawijining kaca ora ngrujuk data ing kaca liya).

Kabeh kaca diwenehi nomer kanthi urutan alami (ing urutan munggah alamat), diwiwiti kanthi nomer 0 (kaca nol diwiwiti ing alamat 0, kaca pisanan diwiwiti kanthi 32Kb, kaca kapindho diwiwiti kanthi 64Kb, lsp.)

Chip memori digunakake minangka buffer siklik (ring buffer), yaiku, nulis pisanan menyang kaca nomer 0, banjur nomer 1, ..., nalika kita ngisi kaca pungkasan, siklus anyar diwiwiti lan rekaman terus saka kaca nol. .

Nang kaca

implementasine sandi ring buffer ing NOR lampu kilat
Ing wiwitan kaca, header kaca 4-byte disimpen, banjur checksum header (CRC-32C), banjur cathetan disimpen ing format "header, data, checksum".

Judhul kaca (ijo reged ing diagram) kalebu:

  • kolom Magic Number rong bait (uga minangka tandha versi format)
    kanggo versi saiki format diwilang minangka 0xed00 ⊕ номер страницы;
  • loro-bait counter "Versi kaca" (memori nulis ulang nomer siklus).

Entri ing kaca disimpen ing wangun kompres (algoritma deflate digunakake). Kabeh cathetan ing siji kaca dikompres ing siji thread (kamus umum digunakake), lan ing saben komprèsi kaca anyar wiwit anew. Sing, kanggo decompress sembarang rekaman, kabeh cathetan sadurungé saka kaca iki (lan mung siji iki) dibutuhake.

Saben rekaman bakal dikompres nganggo gendera Z_SYNC_FLUSH, lan ing pungkasan stream sing dikompres bakal ana 4 bait 0x00, 0x00, 0xff, 0xff, bisa uga didhisiki siji utawa rong bita nol maneh.
We discard urutan iki (4, 5 utawa 6 bait dawa) nalika nulis kanggo flash memori.

Header rekaman yaiku nyimpen 1, 2 utawa 3 bita:

  • siji bit (T) nuduhake jinis rekaman: 0 - konteks, 1 - log;
  • kolom dawa variabel (S) saka 1 nganti 7 bit, nemtokake dawa header lan "buntut" sing kudu ditambahake menyang rekaman kanggo dekompresi;
  • dawa rekaman (L).

Tabel Nilai S:

S
Dawane header, bita
Dibuwang ing nulis, byte

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)

Aku nyoba kanggo ilustrasi, aku ora ngerti carane cetha dadi:
implementasine sandi ring buffer ing NOR lampu kilat
Kuning ing kene nuduhake lapangan T, putih lapangan S, ijo L (dawa data sing dikompres ing bita), biru data sing dikompres, abang bita pungkasan saka data sing dikompres sing ora ditulis ing memori flash.

Mangkono, kita bisa nulis header rekaman kanthi dawa sing paling umum (nganti 63 + 5 bait ing wangun kompres) ing siji bait.

Sawise saben rekaman, checksum CRC-32C disimpen, ing ngendi nilai terbalik saka checksum sadurunge digunakake minangka nilai awal (init).

CRC nduweni sifat "durasi", rumus ing ngisor iki bisa digunakake (plus utawa minus inversi bit ing proses kasebut): implementasine sandi ring buffer ing NOR lampu kilat.
Yaiku, nyatane, kita ngetung CRC kabeh byte header lan data sadurunge ing kaca iki.

Langsung ngetutake checksum yaiku header rekaman sabanjure.

Header dirancang kanthi cara sing bait pisanane tansah beda karo 0x00 lan 0xff (yen tinimbang bait pisanan saka header kita nemoni 0xff, tegese iki minangka area sing ora digunakake; 0x00 menehi sinyal kesalahan).

Tuladha Algoritma

Maca saka Flash Memory

Sembarang maca teka karo mriksa checksum.
Yen checksum ora cocog, wacan kasebut diulang kaping pirang-pirang kanthi pangarep-arep bisa maca data sing bener.

(iki nggawe akal, Linux ora cache maca saka NOR Flash, dites)

Tulis menyang memori flash

Kita ngrekam data.
Ayo padha maca.

Yen data sing diwaca ora cocog karo data sing ditulis, kita ngisi area kasebut kanthi nul lan menehi tandha kesalahan.

Nyiyapake microcircuit anyar kanggo operasi

Kanggo inisialisasi, header kanthi versi 1 ditulis ing kaca pisanan (utawa nol).
Sawise iku, konteks awal ditulis ing kaca iki (ngemot UUID mesin lan setelan gawan).

Mekaten, memori lampu kilat siap digunakake.

Loading mesin

Nalika mbukak, 8 bait pisanan saben kaca (header + CRC) diwaca, kaca sing nomer Piandel sing ora dingerteni utawa CRC sing salah ora digatekake.
Saka kaca "bener", kaca kanthi versi maksimum dipilih, lan kaca kanthi jumlah paling dhuwur dijupuk saka kaca kasebut.
Cathetan pisanan diwaca, kabeneran CRC lan anané gendera "konteks" dicenthang. Yen kabeh apik, kaca iki dianggep saiki. Yen ora, kita bali menyang sing sadurunge nganti kita nemokake kaca "urip".
lan ing kaca sing ditemokake, kita maca kabeh cathetan, sing digunakake karo gendera "konteks".
Simpen kamus zlib (bakal dibutuhake kanggo nambah menyang kaca iki).

Mekaten, download rampung, konteks dibalekake, sampeyan bisa kerja.

Nambahake Entri Jurnal

Kita ngompres rekaman nganggo kamus sing bener, nemtokake Z_SYNC_FLUSH. Kita ndeleng manawa rekaman sing dikompres cocog karo kaca saiki.
Yen ora pas (utawa ana kesalahan CRC ing kaca), miwiti kaca anyar (ndeleng ngisor).
Kita nulis rekaman lan CRC. Yen ana kesalahan, miwiti kaca anyar.

Kaca anyar

Kita milih kaca gratis kanthi jumlah minimal (kita nganggep kaca gratis minangka kaca kanthi checksum sing salah ing header utawa kanthi versi kurang saka sing saiki). Yen ora ana kaca kasebut, pilih kaca kanthi jumlah minimal saka kaca sing duwe versi sing padha karo sing saiki.
Kita mbusak kaca sing dipilih. Kita mriksa isi karo 0xff. Yen ana sing salah, njupuk kaca gratis sabanjure, lsp.
Kita nulis header ing kaca sing wis dibusak, entri pisanan minangka kahanan konteks saiki, sabanjure yaiku entri log sing ora ditulis (yen ana).

Aplikasi format

Ing mratelakake panemume, iku dadi format apik kanggo nyimpen liyane utawa kurang compressible lepen informasi (teks biasa, JSON, MessagePack, CBOR, bisa uga protobuf) ing NOR Flash.

Mesthine, format kasebut "disesuaikan" kanggo SLC NOR Flash.

Sampeyan ngirim ora digunakake karo media BER dhuwur kayata NAND utawa MLC NOR (Memori kuwi malah kasedhiya kanggo Advertisement? Aku wis mung katon kasebut ing karya ing kode koreksi).

Kajaba iku, ora bisa digunakake karo piranti sing duwe FTL dhewe: USB flash, SD, MicroSD, lsp (kanggo memori kasebut, aku nggawe format kanthi ukuran kaca 512 bait, teken ing wiwitan saben kaca lan nomer rekaman unik - kadhangkala bisa mbalekake kabeh data saka flash drive "glitched" kanthi maca urutan sing prasaja).

Gumantung ing tugas, format bisa digunakake tanpa owah-owahan ing flash drive saka 128Kbit (16Kb) dadi 1Gbit (128MB). Yen dikarepake, sampeyan bisa nggunakake ing Kripik luwih gedhe, nanging sampeyan mbokmenawa kudu nyetel ukuran kaca (Nanging ing kene pitakonan babagan kelayakan ekonomi wis muncul; rega kanggo NOR Flash volume gedhe ora nyemangati).

Yen ana wong sing nemokake format kasebut menarik lan pengin digunakake ing proyek sing mbukak, tulis, aku bakal nyoba golek wektu, polish kode lan ngirim ing github.

kesimpulan

Minangka sampeyan bisa ndeleng, ing pungkasan format dadi prasaja lan malah mboseni.

Pancen angel nggambarake evolusi sudut pandangku ing sawijining artikel, nanging pracaya marang aku: wiwitane aku pengin nggawe sing canggih, ora bisa dirusak, bisa urip sanajan ledakan nuklir ing jarak sing cedhak. Nanging, alesan (mugi-mugi) isih menang lan mboko sithik prioritas pindhah menyang gamblang lan compactness.

Apa aku salah? Iya tenanan. Bisa uga, umpamane, kita tuku pirang-pirang microcircuits kualitas rendah. Utawa kanggo sawetara alesan liyane peralatan ora bakal ketemu pangarepan linuwih.

Apa aku duwe rencana iki? Aku sing sawise maca artikel sampeyan ora mangu sing ana rencana. Lan ora malah piyambak.

Ing cathetan sing rada serius, format kasebut dikembangake minangka pilihan sing bisa digunakake lan minangka "balon uji coba".

Ing wayahe kabeh ing meja bisa digunakake kanthi becik, ing dina liyane solusi kasebut bakal disebarake (kira-kira) ing atusan piranti, ayo ndeleng apa sing kedadeyan ing operasi "pertempuran" (muga-muga format kasebut ngidini sampeyan ndeteksi kegagalan kanthi andal; supaya sampeyan bisa ngumpulake statistik lengkap). Ing sawetara sasi bakal bisa nggawe kesimpulan (lan yen sampeyan ora beruntung, malah luwih dhisik).

Yen adhedhasar asil panggunaan, masalah serius ditemokake lan perbaikan dibutuhake, mula aku bakal nulis babagan iki.

Sastra

Aku ora pengin nggawe dhaptar karya sing digunakake; sawise kabeh, kabeh wong duwe Google.

Ing kene aku mutusake ninggalake dhaptar temuan sing katon menarik banget kanggo aku, nanging mboko sithik dheweke langsung pindhah menyang teks artikel, lan siji item tetep ana ing dhaptar:

  1. Utilitas infgen saka penulis zlib. Bisa nampilake kanthi jelas isi arsip deflate/zlib/gzip. Yen sampeyan kudu ngatasi struktur internal format deflate (utawa gzip), aku menehi saran banget.

Source: www.habr.com

Add a comment