{"id":7930,"date":"2019-08-22T17:08:36","date_gmt":"2019-08-22T15:08:36","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=7930"},"modified":"2025-05-07T12:00:55","modified_gmt":"2025-05-07T10:00:55","slug":"iot-hub-czyli-zrobmy-ciekawy-projekt","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/iot-hub-czyli-zrobmy-ciekawy-projekt\/","title":{"rendered":"IoT HUB, czyli zr\u00f3bmy ciekawy projekt"},"content":{"rendered":"\n<p>Poni\u017cszy artyku\u0142 przedstawia wewn\u0119trzny projekt, realizowany przez in\u017cynier\u00f3w-programist\u00f3w z Centrum Kompetencyjnego Embedded firmy Sii.<\/p>\n\n\n\n<p>Od strony technicznej projekt pokazuje rozwi\u0105zanie uniwersalnego koncentratora (HUBa) zbieraj\u0105cego dane z wszelkiej ma\u015bci sensor\u00f3w czym wpisuje si\u0119 jednoznacznie w tematyk\u0119 Internet of Things. &nbsp;Z drugiej strony tekst skupia si\u0119 na ca\u0142ym procesie my\u015blowym jaki doprowadzi\u0142 do realizacji technicznej \u2013 a wi\u0119c od pomys\u0142u, przez projekt po implementacj\u0119 oraz zapewnienie jako\u015bci.<\/p>\n\n\n\n<p><iframe style=\"width: 560px;\" src=\"https:\/\/www.youtube.com\/embed\/pUG7-HzjJ8A\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak do tego dosz\u0142o?<\/h2>\n\n\n\n<p>Idea projekt\u00f3w wewn\u0119trznych narodzi\u0142a si\u0119 dawno temu wraz z samym Centrum Kompetencyjnym Embedded. Skoro bowiem ponad setka in\u017cynier\u00f3w jest w stanie realizowa\u0107 projekty dla szerokiego grona klient\u00f3w, to dlaczego by nie po\u0142\u0105czy\u0107 ich umiej\u0119tno\u015bci programistycznych, pracy w grupie wraz z dobrymi praktykami projektowania oprogramowania. To wszystko okrasi\u0107 elementami Agile\u2019a i mamy gotowy przepis na sukces oraz ciekawy projekt zarazem.<\/p>\n\n\n\n<p>Szybko znalaz\u0142a si\u0119 w firmie grupka pasjonat\u00f3w gotowa po\u0142\u0105czy\u0107 swe si\u0142y pod szyldem wspomnianego projektu wewn\u0119trznego.<\/p>\n\n\n\n<p>Bezpo\u015brednim <strong>celem<\/strong> by\u0142o zaprojektowanie i wykonanie kompletnego systemu\/produktu z jednoczesnym poszerzeniem i pog\u0142\u0119bieniem wiedzy z dziedziny Internet of Things oraz spi\u0119cie w ramach jednego projektu mo\u017cliwie du\u017cej liczby technologii ze wspomnianego ju\u017c IoT. Jednocze\u015bnie chcieli\u015bmy po prostu zrobi\u0107 co\u015b ciekawego od A do Z i mie\u0107 z tego czysto in\u017cyniersk\u0105 przyjemno\u015b\u0107.<\/p>\n\n\n\n<p>Okaza\u0142o si\u0119 jednak, \u017ce sam wyb\u00f3r tematu projektu \u2013 cz\u0119\u015bci wydawa\u0142oby si\u0119 prozaiczna (w por\u00f3wnaniu oczywi\u015bcie do p\u00f3\u017aniejszej realizacji) stanowi pierwsz\u0105 ko\u015b\u0107 niezgody. Pada\u0142y przer\u00f3\u017cne pomys\u0142y zwi\u0105zane z technologiami bezprzewodowymi, kryptografi\u0105, domen\u0105 automotive, czy nawet sztuczn\u0105 inteligencj\u0105. Do kompletu chmura i element technologii webowych\u2026 a\u017c chcia\u0142oby si\u0119 zapyta\u0107 czy mo\u017ce jeszcze frytki do tego.<\/p>\n\n\n\n<p>W ko\u0144cu jeden z koleg\u00f3w przypomnia\u0142, \u017ce ju\u017c od dawna dyskutowali\u015bmy na forum wewn\u0119trznym o zrobieniu uniwersalnego koncentratora do wszelkiej ma\u015bci urz\u0105dze\u0144 z domeny IoT. Mo\u017ce warto wi\u0119c efekty wcze\u015bniejszych dyskusji przeku\u0107 w czyn? Tak oto dobrn\u0119li\u015bmy do ko\u0144ca pocz\u0105tku \u2013 znale\u017ali\u015bmy temat projektu: Th\u00e1lassa, Th\u00e1lassa!<a href=\"#_ftn1\" name=\"_ftnref1\" rel=\"nofollow\" >[1]<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">This is madness<\/h3>\n\n\n\n<p>Pierwotnym pomys\u0142em by\u0142o zastosowanie wspomnianego koncentratora (nazwanego na potrzeby projektu <strong>IoT HUBem<\/strong>) do cel\u00f3w typu home automation. Ale zaraz, zaraz. Przecie\u017c istnieje szereg gotowych rozwi\u0105za\u0144 \u2013 tutaj ka\u017cdy zaznajomiony z tematem automatyki domowej wymieni jednym tchem takie rozwi\u0105zania open source jak Domoticz<a href=\"#_ftn2\" name=\"_ftnref2\" rel=\"nofollow\" >[2]<\/a>, OpenHAB<a href=\"#_ftn3\" name=\"_ftnref3\" rel=\"nofollow\" >[3]<\/a>, czy Home Assistant<a href=\"#_ftn4\" name=\"_ftnref4\" rel=\"nofollow\" >[4]<\/a>. Prawda, za to zesp\u00f3\u0142 postawi\u0142 sobie za cel:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>opracowanie W\u0141ASNEGO, uniwersalnego koncentratora (IoT HUBa) umo\u017cliwiaj\u0105cego komunikacj\u0119 z ca\u0142\u0105 gam\u0105 urz\u0105dze\u0144 ko\u0144cowych<\/li>\n\n\n\n<li>przygotowanie prostego, otwartego protoko\u0142u komunikacyjnego<\/li>\n\n\n\n<li>integracj\u0119 z mo\u017cliwie najwi\u0119ksz\u0105 ilo\u015bci\u0105 urz\u0105dze\u0144 ko\u0144cowych<\/li>\n<\/ul>\n\n\n\n<p>Urz\u0105dzenie to zostanie nast\u0119pnie wyprodukowane w ilo\u015bci kilku egzemplarzy i umieszczone w r\u00f3\u017cnych oddzia\u0142ach Sii.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Od teorii do praktyki, czyli projekt rozwi\u0105zania<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Najtrudniej jest zacz\u0105\u0107 (aka przypadki u\u017cycia)<\/h3>\n\n\n\n<p>Kiedy ju\u017c zesp\u00f3\u0142 chcia\u0142 ochoczo i z kopyta wzi\u0105\u0107 si\u0119 do wyboru platformy oraz pisania kodu, postanowi\u0142em zada\u0107 kluczowe pytanie \u2013 \u201eCzy aby na pewno wiecie co mamy do opracowania?\u201d. W pierwszym odruchu wszyscy przytakn\u0119li nie\u015bmia\u0142o, ale gdy ka\u017cdy opisa\u0142 s\u0142owami swoj\u0105 wizj\u0119 produktu, to wysz\u0142y na jaw znaczne rozbie\u017cno\u015bci co do og\u00f3lnej koncepcji, u\u017cytej platformy i systemu operacyjnego.<\/p>\n\n\n\n<p>Zaproponowa\u0142em wi\u0119c od\u0142o\u017cenie dyskusji nad technicznymi szczeg\u00f3\u0142ami na p\u00f3\u017aniej oraz zastosowanie w tym projekcie zasad, jakimi kierujemy si\u0119 w projektach komercyjnych. Odrzucaj\u0105c najlepsze praktyki z pocz\u0105tk\u00f3w takich gigant\u00f3w jak Apple, Google czy Microsoft (a wszystkie one powsta\u0142y w przydomowych gara\u017cach swoich w\u0142a\u015bcicieli) postanowili\u015bmy nie robi\u0107 przys\u0142owiowej gara\u017c\u00f3wy i zacz\u0105\u0107 od wyspecyfikowania abstrakcyjnych przypadk\u00f3w u\u017cycia.<\/p>\n\n\n\n<p>Zak\u0142adaj\u0105c, \u017ce nasz IoT HUB b\u0119dzie czarn\u0105 skrzynk\u0105, ka\u017cdy z nas zada\u0142 sobie pytanie \u2013 &#8222;Jak i do czego chcia\u0142bym u\u017cywa\u0107 wspomnianego urz\u0105dzenia?&#8221;. &nbsp;W efekcie powsta\u0142o 12 przypadk\u00f3w u\u017cycia w formie graficznej, ka\u017cdy poparty bardziej szczeg\u00f3\u0142owym opisem s\u0142owno-muzycznym.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.png\"><img decoding=\"async\" width=\"350\" height=\"565\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.png\" alt=\"Kilka zagregowanych przypadk\u00f3w u\u017cycia\" class=\"wp-image-7940\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.png 350w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1-186x300.png 186w\" sizes=\"(max-width: 350px) 100vw, 350px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1. Kilka zagregowanych przypadk\u00f3w u\u017cycia<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Wymagania i og\u00f3lna koncepcja urz\u0105dzenia<\/h3>\n\n\n\n<p>W nast\u0119pnym kroku poddali\u015bmy pod dyskusj\u0119 og\u00f3ln\u0105 koncepcj\u0119 sprz\u0119tow\u0105 urz\u0105dzenia bior\u0105c pod uwag\u0119 dwie mo\u017cliwo\u015bci:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>all-in-one z wbudowanymi w IoT HUBa modu\u0142ami komunikacyjnymi<\/li>\n\n\n\n<li>rozszerzaln\u0105: z p\u0142yt\u0105 g\u0142\u00f3wn\u0105 i doczepianymi expanderami\/gateway\u2019ami<\/li>\n<\/ul>\n\n\n\n<p>Ostatecznie zdecydowali\u015bmy si\u0119 na wersj\u0119 rozszerzaln\u0105, za\u015b koronnym argumentem by\u0142a mo\u017cliwo\u015b\u0107 zbudowania takiej konfiguracji przy u\u017cyciu og\u00f3lnodost\u0119pnych zestaw\u00f3w developerskich.<\/p>\n\n\n\n<p>Uzgodniwszy og\u00f3lny schemat sprz\u0119towy, przyst\u0105pili\u015bmy do przekucia przypadk\u00f3w u\u017cycia w proste, jasne i kr\u00f3tkie wymagania. Tym sposobem powsta\u0142a lista kilkudziesi\u0119ciu wymaga\u0144, kt\u00f3re wraz z przypadkami u\u017cycia zamkni\u0119te zosta\u0142y w LaTexowym dokumencie.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.1.jpg\"><img decoding=\"async\" width=\"813\" height=\"281\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.1.jpg\" alt=\"Kr\u00f3tki wyci\u0105g z \u00a0wymaga\u0144\" class=\"wp-image-7946\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.1.jpg 813w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot1.1-300x104.jpg 300w\" sizes=\"(max-width: 813px) 100vw, 813px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2. Kr\u00f3tki wyci\u0105g z \u00a0wymaga\u0144<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Wyb\u00f3r platformy i systemu operacyjnego<\/h3>\n\n\n\n<p>Maj\u0105c zdefiniowan\u0105 list\u0119 wymaga\u0144 oraz uzgodniony og\u00f3lny schemat cz\u0119\u015bci sprz\u0119towej przyst\u0105pili\u015bmy do wyboru platformy i systemu operacyjnego. Zesp\u00f3\u0142 podzieli\u0142 si\u0119 na dwie, r\u00f3wnoliczne grupy: zwolennik\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>rozwi\u0105za\u0144 opartych o Linuxa<\/li>\n\n\n\n<li>rozwi\u0105za\u0144 opartych o systemy operacyjne czasu rzeczywistego<\/li>\n<\/ul>\n\n\n\n<p>Dyskusjom, argumentom i kontr-argumentom nie by\u0142o ko\u0144ca. Ostatecznie zwa\u015bnione strony pogodzi\u0142a koncepcja rozwi\u0105zania (o zgrozo) uniwersalnego, mog\u0105cego pracowa\u0107 pod kontrol\u0105<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dowolnego systemu operacyjnego<\/li>\n\n\n\n<li>szerokiego spektrum platform sprz\u0119towych: g\u0142\u00f3wnie 32 bitowych<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Struktura oprogramowania<\/h3>\n\n\n\n<p>Maj\u0105c na uwadze wspomnian\u0105 wcze\u015bniej uniwersalno\u015b\u0107 podzielili\u015bmy oprogramowanie na 4 zasadnicze bloki:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>warstw\u0119 abstrakcji od sprz\u0119tu (HAL), wystawiaj\u0105c\u0105 quasi-CMSIS<a href=\"#_ftn5\" name=\"_ftnref5\" rel=\"nofollow\" ><\/a>owe<a href=\"#_ftn5\" name=\"_ftnref5\" rel=\"nofollow\" >[5]<\/a> API<\/li>\n\n\n\n<li>warstw\u0119 services, wystawiaj\u0105c\u0105 za pomoc\u0105 dedykowanego API bloki funkcji do aplikacji oraz systemu operacyjnego<\/li>\n\n\n\n<li>warstw\u0119 aplikacji, wykorzystuj\u0105c\u0105 zar\u00f3wno API od services jak i funkcje wystawione przez system operacyjny<\/li>\n\n\n\n<li>complex driver<a href=\"#_ftn6\" name=\"_ftnref6\" rel=\"nofollow\" >[6]<\/a>, b\u0119d\u0105cy uk\u0142onem w stron\u0119 \u015bwiata automotive i zawieraj\u0105cy te modu\u0142y, kt\u00f3re nie dadz\u0105 si\u0119 wpi\u0105\u0107\/przyporz\u0105dkowa\u0107 do \u017cadnej z powy\u017cszych warstw.<\/li>\n<\/ul>\n\n\n\n<p>Na poni\u017cszym rysunku widzimy poszczeg\u00f3lne, opisane powy\u017cej bloki funkcjonalne. Wszelkie interfejsy z modu\u0142\u00f3w zaznaczone s\u0105 kolorami.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot2.jpg\"><img decoding=\"async\" width=\"1036\" height=\"871\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot2.jpg\" alt=\"Podzia\u0142 oprogramowania na warstwy funkcjonalne\" class=\"wp-image-7941\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot2.jpg 1036w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot2-300x252.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot2-1024x861.jpg 1024w\" sizes=\"(max-width: 1036px) 100vw, 1036px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3. Podzia\u0142 oprogramowania na warstwy funkcjonalne<\/figcaption><\/figure>\n\n\n\n<p>Osobn\u0105 kwesti\u0105 sta\u0142o si\u0119 opakowanie systemu operacyjnego w taki spos\u00f3b, aby \u0142atwo da\u0142o si\u0119 go podmieni\u0107 na inny. St\u0105d dedykowane API wzorowane na POSIXie.<\/p>\n\n\n\n<p>Do kompletu powsta\u0142 jeszcze d\u0142ugi (i nudny) opis API wystawianego przez ka\u017cd\u0105 z w\/w warstw.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Specyfikacja blok\u00f3w funkcjonalnych<\/h3>\n\n\n\n<p>Kolejnym przed-implementacyjnym etapem projektowania by\u0142a specyfikacja blok\u00f3w funkcjonalnych na warstwie aplikacji naszego IoT HUBa. Uzgodnili\u015bmy z ca\u0142\u0105 pewno\u015bci\u0105, \u017ce potrzebujemy blok\u00f3w odpowiedzialnych za:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>og\u00f3lne zarz\u0105dzanie urz\u0105dzeniem, co spad\u0142o na barki System Managera<\/li>\n<\/ul>\n\n\n\n<p>System Manager jest najwazniejszym \u201ebytem\u201d. Jego zadaniem jest inicjalizacja wszystkich podleg\u0142ych mu modu\u0142\u00f3w funkcjonalnych, obieranie od nich event\u00f3w informuj\u0105cych o zdarzeniach oraz wyzwalanie akcji w odpowiedzi na nie.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zarz\u0105dzanie urz\u0105dzeniami ko\u0144cowymi (sensorami i efektorami)<\/li>\n<\/ul>\n\n\n\n<p>W zamy\u015ble blok ten odpowiada za dodawanie\/usuwanie\/aktualizowanie stanu urz\u0105dze\u0144 ko\u0144cowych. Zar\u00f3wno bezprzewodowych, jak i przewodowych.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zarz\u0105dzanie expanderami<\/li>\n<\/ul>\n\n\n\n<p>Podobnie jak to ma miejsce w przypadku urz\u0105dze\u0144 ko\u0144cowcych istnieje mo\u017cliwo\u015b\u0107 wykrywania\/dodawania\/usuwania expander\u00f3w (modu\u0142\u00f3w rozszerze\u0144) za po\u015brednictwem dedykowanego bloku.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>obs\u0142ug\u0119 akcji<\/li>\n<\/ul>\n\n\n\n<p>U\u017cytkownik IoT HUBa ma mo\u017cliwo\u015b\u0107 definiowania zdarze\u0144\/akcji w stylu \u201eje\u017celi nast\u0105pi\u0142o X to wykonaj Y\u201d. Manager akcji ma za zadanie umo\u017cliwi\u0107 dodawanie\/usuwanie\/wykonywanie wspomnianych zdarze\u0144 w reakcji na inne zdarzenie.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>baz\u0119 danych<\/li>\n<\/ul>\n\n\n\n<p>S\u0142u\u017c\u0105c\u0105 do zapisu konfiguracji oraz wszelkich potrzebnych systemowi danych nieulotnych (np. log\u00f3w)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>zarz\u0105dzanie poborem energii i stanem baterii<\/li>\n<\/ul>\n\n\n\n<p>IoT HUB pozwala na prac\u0119 zar\u00f3wno przy zasilaniu z sieci (domy\u015blne) jak i z baterii. St\u0105d istnieje konieczno\u015b\u0107 racjonalizacji zu\u017cycia energii oraz generowania akcji gdy np. napi\u0119cie baterii spadnie poni\u017cej pewnego poziomu<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>komunikacj\u0119<\/li>\n<\/ul>\n\n\n\n<p>Wszelka komunikacja przewodowa\/bezprzewodowa\/szeregowa\/r\u00f3wnoleg\u0142a jest zarz\u0105dzana z poziomu tego bloku.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot3.jpg\"><img decoding=\"async\" width=\"934\" height=\"299\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot3.jpg\" alt=\"Og\u00f3lny zarys blok\u00f3w funkcjonalnych IoT HUBa\" class=\"wp-image-7942\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot3.jpg 934w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot3-300x96.jpg 300w\" sizes=\"(max-width: 934px) 100vw, 934px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4. Og\u00f3lny zarys blok\u00f3w funkcjonalnych IoT HUBa<\/figcaption><\/figure>\n\n\n\n<p>Wspomniane bloki funkcjonalne nale\u017ca\u0142o podzieli\u0107 mi\u0119dzy poszczeg\u00f3lne w\u0105tki \u2013 uzgodnili\u015bmy w ko\u0144cu, \u017ce korzystamy z dobrodziejstw systemu operacyjnego. Sztywne podej\u015bcie z jednym w\u0105tkiem na ka\u017cdy blok funkcjonalny wyda\u0142o nam si\u0119 zbytni\u0105 rozrzutno\u015bci\u0105. St\u0105d zdecydowali\u015bmy si\u0119 na 5 wsp\u00f3\u0142pracuj\u0105cych ze sob\u0105 w\u0105tk\u00f3w o 3 r\u00f3\u017cnych priorytetach.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot4.jpg\"><img decoding=\"async\" width=\"851\" height=\"734\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot4.jpg\" alt=\"Podzia\u0142 blok\u00f3w funkcjonalnych mi\u0119dzy w\u0105tki\" class=\"wp-image-7943\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot4.jpg 851w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot4-300x259.jpg 300w\" sizes=\"(max-width: 851px) 100vw, 851px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 5. Podzia\u0142 blok\u00f3w funkcjonalnych mi\u0119dzy w\u0105tki<\/figcaption><\/figure>\n\n\n\n<p>Ostatnim elementem architektonicznej uk\u0142adanki jest spos\u00f3b komunikacji mi\u0119dzy w\u0105tkami. Ka\u017cdy w\u0105tek dysponuje pojedyncza kolejk\u0105 przez kt\u00f3r\u0105 przekazywane s\u0105 wiadomo\u015bci w ustandaryzowanym formacie. Wiadomo\u015b\u0107 zawiera m.in.:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>identyfikator w\u0105tku nadawczego (warto\u015b\u0107 liczbowa)<\/li>\n\n\n\n<li>identyfikator wiadomo\u015bci, jest to warto\u015b\u0107 odpowiadaj\u0105ca konkretnemu zdarzeniu\/\u017c\u0105daniu<\/li>\n\n\n\n<li>wska\u017anik na payload (opcjonalny)<\/li>\n\n\n\n<li>wielko\u015b\u0107 payloadu w bajtach (warto\u015b\u0107 liczbowa)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Realizacja, czyli wcielamy s\u0142owo w czyn<\/h2>\n\n\n\n<p>Do\u015b\u0107 ju\u017c teorii, przejd\u017amy do opisu realizacji projektu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Zesp\u00f3\u0142 projektowy<\/h3>\n\n\n\n<p>Zesp\u00f3\u0142 projektowy by\u0142, jest i b\u0119dzie p\u0142ynny oraz z za\u0142o\u017cenia rozproszony lokalizacyjnie. Sk\u0142adaj\u0105 si\u0119 na niego osoby pracuj\u0105ce ze wszystkich biur firmy Sii i dok\u0142adaj\u0105ce swoj\u0105 cegie\u0142k\u0119 w ramach posiadanych umiej\u0119tno\u015bci\/do\u015bwiadczenia\/opanowanego zakresu technologii jak r\u00f3wnie\u017c posiadanego czasu.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Zarz\u0105dzanie zadaniami<\/h4>\n\n\n\n<p>Wszystkie zadania projektowe zar\u00f3wno te wynikaj\u0105ce z pierwszej analizy wymaga\u0144 jak i dodane w czasie p\u00f3\u017aniejszym s\u0105 trzymane w trackerze Jira w formie user stories i wynikaj\u0105cych z nich zada\u0144.<\/p>\n\n\n\n<p>W ramach zwinnego podej\u015bcia do wytwarzania oprogramowania zesp\u00f3\u0142 na bie\u017c\u0105co (w 2 tygodniowych cyklach) analizuje, estymuje, wdra\u017ca i testuje kolejne funkcjonalno\u015bci systemu.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Przegl\u0105d kodu<\/h4>\n\n\n\n<p>W ramach wsp\u00f3lnej kolaboracji nad kodem, wdro\u017cyli\u015bmy prosty proces przegl\u0105du i oceny kodu oparty o GitHuba. W ramach niego ka\u017cda zmiana, wykonana na odpowiednim branchu i wystawiona w formie pull-requesta jest oceniania przez co najmniej dw\u00f3ch cz\u0142onk\u00f3w zespo\u0142u pod k\u0105tem:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Poprawno\u015bci implementacji wzgl\u0119dem dokumentacji\/projektu<\/li>\n\n\n\n<li>Poprawno\u015bci implementacji pod k\u0105tem programistycznym<\/li>\n\n\n\n<li>Istnienia test\u00f3w pokrywaj\u0105cych now\u0105 funkcjonalno\u015b\u0107<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot5.jpg\"><img decoding=\"async\" width=\"790\" height=\"307\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot5.jpg\" alt=\"Ma\u0142y wyci\u0105g z historii pull request\u00f3w\" class=\"wp-image-7944\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot5.jpg 790w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot5-300x117.jpg 300w\" sizes=\"(max-width: 790px) 100vw, 790px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6. Ma\u0142y wyci\u0105g z historii pull request\u00f3w<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Struktura projektu<\/h3>\n\n\n\n<p>Kod \u017ar\u00f3d\u0142owy podzielili\u015bmy na cz\u0119\u015bci odpowiedzialne za:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zale\u017cn\u0105 od sprz\u0119tu cz\u0119\u015b\u0107 zawieraj\u0105c\u0105 niskopoziomowe sterowniki (zaznaczone na zielono)<\/li>\n\n\n\n<li>Aplikacj\u0119 (zaznaczon\u0105 na zielono) implementuj\u0105c\u0105 opisane wcze\u015bniej modu\u0142y funkcjonalne<\/li>\n\n\n\n<li>Warstw\u0119 po\u015bredni\u0105 (services) dostarczaj\u0105c\u0105 niezale\u017cne od sprz\u0119tu funkcjonalno\u015bci (zaznaczone na pomara\u0144czowo)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot7.jpg\"><img decoding=\"async\" width=\"355\" height=\"497\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot7.jpg\" alt=\"Struktura katalog\u00f3w w projekcie\" class=\"wp-image-7945\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot7.jpg 355w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot7-214x300.jpg 214w\" sizes=\"(max-width: 355px) 100vw, 355px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 7. Struktura katalog\u00f3w w projekcie<\/figcaption><\/figure>\n\n\n\n<p>Do tego kilka katalog\u00f3w zawieraj\u0105cych pliki nag\u0142\u00f3wkowe od:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>POSIX API oddzielaj\u0105cego system operacyjny od aplikacji<\/li>\n\n\n\n<li>API warstwy services (po\u015bredniej)<\/li>\n\n\n\n<li>CMSIS API warstwy abstrakcji od sprz\u0119tu<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Kod \u017ar\u00f3d\u0142owy i podej\u015bcie do programowania<\/h3>\n\n\n\n<p>Sam kod \u017ar\u00f3d\u0142owy napisali\u015bmy w j\u0119zyku C. Poni\u017cej nieco przyd\u0142ugi, ale jednocze\u015bnie tre\u015bciwy fragment obrazuj\u0105cy proces inicjalizacji systemu, jego w\u0105tk\u00f3w i kolejek.<\/p>\n\n\n\n<p>Wszystkie funkcjonalno\u015bci dostarczane przez system operacyjny zosta\u0142y opakowane \u2013 widzimy je w postaci makr i funkcji z przedrostkiem OS.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot8.jpg\"><img decoding=\"async\" width=\"948\" height=\"930\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot8.jpg\" alt=\"\" class=\"wp-image-7932\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot8.jpg 948w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot8-300x294.jpg 300w\" sizes=\"(max-width: 948px) 100vw, 948px\" \/><\/a><\/figure>\n\n\n\n<p>Identyczne podej\u015bcie zastosowali\u015bmy przy implementacji poszczeg\u00f3lnych w\u0105tk\u00f3w. Wewn\u0105trz umieszczonej w w\u0105tku p\u0119tli niesko\u0144czonej nast\u0119puje:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cykliczne aktualizowanie statusu (jak w przypadku zamieszonego poni\u017cej w\u0105tku systemowego)<\/li>\n\n\n\n<li>Oczekiwanie na pojawienie si\u0119 wiadomo\u015bci w przypisanej kolejce<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9.jpg\"><img decoding=\"async\" width=\"1024\" height=\"648\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9-1024x648.jpg\" alt=\"\" class=\"wp-image-24558\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9-1024x648.jpg 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9-300x190.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9-768x486.jpg 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/iot9.jpg 1049w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Wybrane rozwi\u0105zania<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Konsola debugowa<\/h4>\n\n\n\n<p>Zgodnie z wymaganiami istnieje mo\u017cliwo\u015b\u0107 diagnozowania i podgl\u0105dania stanu IoT HUBa. W tym celu zaimplementowali\u015bmy konsol\u0119 debugow\u0105 wraz z prostym menu.<\/p>\n\n\n\n<p>Z jednej strony kluczowe dla dzia\u0142ania systemu informacje s\u0105 \u201ewyrzucane\u201d na port szeregowy &#8211;&nbsp; wystarczy umie\u015bci\u0107 w kodzie wywo\u0142anie stosownego makra. Jednocze\u015bnie istnieje te\u017c mo\u017cliwo\u015b\u0107 wys\u0142ania prostego, znakowego zapytania (jest to pojedynczy znak ASCII) i otrzymania np. aktualnego IP urz\u0105dzenia.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot10.jpg\"><img decoding=\"async\" width=\"747\" height=\"201\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot10.jpg\" alt=\"Obecny kszta\u0142t konsoli debugowej\" class=\"wp-image-7934\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot10.jpg 747w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot10-300x81.jpg 300w\" sizes=\"(max-width: 747px) 100vw, 747px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 8. Obecny kszta\u0142t konsoli debugowej<\/figcaption><\/figure>\n\n\n\n<p>Kolejnym etapem b\u0119dzie implementacja logu w pami\u0119ci nieulotnej wraz z mo\u017cliwo\u015bci\u0105 jego odczytywania i czyszczenia z poziomu powy\u017cszej konsoli.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Serwer WWW<\/h4>\n\n\n\n<p>Aby usprawni\u0107 i przyspieszy\u0107 konfiguracj\u0119 IoT HUBa oraz umo\u017cliwi\u0107 zdalny dost\u0119p do jego zasob\u00f3w, postawili\u015bmy na nim serwer WWW, oparty o LwIP. Sama integracja LwIP do projektu posz\u0142a sprawnie \u2013 wspierali\u015bmy si\u0119 przy tym oprogramowaniem do generowania kodu, dostarczonym przez ST (CubeMX).<\/p>\n\n\n\n<p>Na poni\u017cszym przyk\u0142adzie widoczne jest okno s\u0142u\u017c\u0105ce do konfigurowania i wizualizowania funkcji termostatu \u2013 o czym opowiem szerzej w cz\u0119\u015bci opisuj\u0105cej przygotowane demo.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot11.jpg\"><img decoding=\"async\" width=\"1048\" height=\"898\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot11.jpg\" alt=\"Wizualizacja stanu funkcji termostatu\" class=\"wp-image-7935\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot11.jpg 1048w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot11-300x257.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot11-1024x877.jpg 1024w\" sizes=\"(max-width: 1048px) 100vw, 1048px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 9. Wizualizacja stanu funkcji termostatu.<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Manager scen<\/h4>\n\n\n\n<p>Obecnie trwaj\u0105 prac\u0119 nad dodatkiem pozwalaj\u0105cym na dodawanie\/usuwanie\/monitorowanie akcji (nazwanym dalej scenami). W tym celu zaprz\u0119gni\u0119ty zosta\u0142 silnik graficzny oparty o googlowe Blockly.<a href=\"#_ftn7\" name=\"_ftnref7\" rel=\"nofollow\" >[7]<\/a><\/p>\n\n\n\n<p>Za jego pomoc\u0105 mo\u017cna w prosty spos\u00f3b zmontowa\u0107 konkretn\u0105 scen\u0119 i zapisa\u0107 j\u0105 w pami\u0119ci IoT HUBa w formie pliku JSON. Nast\u0119pnie scena jest wykonywana, przy zaj\u015bciu zdefiniowanych w niej warunk\u00f3w, przez wbudowany w IoT HUBa interpreter kodu Java Script.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot12.jpg\"><img decoding=\"async\" width=\"1165\" height=\"469\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot12.jpg\" alt=\"Manager scen w obecnym (nieuko\u0144czonym jeszcze) kszta\u0142cie\" class=\"wp-image-7936\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot12.jpg 1165w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot12-300x121.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot12-1024x412.jpg 1024w\" sizes=\"(max-width: 1165px) 100vw, 1165px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 10. Manager scen w obecnym (nieuko\u0144czonym jeszcze) kszta\u0142cie<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Jenkins, testowanie \u2013 jednym s\u0142owem jako\u015b\u0107<\/h2>\n\n\n\n<p>\u017baden projekt, do kt\u00f3rego kontrybuuje wiele os\u00f3b, nie mo\u017ce si\u0119 oby\u0107 bez zapewnienia cho\u0107by minimum testowania\/jako\u015bci.<\/p>\n\n\n\n<p>Do tego kwestia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>automatyzacji wykonywanych test\u00f3w i generowania raport\u00f3w testowych,<\/li>\n\n\n\n<li>tworzenia paczek releasowych,<\/li>\n\n\n\n<li>statycznej analizy kodu<\/li>\n<\/ul>\n\n\n\n<p>r\u00f3wnie\u017c powinna zosta\u0107 zaadresowana i zaimplementowana w projekcie.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Google test (Gtest)<\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot13.jpg\"><img decoding=\"async\" width=\"172\" height=\"499\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot13.jpg\" alt=\"Struktura test\u00f3w jednostkowych w projekcie\" class=\"wp-image-7937\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot13.jpg 172w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot13-103x300.jpg 103w\" sizes=\"(max-width: 172px) 100vw, 172px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 11. Struktura test\u00f3w jednostkowych w projekcie<\/figcaption><\/figure>\n\n\n\n<p>Testy niskopoziomowych driver\u00f3wZdecydowali\u015bmy si\u0119 na wdro\u017cenie w projekcie biblioteki unit testowej od Google\u2019a. &nbsp;Wymaga\u0142o to napisania sporej liczby mock\u00f3w. Przy czym same testy podzielili\u015bmy w spos\u00f3b identyczny jak samo oprogramowanie:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Testy warstwy po\u015bredniej (services)<\/li>\n\n\n\n<li>Testy warstwy aplikacyjnej<\/li>\n<\/ul>\n\n\n\n<p>Sam framework testowy daje du\u017co mo\u017cliwo\u015bci je\u017celi chodzi o raportowanie \u2013 za jego pomoc\u0105 mo\u017cemy wygenerowa\u0107 szczeg\u00f3\u0142owy raport dla ka\u017cdego z plik\u00f3w \u017ar\u00f3d\u0142owych z konkretnym podzia\u0142em pokrycia testami na:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Linie kodu \u017ar\u00f3d\u0142owego<\/li>\n\n\n\n<li>Rozga\u0142\u0119zienia w kodzie (branche)<\/li>\n\n\n\n<li>Konkretne funkcje<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot14.jpg\"><img decoding=\"async\" width=\"1391\" height=\"366\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot14.jpg\" alt=\"Gtestowy raport dla IoT HUBa\" class=\"wp-image-7938\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot14.jpg 1391w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot14-300x79.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot14-1024x269.jpg 1024w\" sizes=\"(max-width: 1391px) 100vw, 1391px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 12. Gtestowy raport dla IoT HUBa<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Statyczna analiza kodu (CppCheck)<\/h3>\n\n\n\n<p>Dodatkowo postanowili\u015bmy narzuci\u0107 sobie jeszcze jeden element &#8211; narz\u0119dzie do statycznej analizy kodu, celem wyeliminowania potencjalnych i realnych luk w kodzie \u017ar\u00f3d\u0142owym oraz zabezpieczenia si\u0119 przed wszelkimi programistycznymi gafami, kt\u00f3re umkn\u0119\u0142y uwadze recenzent\u00f3w.<\/p>\n\n\n\n<p>Znowu rozgorza\u0142y jednak dyskusje na temat wyboru konkretnego narz\u0119dzia. Ostatecznie podj\u0119li\u015bmy decyzj\u0119 o u\u017cyciu CppChecka i traktowaniu generowanych przez niego wynik\u00f3w w charakterze wskaz\u00f3wek.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testy automatyczne<\/h3>\n\n\n\n<p>Wymienione wy\u017cej elementy zosta\u0142y spi\u0119te pod sztandarem Jenkinsa, zainstalowanego na dedykowanej maszynie testowej. Dzi\u0119ki temu w ci\u0105gu kilku minut otrzymujemy w pe\u0142ni automatyczny i obiektywny status na temat jako\u015bci oprogramowania IoT HUBa.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot15.jpg\"><img decoding=\"async\" width=\"1383\" height=\"767\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot15.jpg\" alt=\"Szybki rzut okiem w IoT HUBowego Jenkinsa\" class=\"wp-image-7939\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot15.jpg 1383w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot15-300x166.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot15-1024x568.jpg 1024w\" sizes=\"(max-width: 1383px) 100vw, 1383px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 13. Szybki rzut okiem w IoT HUBowego Jenkinsa<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie<\/h2>\n\n\n\n<p>Projekt IoT HUB pozwoli\u0142 nam znacz\u0105co poszerzy\u0107 i ugruntowa\u0107 kompetencje z dziedziny Internet of Things. W ramach realizacji powsta\u0142, w dalszym ci\u0105gu rozwijany i udoskonalany, produkt \u0142\u0105cz\u0105cy w sobie wiele technologii.<\/p>\n\n\n\n<p>W toku prac dotychczasowych rozwi\u0105zali\u015bmy spor\u0105 ilo\u015b\u0107 in\u017cynierskich i typowo organizacyjnych problem\u00f3w, takich jak na przyk\u0142ad:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Szybkie wdra\u017canie nowych os\u00f3b, z r\u00f3\u017cnych lokalizacji, do projektu<\/li>\n<\/ul>\n\n\n\n<p>W tej kwestii pomog\u0142o opracowanie kompleksowej instrukcji, przeprowadzaj\u0105cej krok po kroku przez proces zestawiania \u015brodowiska oraz wdra\u017caj\u0105cej w arkana projektu<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nieoczekiwany reset urz\u0105dzenia spowodowany pojawieniem si\u0119 wyj\u0105tku<\/li>\n<\/ul>\n\n\n\n<p>Tutaj pomog\u0142o wyposa\u017cenie exception handlera w dedykowany fragment kodu, s\u0142u\u017c\u0105cy do odszukania adresu w pami\u0119ci programu, z kt\u00f3rego nast\u0105pi\u0142o wygenerowanie wyj\u0105tku. Zwykle problem by\u0142 spowodowany wyciekiem pami\u0119ci lub nadpisaniem stosu w\u0105tku przez inny w\u0105tek.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Brakiem przestrzeni dyskowej na maszynie Jenkinsowej<\/li>\n<\/ul>\n\n\n\n<p>Na wczesnym etapie projektu wszystkie artefakty budowania by\u0142y niepotrzebnie archiwizowane po stronie Jenkinsa. Gdy ilo\u015b\u0107 danych przekroczy\u0142a 300 GB zacz\u0119\u0142y pojawia\u0107 si\u0119 b\u0142\u0119dy&nbsp; spowodowane niemo\u017cno\u015bci\u0105 zapisu kolejnych plik\u00f3w. Wyczyszczenie przestrzeni roboczej Jenkinsa po\u0142\u0105czone z ograniczeniem ilo\u015bci archiwizowanych artefakt\u00f3w do ostatnich 30 build\u00f3w rozwi\u0105za\u0142o problem.<\/p>\n\n\n\n<p>Patrz\u0105c na projekt od strony czysto technicznej wykorzystali\u015bmy nast\u0119puj\u0105ce technologie i narz\u0119dzia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Od strony programistycznej\n<ul class=\"wp-block-list\">\n<li>C<\/li>\n\n\n\n<li>C++<\/li>\n\n\n\n<li>Java Script<\/li>\n\n\n\n<li>Groovy<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Od strony komunikacyjnej\n<ul class=\"wp-block-list\">\n<li>Bluetooth Low Energy<\/li>\n\n\n\n<li>LoRa<\/li>\n\n\n\n<li>UART, I2C, SPI<\/li>\n\n\n\n<li>LwIP<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Narz\u0119dzia\n<ul class=\"wp-block-list\">\n<li>Eclipse<\/li>\n\n\n\n<li>CubeMX,<\/li>\n\n\n\n<li>GitHub<\/li>\n\n\n\n<li>Jira<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Zapewnienie jako\u015bci\n<ul class=\"wp-block-list\">\n<li>Jenkins<\/li>\n\n\n\n<li>GTest<\/li>\n\n\n\n<li>CppCheck<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>.223rem<\/p>\n\n\n\n<p><a href=\"#_ftnref1\" name=\"_ftn1\" rel=\"nofollow\" >[1]<\/a> Za Histori\u0105 Greck\u0105 Ksenofronta<\/p>\n\n\n\n<p><a href=\"#_ftnref2\" name=\"_ftn2\" rel=\"nofollow\" >[2]<\/a> <a href=\"http:\/\/www.domoticz.com\/\" rel=\"nofollow\" >http:\/\/www.domoticz.com\/<\/a>,<\/p>\n\n\n\n<p><a href=\"#_ftnref3\" name=\"_ftn3\" rel=\"nofollow\" >[3]<\/a> <a href=\"https:\/\/www.openhab.org\/\" rel=\"nofollow\" >https:\/\/www.openhab.org\/<\/a><\/p>\n\n\n\n<p><a href=\"#_ftnref4\" name=\"_ftn4\" rel=\"nofollow\" >[4]<\/a> <a href=\"https:\/\/www.home-assistant.io\/\" rel=\"nofollow\" >https:\/\/www.home-assistant.io\/<\/a><\/p>\n\n\n\n<p><a href=\"#_ftnref5\" name=\"_ftn5\" rel=\"nofollow\" >[5]<\/a> CMSIS &#8211; Cortex Microcontroller Software Interface Standard<\/p>\n\n\n\n<p><a href=\"#_ftnref6\" name=\"_ftn6\" rel=\"nofollow\" >[6]<\/a> Complex driver jest poj\u0119ciem ze standardu AUTOSAR i okre\u015bla modu\u0142\/modu\u0142y, kt\u00f3re nie s\u0105 zdefiniowane przez ten standard. G\u0142\u00f3wnym celem complex driver\u2019a jest zamkni\u0119cie w nim z\u0142o\u017conych, niestandardowych czy odziedziczonych sterownik\u00f3w (legacy drivers).<\/p>\n\n\n\n<p><a href=\"#_ftnref7\" name=\"_ftn7\" rel=\"nofollow\" >[7]<\/a> <a href=\"https:\/\/developers.google.com\/blockly\/\" rel=\"nofollow\" >https:\/\/developers.google.com\/blockly\/<\/a><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;7930&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;6&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 6)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;IoT HUB, czyli zr\u00f3bmy ciekawy projekt&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 6)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Poni\u017cszy artyku\u0142 przedstawia wewn\u0119trzny projekt, realizowany przez in\u017cynier\u00f3w-programist\u00f3w z Centrum Kompetencyjnego Embedded firmy Sii. Od strony technicznej projekt pokazuje rozwi\u0105zanie &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/iot-hub-czyli-zrobmy-ciekawy-projekt\/\">Continued<\/a><\/p>\n","protected":false},"author":161,"featured_media":7949,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[563,129,1032,435],"class_list":["post-7930","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-embedded","tag-c","tag-case-study","tag-iot"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/08\/iot-hub.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7930"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/161"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=7930"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7930\/revisions"}],"predecessor-version":[{"id":24560,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7930\/revisions\/24560"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/7949"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=7930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=7930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=7930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}