{"id":803,"date":"2018-05-03T23:12:16","date_gmt":"2018-05-03T23:12:16","guid":{"rendered":"http:\/\/hayperek.pl\/?p=803"},"modified":"2018-05-04T09:28:37","modified_gmt":"2018-05-04T09:28:37","slug":"co-z-ta-konfiguracja-czesc-3","status":"publish","type":"post","link":"https:\/\/hayperek.pl\/en\/2018\/05\/03\/co-z-ta-konfiguracja-czesc-3\/","title":{"rendered":"Co z t\u0105 konfiguracj\u0105? \u2013 cz\u0119\u015b\u0107 3"},"content":{"rendered":"<p>Dzi\u015b na moment ponownie powr\u00f3cimy do tematu konfiguracji. Jak pami\u0119tacie z <a href=\"http:\/\/hayperek.pl\/en\/2018\/04\/30\/co-z-ta-konfiguracja-czesc-2\/\">poprzednich artyku\u0142\u00f3w<\/a>, zdecydowali\u015bmy si\u0119 przechowywa\u0107 ca\u0142\u0105 konfiguracj\u0119 w formie pliku JSON na karcie pami\u0119ci. Uda\u0142o si\u0119 tak\u017ce stworzy\u0107 odpowiedni parser, kt\u00f3rego zadaniem b\u0119dzie przet\u0142umaczenie tekstowego formatu pliku JSON na binarn\u0105 struktur\u0119, zrozumia\u0142\u0105 dla naszych aplikacji. Spr\u00f3bujmy zastanowi\u0107 si\u0119 jak powinien wygl\u0105da\u0107 przep\u0142yw informacji: od pliku na karcie SD a\u017c do momentu zaaplikowania konfiguracji w okre\u015blonych komponentach systemu.<\/p>\n<p>Samo wczytanie pliku JSON z karty pami\u0119ci nie nastr\u0119cza szczeg\u00f3lnych trudno\u015bci &#8211; wykorzystamy w tym celu driver FatFs. Ale co dalej?<\/p>\n<p>Napisany na potrzeby projektu parser formatu JSON oczekuje na swoim wej\u015bciu tekstu <em>(\u015bci\u015blej: wska\u017anika na tablic\u0119 znak\u00f3w &#8211; takie ekstra info dla nerd\u00f3w \ud83d\ude00 )<\/em>. Naturalnym rozwi\u0105zaniem wydaje si\u0119 zastosowanie jakiego\u015b bufora, do kt\u00f3rego wst\u0119pnie wczytamy ca\u0142y plik konfiguracyjny. Nast\u0119pnie tak przygotowany bufor przeka\u017cemy parserowi.<\/p>\n<blockquote><p>Hm&#8230; Po co traci\u0107 czas i miejsce w pami\u0119ci na buforowanie danych? Przecie\u017c parser mo\u017ce wczytywa\u0107 tekst bezpo\u015brednio z pliku.<\/p><\/blockquote>\n<p>Owszem, mo\u017ce &#8211; jednak na pewno nie b\u0119dzie to rozwiazanie szybsze.<\/p>\n<blockquote><p>Dlaczego?<\/p><\/blockquote>\n<p>Parser interpretuje tekst znak po znaku, co oznacza, jednorazowo wczytywa\u0142by jeden lub dwa bajty <em>(kodowanie UTF\/Unicode)<\/em> z pliku. Ka\u017cde \u017c\u0105danie odczytu danych z karty wymaga odwo\u0142ania si\u0119 do interfejsu SDIO i poczekania a\u017c karta odpowie paczk\u0105 danych. Powstaje wi\u0119c ogromny narzut danych kontrolnych w stosunku do liczby faktycznie odczytanych bajt\u00f3w. Dodatkowo nale\u017cy pami\u0119ta\u0107, i\u017c karty SD s\u0105 najefektywniejsze (czyli najszybsze) w trybie pakietowego strumieniowania danych, kiedy odczytywany jest d\u0142ugi, ci\u0105g\u0142y fragment pami\u0119ci. W takim przypadku narzut operacji kontrolnych jest minimalny, a realna pr\u0119dko\u015b\u0107 odczytu ograniczona jedynie przez przepustowo\u015b\u0107 interfejsu SDIO oraz mo\u017cliwo\u015bci (klas\u0119) samej karty.<\/p>\n<blockquote><p>Ok, ale nadal marnujemy spory kawa\u0142ek cennej pami\u0119ci RAM na bufor&#8230;<\/p><\/blockquote>\n<p>Po pierwsze pami\u0119\u0107 ta mo\u017ce zosta\u0107 zwolniona po wykonaniu operacji parsowania i u\u017cyta ponownie przez inne aplikacje. Po drugie, wyodr\u0119bnienie mechanizmu buforuj\u0105cego zawarto\u015b\u0107 pliku w pami\u0119ci wydaje si\u0119 by\u0107 dobrym kandydatem na kawa\u0142ek kodu, kt\u00f3ry mo\u017ce nam si\u0119 przyda\u0107 ponownie w przysz\u0142o\u015bci. Przemawiaj\u0105 za nim: uniwersalny interfejs oraz \u015bci\u015ble okre\u015blone zadanie, kt\u00f3re ma wykonywa\u0107. Ponadto w my\u015bl regu\u0142y DRY, ka\u017cdy dobrze zdefiniowany fragment kod, tworz\u0105cy kompletn\u0105, odr\u0119bn\u0105 funkcjonalno\u015b\u0107 warto wyekstrahowa\u0107 w formie biblioteki\/funkcji\/komponentu.<\/p>\n<blockquote><p>Id\u017amy krok dalej &#8211; parser przet\u0142umaczy\u0142 tekst na struktur\u0119 binarn\u0105. Co si\u0119 z ni\u0105 stanie p\u00f3\u017aniej?<\/p><\/blockquote>\n<p>Sam format JSON wymusza pewn\u0105 hierarchiczn\u0105 struktur\u0119 danych. Poszczeg\u00f3lne zestawy parametr\u00f3w mog\u0105 zosta\u0107 pogrupowane i przypisane do nadrz\u0119dnych struktur, a te z kolei stan\u0105 si\u0119 sk\u0142adowymi kolejnych struktur, itd itd itd. Oczywi\u015bcie mo\u017cna tak\u017ce rozpatrywa\u0107 &#8222;p\u0142ask\u0105&#8221; struktur\u0119 parametr\u00f3w, bez \u017cadnej hierarchii, jednak taka forma pliku b\u0119dzie bardzo nieczytelna dla cz\u0142owieka. Ponadto istotnym problemem b\u0119dzie stworzenie tak du\u017cej ilo\u015bci unikalnych nazw dla ka\u017cdego z parametr\u00f3w.<\/p>\n<blockquote><p>Jak wi\u0119c powinna wygl\u0105da\u0107 taka struktura?<\/p><\/blockquote>\n<p>Wyobra\u017amy sobie, \u017ce chcemy przechowywa\u0107 czas, po jakim zadzia\u0142a asystent przypominaj\u0105cy o odpoczynku kierowcy. Nazwijmy ten parametr <em>czasDoOdpoczynku<\/em>. Naturalnie jest on parametrem, kt\u00f3ry przynale\u017cy tylko i wy\u0142\u0105cznie do asystenta odpoczynku &#8211; mo\u017cna wi\u0119c przypisa\u0107 go do struktury <em>asystentOdpoczynku<\/em>. Poniewa\u017c w systemie istnieje kilku asystent\u00f3w, mo\u017cna utworzy\u0107 struktur\u0119 nadrz\u0119dn\u0105 o nazwie <em>asystenci<\/em>. <\/p>\n<p>Aby lepiej zobrazowa\u0107 t\u0105 ide\u0119, poni\u017cej przedstawiam przyk\u0142adow\u0105 struktur\u0119 takiej konfiguracji:<\/p>\n<ul>\n<li>konfiguracja\n<ul>\n<li>asystenci\n<ul>\n<li>asystentOdpoczynku\n<ul>\n<li>czasDoOdpoczynku<\/li>\n<li>czasDrzemki<\/li>\n<\/ul>\n<\/li>\n<li>asystent\u015awiate\u0142<\/li>\n<li>asystentPas\u00f3wBezpiecze\u0144stwa<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Hierarchiczna struktura pozwala na przekazanie do poszczeg\u00f3lnych komponent\u00f3w jedynie sekcji zawieraj\u0105cej ustawienia przypisane do wybranej aplikacji. W ten spos\u00f3b skracamy efektywnie czas aplikowania konfiguracji, poniewa\u017c odbiorca nie musi przeszukiwa\u0107 ca\u0142ego drzewa ustawie\u0144, a jedynie niewielki jego fragment.<\/p>\n<p>Ca\u0142y proces \u0142adowania ustawie\u0144 mo\u017cna przedstawi\u0107 nast\u0119puj\u0105cym schematem:<br \/>\n<a href=\"http:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme.png\" alt=\"\" width=\"800\" height=\"367\" class=\"aligncenter size-full wp-image-814\" srcset=\"https:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme.png 800w, https:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme-600x275.png 600w, https:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme-300x138.png 300w, https:\/\/hayperek.pl\/wp-content\/uploads\/2018\/05\/config_scheme-768x352.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Dzi\u015b na moment ponownie powr\u00f3cimy do tematu konfiguracji. Jak pami\u0119tacie z poprzednich artyku\u0142\u00f3w, zdecydowali\u015bmy si\u0119 przechowywa\u0107 ca\u0142\u0105 konfiguracj\u0119 w formie pliku JSON na karcie pami\u0119ci. Uda\u0142o si\u0119 tak\u017ce stworzy\u0107 odpowiedni parser, kt\u00f3rego zadaniem b\u0119dzie przet\u0142umaczenie tekstowego formatu pliku JSON na binarn\u0105 struktur\u0119, zrozumia\u0142\u0105 dla naszych aplikacji. Spr\u00f3bujmy zastanowi\u0107 si\u0119 jak powinien wygl\u0105da\u0107 przep\u0142yw informacji: od [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":816,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":{"0":"post-803","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-stodni","9":"post-with-thumbnail","10":"post-with-thumbnail-large"},"_links":{"self":[{"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts\/803","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/comments?post=803"}],"version-history":[{"count":11,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts\/803\/revisions"}],"predecessor-version":[{"id":818,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts\/803\/revisions\/818"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/media\/816"}],"wp:attachment":[{"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/media?parent=803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/categories?post=803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/tags?post=803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}