{"id":347,"date":"2018-03-23T21:33:15","date_gmt":"2018-03-23T21:33:15","guid":{"rendered":"http:\/\/hayperek.pl\/?p=347"},"modified":"2018-03-23T21:37:30","modified_gmt":"2018-03-23T21:37:30","slug":"software-czyli-jak-tchnac-zycie-w-sprzet","status":"publish","type":"post","link":"https:\/\/hayperek.pl\/en\/2018\/03\/23\/software-czyli-jak-tchnac-zycie-w-sprzet\/","title":{"rendered":"Software &#8211; czyli jak tchn\u0105\u0107 \u017cycie w sprz\u0119t"},"content":{"rendered":"<h5>J\u0119zyk programowania<\/h5>\n<p>Zacznijmy dzi\u015b troch\u0119 nietypowo, od klasyka:<\/p>\n<blockquote><p><span class=\"font-italic\">Chodzi mi o to, aby j\u0119zyk gi\u0119tki<br \/>\nPowiedzia\u0142 wszystko, co pomy\u015bli g\u0142owa:<br \/>\nA czasem by\u0142 jak piorun jasny, pr\u0119dki,<br \/>\nA czasem smutny jako pie\u015b\u0144 stepowa,<br \/>\nA czasem jako skarga nimfy mi\u0119tki,<br \/>\nA czasem pi\u0119kny jak anio\u0142\u00f3w mowa&#8230;<br \/>\nAby przelecia\u0142 wszystka ducha skrzyd\u0142em.<br \/>\nStrofa by\u0107 winna taktem, nie w\u0119dzid\u0142em.<\/span><\/p><\/blockquote>\n<p>Co prawda w\u0105tpi\u0119, i\u017c S\u0142owacki mia\u0142 na my\u015bli j\u0119zyk programowania, jednak ten fragment &#8222;Beniowskiego&#8221; dobrze wpisuje si\u0119 w nasze dzisiejsze rozwa\u017cania \ud83d\ude42<\/p>\n<p>Jaki j\u0119zyk wybra\u0107 &#8211; to pytanie zadaje sobie ka\u017cdy, kto zaczyna przygod\u0119 z programowaniem. W Sieci toczy\u0142y si\u0119, tocz\u0105 si\u0119 i b\u0119d\u0105 si\u0119 toczy\u0142y za\u017carte boje i gor\u0105ce dyskusje, na temat wy\u017cszo\u015bci danego j\u0119zyka nad innym. I w zasadzie, ka\u017cda strona sporu&#8230; ma racj\u0119. Ka\u017cdy j\u0119zyk jest dobry <strong>w konkretnym zastosowaniu<\/strong>. Parsowanie tekstu &#8211; Perl. Przeno\u015bno\u015b\u0107? Java! Lubisz liczy\u0107 wska\u017aniki na palcach? C. A mo\u017ce jeste\u015b milcz\u0105cym samotnikiem? Prosz\u0119 bardzo, <a href=\"https:\/\/pl.wikipedia.org\/wiki\/Whitespace\">Whitespace<\/a>.<\/p>\n<blockquote><p>Jaki j\u0119zyk wybra\u0107 dla naszego projektu?<\/p><\/blockquote>\n<p>Poniewa\u017c operujemy w \u015bwiecie system\u00f3w wbudowanych, dost\u0119pno\u015b\u0107 narz\u0119dzi i zdrowy rozs\u0105dek ogranicza nas tak na prawd\u0119 do dw\u00f3ch j\u0119zyk\u00f3w: C oraz C++. Oba maj\u0105 tylu\u017c zwolennik\u00f3w co przeciwnik\u00f3w i cz\u0119sto programi\u015bci jednego z nich nie darz\u0105 szczeg\u00f3ln\u0105 sympati\u0105 tego drugiego. Jak zatem maj\u0105 si\u0119 one do siebie w przypadku mikrokontroler\u00f3w? Sp\u00f3jrzmy:<\/p>\n<h5>C:<\/h5>\n<p>Zalety:<\/p>\n<ul class=\"pro_cons_list\">\n<li class=\"pro_item\">lekko\u015b\u0107,<\/li>\n<li class=\"pro_item\">podatno\u015b\u0107 na optymalizacj\u0119 w trakcie kompilacji,<\/li>\n<li class=\"pro_item\">\u0142atwo\u015b\u0107 debugowania,<\/li>\n<\/ul>\n<p>Wady:<\/p>\n<ul class=\"pro_cons_list\">\n<li class=\"cons_item\">trudne instancjonowanie obiekt\u00f3w,<\/li>\n<li class=\"cons_item\">brak dziedziczenia,<\/li>\n<li class=\"cons_item\">brak wbudowanych bibliotek standardowych (kontenery, algorytmy),<\/li>\n<\/ul>\n<hr>\n<h5>C++:<\/h5>\n<p>Zalety:<\/p>\n<ul class=\"pro_cons_list\">\n<li class=\"pro_item\">trywialnie proste instancjonowanie,<\/li>\n<li class=\"pro_item\">enkapsulacja (ograniczenie zakresu widzialno\u015bci danych),<\/li>\n<li class=\"pro_item\">dziedziczenie (zw\u0142aszcza interfejs\u00f3w),<\/li>\n<li class=\"pro_item\">biblioteka standardowa,<\/li>\n<\/ul>\n<p>Wady:<\/p>\n<ul class=\"pro_cons_list\">\n<li class=\"cons_item\">automatyczna alokacja na stercie,<\/li>\n<li class=\"cons_item\">utrudnione debugowanie na sprz\u0119cie,<\/li>\n<li class=\"cons_item\">wi\u0119ksza liczba odwo\u0142a\u0144 do pami\u0119ci (dereferencje przy dost\u0119pie do sk\u0142adowych klas, funkcje wirtualne) ,<\/li>\n<li class=\"cons_item\">nieco ni\u017csza wydajno\u015b\u0107,<\/li>\n<\/ul>\n<p>Patrz\u0105c na to kr\u00f3tkie zestawienie trudno jest wybra\u0107 zwyci\u0119zc\u0119. W przypadku niewielkiego, prostego systemu werdykt by\u0142by prosty &#8211; C. Ale to co planujemy zbudowa\u0107 absolutnie nie zalicza si\u0119 do tej kategorii.<\/p>\n<p>Dany j\u0119zyk warto wybra\u0107, je\u015bli mamy w perspektywie szans\u0119 wykorzysta\u0107 to, co sob\u0105 oferuje. Nie potrzebujemy ekspresji j\u0119zyka C++, je\u015bli wszystko w naszym projekcie jest statycznie zdefiniowane, a wszystkie operacje mo\u017cna \u0142atwo wyrazi\u0107 programowaniem funkcyjnym. R\u00f3wnie nieodpowiedni b\u0119dzie czysty C w przypadku, w kt\u00f3rym chcemy dynamicznie tworzy\u0107 chmur\u0119 obiekt\u00f3w w trakcie dzia\u0142ania systemu i odwo\u0142ywa\u0107 si\u0119 do nich za pomoc\u0105 uniwersalnego interfejsu. U\u017cycie danego j\u0119zyka powinno wi\u0119c by\u0107 podyktowane nie subiektywnymi odczuciami, upodobaniami czy mod\u0105, a jasn\u0105 i konkretn\u0105 analiz\u0105: czego <strong>na prawd\u0119<\/strong> potrzebujemy.<\/p>\n<blockquote><p>No wi\u0119c czego <strong>na prawd\u0119<\/strong> potrzebujemy?<\/p><\/blockquote>\n<p>Kr\u00f3tko: niskopoziomowy kod obs\u0142uguj\u0105cy peryferia, przerwania jest domena j\u0119zyka C. Bardziej wysokopoziomowe elementy, jak interfejs u\u017cytkownika to pole do popisu dla C++. Poniewa\u017c w naszym projekcie spotykaj\u0105 si\u0119 oba te \u015bwiaty, nie pozostaje nam nic innego jak&#8230; u\u017cy\u0107 obu.<\/p>\n<blockquote><p>Takie mieszanie dw\u00f3ch j\u0119zyk\u00f3w jest nieeleganckie. Wprowadza tyle niesp\u00f3jno\u015bci&#8230;<\/p><\/blockquote>\n<p>Wr\u0119cz przeciwnie! Naszym celem jest przede wszystkim u\u017cycie danego j\u0119zyka tam, gdzie b\u0119dzie najbardziej efektywny, gdzie mo\u017cliwo\u015bci jego ekspresji b\u0119d\u0105 stanowi\u0107 zalet\u0119. Przyk\u0142ad?<\/p>\n<p>Ka\u017cdy, kto ma troch\u0119 zaci\u0119cia do majsterkowania wie, \u017ce dla ka\u017cdego rozmiaru \u015bruby mamy osobny klucz. Owszem, mo\u017cemy pr\u00f3bowa\u0107 odkr\u0119ci\u0107 ka\u017cd\u0105 \u015brub\u0119 jednym kluczem &#8211; francuskim. Ale na pewno nie b\u0119dzie to ani \u0142atwe, ani eleganckie.<\/p>\n<p>&nbsp;<\/p>\n<h5>System operacyjny czy bare-metal<\/h5>\n<p>Wiele os\u00f3b, zw\u0142aszcza posiadaj\u0105cych ju\u017c pewne do\u015bwiadczenie w programowaniu, rozpoczyna przygod\u0119 z mikrokontrolerami od postawienia na nich niewielkiego systemu operacyjnego. Na pierwszy rzut oka jest to rozwi\u0105zanie idealne &#8211; przy stosunkowo niewielkim nak\u0142adzie pracy powstaje wygodne \u015brodowisko, zapewniaj\u0105ce wielow\u0105tkowo\u015b\u0107, komunikacj\u0119 mi\u0119dzyprocesow\u0105, zarz\u0105dzanie pami\u0119ci\u0105, cz\u0119sto nawet gotowe drivery sprz\u0119towe.<\/p>\n<p>Istnieje r\u00f3wnie\u017c do\u015b\u0107 powszechny (i niestety b\u0142\u0119dny) pogl\u0105d, i\u017c bez systemu operacyjnego czy nawet prostego schedulera zada\u0144, nie da si\u0119 stworzy\u0107 jakiejkolwiek z\u0142o\u017conej aplikacji na systemie wbudowanym. Bo maks co mo\u017cna zrobi\u0107 w &#8222;p\u0119tli&#8221; to miga\u0107 diod\u0105 LED&#8230; \ud83d\ude09 <\/p>\n<p>Wszystkie zewn\u0119trzne zdarzenia, kt\u00f3re nasz system musi obs\u0142u\u017cy\u0107 mog\u0105 trafi\u0107 do niego jedynie przez peryferia. Ka\u017cde z nich jest w stanie zazwyczaj wygenerowa\u0107 przerwanie, kt\u00f3re efektywnie jest w stanie zast\u0105pi\u0107 w\u0105tek w systemie operacyjnym.<\/p>\n<blockquote><p>Mo\u017ce jaki\u015b przyk\u0142ad?<\/p><\/blockquote>\n<p>Ok, wyobra\u017amy sobie prosty terminal: wy\u015bwietlacz i port szeregowy (RS-232). Naszym zadaniem jest wy\u015bwietlanie bajt\u00f3w kt\u00f3re nap\u0142ywaj\u0105 po lini Rx. Rozwi\u0105zanie z systemem operacyjnym jest do\u015b\u0107 intuicyjne. Sp\u00f3jrzmy zatem na &#8222;go\u0142y metal&#8221;:<\/p>\n<ol>\n<li>W p\u0119tli sprawdzamy czy pojawi\u0142 si\u0119 nowy znak w buforze portu szeregowego, je\u015bli tak pobieramy go i wyrzucamy na wy\u015bwietlacz.<\/li>\n<li>Ka\u017cdy odebrany bajt generuje przerwanie, bajt wrzucany jest do programowej kolejki FIFO. W p\u0119tli procesor sprawdza jedynie czy cokolwiek znajduje si\u0119 w kolejce i wypisuje ciurkiem wszystko co ewentualnie w niej znajdzie.<\/li>\n<\/ol>\n<p>Rozwi\u0105zanie 1. ma jedn\u0105, zasadnicz\u0105 wad\u0119 &#8211; je\u015bli czas potrzebny na wypisanie znaku na ekran jest d\u0142u\u017cszy ni\u017c czas przes\u0142ania jednego znaku po RS-232, b\u0119dziemy gubi\u0107 bajty. Rozwi\u0105zanie 2. wolne jest od tego problemu, no mo\u017ce poza przypadkiem przepe\u0142nienia si\u0119 kolejki FIFO. Dla bardziej zaznajomionych z tematem: mo\u017cna r\u00f3wnie\u017c p\u00f3j\u015b\u0107 krok dalej i zaprz\u0105c do pracy transfer DMA, kt\u00f3ry wyr\u0119czy procesor w obs\u0142udze przerwania.<\/p>\n<p>Na tym prostym przyk\u0142adzie widzimy, \u017ce umiej\u0119tnie deleguj\u0105c zadania mi\u0119dzy przerwaniami a g\u0142\u00f3wn\u0105 p\u0119tl\u0105 programu mo\u017cna skutecznie obs\u0142ugiwa\u0107 wiele &#8222;pseudo-wsp\u00f3\u0142bie\u017cnych&#8221; zada\u0144. Nale\u017cy przy tym pami\u0119ta\u0107, i\u017c mimo braku systemu operacyjnego wci\u0105\u017c obowi\u0105zuje nas konieczno\u015b\u0107 zapewnienia synchronizacji i sp\u00f3jno\u015bci danych (patrz wspomniana kolejka FIFO).<\/p>\n<blockquote><p>Kiedy wi\u0119c system operacyjny na mikrokontrolerze ma sens?<\/p><\/blockquote>\n<p>Na to pytanie nie da si\u0119 udzieli\u0107 jednoznacznej odpowiedzi, mo\u017cna natomiast wskaza\u0107 pewien obszar zastosowa\u0144,\u00a0 w kt\u00f3rym u\u017cywanie schedulera u\u0142atwia \u017cycie. S\u0105 nim wszelkie systemy, w kt\u00f3rych wyst\u0119puje wsp\u00f3\u0142bie\u017cne przetwarzanie asynchronicznie nadchodz\u0105cych \u017c\u0105da\u0144, co do kt\u00f3rych trudno okre\u015bli\u0107 jest czas wymagany na ich obs\u0142u\u017cenie. <\/p>\n<blockquote><p>Brzmi zagadkowo&#8230;<\/p><\/blockquote>\n<p>Wyobra\u017amy sobie zadania A, B i C. Zadanie A jest relatywnie du\u017ce, ale ma niski priorytet. Zadania B oraz C s\u0105 mniejsze i maj\u0105 r\u00f3wny priorytet, r\u00f3\u017cni\u0105 si\u0119 jednak mi\u0119dzy sob\u0105 czasem potrzebnym na ich wykonanie. Mamy wi\u0119c trzy zadania\/w\u0105tki: A &#8211; tocz\u0105cy si\u0119 powoli w &#8222;tle&#8221; oraz B i C, kt\u00f3re walcz\u0105 mi\u0119dzy sob\u0105 o dost\u0119p do czasu CPU. W podany przyk\u0142ad \u015bwietnie wpisuj\u0105 si\u0119 m.in. urz\u0105dzenia sieciowe, przetwarzaj\u0105ce dane powy\u017cej warstwy drugiej (routery). Przy braku systemu operacyjnego, implementacja prze\u0142\u0105czania si\u0119 kontekstu przetwarzania &#8222;w locie&#8221;, w obr\u0119bie pojedynczej jednostki wykonania by\u0142aby niezwykle z\u0142o\u017cona.<\/p>\n<blockquote><p>Czy zatem w naszym projekcie b\u0119dzie system operacyjny?<\/p><\/blockquote>\n<p>Odpowied\u017a jest kr\u00f3tka &#8211; nie.<\/p>\n<blockquote><p>Jak to &#8222;nie&#8221;? Przecie\u017c jest tyle r\u00f3\u017cnych zada\u0144: magistrala CAN, diagnostyka, karta pami\u0119ci, d\u017awi\u0119k, przyciski no i przecie\u017c grafik\u0119 trzeba rysowa\u0107!<\/p><\/blockquote>\n<p>No w\u0142a\u015bnie o tym sceptycyzmie pisa\u0142em na pocz\u0105tku&#8230;. Postaram si\u0119 zatem udowodni\u0107, \u017ce nawet w przypadku tak rozbudowanego systemu da si\u0119 zno\u015bnie \u017cy\u0107 bez systemu.<\/p>","protected":false},"excerpt":{"rendered":"<p>J\u0119zyk programowania Zacznijmy dzi\u015b troch\u0119 nietypowo, od klasyka: Chodzi mi o to, aby j\u0119zyk gi\u0119tki Powiedzia\u0142 wszystko, co pomy\u015bli g\u0142owa: A czasem by\u0142 jak piorun jasny, pr\u0119dki, A czasem smutny jako pie\u015b\u0144 stepowa, A czasem jako skarga nimfy mi\u0119tki, A czasem pi\u0119kny jak anio\u0142\u00f3w mowa&#8230; Aby przelecia\u0142 wszystka ducha skrzyd\u0142em. Strofa by\u0107 winna taktem, nie [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":360,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":{"0":"post-347","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\/347","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=347"}],"version-history":[{"count":12,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts\/347\/revisions"}],"predecessor-version":[{"id":359,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/posts\/347\/revisions\/359"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/media\/360"}],"wp:attachment":[{"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/media?parent=347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/categories?post=347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hayperek.pl\/en\/wp-json\/wp\/v2\/tags?post=347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}