{"id":53751,"date":"2019-12-09T00:00:00","date_gmt":"2019-12-08T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash"},"modified":"2020-02-18T14:01:41","modified_gmt":"2020-02-18T11:01:41","slug":"moya-realizatsiya-koltsevogo-bufera-v-nor-flash","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash","title":{"rendered":"Implementimi im i buffers ring n\u00eb NOR flash","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"predystoriya\">Pas historia<\/h1>\n<p><\/p>\n<p>Ka jan\u00eb automate tregtare t\u00eb zhvilluar vet\u00eb. Brenda ka Raspberry Pi dhe pak lidhje n\u00eb nj\u00eb pllak\u00eb t\u00eb ve\u00e7ant\u00eb. Jan\u00eb t\u00eb lidhura nj\u00eb pranues monedhash, nj\u00eb pranues bankar, nj\u00eb terminal bankar... T\u00eb gjitha kontrollohen nga nj\u00eb program t\u00eb shkruar vet\u00eb. Historia e plot\u00eb e pun\u00ebs regjistrohet n\u00eb nj\u00eb ditar n\u00eb nj\u00eb flash drive (MicroSD), i cili pastaj transferohet p\u00ebrmes internetit (n\u00ebp\u00ebrmjet nj\u00eb modemi USB) n\u00eb nj\u00eb server ku ruhet n\u00eb nj\u00eb database. Informacioni p\u00ebr shitjet ngarkohet n\u00eb 1C, gjithashtu ka nj\u00eb nd\u00ebrfaqe t\u00eb thjesht\u00eb n\u00eb web p\u00ebr monitorim etj. <\/p>\n<p><\/p>\n<p>Pra, ditari \u00ebsht\u00eb jetik \u2014 p\u00ebr llogaritje (aty ka t\u00eb ardhurat, shitjet etj.), monitorim (t\u00eb gjith\u00eb defektet e mundshme dhe rrethana t\u00eb tjera t\u00eb paparashikuara); mund t\u00eb thuhet se kjo \u00ebsht\u00eb e gjitha informacioni q\u00eb ne kemi p\u00ebr k\u00ebt\u00eb automat. <\/p>\n<p><\/p>\n<h1 id=\"problema\">Problemi<\/h1>\n<p><\/p>\n<p>Flash drive-t tregohen si disqe shum\u00eb t\u00eb pasigurt. Ato d\u00ebshtojn\u00eb me nj\u00eb rregullshm\u00ebri t\u00eb admirueshme. Kjo \u00e7on si n\u00eb pezullimin e automateve, ashtu edhe (n\u00ebse p\u00ebr ndonj\u00eb arsye ditari nuk mund t\u00eb d\u00ebrgohet online) n\u00eb humbjen e t\u00eb dh\u00ebnave.<\/p>\n<p><\/p>\n<p><em>Kjo nuk \u00ebsht\u00eb hera e par\u00eb q\u00eb p\u00ebrdorim flash drive, m\u00eb par\u00eb kemi pasur nj\u00eb projekt tjet\u00ebr me m\u00eb shum\u00eb se nj\u00ebqind pajisje, ku ditari ruhej n\u00eb flash drive USB, aty gjithashtu ishin probleme me besueshm\u00ebrin\u00eb, her\u00eb pas here numri i pajisjeve t\u00eb prishura arrinte disa dhjet\u00ebra. Provuam flash drive t\u00eb ndrysh\u00ebm, p\u00ebrfshir\u00eb ato t\u00eb markave me memorie SLC, disa modele ishin m\u00eb t\u00eb besueshme se t\u00eb tjera, por z\u00ebvend\u00ebsimi i flash drive-ve nuk e zgjidhi problemin n\u00eb m\u00ebnyr\u00eb radikale.<\/em><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <\/p>\n<p><strong>Kujdes!<\/strong> Longread! If you are not interested in 'why', but only in 'how', you can go straight to it. <noindex><a rel=\"nofollow\" href=\"#format\">n\u00eb fund<\/a><\/noindex> t\u00eb artikullit.<\/p>\n<p><\/p>\n<h1 id=\"reshenie\">Zgjidhja<\/h1>\n<p><\/p>\n<p>E para q\u00eb m\u00eb vije n\u00eb mendje: t\u00eb heqim dor\u00eb nga MicroSD, t\u00eb vendosim, p\u00ebr shembull, SSD dhe t\u00eb startojm\u00eb nga ai. Teorikisht \u00ebsht\u00eb e mundur, ndoshta, por relativisht e shtrenjt\u00eb, dhe as nuk \u00ebsht\u00eb aq e besueshme (shtohet nj\u00eb adapter USB-SATA; p\u00ebr SSD t\u00eb lira statistikat e d\u00ebshtimeve gjithashtu nuk jan\u00eb inkurajuese).<\/p>\n<p><\/p>\n<p>USB HDD gjithashtu nuk duket si nj\u00eb zgjidhje t\u00ebrheq\u00ebse.<\/p>\n<p><\/p>\n<p>Prandaj erdh\u00ebm n\u00eb k\u00ebt\u00eb variant: l\u00ebvizni me MicroSD, por t\u2019i p\u00ebrdorim ato n\u00eb m\u00ebnyr\u00eb read-only, dhe t\u00eb ruajm\u00eb ditarin e pun\u00ebs (dhe informacione t\u00eb tjera unike p\u00ebr pajisjen specifike \u2014 numri serial, kalibrimet e sensor\u00ebve, etj.) diku tjet\u00ebr. <\/p>\n<p><\/p>\n<p>Tematika e sistemit t\u00eb skedave read-only p\u00ebr Raspberry Pi \u00ebsht\u00eb studiuar p\u00ebr s\u00eb mbari, nuk do t\u00eb ndalem n\u00eb detajet e realizimit n\u00eb k\u00ebt\u00eb artikull. <em>(por n\u00ebse ka interes \u2014 ndoshta do t\u00eb shkruaj nj\u00eb mini-artikull mbi k\u00ebt\u00eb tem\u00eb)<\/em>. Nj\u00eb moment i vet\u00ebm q\u00eb duam t\u00eb theksojm\u00eb: si nga p\u00ebrvoja personale, ashtu edhe nga feedback-u i atyre q\u00eb e kan\u00eb zbatuar, ka nj\u00eb fitim n\u00eb besueshm\u00ebri. Po, nuk mund t\u00eb eliminohemi plot\u00ebsisht nga defektet, megjithat\u00eb reduktimi i frekuenc\u00ebs s\u00eb tyre \u00ebsht\u00eb plot\u00ebsisht i realizuesh\u00ebm. Dhe gjithashtu kartat b\u00ebhen t\u00eb unifikuara, q\u00eb e thjeshtojn\u00eb ndjesh\u00ebm z\u00ebvend\u00ebsimin p\u00ebr personelin mb\u00ebshtet\u00ebs.<\/p>\n<p><\/p>\n<h2 id=\"apparatnaya-chast\">Pjesa hardware<\/h2>\n<p><\/p>\n<p>Nuk kishte dyshime t\u00eb m\u00ebdha p\u00ebr tipusin e memories \u2014 NOR Flash.<br \/>\nArgumentet: <\/p>\n<p><\/p>\n<ul>\n<li>Simple connection (most often an SPI bus, which we already have experience with, so 'hardware' issues are not foreseen);<\/li>\n<li>\u00e7mim i qeshur;<\/li>\n<li>protokolli standard i pun\u00ebs (implementimi \u00ebsht\u00eb tashm\u00eb n\u00eb b\u00ebrtham\u00ebn e Linux, n\u00ebse d\u00ebshiron, mund t\u00eb marr\u00ebsh nj\u00eb pal\u00eb t\u00eb jashtme, q\u00eb gjithashtu jan\u00eb t\u00eb pranishme, ose madje t\u00eb shkruash t\u00eb tuaj\u00ebn, pasi gjith\u00e7ka \u00ebsht\u00eb e thjesht\u00eb);<\/li>\n<li>besueshm\u00ebria dhe burimi:<br \/>\nnga fleta e t\u00eb dh\u00ebnave tipike: t\u00eb dh\u00ebnat ruhen p\u00ebr 20 vjet, 100000 cikle fshirje p\u00ebr secil\u00ebn bllok;<br \/>\nnga burime t\u00eb jashtme: BER shum\u00eb i ul\u00ebt, postulon se nuk \u00ebsht\u00eb e nevojshme p\u00ebr kodet e korrigjimit t\u00eb gabimeve <em>(n\u00eb disa punime shqyrtohet ECC p\u00ebr NOR, por zakonisht aty ku merret n\u00eb konsiderat\u00eb MLC NOR, ndodh edhe kjo)<\/em>.<\/li>\n<\/ul>\n<p><\/p>\n<p>Le ta llogarisim k\u00ebrkesat p\u00ebr v\u00ebllimin dhe burimin.<\/p>\n<p><\/p>\n<p>D\u00ebshirojm\u00eb q\u00eb t\u00eb dh\u00ebnat t\u00eb ruajten garantuar p\u00ebr disa dit\u00eb. Kjo \u00ebsht\u00eb e nevojshme n\u00eb m\u00ebnyr\u00eb q\u00eb n\u00eb rast t\u00eb ndonj\u00eb problemi me lidhjen, historia e shitjeve t\u00eb mos humbas\u00eb. Do t\u00eb orientoheni p\u00ebr 5 dit\u00eb, p\u00ebr k\u00ebt\u00eb periudh\u00eb <em>(madje duke marr\u00eb parasysh fundjav\u00ebt dhe festat)<\/em> mund t\u00eb zgjidhet problemi.<\/p>\n<p><\/p>\n<p>Tani p\u00ebr tani mbledhim rreth 100 KB ditarin (3-4 mij\u00eb regjistrime) p\u00ebr dit\u00eb, por gradualisht ky num\u00ebr po rritet \u2014 po rritet detajizimi, po shtohen ngjarje t\u00eb reja. P\u00ebr m\u00eb tep\u00ebr, ndonj\u00ebher\u00eb ka pik\u00eb t\u00eb papritura (ndonj\u00eb sensor fillon t\u00eb d\u00ebrgoj\u00eb alarmet e rreme, p\u00ebr shembull). Do t\u00eb llogarisim p\u00ebr 10 mij\u00eb regjistrime me 100 byte \u2014 nj\u00eb megabajt n\u00eb dit\u00eb.<\/p>\n<p><\/p>\n<p>Pra, gjithsej del 5 MB t\u00eb dh\u00ebnash t\u00eb past\u00ebr (t\u00eb kompresueshme) . K\u00ebtyre i shtohet <em>(vler\u00ebsim i qart\u00eb)<\/em> 1 MB t\u00eb dh\u00ebna sh\u00ebrbimi.<\/p>\n<p><\/p>\n<p>Kjo do t\u00eb thot\u00eb se na nevojitet nj\u00eb mikro\u00e7ip prej 8 MB n\u00ebse nuk p\u00ebrdorim kompresimin, ose 4 MB n\u00ebse p\u00ebrdorim. Numra t\u00eb realizuesh\u00ebm p\u00ebr k\u00ebt\u00eb tip memorjeje.<\/p>\n<p><\/p>\n<p>Sa i p\u00ebrket burimit: n\u00ebse ne e planifikojm\u00eb q\u00eb memorja t\u00eb riprogramohet t\u00ebr\u00eb her\u00eb m\u00eb pak se nj\u00eb her\u00eb n\u00eb 5 dit\u00eb, at\u00ebher\u00eb p\u00ebr 10 vjet sh\u00ebrbimi ne marrim m\u00eb pak se nj\u00eb mij\u00eb cikle riprogramimi.<br \/>\nT\u00eb kujtoj, prodhuesi premton nj\u00ebqind mij\u00eb.<\/p>\n<p>\n<b class=\"spoiler_title\">Nj\u00eb pak p\u00ebr NOR vs NAND<\/b><\/p>\n<p>Sotiria, padyshim, \u00ebsht\u00eb m\u00eb e njohur memori NAND, por p\u00ebr k\u00ebt\u00eb projekt nuk do ta p\u00ebrdorja: NAND, n\u00eb krahasim me NOR, patjet\u00ebr k\u00ebrkon p\u00ebrdorimin e kod\u00ebve p\u00ebr korrigjimin e gabimeve, tabelave t\u00eb bllokave me gabime etj., dhe zakonisht ka m\u00eb shum\u00eb pin\u00eb.<\/p>\n<p><\/p>\n<p>Si disavantazhe t\u00eb NOR mund t\u00eb p\u00ebrmenden:<\/p>\n<p><\/p>\n<ul>\n<li>kapacitet i vog\u00ebl (dhe, p\u00ebr rrjedhoj\u00eb, \u00e7mimi i lart\u00eb p\u00ebr megabajt);<\/li>\n<li>shpejt\u00ebsi e ul\u00ebt e transferimit (n\u00eb shum\u00eb m\u00ebnyra p\u00ebr shkak se p\u00ebrdoret nj\u00eb nd\u00ebrfaqe seriale, zakonisht SPI ose I2C);<\/li>\n<li>fshirje e ngadalt\u00eb (var\u00ebsisht nga madh\u00ebsia e bllokut, merr nga pjes\u00eb t\u00eb sekond\u00ebs deri n\u00eb disa sekonda).<\/li>\n<\/ul>\n<p><\/p>\n<p>Nuk duket se ka di\u00e7ka kritike p\u00ebr ne, k\u00ebshtu q\u00eb vazhdojm\u00eb.<\/p>\n<p><\/p>\n<p>N\u00ebse jeni t\u00eb interesuar p\u00ebr detajet, \u00ebsht\u00eb zgjedhur \u00e7ipi <noindex><a rel=\"nofollow\" href=\"https:\/\/www.adestotech.com\/wp-content\/uploads\/doc3686.pdf\">at25df321a<\/a><\/noindex> <em>(megjithat\u00eb, kjo nuk \u00ebsht\u00eb thelb\u00ebsore, n\u00eb treg ka shum\u00eb analoge, t\u00eb p\u00ebrputhshme p\u00ebr pinout dhe sistem komandash; madje edhe n\u00ebse d\u00ebshirojm\u00eb t\u00eb vendosim nj\u00eb \u00e7ip nga nj\u00eb prodhues tjet\u00ebr dhe\/ose me nj\u00eb kapacitet tjet\u00ebr, do t\u00eb funksionoj\u00eb pa ndryshuar kodin)<\/em>.<\/p>\n<p><\/p>\n<p>Un\u00eb p\u00ebrdor drivin e integruar n\u00eb kernelin e Linux, n\u00eb Raspberry p\u00ebr shkak t\u00eb mb\u00ebshtetjes t\u00eb overlay t\u00eb pem\u00ebs s\u00eb pajisjeve \u00ebsht\u00eb shum\u00eb e thjesht\u00eb \u2014 thjesht duhet t\u00eb vendosni overlay t\u00eb kompiluar n\u00eb \/boot\/overlays dhe t\u00eb modifikoni pak \/boot\/config.txt.<\/p>\n<p>\n<b class=\"spoiler_title\">Shembuj i skedarit dts<\/b><\/p>\n<p>Sinqerisht, nuk jam i sigurt se \u00ebsht\u00eb shkruar pa gabime, por funksionon.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">\/*\n * Device tree overlay for at25 at spi0.1\n *\/\n\n\/dts-v1\/;\n\/plugin\/;\n\n\/ {\n    compatible = \"brcm,bcm2835\", \"brcm,bcm2836\", \"brcm,bcm2708\", \"brcm,bcm2709\"; \n\n    \/* disable spi-dev for spi0.1 *\/\n    fragment@0 {\n        target = &lt;&amp;spi0&gt;;\n        __overlay__ {\n            status = \"okay\";\n            spidev@1{\n                status = \"disabled\";\n            };\n        };\n    };\n\n    \/* the spi config of the at25 *\/\n    fragment@1 {\n        target = &lt;&amp;spi0&gt;;\n        __overlay__ {\n            #address-cells = &lt;1&gt;;\n            #size-cells = &lt;0&gt;;\n            flash: m25p80@1 {\n                    compatible = \"atmel,at25df321a\";\n                    reg = &lt;1&gt;;\n                    spi-max-frequency = &lt;50000000&gt;;\n\n                    \/* default to false:\n                    m25p,fast-read ;\n                    *\/\n            };\n        };\n    };\n\n    __overrides__ {\n        spimaxfrequency = &lt;&amp;flash&gt;,\"spi-max-frequency:0\";\n        fastread = &lt;&amp;flash&gt;,\"m25p,fast-read?\";\n    };\n};<\/code><\/pre>\n<p>\n<b class=\"spoiler_title\">Dhe nj\u00eb rresht n\u00eb config.txt<\/b><\/p>\n<pre><code class=\"plaintext\">dtoverlay=at25:spimaxfrequency=50000000<\/code><\/pre>\n<p><\/p>\n<p>P\u00ebrshkrimin e lidhjes s\u00eb \u00e7ipit me Raspberry Pi e l\u00eb m\u00ebnjan\u00eb. N\u00eb nj\u00eb an\u00eb, nuk jam specialist n\u00eb elektronik\u00eb, n\u00eb an\u00ebn tjet\u00ebr \u2014 k\u00ebtu gjith\u00e7ka \u00ebsht\u00eb banale madje edhe p\u00ebr mua: \u00e7ipi ka vet\u00ebm 8 pin\u00eb, nga t\u00eb cilat na nevojiten toka, energjia, SPI (CS, SI, SO, SCK); nivelet p\u00ebrputhen me ato t\u00eb Raspberry Pi, nuk k\u00ebrkohet ndonj\u00eb lidhje shtes\u00eb \u2014 thjesht lidhni k\u00ebto 6 kontakte.<\/p>\n<p><\/p>\n<h2 id=\"postanovka-zadachi\">Vendosja e detyr\u00ebs<\/h2>\n<p><\/p>\n<p>Si zakonisht, p\u00ebrcaktimi i detyr\u00ebs kalon disa iteracione, m\u00eb duket se ka ardhur koha p\u00ebr nj\u00eb tjet\u00ebr. Pra, le t\u00eb ndalojm\u00eb, t\u00eb mbledhim bashk\u00eb at\u00eb q\u00eb \u00ebsht\u00eb shkruar tashm\u00eb, dhe t\u00eb qart\u00ebsojm\u00eb detajet e mbetura n\u00eb hije.<\/p>\n<p><\/p>\n<p>K\u00ebshtu, ne p\u00ebrcaktoi se regjistri do t\u00eb ruhen n\u00eb SPI NOR Flash.<\/p>\n<p>\n<b class=\"spoiler_title\">\u00c7far\u00eb \u00ebsht\u00eb NOR Flash p\u00ebr ata q\u00eb nuk e din\u00eb<\/b><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb memories q\u00eb nuk humb t\u00eb dh\u00ebnat, me t\u00eb cilat mund t\u00eb kryejm\u00eb tre operacione:<\/p>\n<p><\/p>\n<ol>\n<li>Leximi:<br \/>\nLeximi m\u00eb i zakonsh\u00ebm: d\u00ebrgojm\u00eb adres\u00ebn dhe lexojm\u00eb aq bite sa na nevojitet;<\/li>\n<li>Shkrimi:<br \/>\nShkrimi n\u00eb NOR flash duket si e zakonshmja, por ka nj\u00eb ve\u00e7ori: mund t\u00eb ndryshojm\u00eb vet\u00ebm 1 n\u00eb 0, por jo anasjelltas. P\u00ebr shembull, n\u00ebse kemi 0x55 n\u00eb qeliz\u00ebn e memories, pas shkrimit t\u00eb 0x0f, do t\u00eb ruhet 0x05 <em>(shih tabel\u00ebn pak m\u00eb posht\u00eb)<\/em>;<\/li>\n<li>Fshirja:<br \/>\nNatyrisht, na nevojitet t\u00eb dim\u00eb t\u00eb b\u00ebjm\u00eb edhe operacionin e kund\u00ebrt \u2014 t\u00eb ndryshojm\u00eb 0 n\u00eb 1, p\u00ebr k\u00ebt\u00eb ekziston operacioni i fshirjes. Ndryshe nga dy t\u00eb par\u00ebt, ai punon jo me bite, por me blloqe (blloku m\u00eb i vog\u00ebl i fshirjes n\u00eb \u00e7ipin e zgjedhur \u00ebsht\u00eb 4kb). Fshirja shkat\u00ebrron t\u00eb gjith\u00eb bllokun si t\u00ebr\u00ebsi dhe ky \u00ebsht\u00eb m\u00ebnyra e vetme p\u00ebr t\u00eb ndryshuar 0 n\u00eb 1. Prandaj, kur punojm\u00eb me flash, shpesh duhet t\u00eb rregullojm\u00eb strukturat e t\u00eb dh\u00ebnave n\u00eb kufirin e bllokut t\u00eb fshirjes.<br \/>\nShkrimi n\u00eb NOR Flash:<\/li>\n<\/ol>\n<p><\/p>\n<p>T\u00eb dh\u00ebna binare<\/p>\n<p><strong>Ishte<\/strong><br \/>\n<code>01010101<\/code><\/p>\n<p><strong>E shkruam<\/strong><br \/>\n<code>00001111<\/code><\/p>\n<p><strong>Nisi<\/strong><br \/>\n<code>00000101<\/code><\/p>\n<p><\/p>\n<p>Regjistri p\u00ebrb\u00ebhet nga nj\u00eb s\u00ebr\u00eb sh\u00ebnimesh me gjat\u00ebsi t\u00eb ndryshueshme. Gjat\u00ebsia mesatare e sh\u00ebnimit \u00ebsht\u00eb rreth 30 bite (ndon\u00ebse ndonj\u00ebher\u00eb ndodhin sh\u00ebnime me gjat\u00ebsi disa kilobajt). <em>N\u00eb k\u00ebt\u00eb rast, ne i trajtojm\u00eb ato thjesht si nj\u00eb grup bites, por, n\u00ebse jeni t\u00eb interesuar, brenda sh\u00ebnimeve p\u00ebrdoret CBOR<\/em><\/p>\n<p><\/p>\n<p>In addition to the log, we need to store some 'tuning' information, both updatable and static: some device ID, sensor calibrations, a flag 'device temporarily turned off', etc.<br \/>\nK\u00ebto informacione p\u00ebrb\u00ebjn\u00eb nj\u00eb grup sh\u00ebnimesh me \u00e7el\u00ebs-vler\u00eb, gjithashtu ruhen n\u00eb CBOR. K\u00ebto informacione nuk jan\u00eb shum\u00eb (maksimumi disa kilobajt), p\u00ebrdit\u00ebsohen jo shpesh.<br \/>\nN\u00eb t\u00eb ardhmen do t'i referohemi asaj si konteksti.<\/p>\n<p><\/p>\n<p>N\u00ebse kujtojm\u00eb nga filloi ky artikull, \u00ebsht\u00eb shum\u00eb e r\u00ebnd\u00ebsishme t\u00eb sigurohet besueshm\u00ebria e ruajtjes s\u00eb t\u00eb dh\u00ebnave dhe, sa m\u00eb shum\u00eb t\u00eb jet\u00eb e mundur, funksionimi i pand\u00ebrprer\u00eb edhe n\u00eb rast t\u00eb gabimeve t\u00eb harduerit\/d\u00ebmtimeve t\u00eb t\u00eb dh\u00ebnave.<\/p>\n<p><\/p>\n<p>Cilat jan\u00eb burimet e problemeve q\u00eb mund t\u00eb shqyrtohen?<\/p>\n<p><\/p>\n<ul>\n<li>Power disconnection during write\/erase operations. This falls under the saying 'there's no means against a brick'.<br \/>\nInformacioni nga <noindex><a rel=\"nofollow\" href=\"https:\/\/electronics.stackexchange.com\/questions\/225956\/what-would-happen-in-case-of-power-outage-during-nor-flash-erase-or-programming\">diskutime<\/a><\/noindex> On stackexchange: when power is disconnected during work with flash, both erase (set to 1) and write (set to 0) lead to undefined behavior: data may or may not be written, partially written (for example, we sent 10 bytes\/80 bits, but only managed to write 45 bits), and it is also possible that some bits will be in a 'transitional' state (reading may return either 0 or 1);<\/li>\n<li>Gabimet e flashes vet\u00eb.<br \/>\nBER, edhe pse shum\u00eb i ul\u00ebt, nuk mund t\u00eb jet\u00eb i barabart\u00eb me zero;<\/li>\n<li>Gabimet n\u00eb autobus<br \/>\nT\u00eb dh\u00ebnat e d\u00ebrguara p\u00ebrmes SPI nuk jan\u00eb t\u00eb mbrojtura, mund t\u00eb ndodhin si gabime individuale t\u00eb bit\u00ebve, ashtu edhe gabime sinhronizimi \u2014 humbja ose shtimi i bit\u00ebve (\u00e7ka \u00e7on n\u00eb ndotjen masive t\u00eb t\u00eb dh\u00ebnave);<\/li>\n<li>Gabime t\u00eb tjera\/gabime<br \/>\nErrors in the code, 'glitches' of Raspberry, alien interference\u2026<\/li>\n<\/ul>\n<p><\/p>\n<p>Un\u00eb kam formuluar k\u00ebrkesat q\u00eb, sipas mendimit tim, jan\u00eb t\u00eb nevojshme p\u00ebr t\u00eb siguruar besueshm\u00ebrin\u00eb:<\/p>\n<p><\/p>\n<ul>\n<li>t\u00eb dh\u00ebnat duhet t\u00eb shkruhen menj\u00ebher\u00eb n\u00eb memorie flash, regjistrimi i vonuar nuk merret parasysh; - n\u00ebse ndodhi nj\u00eb gabim, ai duhet t\u00eb zbulohet dhe t\u00eb p\u00ebrpunohen sa m\u00eb shpejt t\u00eb jet\u00eb e mundur; - sistemi duhet t\u00eb rikthej\u00eb funksionimin pas gabimeve sa m\u00eb shum\u00eb q\u00eb t\u00eb jet\u00eb e mundur.<br \/>\n<em>(an example from life 'how it shouldn't be', which I think everyone has encountered: after an emergency reboot, the file system was 'damaged' and the operating system does not load)<\/em><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"idei-podhody-razmyshleniya\">Ide, qasje, mendime<\/h2>\n<p><\/p>\n<p>Kur fillova t\u00eb mendoja p\u00ebr k\u00ebt\u00eb detyr\u00eb, n\u00eb mendjen time kaluan nj\u00eb mori ide, p\u00ebr shembull:<\/p>\n<p><\/p>\n<ul>\n<li>p\u00ebrdorimi i kompresimit t\u00eb t\u00eb dh\u00ebnave;<\/li>\n<li>p\u00ebrdorimi i strukturave t\u00eb dh\u00ebnash t\u00eb zgjuara, p\u00ebr shembull, ruajtja e titujve t\u00eb regjistrimeve ve\u00e7mas nga vet\u00eb regjistrimet, n\u00eb m\u00ebnyr\u00eb q\u00eb, n\u00eb rast gabimi n\u00eb nj\u00eb regjistrim, t\u00eb ishte e mundur t\u00eb lexohej pa probleme t\u00eb tjerat;<\/li>\n<li>p\u00ebrdorimi i fushave bit p\u00ebr t\u00eb kontrolluar p\u00ebrfundimin e regjistrimit n\u00eb rast nd\u00ebrprerjeje t\u00eb energjis\u00eb;<\/li>\n<li>ruajtja e kontrollor\u00ebve p\u00ebr gjith\u00e7ka;<\/li>\n<li>p\u00ebrdorimi i ndonj\u00eb variante t\u00eb kodimit t\u00eb q\u00ebndres\u00ebs ndaj nd\u00ebrhyrjeve.<\/li>\n<\/ul>\n<p><\/p>\n<p>Disa nga k\u00ebto ide u p\u00ebrdor\u00ebn, t\u00eb tjerat u hodh\u00ebn posht\u00eb. Le t\u00eb shkojm\u00eb me radh\u00eb.<\/p>\n<p><\/p>\n<h3 id=\"szhatie-dannyh\">Kompresimi i t\u00eb dh\u00ebnave<\/h3>\n<p><\/p>\n<p>The events that we log are quite similar and repetitive ('threw a coin 5 rubles', 'pressed the change button', ...). Therefore, compression should be quite efficient.<\/p>\n<p><\/p>\n<p>Shpenzimet p\u00ebr kompresim jan\u00eb t\u00eb pap\u00ebrfillshme (procesori yn\u00eb \u00ebsht\u00eb mjaft i fort\u00eb, madje edhe n\u00eb Pi-n\u00eb e par\u00eb kishte nj\u00eb b\u00ebrtham\u00eb me frekuenc\u00eb 700MHz, n\u00eb modelet aktuale disa b\u00ebrthama me frekuenc\u00eb mbi nj\u00eb gigahertz), shpejt\u00ebsia e shk\u00ebmbimit me ruajtjen nuk \u00ebsht\u00eb e lart\u00eb (disa megabajt n\u00eb sekond\u00eb), madh\u00ebsia e regjistrimeve \u00ebsht\u00eb e vog\u00ebl. N\u00eb p\u00ebrgjith\u00ebsi, n\u00ebse kompresimi ndikon n\u00eb performanc\u00eb, do t\u00eb jet\u00eb vet\u00ebm pozitiv. <em>(absolutisht jo kritik, thjesht po e konstatoj)<\/em>. P\u00ebr m\u00eb tep\u00ebr, nuk kemi nj\u00eb embedded t\u00eb v\u00ebrtet\u00eb, por nj\u00eb Linux t\u00eb zakonsh\u00ebm \u2014 k\u00ebshtu q\u00eb realizimi nuk duhet t\u00eb k\u00ebrkoj\u00eb shum\u00eb p\u00ebrpjekje (mjafton t\u00eb lidhim bibliotek\u00ebn dhe t\u00eb p\u00ebrdorim disa funksione nga ajo).<\/p>\n<p><\/p>\n<p>U mor nj\u00eb cop\u00eb logu nga nj\u00eb pajisje funksionale (1.7Mb, 70 mij\u00eb regjistrime) dhe fillimisht u kontrollua p\u00ebr kompresueshm\u00ebri me ndihm\u00ebn e gzip, lz4, lzop, bzip2, xz, zstd q\u00eb ishin n\u00eb kompjuter.<\/p>\n<p><\/p>\n<ul>\n<li>gzip, xz, zstd treguan rezultate t\u00eb ngjashme (40Kb).<br \/>\nM\u00eb befasoi q\u00eb xz e modishme tregoi veten n\u00eb t\u00eb nj\u00ebjtin nivel me gzip ose zstd;<\/li>\n<li>lzip me cil\u00ebsime t\u00eb parazgjedhura dha nj\u00eb rezultat pak m\u00eb t\u00eb dob\u00ebt;<\/li>\n<li>lz4 dhe lzop treguan rezultat jo shum\u00eb t\u00eb mir\u00eb (150Kb);<\/li>\n<li>bzip2 tregoi nj\u00eb rezultat befasues mir\u00eb (18Kb).<\/li>\n<\/ul>\n<p><\/p>\n<p>Pra, t\u00eb dh\u00ebnat kompresohen shum\u00eb mir\u00eb.<br \/>\nPra, (n\u00ebse nuk gjejm\u00eb mang\u00ebsi fatale) kompresimi p\u00ebr t\u00eb qen\u00eb! Thjesht sepse do t\u00eb ket\u00eb m\u00eb shum\u00eb t\u00eb dh\u00ebna n\u00eb t\u00eb nj\u00ebjt\u00ebn flash.<\/p>\n<p><\/p>\n<p>Le t\u00eb mendojm\u00eb p\u00ebr disavantazhet.<\/p>\n<p><\/p>\n<p>Problemi i par\u00eb: ne tashm\u00eb u dakorduam se \u00e7do regjistrim duhet t\u00eb mb\u00ebrrij\u00eb menj\u00ebher\u00eb n\u00eb flash. Zakonisht, nj\u00eb arkivues grumbullon t\u00eb dh\u00ebna nga rrjedha hyr\u00ebse deri sa t\u00eb vendos\u00eb se \u00ebsht\u00eb koha t\u00eb shkruaj\u00eb n\u00eb daljen. Ne, megjithat\u00eb, na nevojitet t\u00eb marrim menj\u00ebher\u00eb nj\u00eb bllok t\u00eb dh\u00ebnash t\u00eb kompresuara dhe ta ruajm\u00eb ato n\u00eb kujtes\u00ebn jo t\u00eb fikshme.<\/p>\n<p><\/p>\n<p>Un\u00eb shoh tri mund\u00ebsi:<\/p>\n<p><\/p>\n<ol>\n<li>T\u00eb kompresojm\u00eb \u00e7do regjistrim me ndihm\u00ebn e kompresimit me fjalor n\u00eb vend t\u00eb algoritemeve t\u00eb ndryshme t\u00eb shqyrtuara m\u00eb sip\u00ebr.<br \/>\nA workable option, but I don't like it. To ensure a reasonably decent level of compression, the dictionary must be 'tuned' to specific data; any change will lead to a catastrophic drop in the level of compression. Yes, this problem can be solved by creating a new version of the dictionary, but it's a headache \u2014 we will need to store all versions of the dictionary; in each record, we need to specify which version of the dictionary it was compressed with\u2026<\/li>\n<li>Compress each record using 'classical' algorithms, but independently from each other.<br \/>\nAlgoritmet e shqyrtuara p\u00ebr kompresim nuk jan\u00eb t\u00eb dizajnuara p\u00ebr pun\u00eb me regjistrime t\u00eb k\u00ebtij p\u00ebrmasash (dhjet\u00ebra byte), koeficenti i kompresimit do t\u00eb jet\u00eb duksh\u00ebm m\u00eb pak se 1 (pra, nj\u00eb rritje e volumit t\u00eb t\u00eb dh\u00ebnave n\u00eb vend t\u00eb kompresimit);<\/li>\n<li>T\u00eb b\u00ebjm\u00eb FLUSH pas \u00e7do regjistrimi.<br \/>\nN\u00eb shum\u00eb biblioteka kompresimi ka mb\u00ebshtetje p\u00ebr FLUSH. Kjo \u00ebsht\u00eb nj\u00eb komand\u00eb (ose parametr p\u00ebr procedur\u00ebn e kompresimit), duke e marr\u00eb at\u00eb, arkivuesi formon nj\u00eb rrjedh\u00eb t\u00eb kompresuar, n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb jet\u00eb e mundur t\u00eb rikthej\u00eb <strong>t\u00eb gjitha<\/strong> t\u00eb dh\u00ebnat e pakompresuara, q\u00eb tashm\u00eb jan\u00eb marr\u00eb. Nj\u00eb analogji e till\u00eb <code>sync<\/code> n\u00eb sistemet e skedar\u00ebve ose <code>commit<\/code> n\u00eb sql.<br \/>\nE r\u00ebnd\u00ebsishme \u00ebsht\u00eb q\u00eb operacionet e ardhshme t\u00eb kompresimit mund t\u00eb p\u00ebrdorin fjalorin e akumuluar dhe niveli i kompresimit nuk do t\u00eb vuaj\u00eb aq shum\u00eb si n\u00eb variantin e m\u00ebparsh\u00ebm.<\/li>\n<\/ol>\n<p><\/p>\n<p>Mendoj se \u00ebsht\u00eb e qart\u00eb se zgjodha variantin e tret\u00eb, le t\u00eb ndalemi m\u00eb shum\u00eb mbi t\u00eb.<\/p>\n<p><\/p>\n<p>Gjeti <noindex><a rel=\"nofollow\" href=\"https:\/\/www.bolet.org\/~pornin\/deflate-flush.html\">artikull i shk\u00eblqyer<\/a><\/noindex> p\u00ebr FLUSH n\u00eb zlib.<\/p>\n<p><\/p>\n<p>Kam p\u00ebrqendrova n\u00eb nj\u00eb test t\u00eb ngjash\u00ebm me artikuj, duke marr\u00eb 70 mij\u00eb regjistrime nga nj\u00eb pajisje reale, me nj\u00eb madh\u00ebsi faqesh prej 60 KB. <em>(p\u00ebr madh\u00ebsin\u00eb e faqes ne do t\u00eb kthehemi p\u00ebrs\u00ebri)<\/em> kam marr\u00eb:<\/p>\n<p><\/p>\n<p>T\u00eb dh\u00ebnat fillestare<br \/>\nKompresimi gzip -9 (pa FLUSH)<br \/>\nzlib me Z_PARTIAL_FLUSH<br \/>\nzlib me Z_SYNC_FLUSH<\/p>\n<p><strong>V\u00ebllimi, KB<\/strong><br \/>\n1692<br \/>\n40<br \/>\n352<br \/>\n604<\/p>\n<p><\/p>\n<p>N\u00eb shikim t\u00eb par\u00eb, \u00e7mimi q\u00eb merret nga FLUSH duket shum\u00eb i lart\u00eb, megjithat\u00eb n\u00eb t\u00eb v\u00ebrtet\u00eb kemi nj\u00eb zgjedhje t\u00eb varf\u00ebr \u2014 ose t\u00eb mos kompresojm\u00eb fare, ose t\u00eb kompresojm\u00eb (dhe mjaft efektivisht) me FLUSH. Nuk duhet harruar se kemi 70 mij\u00eb regjistrime, mbi 4-5 byte p\u00ebr regjistrim q\u00eb sjell Z_PARTIAL_FLUSH. Dhe raporti i kompresimit rezultoi t\u00eb ishte pothuajse 5:1, q\u00eb \u00ebsht\u00eb m\u00eb shum\u00eb se nj\u00eb rezultat i shk\u00eblqyer.<\/p>\n<p>\n<b class=\"spoiler_title\">It may seem surprising, but in fact, Z_SYNC_FLUSH is a more effective way to perform FLUSH.<\/b><\/p>\n<p>N\u00eb rastin e p\u00ebrdorimit t\u00eb Z_SYNC_FLUSH, 4 byte t\u00eb fundit t\u00eb \u00e7do regjistrimi gjithmon\u00eb do t\u00eb jen\u00eb 0x00, 0x00, 0xff, 0xff. Dhe n\u00ebse i dim\u00eb, mund t'i injorojm\u00eb, k\u00ebshtu q\u00eb madh\u00ebsia p\u00ebrfundimtare del t\u00eb jet\u00eb vet\u00ebm 324 KB.<\/p>\n<p><\/p>\n<p>N\u00eb artikullin q\u00eb citoj, ka nj\u00eb shpjegim:<\/p>\n<p><\/p>\n<blockquote><p>Nj\u00eb bllok i ri tipi 0 me p\u00ebrmbajtje t\u00eb zbraz\u00ebt \u00ebsht\u00eb shtuar.<\/p>\n<p>Nj\u00eb bllok i tipit 0 me p\u00ebrmbajtje t\u00eb zbraz\u00ebt p\u00ebrb\u00ebhet nga:<\/p>\n<ul>\n<li>koka e bllokut tre-bit;<\/li>\n<li>0 deri n\u00eb 7 bit t\u00eb barabart\u00eb me zero, p\u00ebr t\u00eb arritur p\u00ebrputhjen e byte;<\/li>\n<li>sekuenca kat\u00ebr-byte 00 00 FF FF.<\/li>\n<\/ul>\n<p>\n<\/p><\/blockquote>\n<p>Si\u00e7 \u00ebsht\u00eb e leht\u00eb t\u00eb v\u00ebrehet, n\u00eb bllokun e fundit p\u00ebrpara k\u00ebtyre 4 byte, ka nga 3 deri n\u00eb 10 bit\u00eb zero. Megjithat\u00eb, praktika ka treguar se bit\u00ebt zero n\u00eb t\u00eb v\u00ebrtet\u00eb jan\u00eb minimum 10.<\/p>\n<p><\/p>\n<p>Duket se blloqet kaq t\u00eb shkurtra t\u00eb t\u00eb dh\u00ebnave zakonisht ( gjithmon\u00eb?) kodohen me nj\u00eb bllok tipi 1 (bllok i fiksur), i cili domosdoshm\u00ebrisht p\u00ebrfundon me 7 bit\u00eb zero, duke rezultuar me 10-17 bit\u00eb zero t\u00eb garantuara (nd\u00ebrsa t\u00eb tjer\u00ebt do t\u00eb jen\u00eb zero me nj\u00eb probabilitet rreth 50%).<\/p>\n<p><\/p>\n<p>Pra, n\u00eb t\u00eb dh\u00ebnat testuese, n\u00eb 100% t\u00eb rasteve p\u00ebrpara 0x00, 0x00, 0xff, 0xff ka nj\u00eb byte zero, dhe n\u00eb m\u00eb shum\u00eb se nj\u00eb t\u00eb tret\u00ebn e rasteve \u2014 dy byte zero. <em>(ndoshta shkaku \u00ebsht\u00eb se po p\u00ebrdor CBOR binar, dhe duke p\u00ebrdorur JSON tekstual do t\u00eb haseshin m\u00eb shpesh blloqet e tipit 2 \u2014 bllok dinamik, p\u00ebrkat\u00ebsisht do t\u00eb ndodhnin blloqe pa byte shtes\u00eb zero p\u00ebrpara 0x00, 0x00, 0xff, 0xff)<\/em>.<\/p>\n<p><\/p>\n<p>P\u00ebrfundimisht, n\u00eb t\u00eb dh\u00ebnat testuese t\u00eb disponueshme mund t\u00eb p\u00ebrfshihemi n\u00eb m\u00eb pak se 250 KB t\u00eb dh\u00ebnash t\u00eb kompresuara.<\/p>\n<p><\/p>\n<p>Mund t\u00eb kursej m\u00eb shum\u00eb duke u marr\u00eb me manovrimin e bit\u00ebve: tani ne injorojm\u00eb pranin\u00eb e disa bit\u00ebve zero n\u00eb fund t\u00eb bllokut, disa bit\u00eb n\u00eb fillim t\u00eb bllokut gjithashtu nuk ndryshojn\u00eb...<br \/>\nPor k\u00ebtu mora nj\u00eb vendim t\u00eb fort\u00eb p\u00ebr t\u00eb ndalur, p\u00ebrndryshe me k\u00ebt\u00eb rit\u00ebm mund t\u00eb arrij n\u00eb zhvillimin e arkivuesit tim.<\/p>\n<p><\/p>\n<p>Prandaj, nga t\u00eb dh\u00ebnat e mia testuese kam marr\u00eb 3-4 byte p\u00ebr regjistrim, raporti i kompresimit rezultoi m\u00eb shum\u00eb se 6:1. T\u00eb jem i sinqert\u00eb: nuk prisja nj\u00eb rezultat t\u00eb till\u00eb, p\u00ebr mendimin tim, gjith\u00e7ka q\u00eb \u00ebsht\u00eb m\u00eb mir\u00eb se 2:1 \u2014 tashm\u00eb \u00ebsht\u00eb nj\u00eb rezultat q\u00eb justifikon p\u00ebrdorimin e kompresimit.<\/p>\n<p><\/p>\n<p>T\u00eb gjitha jan\u00eb t\u00eb shk\u00eblqyera, por zlib (deflate) \u2014 megjithat\u00eb, \u00ebsht\u00eb nj\u00eb algorit\u00ebm kompresimi i trash\u00ebguar dhe pak jasht\u00eb modes. Vet\u00ebm fakti se si fjalor p\u00ebrdoren 32KB t\u00eb fundit nga stream-et e t\u00eb dh\u00ebnave t\u00eb pathemeluar duket e \u00e7uditshme sot (dmth, n\u00ebse ndonj\u00eb bllok t\u00eb dh\u00ebnash \u00ebsht\u00eb shum\u00eb i ngjash\u00ebm me at\u00eb q\u00eb ishte n\u00eb stream-in hyr\u00ebs 40KB m\u00eb par\u00eb, ai do t\u00eb arkivohet p\u00ebrs\u00ebri, dhe nuk do t\u00eb referohet n\u00eb shfaqjen e m\u00ebparshme). N\u00eb arkivuesit modern\u00eb, madh\u00ebsia e fjalorit shpesh matet n\u00eb megabyte e jo n\u00eb kilobyte.<\/p>\n<p><\/p>\n<p>Prandaj, vazhdojm\u00eb mini-studimin ton\u00eb mbi arkivuesit.<\/p>\n<p><\/p>\n<p>I fundit q\u00eb kam provuar ishte bzip2 (kujdes, pa FLUSH ai tregoi nj\u00eb shkall\u00eb fantastike kompresimi, pothuajse 100:1). Fatin e keq, me FLUSH ai u tregua shum\u00eb keq, madh\u00ebsia e t\u00eb dh\u00ebnave t\u00eb kompresuara doli t\u00eb ishte m\u00eb e madhe se e pathemelura.<\/p>\n<p>\n<b class=\"spoiler_title\">Dyshimet e mia p\u00ebr arsyet e d\u00ebshtimit<\/b><\/p>\n<p>Libbz2 ofron vet\u00ebm nj\u00eb opsion flush, i cili duket se shfrynt fjalorin (analog i Z_FULL_FLUSH n\u00eb zlib), nuk mund t\u00eb flitet p\u00ebr ndonj\u00eb kompresim efektiv pas k\u00ebsaj.<\/p>\n<p><\/p>\n<p>Dhe e fundit q\u00eb provoj ishte zstd. N\u00eb var\u00ebsi t\u00eb parametrave, ai kompreson ose n\u00eb nivelin e gzip, por shum\u00eb m\u00eb shpejt, ose m\u00eb mir\u00eb se gzip.<\/p>\n<p><\/p>\n<p>Unfortunately, with FLUSH it showed 'not very' well: the size of the compressed data was about 700Kb.<\/p>\n<p><\/p>\n<p>Un\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/zstd\/issues\/900\">i b\u00ebra nj\u00eb pyetje<\/a><\/noindex> n\u00eb faqen e projektit n\u00eb github, mora p\u00ebrgjigje q\u00eb duhet t\u00eb marr\u00ebsh deri n\u00eb 10 byte t\u00eb dh\u00ebnash ndihm\u00ebse p\u00ebr \u00e7do bllok t\u00eb dh\u00ebnash t\u00eb kompresuara, q\u00eb \u00ebsht\u00eb af\u00ebr rezultateve t\u00eb marr\u00eb, nuk do t\u00eb mund t\u00eb arrihja deflate.<\/p>\n<p><\/p>\n<p>N\u00eb k\u00ebt\u00eb pik\u00eb vendosa t\u00eb ndal eksperimentet me arkivuesit (duke p\u00ebrmendur, xz, lzip, lzo, lz4 nuk treguan nj\u00eb performanc\u00eb t\u00eb mir\u00eb edhe n\u00eb faz\u00ebn e testimit pa FLUSH, dhe nuk vendosa t\u00eb shqyrtoj algoritme m\u00eb ekzotike t\u00eb kompresimit).<\/p>\n<p><\/p>\n<p>Kthehemi n\u00eb problemet e arkivimit.<\/p>\n<p><\/p>\n<p>Problemi i dyt\u00eb (si\u00e7 thuhet n\u00eb renditje, e jo p\u00ebr r\u00ebnd\u00ebsi) \u00ebsht\u00eb se t\u00eb dh\u00ebnat e kompresuara p\u00ebrb\u00ebjn\u00eb nj\u00eb stream t\u00eb vet\u00ebm, n\u00eb t\u00eb cilin vazhdimisht ka referenca n\u00eb pjes\u00eb t\u00eb m\u00ebparshme. Pra, n\u00ebse ndonj\u00eb pjes\u00eb e t\u00eb dh\u00ebnave t\u00eb kompresuara d\u00ebmtohet, humbasim jo vet\u00ebm blloqet e lidhura me t\u00eb, por edhe t\u00eb gjitha ato pasuese.<\/p>\n<p><\/p>\n<p>Ka qasje p\u00ebr zgjidhjen e k\u00ebtij problemi:<\/p>\n<p><\/p>\n<ol>\n<li>Parandalimi i shfaqjes s\u00eb problemeve \u2014 shtimi i tep\u00ebrt n\u00eb t\u00eb dh\u00ebnat e kompresuara, i cili do t\u00eb lejoj\u00eb identifikimin dhe rregullimin e gabimeve; p\u00ebr k\u00ebt\u00eb do t\u00eb flasim m\u00eb von\u00eb;<\/li>\n<li>Minimizoni pasojat n\u00eb rast se shfaqet nj\u00eb problem<br \/>\nKemi biseduar m\u00eb par\u00eb se \u00e7do bllok t\u00eb dh\u00ebnash mund t\u00eb kompresohet n\u00eb m\u00ebnyr\u00eb t\u00eb pavarur, k\u00ebshtu q\u00eb problemi do t\u00eb zhduket nga vetvetja (d\u00ebmtimi i t\u00eb dh\u00ebnave n\u00eb nj\u00eb bllok do t\u00eb \u00e7oj\u00eb n\u00eb humbjen e t\u00eb dh\u00ebnave vet\u00ebm n\u00eb at\u00eb bllok). Megjithat\u00eb, kjo \u00ebsht\u00eb nj\u00eb rast ekstrem, ku kompresimi i t\u00eb dh\u00ebnave do t\u00eb jet\u00eb i paefektsh\u00ebm. Ekstreme e kund\u00ebrt: p\u00ebrdorimi i t\u00eb gjitha 4MB t\u00eb \u00e7ipit ton\u00eb si nj\u00eb arkiv t\u00eb vet\u00ebm, i cili do t\u00eb na jap\u00eb nj\u00eb kompresim t\u00eb shk\u00eblqyer, por pasoja katastrofike n\u00eb rastin e d\u00ebmtimit t\u00eb t\u00eb dh\u00ebnave.<br \/>\n<em>Po, \u00ebsht\u00eb e nevojshme nj\u00eb kompromis nga ana e besueshm\u00ebris\u00eb. Por duhet t\u00eb mbajm\u00eb parasysh se ne po zhvillojm\u00eb nj\u00eb format ruajtjeje p\u00ebr memorien q\u00eb nuk ka nevoj\u00eb p\u00ebr energji me nj\u00eb BER tep\u00ebr t\u00eb ul\u00ebt dhe nj\u00eb periudh\u00eb ruajtjeje t\u00eb deklaruar prej 20 vjet\u00ebsh.<\/em><\/li>\n<\/ol>\n<p><\/p>\n<p>Gjat\u00eb eksperimentimeve, kam zbuluar se humbjet m\u00eb t\u00eb dukshme t\u00eb nivelit t\u00eb kompresimit fillojn\u00eb n\u00eb blloqe t\u00eb dh\u00ebnash t\u00eb kompresuara me madh\u00ebsi m\u00eb t\u00eb vog\u00ebl se 10 KB.<br \/>\nIt was previously mentioned that the memory used has a paged organization; I see no reason not to use the correspondence 'one page \u2014 one block of compressed data'.<\/p>\n<p><\/p>\n<p>Pra, madh\u00ebsia minimale e arsyeshme e faqes \u00ebsht\u00eb 16 KB (me rezerv\u00eb p\u00ebr informacionin sh\u00ebrbim). Megjithat\u00eb, nj\u00eb madh\u00ebsi kaq t\u00eb vog\u00ebl faqe v\u00eb kufizime t\u00eb r\u00ebnd\u00ebsishme mbi madh\u00ebsin\u00eb maksimale t\u00eb sh\u00ebnimeve.<\/p>\n<p><\/p>\n<p>Edhe pse aktualisht nuk parashikoj sh\u00ebnime m\u00eb t\u00eb m\u00ebdha se nj\u00eb kilobajt n\u00eb form\u00eb t\u00eb kompresuar, kam vendosur t\u00eb p\u00ebrdor faqe me madh\u00ebsi 32 KB (n\u00eb total b\u00ebhen 128 faqe p\u00ebr \u00e7ip).<\/p>\n<p><\/p>\n<p><strong>P\u00ebrmbledhje:<\/strong><\/p>\n<p><\/p>\n<ul>\n<li>T\u00eb dh\u00ebnat i ruajm\u00eb t\u00eb kompresuara me zlib (deflate);<\/li>\n<li>P\u00ebr \u00e7do sh\u00ebnim vendosim Z_SYNC_FLUSH;<\/li>\n<li>\u00c7do sh\u00ebnim t\u00eb kompresuar i presim bajt\u00ebt e fundit <em>(p.sh., 0x00, 0x00, 0xff, 0xff)<\/em>; n\u00eb krye tregojm\u00eb se sa bajt\u00eb kemi prer\u00eb;<\/li>\n<li>T\u00eb dh\u00ebnat i ruajm\u00eb n\u00eb faqe prej 32 KB; brenda faqes ka nj\u00eb rrjedh\u00eb t\u00eb vetme t\u00eb dh\u00ebnash t\u00eb kompresuara; n\u00eb \u00e7do faqe kompresimi fillojm\u00eb s\u00ebrish.<\/li>\n<\/ul>\n<p><\/p>\n<p>Dhe, para se t\u00eb p\u00ebrfundoj me kompresimin, do t\u00eb doja t\u00eb theksoj se t\u00eb dh\u00ebnat e kompresuara p\u00ebrb\u00ebjn\u00eb vet\u00ebm disa bajta p\u00ebr sh\u00ebnim, prandaj \u00ebsht\u00eb jasht\u00ebzakonisht e r\u00ebnd\u00ebsishme t\u00eb mos e fryjm\u00eb informacionin sh\u00ebrbim, \u00e7do bajt k\u00ebtu ka r\u00ebnd\u00ebsi.<\/p>\n<p><\/p>\n<h3 id=\"hranenie-zagolovkov-dannyh\">Ruajtja e kryeshemes t\u00eb t\u00eb dh\u00ebnave<\/h3>\n<p><\/p>\n<p>Duke pasur parasysh se sh\u00ebnimet jan\u00eb t\u00eb gjat\u00eb variabile, na nevojitet nj\u00eb m\u00ebnyr\u00eb p\u00ebr t\u00eb p\u00ebrcaktuar vendosjen\/kufijt\u00eb e sh\u00ebnimeve.<\/p>\n<p><\/p>\n<p>Njoh tri qasje:<\/p>\n<p><\/p>\n<ol>\n<li>T\u00eb gjitha sh\u00ebnimet ruhen n\u00eb nj\u00eb rrjedh\u00eb t\u00eb vazhdueshme, fillimisht \u00ebsht\u00eb kryeza e sh\u00ebnimit q\u00eb p\u00ebrmban gjat\u00ebsi, dhe pastaj vjen vet\u00eb sh\u00ebnimi.<br \/>\nN\u00eb k\u00ebt\u00eb variant, dhe kryezat dhe t\u00eb dh\u00ebnat mund t\u00eb ken\u00eb gjat\u00ebsi variabile.<br \/>\nN\u00eb thelb, rezulton nj\u00eb list\u00eb e lidhur nj\u00ebdrejt, e cila p\u00ebrdoret shum\u00eb shpesh;<\/li>\n<li>Kryezat dhe vet\u00eb sh\u00ebnimet ruhen n\u00eb rrjedha t\u00eb ndara.<br \/>\nDuke p\u00ebrdorur kryezat me gjat\u00ebsi t\u00eb q\u00ebndrueshme, arrijm\u00eb q\u00eb d\u00ebmtimi i nj\u00eb kryeze nuk ndikon n\u00eb t\u00eb tjer\u00ebt.<br \/>\nNj\u00eb qasje e till\u00eb p\u00ebrdoret, p\u00ebr shembull, n\u00eb shum\u00eb sisteme skedash;<\/li>\n<li>Sh\u00ebnimet ruhen n\u00eb nj\u00eb rrjedh\u00eb t\u00eb vazhdueshme, kufiri i sh\u00ebnimit p\u00ebrcaktohet nga nj\u00eb simbol (simbol\/ose nj\u00eb sekuenc\u00eb simbolesh, q\u00eb jan\u00eb t\u00eb ndaluara brenda blloqeve t\u00eb dh\u00ebnash). N\u00ebse brenda sh\u00ebnimit haset nj\u00eb simbol, at\u00ebher\u00eb ne e z\u00ebvend\u00ebsojm\u00eb at\u00eb me nj\u00eb sekuenc\u00eb t\u00eb caktuar (e sh\u00ebnojm\u00eb).<br \/>\nNj\u00eb qasje e till\u00eb p\u00ebrdoret, p\u00ebr shembull, n\u00eb protokollin PPP.<\/li>\n<\/ol>\n<p><\/p>\n<p>Do ta ilustroj.<\/p>\n<p><\/p>\n<p>Opsioni 1:<br \/>\n<img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/e5a9676ca21eaca07e64ddf9fcd9f2eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nK\u00ebtu gjith\u00e7ka \u00ebsht\u00eb shum\u00eb e thjesht\u00eb: duke ditur gjat\u00ebsi sh\u00ebnimi, mund t\u00eb llogarisim adres\u00ebn e kryeza tjet\u00ebr. K\u00ebshtu ne l\u00ebvizim p\u00ebrmes kryezave, derisa t\u00eb hasim nj\u00eb zon\u00eb t\u00eb mbushur me 0xff (zon\u00eb t\u00eb lir\u00eb) ose fundin e faqes.<\/p>\n<p><\/p>\n<p>Opsioni 2:<br \/>\n<img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/4fed4860fb659ab6042be9aeeb5c041a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nP\u00ebr shkak t\u00eb gjat\u00ebsis\u00eb s\u00eb ndryshueshme t\u00eb regjistrimeve, ne nuk mund t\u00eb parashikojm\u00eb se sa shum\u00eb regjistrime (dhe p\u00ebr pasoj\u00eb tituj) do t\u00eb na nevojiten n\u00eb nj\u00eb faqe. Mund t\u00eb ndarim titujt dhe t\u00eb dh\u00ebnat n\u00eb faqe t\u00eb ndryshme, por m\u00eb p\u00eblqen nj\u00eb qasje tjet\u00ebr: t\u00eb vendosim si titujt (me gjat\u00ebsi t\u00eb q\u00ebndrueshme) q\u00eb nga fillimi i faqes, ashtu edhe t\u00eb dh\u00ebnat (me gjat\u00ebsi t\u00eb ndryshueshme) nga fundi. Sa her\u00eb q\u00eb ato<\/p>\n<p><\/p>\n<p>Opsioni 3:<br \/>\n<img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/dfb64009aa7781fcb8a47423ff4160c6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nK\u00ebtu nuk ka nevoj\u00eb t\u00eb ruajm\u00eb n\u00eb kryez\u00eb gjat\u00ebsi ose informacion tjet\u00ebr mbi vendosjen e t\u00eb dh\u00ebnave, mjafton markat q\u00eb tregojn\u00eb kufijt\u00eb e sh\u00ebnimeve. Megjithat\u00eb, t\u00eb dh\u00ebnat duhet t\u00eb p\u00ebrpunohen gjat\u00eb shkrimit\/leht\u00ebsimit.<br \/>\nSi nj\u00eb mark\u00eb do t\u00eb p\u00ebrdorja 0xff (me t\u00eb cilin \u00ebsht\u00eb mbushur faqa pas fshirjes), k\u00ebshtu q\u00eb zona e lir\u00eb nuk do t\u00eb interpretohet si t\u00eb dh\u00ebna.<\/p>\n<p><\/p>\n<p>Tabela krahasuese:<\/p>\n<p><\/p>\n<p>Mund\u00ebsia 1<br \/>\nVariant 2<br \/>\nVarianti 3<\/p>\n<p><strong>Q\u00ebndrueshm\u00ebria ndaj gabimeve<\/strong><br \/>\n\u2014<br \/>\n+<br \/>\n+<\/p>\n<p><strong>Kompakt\u00ebsia<\/strong><br \/>\n+<br \/>\n\u2014<br \/>\n+<\/p>\n<p><strong>V\u00ebshtir\u00ebsia n\u00eb realizim<\/strong><br \/>\n*<br \/>\n**<br \/>\n**<\/p>\n<p><\/p>\n<p>Variantin 1 ka nj\u00eb defekt fatal: n\u00ebse d\u00ebmtohet ndonj\u00eb nga titujt, ne shkat\u00ebrrojm\u00eb t\u00ebr\u00eb zinxhiri pasues. Variantet e tjera lejojn\u00eb rikuperimin e pjes\u00ebs s\u00eb t\u00eb dh\u00ebnave edhe n\u00eb rast d\u00ebshtimesh masive.<br \/>\nPor k\u00ebtu \u00ebsht\u00eb e r\u00ebnd\u00ebsishme t\u00eb kujtojm\u00eb se ne vendos\u00ebm t\u00eb ruajm\u00eb t\u00eb dh\u00ebnat n\u00eb form\u00eb t\u00eb kompresuar, k\u00ebshtu q\u00eb humbasim t\u00eb gjitha t\u00eb dh\u00ebnat n\u00eb faqe pas nj\u00eb regjistrimi 't\u00eb prishur', k\u00ebshtu q\u00eb edhe pse n\u00eb tabel\u00eb q\u00ebndron nj\u00eb minus, ne nuk e konsiderojm\u00eb at\u00eb.<\/p>\n<p><\/p>\n<p>Kompakt\u00ebsia:<\/p>\n<p><\/p>\n<ul>\n<li>n\u00eb variantin e par\u00eb na nevojitet t\u00eb ruajm\u00eb vet\u00ebm gjat\u00ebsin\u00eb n\u00eb titull, dhe n\u00eb qoft\u00eb se p\u00ebrdorim variabla me gjat\u00ebsi t\u00eb ndryshueshme, n\u00eb shumic\u00ebn e rasteve mund t\u00eb p\u00ebrmbushim me nj\u00eb byte;<\/li>\n<li>n\u00eb variantin e dyt\u00eb na nevojitet t\u00eb ruajm\u00eb adres\u00ebn fillestare dhe gjat\u00ebsin\u00eb; shkrimi duhet t\u00eb ket\u00eb nj\u00eb madh\u00ebsi t\u00eb konstant\u00eb, e vler\u00ebsoj n\u00eb 4 byte p\u00ebr shkrim (dy byte p\u00ebr deslocim, dhe dy byte p\u00ebr gjat\u00ebsi);<\/li>\n<li>n\u00eb variantin e tret\u00eb, na mjafton nj\u00eb simbol i vet\u00ebm p\u00ebr t\u00eb treguar fillimin e shkrimit, plus shkrimi vet\u00eb p\u00ebr shkak t\u00eb pakoh\u00ebsis\u00eb do t\u00eb rritet me 1-2%. Si rezultat, ka nj\u00eb barazim t\u00eb p\u00ebraf\u00ebrt me variantin e par\u00eb.<\/li>\n<\/ul>\n<p><\/p>\n<p>Fillimisht, e konsiderova variantin e dyt\u00eb si variantin kryesor (madje e shkrova dhe implementimin). E hoqa at\u00eb vet\u00ebm kur vendosa p\u00ebrfundimisht t\u00eb p\u00ebrdor kompresimin.<\/p>\n<p><\/p>\n<p><em>Ndoshta, ndonj\u00ebher\u00eb, do ta p\u00ebrdor k\u00ebt\u00eb variant. P\u00ebr shembull, n\u00ebse do t\u00eb m\u00eb duhet t\u00eb merrem me ruajtjen e t\u00eb dh\u00ebnave p\u00ebr nj\u00eb anije q\u00eb lundron midis Tok\u00ebs dhe Marsit - k\u00ebrkesat jan\u00eb krejt\u00ebsisht t\u00eb tjera p\u00ebr besueshm\u00ebri, rrezatimi kozmik, ...<\/em><\/p>\n<p><\/p>\n<p>Sa i p\u00ebrket variantit t\u00eb tret\u00eb: i kam dh\u00ebn\u00eb dy yje p\u00ebr kompleksitetin e implementimit thjesht sepse nuk e dua t\u00eb merrem me pakoh\u00ebsin\u00eb, ndryshimin e gjat\u00ebsi gjat\u00eb procesit etj. Po, ndoshta \u00ebsht\u00eb subjektiv, por kodi do t\u00eb duhet t\u00eb shkruhet nga un\u00eb - p\u00ebrse t\u00eb detyroj veten t\u00eb b\u00ebj di\u00e7ka q\u00eb nuk m\u00eb p\u00eblqen.<\/p>\n<p><\/p>\n<p><strong>P\u00ebrmbledhje:<\/strong> Zgjidhim variantin e ruajtjes n\u00eb form\u00eb zinxhiri 'titulli me gjat\u00ebsi - t\u00eb dh\u00ebna t\u00eb gjat\u00eb variable' p\u00ebr shkak t\u00eb efikasitetit dhe thjesht\u00ebsis\u00eb s\u00eb realizimit.<\/p>\n<p><\/p>\n<h3 id=\"ispolzovanie-bitovyh-poley-dlya-kontrolya-uspeshnosti-operaciy-zapisi\">P\u00ebrdorimi i fushave bit p\u00ebr kontrollin e suksessh\u00ebm t\u00eb operacioneve t\u00eb shkrimit<\/h3>\n<p><\/p>\n<p>Tani nuk e mbaj mend se ku e pash\u00eb iden\u00eb, por duket m\u00eb pak k\u00ebshtu:<br \/>\nP\u00ebr \u00e7do shkrim, ndajn\u00eb disa bit p\u00ebr ruajtjen e flamujve.<br \/>\n<em>Si\u00e7 tham\u00eb m\u00eb par\u00eb, pas erase t\u00eb gjith\u00eb bit\u00ebt jan\u00eb mbushur me 1, dhe ne mund t\u00eb ndryshojm\u00eb 1 n\u00eb 0, por jo p\u00ebrkundrazi.<\/em> Pra, p\u00ebr 'flag nuk \u00ebsht\u00eb vendosur' p\u00ebrdorim 1, p\u00ebr 'flag \u00ebsht\u00eb vendosur' - 0.<\/p>\n<p><\/p>\n<p>Ja si mund t\u00eb duket vendosja e nj\u00eb shkrimi me gjat\u00ebsi t\u00eb ndryshueshme n\u00eb flash:<\/p>\n<p><\/p>\n<ol>\n<li>Vendosim flamurin 'shkrimi i gjat\u00eb filloi';<\/li>\n<li>Shkruajm\u00eb gjat\u00ebsin\u00eb;<\/li>\n<li>Vendosim flamurin 'shkrimi i t\u00eb dh\u00ebnave filloi';<\/li>\n<li>Shkruajm\u00eb t\u00eb dh\u00ebnat;<\/li>\n<li>Vendosim flamurin 'shkrimi p\u00ebrfundoi'.<\/li>\n<\/ol>\n<p><\/p>\n<p>P\u00ebrve\u00e7 k\u00ebsaj, do t\u00eb kemi flamurin 'ndodhi nj\u00eb gabim', n\u00eb total 4 flamuj bit.<\/p>\n<p><\/p>\n<p>N\u00eb k\u00ebt\u00eb rast, ne kemi dy gjendje t\u00eb q\u00ebndrueshme '1111' - shkrimi nuk ka filluar dhe '1000' - shkrimi ka p\u00ebrfunduar me sukses; n\u00eb rast t\u00eb nj\u00eb nd\u00ebrprerje t\u00eb papritur t\u00eb procesit t\u00eb shkrimit do t\u00eb marrim gjendje t\u00eb nd\u00ebrmjetme, t\u00eb cilat ne m\u00eb pas mund t'i zbulojm\u00eb dhe t'i trajtojm\u00eb.<\/p>\n<p><\/p>\n<p>Qasja \u00ebsht\u00eb interesante, por ajo mbron vet\u00ebm nga fikja e papritur e energjis\u00eb dhe d\u00ebshtime t\u00eb ngjashme, gj\u00eb q\u00eb, natyrisht, \u00ebsht\u00eb e r\u00ebnd\u00ebsishme, megjithat\u00eb, kjo nuk \u00ebsht\u00eb arsyeja e vetme (dhe as kryesore) p\u00ebr d\u00ebshtimet e mundshme.<\/p>\n<p><\/p>\n<p><strong>P\u00ebrmbledhje:<\/strong> vazhdojm\u00eb n\u00eb k\u00ebrkimin e nj\u00eb zgjidhjeje t\u00eb mir\u00eb.<\/p>\n<p><\/p>\n<h3 id=\"kontrolnye-summy\">Kontrolli i shumave<\/h3>\n<p><\/p>\n<p>Kontrolli i shumave gjithashtu ofron mund\u00ebsin\u00eb p\u00ebr t\u00eb siguruar (me nj\u00eb probabilitet t\u00eb mjaftuesh\u00ebm) q\u00eb po lexojm\u00eb pik\u00ebrisht at\u00eb q\u00eb duhej t\u00eb ishte shkruar. Dhe, p\u00ebrkundrazi nga fushat e m\u00ebsip\u00ebrme, ato funksionojn\u00eb gjithmon\u00eb.<\/p>\n<p><\/p>\n<p>N\u00ebse shqyrtojm\u00eb list\u00ebn e burimeve t\u00eb mundshme t\u00eb problemeve, p\u00ebr t\u00eb cilat fol\u00ebm m\u00eb lart, kontrolli i shum\u00ebs \u00ebsht\u00eb n\u00eb gjendje t\u00eb identifikoj\u00eb nj\u00eb gabim pavar\u00ebsisht nga origjina e saj <em>(p\u00ebrve\u00e7 ndoshta alien\u00ebve t\u00eb keq, ata mund t\u00eb fshehin edhe kontrollin e shum\u00ebs)<\/em>.<\/p>\n<p><\/p>\n<p>Pra, n\u00ebse q\u00ebllimi yn\u00eb \u00ebsht\u00eb t\u00eb kontrollojm\u00eb se t\u00eb dh\u00ebnat jan\u00eb t\u00eb paprekura, kontrolli i shum\u00ebs \u00ebsht\u00eb nj\u00eb ide e shk\u00eblqyer.<\/p>\n<p><\/p>\n<p>Zgjedhja e algoritmit t\u00eb llogaritjes s\u00eb kontrollit t\u00eb shum\u00ebs nuk kishte asnj\u00eb pyetje - CRC. Nga nj\u00ebra an\u00eb, pronat matematikore lejojn\u00eb 100% t\u00eb kapin gabimet e disa llojeve, nga ana tjet\u00ebr - n\u00eb t\u00eb dh\u00ebna t\u00eb rast\u00ebsishme zakonisht ky algorit\u00ebm tregon nj\u00eb probabilitet kolizioni jo shum\u00eb m\u00eb t\u00eb lart\u00eb se kufiri teorik <img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/bf9cca3564db7d9d03d3ce49642d3a71.jpg\" style=\"display:block;margin: 0 auto;\" \/>. Le t\u00eb themi se nuk \u00ebsht\u00eb algoritmi m\u00eb i shpejt\u00eb, nuk \u00ebsht\u00eb gjithmon\u00eb minimal n\u00eb numrin e kolizioneve, por ka nj\u00eb cil\u00ebsi shum\u00eb t\u00eb r\u00ebnd\u00ebsishme: n\u00eb testet q\u00eb kam hasur, nuk kam gjetur modele q\u00eb do t\u00eb d\u00ebshtonin n\u00eb m\u00ebnyr\u00eb t\u00eb dukshme. Q\u00ebndrueshm\u00ebria - kjo \u00ebsht\u00eb cil\u00ebsia kryesore n\u00eb k\u00ebt\u00eb rast.<\/p>\n<p><\/p>\n<p>Shembulli i nj\u00eb studimi t\u00eb gjer\u00eb: <noindex><a rel=\"nofollow\" href=\"http:\/\/amsoftware.narod.ru\/algo.html\">pjesa 1<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"http:\/\/amsoftware.narod.ru\/algo2.html\">pjesa 2<\/a><\/noindex> <em>(linket n\u00eb narod.ru, faleminderit)<\/em>.<\/p>\n<p><\/p>\n<p>Megjithat\u00eb, detyra e zgjedhjes s\u00eb kontrollit t\u00eb shum\u00ebs nuk mbaron, CRC - kjo \u00ebsht\u00eb nj\u00eb familje e t\u00ebr\u00eb e kontrolleve t\u00eb shum\u00ebs. Duhet t\u00eb vendosim p\u00ebr gjat\u00ebsi, dhe pastaj t\u00eb zgjidhim polinomin.<\/p>\n<p><\/p>\n<p>Zgjedhja e gjat\u00ebsi s\u00eb kontrollit t\u00eb shum\u00ebs nuk \u00ebsht\u00eb nj\u00eb \u00e7\u00ebshtje e till\u00eb e thjesht\u00eb si\u00e7 duket n\u00eb shikim t\u00eb par\u00eb.<\/p>\n<p><\/p>\n<p>Do t\u00eb ilustroj:<br \/>\nLe t\u00eb supozojm\u00eb se kemi nj\u00eb probabilitet gabimi p\u00ebr \u00e7do bajt <img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/89a9be2edf2a43cc9115eba37fa02fc8.jpg\" style=\"display:block;margin: 0 auto;\" \/> dhe nj\u00eb checksum t\u00eb p\u00ebrsosur, llogarisim numrin mesatar t\u00eb gabimeve p\u00ebr nj\u00eb milion rekordesh:<\/p>\n<p><\/p>\n<p>T\u00eb dh\u00ebnat, bajt<br \/>\nChecksum, bajt<br \/>\nGabime t\u00eb padeklaruara<br \/>\nIdentifikime fals\u00eb t\u00eb gabimeve<br \/>\nTotali i goditjeve t\u00eb gabuara<\/p>\n<p>1<br \/>\n0<br \/>\n1000<br \/>\n0<br \/>\n1000<\/p>\n<p>1<br \/>\n1<br \/>\n4<br \/>\n999<br \/>\n1003<\/p>\n<p>1<br \/>\n2<br \/>\n\u22480<br \/>\n1997<br \/>\n1997<\/p>\n<p>1<br \/>\n4<br \/>\n\u22480<br \/>\n3990<br \/>\n3990<\/p>\n<p>10<br \/>\n0<br \/>\n9955<br \/>\n0<br \/>\n9955<\/p>\n<p>10<br \/>\n1<br \/>\n39<br \/>\n990<br \/>\n1029<\/p>\n<p>10<br \/>\n2<br \/>\n\u22480<br \/>\n1979<br \/>\n1979<\/p>\n<p>10<br \/>\n4<br \/>\n\u22480<br \/>\n3954<br \/>\n3954<\/p>\n<p>1000<br \/>\n0<br \/>\n632305<br \/>\n0<br \/>\n632305<\/p>\n<p>1000<br \/>\n1<br \/>\n2470<br \/>\n368<br \/>\n2838<\/p>\n<p>1000<br \/>\n2<br \/>\n10<br \/>\n735<br \/>\n745<\/p>\n<p>1000<br \/>\n4<br \/>\n\u22480<br \/>\n1469<br \/>\n1469<\/p>\n<p><\/p>\n<p>Duket e thjesht\u00eb \u2013 zgjidhni gjat\u00ebsi t\u00eb checksum-it n\u00eb var\u00ebsi t\u00eb t\u00eb dh\u00ebnave q\u00eb mbrohen me nj\u00eb minimum goditjesh t\u00eb gabuara \u2013 dhe pun\u00ebt jan\u00eb zgjidhur.<\/p>\n<p><\/p>\n<p>Megjithat\u00eb, me checksum-a t\u00eb shkurtra paraqitet nj\u00eb problem: ato, p\u00ebrderisa zbulojn\u00eb gabime t\u00eb vetme bajt\u00ebsh mir\u00eb, mund t\u00eb pranojn\u00eb si t\u00eb sakta t\u00eb dh\u00ebna krejt\u00ebsisht t\u00eb rast\u00ebsishme me nj\u00eb probabilitet t\u00eb konsideruesh\u00ebm. N\u00eb Habr\u00eb ka pasur nj\u00eb artikull q\u00eb p\u00ebrshkruan <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/428746\/\">problemin n\u00eb jet\u00ebn reale<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Prandaj, p\u00ebr ta b\u00ebr\u00eb takimin rast\u00ebsor me checksum m\u00eb praktikisht t\u00eb pamundur, duhet t\u00eb p\u00ebrdoren checksum-a me gjat\u00ebsi 32 bit dhe m\u00eb shum\u00eb. <em>(p\u00ebr gjat\u00ebsi mbi 64 bit zakonisht p\u00ebrdoren funksione hash kriptografike)<\/em>.<\/p>\n<p><\/p>\n<p>Megjith\u00ebse m\u00eb par\u00eb kam shkruar se duhet t\u00eb kursejm\u00eb hap\u00ebsir\u00eb me \u00e7do kusht, do t\u00eb p\u00ebrdorim nj\u00eb checksum 32-bit (16 bit \u00ebsht\u00eb pak, probabiliteti i kolizionit \u00ebsht\u00eb m\u00eb shum\u00eb se 0.01%; dhe 24 bit, si\u00e7 thon\u00eb, nuk shkon as k\u00ebtu e as atje).<\/p>\n<p><\/p>\n<p>K\u00ebtu mund t\u00eb ket\u00eb nj\u00eb kund\u00ebrshtim: a \u00ebsht\u00eb v\u00ebrtet aq shum\u00eb kemi kursyer \u00e7do bajt n\u00eb p\u00ebrzgjedhjen e kompresimit, p\u00ebr ta dh\u00ebn\u00eb tani 4 bajta menj\u00ebher\u00eb? A nuk do t\u00eb ishte m\u00eb mir\u00eb t\u00eb mos kompresonim dhe t\u00eb mos shtonim checksum-in? Sigurisht q\u00eb jo, mungesa e kompresimit <em>nuk do t\u00eb thot\u00eb<\/em>, se kontrolli i integritetit nuk \u00ebsht\u00eb i nevojsh\u00ebm p\u00ebr ne.<\/p>\n<p><\/p>\n<p>P\u00ebr zgjedhjen e polinom\u00ebve nuk do t\u00eb shpikim bi\u00e7iklet\u00ebn, por do t\u00eb marrim CRC-32C, q\u00eb \u00ebsht\u00eb tani i njohur.<br \/>\nKy kod zbulohet 6 gabime bajti n\u00eb paketa deri n\u00eb 22 bajt\u00eb (ndoshta rasti m\u00eb i zakonsh\u00ebm p\u00ebr ne), 4 gabime bajti n\u00eb paketa deri n\u00eb 655 bajt (po ashtu rasti i zakonsh\u00ebm), 2 ose \u00e7do num\u00ebr t\u00eb \u00e7uditsh\u00ebm gabimesh bajti n\u00eb paketa t\u00eb \u00e7do gjat\u00ebsie t\u00eb arsyeshme.<\/p>\n<p>\n<b class=\"spoiler_title\">N\u00ebse ndokush \u00ebsht\u00eb i interesuar p\u00ebr detajet<\/b><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cyclic_redundancy_check\">Artikulli n\u00eb Wikipedia<\/a><\/noindex> p\u00ebr CRC.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/users.ece.cmu.edu\/~koopman\/crc\/c32\/0x8f6e37a0_len.txt\">Parametrat e kodit crc-32c<\/a><\/noindex> n\u00eb <noindex><a rel=\"nofollow\" href=\"http:\/\/users.ece.cmu.edu\/~koopman\/crc\/notes.html\">n\u00eb sitin e Kupmanit<\/a><\/noindex> \u2013 ndoshta specialisti kryesor p\u00ebr CRC n\u00eb planet.<\/p>\n<p><\/p>\n<p>N\u00eb <noindex><a rel=\"nofollow\" href=\"http:\/\/users.ece.cmu.edu\/~koopman\/networks\/dsn02\/dsn02_koopman.pdf\">artikulli i tij<\/a><\/noindex> ka <noindex><a rel=\"nofollow\" href=\"https:\/\/users.ece.cmu.edu\/~koopman\/crc\/c32\/0xfa567d89_len.txt\">akoma nj\u00eb kod interesant<\/a><\/noindex>, q\u00eb ofron pak m\u00eb shum\u00eb parametra p\u00ebr gjat\u00ebsi paketa q\u00eb jan\u00eb t\u00eb r\u00ebnd\u00ebsishme p\u00ebr ne, por nuk e kam konsideruar ndryshimin t\u00eb konsideruesh\u00ebm, dhe mendoj q\u00eb jam mjaft kompetent p\u00ebr t\u00eb zgjedhur nj\u00eb kod t\u00eb personalizuar n\u00eb vend t\u00eb nj\u00eb standardi dhe t\u00eb studiuar mir\u00eb.<\/p>\n<p><\/p>\n<p>Gjithashtu, pasi t\u00eb dh\u00ebnat tona jan\u00eb t\u00eb kompresuara, lind pyetja: a duhet t\u00eb llogarisim checksum-in mbi t\u00eb dh\u00ebnat e kompresuara apo t\u00eb pakompresuara?<\/p>\n<p><\/p>\n<p>Argumentet 'p\u00ebr' llogaritjen e checksum-it t\u00eb t\u00eb dh\u00ebnave t\u00eb pakompresuara:<\/p>\n<p><\/p>\n<ul>\n<li>ne p\u00ebrfundimisht na nevojitet t\u00eb kontrollojm\u00eb ruajtjen e t\u00eb dh\u00ebnave \u2013 k\u00ebtu e kontrollojm\u00eb direkt (n\u00eb t\u00eb nj\u00ebjt\u00ebn koh\u00eb do t\u00eb kontrollohet gjithashtu se a ka pasur ndonj\u00eb gabim n\u00eb realizimin e kompresimit\/dekompresimit, d\u00ebmtime t\u00eb shkaktuara nga nj\u00eb kujtes\u00eb me gabime etj.);<\/li>\n<li>algoritmi deflate n\u00eb zlib ka nj\u00eb realizim mjaft t\u00eb pjekur dhe <em>nuk duhet<\/em> ka rrezik t\u00eb bjer\u00eb me 't\u00eb dh\u00ebna t\u00eb prishura', madje shpesh \u00ebsht\u00eb n\u00eb gjendje t\u00eb zbuloj\u00eb gabimet n\u00eb rrjedh\u00ebn hyr\u00ebse, duke e zvog\u00ebluar probabilitetin e p\u00ebrgjithsh\u00ebm t\u00eb moszbulimit t\u00eb gabimeve (kam kryer nj\u00eb test duke invertuar nj\u00eb bit t\u00eb vet\u00ebm n\u00eb nj\u00eb regjistrim t\u00eb shkurt\u00ebr, zlib zbuloi gabimin rreth nj\u00eb t\u00eb tret\u00ebn e rasteve).<\/li>\n<\/ul>\n<p><\/p>\n<p>Argumentet 'kundra' llogaritjes s\u00eb checksum-it t\u00eb t\u00eb dh\u00ebnave t\u00eb pakompresuara:<\/p>\n<p><\/p>\n<ul>\n<li>CRC \u00ebsht\u00eb 'i orientuar' pik\u00ebrisht p\u00ebr disa gabime bit t\u00eb pakta, t\u00eb cilat jan\u00eb karakteristike p\u00ebr kujtes\u00ebn flash (nj\u00eb gabim bit n\u00eb nj\u00eb rrjedh\u00eb t\u00eb kompresuar mund t\u00eb jap\u00eb ndryshime masive n\u00eb rrjedh\u00ebn e daljes, n\u00eb t\u00eb cil\u00ebn, teorikisht, mund t\u00eb 'kapim' nj\u00eb kolizion);<\/li>\n<li>nuk m\u00eb p\u00eblqen shum\u00eb ideja e d\u00ebrgimit t\u00eb t\u00eb dh\u00ebnave t\u00eb mundshme t\u00eb prishura n\u00eb dekompresor, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.cvedetails.com\/vulnerability-list\/vendor_id-72\/product_id-1820\/GNU-Zlib.html\">kush e di<\/a><\/noindex>, si do t\u00eb reagoj\u00eb ai.<\/li>\n<\/ul>\n<p><\/p>\n<p>N\u00eb k\u00ebt\u00eb projekt kam vendosur t\u00eb largohesha nga praktika e zakonshme p\u00ebr ruajtjen e checksum-it mbi t\u00eb dh\u00ebnat e pakompresuara.<\/p>\n<p><\/p>\n<p><strong>P\u00ebrmbledhje:<\/strong> p\u00ebrdorim CRC-32C, dhe checksum-in e llogarisim mbi t\u00eb dh\u00ebnat n\u00eb form\u00ebn e tyre si\u00e7 shkruhen n\u00eb flash (pas kompresimit).<\/p>\n<p><\/p>\n<h3 id=\"izbytochnost\">Mbivendosja<\/h3>\n<p><\/p>\n<p>P\u00ebrdorimi i kodimit t\u00eb tepruar nuk e lejon, sigurisht, p\u00ebrjashtimin e humbjes s\u00eb t\u00eb dh\u00ebnave, megjithat\u00eb, ai mund t\u00eb zvog\u00ebloj\u00eb ndjesh\u00ebm (shpesh disa renditje) probabilitetin e humbjes s\u00eb pakthyeshme t\u00eb t\u00eb dh\u00ebnave.<\/p>\n<p><\/p>\n<p>Ne mund t\u00eb p\u00ebrdorim lloje t\u00eb ndryshme t\u00eb tepric\u00ebs p\u00ebr t\u00eb korrigjuar gabimet.<br \/>\nKodet e Hamming-ut mund t\u00eb korrigjojn\u00eb gabime t\u00eb vetme bajti, kodet e Reed-Solomonit jan\u00eb simbolike, disa kopje t\u00eb t\u00eb dh\u00ebnave s\u00eb bashku me checksum-at ose kodimet si RAID-6 mund t\u00eb ndihmojn\u00eb n\u00eb rikuperimin e t\u00eb dh\u00ebnave edhe n\u00eb rast t\u00eb d\u00ebmtimeve masive.<br \/>\nFillimisht planifikoja t\u00eb p\u00ebrdorja gjer\u00ebsisht kodimin t\u00eb q\u00ebndruesh\u00ebm ndaj nd\u00ebrhyrjeve, por m\u00eb von\u00eb kuptova se fillimisht duhet t\u00eb kemi nj\u00eb ide se nga cilat gabime duam t\u00eb mbrohemi, dhe pastaj t\u00eb zgjedhim kodimin.<\/p>\n<p><\/p>\n<p>Kemi folur m\u00eb par\u00eb se gabimet duhet t\u00eb identifikohen sa m\u00eb shpejt t\u00eb jet\u00eb e mundur. N\u00eb cilat momente mund t\u00eb p\u00ebrballemi me gabime?<\/p>\n<p><\/p>\n<ol>\n<li>Regjistrimi i pap\u00ebrfunduar (p\u00ebr arsye t\u00eb ndryshme, n\u00eb momentin e regjistrimit u nd\u00ebrpre energjia, Raspberry u ngat\u00ebrrua, ...)<br \/>\nMe keqardhje, n\u00eb rastin e nj\u00eb gabimi t\u00eb till\u00eb, mbeten vet\u00ebm t\u00eb injorohen t\u00eb dh\u00ebnat e pavlefshme dhe t\u00eb merren si t\u00eb humbura;<\/li>\n<li>Gabime regjistrimi (p\u00ebr arsye t\u00eb ndryshme, n\u00eb memorien flash \u00ebsht\u00eb regjistruar di\u00e7ka tjet\u00ebr nga ajo q\u00eb u regjistrua)<br \/>\nGabime t\u00eb tilla mund t\u00eb zbulojm\u00eb menj\u00ebher\u00eb, n\u00ebse pas regjistrimit b\u00ebjm\u00eb nj\u00eb lexim kontrollues;<\/li>\n<li>Shk\u00ebputje t\u00eb t\u00eb dh\u00ebnave n\u00eb memorie gjat\u00eb ruajtjes;<\/li>\n<li>Gabime leximi<br \/>\nP\u00ebr ta korrigjuar mjafton t\u00eb p\u00ebrs\u00ebrisim leximin disa her\u00eb n\u00eb rast t\u00eb mosp\u00ebrputhjes s\u00eb checksum-it.<\/li>\n<\/ol>\n<p><\/p>\n<p>Pra, vet\u00ebm gabimet e tipit t\u00eb tret\u00eb (d\u00ebmtim spontan i t\u00eb dh\u00ebnave gjat\u00eb ruajtjes) nuk mund t\u00eb rregullohen pa kodim rezistent ndaj gabimeve. Mendoj se k\u00ebto gabime jan\u00eb shum\u00eb t\u00eb pamundura.<\/p>\n<p><\/p>\n<p><strong>P\u00ebrmbledhje:<\/strong> u vendos q\u00eb t\u00eb heqim dor\u00eb nga kodimi i tep\u00ebrt, por, n\u00ebse shfryt\u00ebzimi tregoi gabueshm\u00ebrin\u00eb e k\u00ebtij vendimi, at\u00ebher\u00eb do t\u00eb kthehemi n\u00eb shqyrtimin e k\u00ebtij \u00e7\u00ebshtje (me statistik\u00ebn e grumbulluar p\u00ebr d\u00ebshtime, e cila do t\u00eb lejoj\u00eb t\u00eb p\u00ebrzgjedhim llojin optimal t\u00eb kodimit).<\/p>\n<p><\/p>\n<h3 id=\"prochee\">T\u00eb tjera<\/h3>\n<p><\/p>\n<p>Natyrisht, formati i artikullit nuk lejon t\u00eb arsyetohet \u00e7do bit n\u00eb format <em>(dhe edhe un\u00eb tashm\u00eb kam mbaruar forc\u00ebn)<\/em>, prandaj do t\u00eb kaloj holl\u00ebsisht mbi disa pika, t\u00eb pa p\u00ebrmendura m\u00eb par\u00eb.<\/p>\n<p><\/p>\n<ul>\n<li>\u00cbsht\u00eb vendosur t\u00eb b\u00ebjm\u00eb t\u00eb gjitha faqet 'me t\u00eb drejta t\u00eb barabarta'<br \/>\nPra, nuk do t\u00eb ket\u00eb faqe speciale me metadata, rrug\u00eb t\u00eb ve\u00e7anta etj., n\u00eb vend t\u00eb k\u00ebsaj nj\u00eb rrjedh\u00eb e vetme, e cila regjistron t\u00eb gjitha faqet nj\u00ebra pas tjetr\u00ebs.<br \/>\nKjo siguron konsum t\u00eb barabart\u00eb t\u00eb faqeve, munges\u00ebn e nj\u00eb pik\u00eb t\u00eb vetme d\u00ebshtimi, dhe thjesht p\u00eblqen;<\/li>\n<li>Patjet\u00ebr q\u00eb duhet t\u00eb parashikohet versioni i formatit.<br \/>\nFormati pa num\u00ebr versioni n\u00eb titull \u2014 \u00ebsht\u00eb nj\u00eb e keqe!<br \/>\nMjafton t\u00eb shtoni n\u00eb titullin e faqes nj\u00eb fush\u00eb me nj\u00eb num\u00ebr Magjik (n\u00ebnshkrimi), i cili do t\u00eb tregoj\u00eb versionin e p\u00ebrdorur t\u00eb formatit <em>(nuk mendoj se n\u00eb praktik\u00eb do t\u00eb jen\u00eb m\u00eb shum\u00eb se dhjet\u00eb)<\/em>;<\/li>\n<li>T\u00eb p\u00ebrdoren p\u00ebr regjistrimet (t\u00eb cilat jan\u00eb shum\u00eb) tituj variab\u00ebl t\u00eb gjat\u00eb, duke u p\u00ebrpjekur p\u00ebr shumic\u00ebn e rasteve ta b\u00ebjm\u00eb at\u00eb me gjat\u00ebsi 1 byte;<\/li>\n<li>P\u00ebr kodimin e gjat\u00eb t\u00eb titullit dhe gjat\u00ebsi t\u00eb pjes\u00ebs s\u00eb prer\u00eb t\u00eb regjistrimit t\u00eb ngjeshur, p\u00ebrdorni kode binar\u00ebsh t\u00eb gjat\u00eb variab\u00ebl.<\/li>\n<\/ul>\n<p><\/p>\n<p>M\u00eb shum\u00eb ndihmoi <noindex><a rel=\"nofollow\" href=\"https:\/\/planetcalc.com\/2481\/\">generaatori online<\/a><\/noindex> i kodimeve Huffman. Gjat\u00eb disa minutave arrit\u00ebm t\u00eb gjejm\u00eb kodet e nevojshme t\u00eb gjat\u00eb variab\u00ebl.<\/p>\n<p><\/p>\n<h1 id=\"anchorformatanchoropisanie-formata-hraneniya-dannyh\"><noindex><a rel=\"nofollow\" name=\"format\"><\/a><\/noindex>P\u00ebrshkrimi i formatit t\u00eb ruajtjes s\u00eb t\u00eb dh\u00ebnave<\/h1>\n<p><\/p>\n<h2 id=\"byte-order\">Rendi i bajt\u00ebve<\/h2>\n<p><\/p>\n<p>Fushat, t\u00eb cilat jan\u00eb m\u00eb t\u00eb m\u00ebdha se nj\u00eb byte, ruhen n\u00eb formatin big-endian (rendi i bajt\u00ebve t\u00eb rrjetit), q\u00eb do t\u00eb thot\u00eb 0x1234 regjistrohet si 0x12, 0x34.<\/p>\n<p><\/p>\n<h2 id=\"delenie-na-stranicy\">Ndarja n\u00eb faqe<\/h2>\n<p><\/p>\n<p>T\u00eb gjith\u00eb memorien flash \u00ebsht\u00eb e ndar\u00eb n\u00eb faqe t\u00eb barabarta.<\/p>\n<p><\/p>\n<p>Madh\u00ebsia e faqes p\u00ebr default \u00ebsht\u00eb 32Kb, por jo m\u00eb shum\u00eb se 1\/4 e madh\u00ebsis\u00eb totale t\u00eb \u00e7ipit t\u00eb memories (p\u00ebr nj\u00eb \u00e7ip prej 4Mb rezulton 128 faqe).<\/p>\n<p><\/p>\n<p>\u00c7do faqe ruan t\u00eb dh\u00ebna n\u00eb m\u00ebnyr\u00eb t\u00eb pavarur nga t\u00eb tjerat (do t\u00eb thot\u00eb t\u00eb dh\u00ebnat e nj\u00eb faqe nuk referohen n\u00eb t\u00eb dh\u00ebnat e nj\u00eb faqe tjet\u00ebr).<\/p>\n<p><\/p>\n<p>T\u00eb gjitha faqet jan\u00eb t\u00eb num\u00ebruara n\u00eb rendin e natyrsh\u00ebm (n\u00eb rritje t\u00eb adresave), duke filluar nga numri 0 (faqja zero fillon me adres\u00ebn 0, e para \u2014 me 32Kb, e dyta \u2014 me 64Kb etj.)<\/p>\n<p><\/p>\n<p>Memoria p\u00ebrdoret si nj\u00eb buffer ciklik (ring buffer), do thot\u00eb se fillimisht regjistrimi shkon n\u00eb faqen me num\u00ebr 0, pastaj n\u00eb faqen me num\u00ebr 1, ..., kur mbushim faqen e fundit, fillon nj\u00eb cik\u00ebl i ri dhe regjistrimi vazhdon nga faqja zero.<\/p>\n<p><\/p>\n<h2 id=\"vnutri-stranicy\">Brenda faqes<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/39b45f83dc46bb2fd7081ed2a0b638c9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nN\u00eb fillim t\u00eb faqes ruhet nj\u00eb header 4-byte i faqes, pastaj nj\u00eb kontrollues i checksum-it (CRC-32C), m\u00eb pas ruhet regjistrimet n\u00eb formatin \"header, t\u00eb dh\u00ebna, checksum.\"<\/p>\n<p><\/p>\n<p>Titulli i faqes (n\u00eb skem\u00ebn e gjelb\u00ebr t\u00eb ndotur) p\u00ebrb\u00ebhet nga:<\/p>\n<p><\/p>\n<ul>\n<li>nj\u00eb fushe dy bajtesh Magic Number (kjo \u00ebsht\u00eb gjithashtu \u2014 shenja e versionit t\u00eb formatit)<br \/>\np\u00ebr versionin aktual t\u00eb formatit konsiderohet si <code>0xed00 \u2295 numri i faqes<\/code>;<\/li>\n<li>Nj\u00eb num\u00ebrues dy-byte \"Versioni i faqes\" (numri i ciklit t\u00eb rip\u00ebrs\u00ebritjes s\u00eb memories).<\/li>\n<\/ul>\n<p><\/p>\n<p>Regjistrimet n\u00eb faqe ruhen n\u00eb form\u00eb t\u00eb ngjeshur (p\u00ebrdoret algoritmi deflate). T\u00eb gjitha regjistrimet n\u00eb nj\u00eb faqe ngjeshen n\u00eb nj\u00eb rrjedh\u00eb (p\u00ebrdoret nj\u00eb fjalor i p\u00ebrbashk\u00ebt), n\u00eb \u00e7do faqe t\u00eb re ngjeshja fillon nga e para. Pra, p\u00ebr dekompresimin e \u00e7do regjistrimi k\u00ebrkohen t\u00eb gjitha regjistrimet e m\u00ebparshme nga kjo faqe (dhe vet\u00ebm nga kjo).<\/p>\n<p><\/p>\n<p>\u00c7do regjistrim ngjeshet me flagun Z_SYNC_FLUSH, n\u00eb at\u00eb rast n\u00eb fund t\u00eb rrjedh\u00ebs s\u00eb ngjeshur gjenden 4 bajt\u00eb 0x00, 0x00, 0xff, 0xff, p\u00ebrpara, mund\u00ebsisht, nga nj\u00eb ose dy bajt\u00eb zero.<br \/>\nK\u00ebt\u00eb sekuenc\u00eb (me gjat\u00ebsi 4, 5 ose 6 bajt\u00eb) ne e heqim kur regjistrojm\u00eb n\u00eb memorien flash.<\/p>\n<p><\/p>\n<p>Titulli i regjistrimit p\u00ebrb\u00ebhet nga 1, 2 ose 3 bajt\u00eb, q\u00eb ruajn\u00eb:<\/p>\n<p><\/p>\n<ul>\n<li>nj\u00eb bit (T), q\u00eb n\u00ebnkupton tipin e regjistrimit: 0 \u2014 kontekst, 1 \u2014 ditar;<\/li>\n<li>Nj\u00eb fush\u00eb me gjat\u00ebsi t\u00eb ndryshueshme (S) nga 1 deri n\u00eb 7 bit, e cila p\u00ebrcakton gjat\u00ebsi e header-it dhe \"bishtit\" q\u00eb duhet shtuar n\u00eb regjistrim p\u00ebr dekompresim;<\/li>\n<li>gjat\u00ebsin\u00eb e regjistrimit (L).<\/li>\n<\/ul>\n<p><\/p>\n<p>Tabela e vlerave S:<\/p>\n<p><\/p>\n<p>S<br \/>\nGjat\u00ebsia e titullit, bajt\u00eb<br \/>\nHeket gjat\u00eb regjistrimit, byte<\/p>\n<p><code>0<\/code><br \/>\n1<br \/>\n5 (<code>00 00 00 ff ff<\/code>)<\/p>\n<p><code>10<\/code><br \/>\n1<br \/>\n6 (<code>00 00 00 00 ff ff<\/code>)<\/p>\n<p><code>110<\/code><br \/>\n2<br \/>\n4 (<code>00 00 ff ff<\/code>)<\/p>\n<p><code>1110<\/code><br \/>\n2<br \/>\n5 (<code>00 00 00 ff ff<\/code>)<\/p>\n<p><code>11110<\/code><br \/>\n2<br \/>\n6 (<code>00 00 00 00 ff ff<\/code>)<\/p>\n<p><code>1111100<\/code><br \/>\n3<br \/>\n4 (<code>00 00 ff ff<\/code>)<\/p>\n<p><code>1111101<\/code><br \/>\n3<br \/>\n5 (<code>00 00 00 ff ff<\/code>)<\/p>\n<p><code>1111110<\/code><br \/>\n3<br \/>\n6 (<code>00 00 00 00 ff ff<\/code>)<\/p>\n<p><\/p>\n<p>P\u00ebrpiqem t\u00eb ilustroj, nuk e di sa qart\u00eb ka dal\u00eb:<br \/>\n<img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/8c9b739eec5af4429395c32b4ba4044a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMe t\u00eb verdh\u00eb \u00ebsht\u00eb sh\u00ebnuar fusha T, me t\u00eb bardh\u00eb fusha S, me t\u00eb gjelb\u00ebr L (gjat\u00ebsia e t\u00eb dh\u00ebnave t\u00eb kompresuara n\u00eb byte), me t\u00eb kalt\u00ebr t\u00eb dh\u00ebnat e kompresuara, me t\u00eb kuqe byte t\u00eb fundit t\u00eb t\u00eb dh\u00ebnave t\u00eb kompresuara, t\u00eb cilat nuk shkruhen n\u00eb flash-memory.<\/p>\n<p><\/p>\n<p>K\u00ebshtu, ne do t\u00eb jemi n\u00eb gjendje t\u00eb regjistrojm\u00eb titujt e regjistrimeve me gjat\u00ebsi m\u00eb t\u00eb zakonshme (deri 63+5 byte n\u00eb form\u00eb t\u00eb kompresuar) me nj\u00eb byte.<\/p>\n<p><\/p>\n<p>Pas \u00e7do regjistrimi ruhet nj\u00eb checksum CRC-32C, ku vlefshm\u00ebria fillestare (init) \u00ebsht\u00eb nj\u00eb vler\u00eb e inversuar e kontrolles s\u00eb m\u00ebparshme.<\/p>\n<p><\/p>\n<p><em>CRC ka nj\u00eb pron\u00eb \"p\u00ebrfshirjeje\", vepron (plus-minus invertimi i biteve gjat\u00eb procesit) me k\u00ebt\u00eb formul\u00eb: <img decoding=\"async\" alt=\"Implementimi im i buffers ring n\u00eb NOR flash\" src=\"\/wp-content\/uploads\/2019\/12\/b194d6a3d18ae2f4ae5d4054a93c0ea3.jpg\" style=\"display:block;margin: 0 auto;\" \/>.<br \/>\nPra, n\u00eb thelb ne llogarisim CRC t\u00eb gjith\u00eb byte t\u00eb titujve dhe t\u00eb dh\u00ebnave t\u00eb k\u00ebsaj faqe.<\/em><\/p>\n<p><\/p>\n<p>Menj\u00ebher\u00eb pas checksum-it ndodhet titulli i regjistrimit t\u00eb ardhsh\u00ebm.<\/p>\n<p><\/p>\n<p>Titulli \u00ebsht\u00eb nd\u00ebrtuar n\u00eb m\u00ebnyr\u00eb q\u00eb byte i pare t\u00eb jet\u00eb gjithmon\u00eb ndryshe nga 0x00 dhe 0xff (n\u00ebse p\u00ebrball\u00eb byte t\u00eb par\u00eb t\u00eb titullit hasim 0xff, at\u00ebher\u00eb kjo \u00ebsht\u00eb nj\u00eb zon\u00eb q\u00eb nuk po p\u00ebrdoret; 0x00 e sinjalizon nj\u00eb gabim).<\/p>\n<p><\/p>\n<h2 id=\"primernye-algoritmy\">Algoritmet p\u00ebrkat\u00ebs<\/h2>\n<p><\/p>\n<h3 id=\"chtenie-iz-flesh-pamyati\">Leximi nga flash-memory<\/h3>\n<p><\/p>\n<p>\u00c7do lexim shoq\u00ebrohet me verifikimin e checksum-it.<br \/>\nN\u00ebse checksum-i nuk p\u00ebrputhet - leximi p\u00ebrs\u00ebritet disa her\u00eb n\u00eb shpres\u00eb p\u00ebr t\u00eb lexuar t\u00eb dh\u00ebnat e sakta.<\/p>\n<p><\/p>\n<p><em>(kjo ka kuptim, Linux nuk ruan leximin nga NOR Flash, e verifikuar)<\/em><\/p>\n<p><\/p>\n<h3 id=\"zapis-v-flesh-pamyat\">Shkruaj n\u00eb flash-memory<\/h3>\n<p><\/p>\n<p>Regjistro b\u00ebj t\u00eb dh\u00ebnat.<br \/>\nLexoj ato.<\/p>\n<p><\/p>\n<p>N\u00ebse t\u00eb dh\u00ebnat e lexuara nuk p\u00ebrputhen me ato t\u00eb regjistruara - mbushim zon\u00ebn me zero dhe sinjalizojm\u00eb p\u00ebr nj\u00eb gabim.<\/p>\n<p><\/p>\n<h3 id=\"podgotovka-novoy-mikroshemy-k-rabote\">P\u00ebrgatitja e mikro\u00e7ip\u00ebve t\u00eb reja p\u00ebr pun\u00eb<\/h3>\n<p><\/p>\n<p>P\u00ebr inicializim n\u00eb faqen e par\u00eb (sakt\u00ebsisht zero) shkruhet nj\u00eb titull me versionin 1.<br \/>\nPas k\u00ebsaj, n\u00eb k\u00ebt\u00eb faqe shkruhet konteksti fillestar (p\u00ebrmban UUID t\u00eb automatit dhe cil\u00ebsimet e paracaktuara). <\/p>\n<p><\/p>\n<p>Kjo, flash-memory \u00ebsht\u00eb gatshme p\u00ebr pun\u00eb.<\/p>\n<p><\/p>\n<h3 id=\"zagruzka-avtomata\">Ngarkimi i automatit<\/h3>\n<p><\/p>\n<p>Me ngarkim lexohen 8 byte t\u00eb par\u00eb t\u00eb \u00e7do faqe (titulli + CRC), faqet me numrin e Magic Number t\u00eb panjohur ose CRC t\u00eb gabuar injorohen.<br \/>\nNga faqet \"e sakta\" p\u00ebrzgjidhen faqet me versionin maksimal, nga ato merret faqja me numrin m\u00eb t\u00eb madh.<br \/>\nRegjistrohet regjistrimi i par\u00eb, verifikohet sakt\u00ebsia e CRC, pranin\u00eb e flamurit \"kontekst.\" N\u00ebse gjith\u00e7ka \u00ebsht\u00eb n\u00eb rregull, kjo faqe konsiderohet aktuale. N\u00ebse jo, kthehemi n\u00eb faqen e kaluar derisa t\u00eb gjejm\u00eb nj\u00eb faqe \"aktive.\"<br \/>\nDhe n\u00eb faqe t\u00eb gjetur regjistrojm\u00eb t\u00eb gjitha regjistrimet, ato me flamurin \"kontekst\" i zbatojm\u00eb.<br \/>\nRuajm\u00eb fjalorin zlib (do t\u00eb nevojitet p\u00ebr regjistrim t\u00eb m\u00ebtejsh\u00ebm n\u00eb k\u00ebt\u00eb faqe).<\/p>\n<p><\/p>\n<p>Kjo, ngarkimi p\u00ebrfundoi, konteksti u rikuperua, mund t\u00eb punojm\u00eb.<\/p>\n<p><\/p>\n<h3 id=\"dobavlenie-zapisi-v-zhurnal\">Shtimi i regjistrimeve n\u00eb ditar<\/h3>\n<p><\/p>\n<p>Kompresojm\u00eb regjistrimin me fjalorin e duhur, duke \u0443\u043a\u0430\u0437\u0438\u0432\u0430\u043b Z_SYNC_FLUSH. Shikojm\u00eb n\u00ebse regjistrimi i kompresuar po hyn n\u00eb faqen aktuale.<br \/>\nN\u00ebse nuk hyn (apo n\u00eb faqe kishte gabime CRC) - fillojm\u00eb nj\u00eb faqe t\u00eb re (shiko t\u00eb m\u00ebposhtme).<br \/>\nRegjistro regjistrimin dhe CRC. N\u00ebse ndodhi nj\u00eb gabim - fillojm\u00eb nj\u00eb faqe t\u00eb re.<\/p>\n<p><\/p>\n<h3 id=\"novaya-stranica\">Faqe e re<\/h3>\n<p><\/p>\n<p>Zgjidhim nj\u00eb faqe t\u00eb lir\u00eb me numrin minimal (faqe e lir\u00eb e konsiderojm\u00eb faqen me checksum t\u00eb gabuar n\u00eb titull ose me version m\u00eb t\u00eb vog\u00ebl se aktuali). N\u00ebse nuk ka faqe t\u00eb tilla - zgjedhim faqen me numrin minimal nga ata q\u00eb kan\u00eb version t\u00eb barabart\u00eb me at\u00eb aktual.<br \/>\nB\u00ebjm\u00eb faqen e zgjedhur erase. Krahasojm\u00eb p\u00ebrmbajtjen me 0xff. N\u00ebse di\u00e7ka nuk \u00ebsht\u00eb n\u00eb rregull - marrim faqen tjet\u00ebr t\u00eb lir\u00eb, etj.<br \/>\nN\u00eb faqen e fshir\u00eb shkruajm\u00eb titullin, regjistrimi i par\u00eb \u00ebsht\u00eb gjendja aktuale e kontekstit, regjistrimi i dyt\u00eb \u00ebsht\u00eb regjistrimi i pa regjistruar n\u00eb ditar (n\u00ebse ka).<\/p>\n<p><\/p>\n<h1 id=\"primenimost-formata\">P\u00ebrkufizimi i formatit<\/h1>\n<p><\/p>\n<p>Sipas mendimit tim, doli nj\u00eb format i mir\u00eb p\u00ebr ruajtjen e \u00e7do informate m\u00eb shum\u00eb se sa e kompresueshme (teksti i thjesht\u00eb, JSON, MessagePack, CBOR, ndoshta protobuf) n\u00eb NOR Flash.<\/p>\n<p><\/p>\n<p>Sigurisht, formati \u00ebsht\u00eb \"i dizajnuar\" p\u00ebr SLC NOR Flash.<\/p>\n<p><\/p>\n<p>Nuk duhet ta p\u00ebrdorni me mbajt\u00ebs me BER t\u00eb lart\u00eb, si\u00e7 jan\u00eb NAND ose MLC NOR <em>(a ka nj\u00eb memory t\u00eb till\u00eb n\u00eb shitje? Kam hasur vet\u00ebm p\u00ebrmendje n\u00eb punime mbi kodet e korrigjimit)<\/em>.<\/p>\n<p><\/p>\n<p>M\u00eb shum\u00eb, nuk duhet ta p\u00ebrdorni me pajisje, q\u00eb kan\u00eb FTL e tyre: USB flash, SD, MicroSD, etj. <em>(p\u00ebr at\u00eb memorie kam b\u00ebr\u00eb nj\u00eb format me madh\u00ebsin\u00eb e faqes 512 byte, me nj\u00eb n\u00ebnshkrim n\u00eb fillim t\u00eb \u00e7do faqe dhe numra unik t\u00eb regjistrimeve \u2014 nganj\u00ebher\u00eb nga nj\u00eb flash \"t\u00eb prishur\" mund t\u00eb rikuperohet t\u00eb dh\u00ebnat e plota me lexim t\u00eb thjesht\u00eb sekondar.)<\/em>.<\/p>\n<p><\/p>\n<p>N\u00eb var\u00ebsi t\u00eb detyrave formati mund t\u00eb p\u00ebrdoret pa ndryshime n\u00eb flash nga 128Kbit (16Kbyte) deri n\u00eb 1Gbit (128Mbyte). N\u00ebse d\u00ebshirohet, mund t\u00eb p\u00ebrdoret edhe n\u00eb \u00e7ipe m\u00eb t\u00eb m\u00ebdhenj, thjesht ndoshta duhet t\u00eb korrigjohet madh\u00ebsia e faqes <em>(Por k\u00ebtu lind pyetja e q\u00ebllimshm\u00ebris\u00eb ekonomike, \u00e7mimi i NOR Flash me kapacitet t\u00eb madh nuk \u00ebsht\u00eb i k\u00ebnaqsh\u00ebm)<\/em>.<\/p>\n<p><\/p>\n<p>N\u00ebse dikujt format i ka dukur interesant dhe d\u00ebshiron ta p\u00ebrdor\u00eb n\u00eb nj\u00eb projekt t\u00eb hapur - na shkruani, do t\u00eb p\u00ebrpiqem t\u00eb gjej koh\u00eb, t\u00eb rregulloj kodin dhe ta publikoj n\u00eb github.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">P\u00ebrfundimi<\/h1>\n<p><\/p>\n<p>Si\u00e7 e shohim, n\u00eb fund formatit i doli t\u00eb ishte i thjesht\u00eb <em>dhe madje i m\u00ebrzitsh\u00ebm<\/em>.<\/p>\n<p><\/p>\n<p>N\u00eb artikull \u00ebsht\u00eb e v\u00ebshtir\u00eb t\u00eb pasqyrosh evolucionin e pik\u00ebpamjes time, por besoni: fillimisht doja t\u00eb krijoja di\u00e7ka t\u00eb sofistikuar, t\u00eb patundshme, e cila do t\u00eb mbijetonte edhe pas nj\u00eb shp\u00ebrthimi b\u00ebrthamor n\u00eb af\u00ebrsi. Sidoqoft\u00eb, arsyetimi (shpresoj) n\u00eb fund t\u00eb fitoi dhe gradualisht prioritetet u zhvendos\u00ebn drejt thjesht\u00ebsis\u00eb dhe kompakt\u00ebsis\u00eb.<\/p>\n<p><\/p>\n<p>A mund t\u00eb ndodh\u00eb q\u00eb kam gabuar? Po, sigurisht. Mund t\u00eb ndodh\u00eb, p\u00ebr shembull, q\u00eb kemi bler\u00eb nj\u00eb koleksion \u00e7ipash t\u00eb dob\u00ebt. Ose p\u00ebr ndonj\u00eb arsye tjet\u00ebr pajisja nuk do t\u00eb p\u00ebrmbush\u00eb pritshm\u00ebrit\u00eb p\u00ebr besueshm\u00ebri.<\/p>\n<p><\/p>\n<p>A kam nj\u00eb plan p\u00ebr k\u00ebt\u00eb rast? Mendoj se pas leximit t\u00eb artikullit nuk keni dyshime se plani ekziston. Dhe madje jo vet\u00ebm nj\u00eb.<\/p>\n<p><\/p>\n<p>N\u00ebse pak m\u00eb seriozisht, formati \u00ebsht\u00eb zhvilluar nj\u00ebkoh\u00ebsisht si nj\u00eb variant funksional dhe si nj\u00eb \"prov\u00eb.\"<\/p>\n<p><\/p>\n<p>Aktualisht, gjith\u00e7ka funksionon mir\u00eb, p\u00ebrdit\u00ebsimi do t\u00eb b\u00ebhet p\u00ebr disa dit\u00eb <em>(p\u00ebr af\u00ebrsisht)<\/em> n\u00eb nj\u00eb qind pajisje, do t\u00eb shohim se \u00e7far\u00eb do ndodh\u00eb n\u00eb \"eksperimentin\" e v\u00ebrtet\u00eb (shpresoj, formati lejon t\u00eb identifikohen besuesh\u00ebm d\u00ebshtimet; k\u00ebshtu q\u00eb do t\u00eb mund t\u00eb mbledhim statistik\u00eb t\u00eb plot\u00eb). Pas disa muajsh do t\u00eb jet\u00eb e mundur t\u00eb nxirren p\u00ebrfundime. <em>(n\u00ebse nuk kemi fat - at\u00ebher\u00eb edhe m\u00eb her\u00ebt)<\/em>.<\/p>\n<p><\/p>\n<p>N\u00ebse pas p\u00ebrdorimit identifikohet ndonj\u00eb problem serioz dhe k\u00ebrkohen rregullime, un\u00eb do t\u00eb shkruaj patjet\u00ebr p\u00ebr t\u00eb.<\/p>\n<p><\/p>\n<h1 id=\"literatura\">Literatura<\/h1>\n<p><\/p>\n<p>Nuk doja t\u00eb p\u00ebrgatitja nj\u00eb list\u00eb t\u00eb gjat\u00eb dhe t\u00eb m\u00ebrzitshme t\u00eb pun\u00ebve t\u00eb p\u00ebrdorura, n\u00eb fund t\u00eb fundit, Google \u00ebsht\u00eb p\u00ebr t\u00eb gjith\u00eb.<\/p>\n<p><\/p>\n<p>Vendosa t\u00eb l\u00eb nj\u00eb list\u00eb nx\u00ebniesh, t\u00eb cilat m\u00eb dukeshin ve\u00e7an\u00ebrisht interesante, megjithat\u00eb gradualisht ato kaluan drejtp\u00ebrdrejt n\u00eb tekstin e artikullit, dhe n\u00eb list\u00eb mbeti vet\u00ebm nj\u00eb pik\u00eb:<\/p>\n<p><\/p>\n<ol>\n<li>Utilitari <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/madler\/infgen\/\">infgen<\/a><\/noindex> nga autori zlib. Ajo tregon p\u00ebrmbajtjen e arkivave deflate\/zlib\/gzip n\u00eb nj\u00eb form\u00eb t\u00eb kuptueshme. N\u00ebse ndiheni t\u00eb detyruar t\u00eb merreni me struktur\u00ebn e brendshme t\u00eb formatit deflate (ose gzip) - e rekomandoj me ngulm.<\/li>\n<\/ol>\n<p>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/479044\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f \u0415\u0441\u0442\u044c \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u043d\u0443\u0442\u0440\u0438 Raspberry Pi \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0432\u044f\u0437\u043a\u0438 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043c\u043e\u043d\u0435\u0442\u043e\u043f\u0440\u0438\u0451\u043c\u043d\u0438\u043a, \u043a\u0443\u043f\u044e\u0440\u043e\u043f\u0440\u0438\u0451\u043c\u043d\u0438\u043a, \u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a\u0438\u0439 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u2026 \u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435\u043c \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430. \u0412\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u043d\u0430 \u0444\u043b\u0435\u0448\u043a\u0435 (MicroSD), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e USB-\u043c\u043e\u0434\u0435\u043c\u0430) \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0442\u0430\u043c \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0411\u0414. \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0432 1\u0441, \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-53751","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f \u0415\u0441\u0442\u044c \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u043d\u0443\u0442\u0440\u0438 Raspberry Pi \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0432\u044f\u0437\u043a\u0438 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041c\u043e\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0432 NOR flash | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f \u0415\u0441\u0442\u044c \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u043d\u0443\u0442\u0440\u0438 Raspberry Pi \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0432\u044f\u0437\u043a\u0438 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-12-08T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:01:41+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Implementimi im i tamponit ring n\u00eb NOR flash | ProHoster","description":"Pas historia Ka jan\u00eb automatet e tregtis\u00eb t\u00eb zhvilluar vet\u00eb. Brenda ka nj\u00eb Raspberry Pi dhe pak komponent\u00eb t\u00eb tjer\u00eb n\u00eb nj\u00eb pllakat t\u00eb ve\u00e7ant\u00eb.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041c\u043e\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0432 NOR flash | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f \u0415\u0441\u0442\u044c \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u043d\u0443\u0442\u0440\u0438 Raspberry Pi \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0432\u044f\u0437\u043a\u0438 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/moya-realizatsiya-koltsevogo-bufera-v-nor-flash","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-12-08T21:00:00+00:00","article:modified_time":"2020-02-18T11:01:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"53751","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 08:36:23","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:18:30","updated":"2026-01-24 08:36:23","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/53751","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=53751"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/53751\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=53751"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=53751"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=53751"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}