{"id":22417,"date":"2023-07-04T05:00:00","date_gmt":"2023-07-04T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=22417"},"modified":"2023-06-22T11:27:06","modified_gmt":"2023-06-22T09:27:06","slug":"watchdog-czyli-pies-strozujacy-twojej-aplikacji","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/watchdog-czyli-pies-strozujacy-twojej-aplikacji\/","title":{"rendered":"Watchdog \u2013 czyli pies str\u00f3\u017cuj\u0105cy Twojej aplikacji"},"content":{"rendered":"\n<p>Ka\u017cdy, kto na co dzie\u0144 zajmuje si\u0119 programowaniem system\u00f3w wbudowanych, spotka\u0142 si\u0119 pewnie nie raz z sytuacj\u0105, w kt\u00f3rej wykonywany program (a w\u0142a\u015bciwie jego w\u0105tek) dociera do p\u0119tli niesko\u0144czonej i w efekcie \u201ezawiesza si\u0119\u201d. Czasem mo\u017ce to by\u0107 po\u017c\u0105dane dzia\u0142anie (np. przy debuggowaniu), jednak najcz\u0119\u015bciej wynika to z b\u0142\u0119du aplikacji (niew\u0142a\u015bciwa obs\u0142uga wyj\u0105tku b\u0142\u0119du czy np. blokuj\u0105ca funkcja <em>Spi_ReadData<\/em> bez zdefiniowanego timeoutu). W takich sytuacjach nieodzowne staje si\u0119 zastosowanie watchdoga.<\/p>\n\n\n\n<p>Wi\u0119cej o tym systemie dowiecie si\u0119 z niniejszego artyku\u0142u.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Czym jest watchdog i po co si\u0119 go stosuje?<\/strong><\/h2>\n\n\n\n<p>Watchdog, jak sama nazwa wskazuje, ma za zadanie czuwa\u0107 nad bezpiecze\u0144stwem naszej aplikacji. W najprostszym uj\u0119ciu jest to specjalny timer, kt\u00f3ry przy odpowiedniej konfiguracji generuje sygna\u0142 resetu procesora\/systemu w odpowiedzi na przepe\u0142nienie swojego licznika, czyli osi\u0105gni\u0119cie przez niego zdefiniowanej warto\u015bci timeoutu.<\/p>\n\n\n\n<p>W momencie, gdy watchdog jest skonfigurowany i w\u0142\u0105czony, jedyn\u0105 mo\u017cliwo\u015bci\u0105 unikni\u0119cia resetu jest od\u015bwie\u017cenie licznika przez aplikacj\u0119 lub ca\u0142kowite wy\u0142\u0105czenie przez ni\u0105 watchdoga, zanim timeout zostanie osi\u0105gni\u0119ty. Jest to mechanizm szczeg\u00f3lnie cz\u0119sto wykorzystywany w systemach, kt\u00f3re musz\u0105 spe\u0142nia\u0107 wymagania zwi\u0105zane z bezpiecze\u0144stwem u\u017cytkownika (np. w bran\u017cy automotive). Mo\u017ce on r\u00f3wnie\u017c znale\u017a\u0107 zastosowanie w aplikacjach niezwi\u0105zanych z bezpiecze\u0144stwem \u2013 jako dodatkowy \u015brodek podnosz\u0105cy niezawodno\u015b\u0107 produktu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Wewn\u0119trzne i zewn\u0119trzne watchdogi<\/strong><\/h3>\n\n\n\n<p>W systemach wbudowanych mo\u017cna spotka\u0107 watchdogi wewn\u0119trzne lub zewn\u0119trzne. W og\u00f3lnym uj\u0119ciu realizuj\u0105 one t\u0119 sam\u0105 funkcj\u0119, jednak r\u00f3\u017cni\u0105 si\u0119 swoj\u0105 implementacj\u0105. Cz\u0119sto dla projekt\u00f3w z wysokimi wymogami bezpiecze\u0144stwa stosowane s\u0105 oba mechanizmy jednocze\u015bnie w celu zapewnienia redundancji.<\/p>\n\n\n\n<p><strong>Watchdog wewn\u0119trzny<\/strong> jest to timer wbudowany w mikrokontroler, na kt\u00f3rym wykonywana jest aplikacja (innymi s\u0142owy \u2013 jest to peryferium tego mikrokontrolera). Konfiguracja oraz obs\u0142uga przez aplikacj\u0119 realizowana jest poprzez bezpo\u015bredni zapis\/odczyt rejestr\u00f3w z przestrzeni adresowej mikrokontrolera. Sygna\u0142 resetu (lub przerwania) przekazywany jest bezpo\u015brednio do wewn\u0119trznej linii resetu (lub przerwania) mikrokontrolera.<\/p>\n\n\n\n<p><strong>Watchdog zewn\u0119trzny<\/strong> to, z perspektywy g\u0142\u00f3wnego kontrolera, osobny uk\u0142ad scalony z w\u0142asnym firmware\u2019em, kt\u00f3rego konfiguracja i obs\u0142uga odbywaj\u0105 si\u0119 poprzez wysy\u0142anie okre\u015blonych komend po zewn\u0119trznej magistrali danych (np. SPI) oraz interakcj\u0119 z jego wej\u015bciami\/wyj\u015bciami cyfrowymi. Spotka\u0107 mo\u017cna zar\u00f3wno uk\u0142ady scalone realizuj\u0105ce praktycznie tylko i wy\u0142\u0105cznie funkcj\u0119 watchdoga lub bardziej zaawansowane, \u0142\u0105cz\u0105ce w sobie np. funkcje CAN transceivera i watchdoga.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Zastosowania watchdoga<\/strong><\/h3>\n\n\n\n<p>Z opisanych wcze\u015bniej w\u0142a\u015bciwo\u015bci watchdoga wynika, \u017ce jest to <strong>dobre narz\u0119dzie do monitorowania i kontroli wywo\u0142ywania okre\u015blonych funkcji programu w narzuconym przedziale czasowym<\/strong>. W oparciu o t\u0119 funkcjonalno\u015b\u0107 mo\u017cna tworzy\u0107 mechanizmy software\u2019owe o r\u00f3\u017cnych praktycznych zastosowaniach:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>alive monitoring<\/em> \u2013 najprostsza forma wykorzystania watchdoga. Polega na zdefiniowaniu jednego lub wielu miejsc w programie, kt\u00f3re z za\u0142o\u017cenia powinny wykonywa\u0107 si\u0119 cyklicznie. Po osi\u0105gni\u0119ciu wszystkich zdefiniowanych miejsc w danym cyklu SW od\u015bwie\u017ca licznik watchdoga. W przeciwnym wypadku nast\u0119puje reset.<\/li>\n\n\n\n<li><em>deadline monitoring<\/em> \u2013 przydatny w sytuacji, gdy czas wykonywania danej operacji nie mo\u017ce (np. ze wzgl\u0119d\u00f3w bezpiecze\u0144stwa) by\u0107 d\u0142u\u017cszy ni\u017c pewna warto\u015b\u0107 graniczna (deadline). Je\u015bli czas wykonywania monitorowanej funkcji przekroczy deadline, to funkcja resetuj\u0105ca licznik watchdoga nie zd\u0105\u017cy si\u0119 wykona\u0107 i nast\u0105pi reset.<\/li>\n\n\n\n<li><em>program flow monitoring<\/em> (logical supervision) \u2013 polega na zdefiniowaniu sekwencji zdarze\u0144 w programie, kt\u00f3re powinny wykona\u0107 si\u0119 w narzuconym czasie. Tylko po wykonaniu wszystkich zdarze\u0144 w odpowiedniej kolejno\u015bci licznik watchdoga jest resetowany.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Konfiguracja watchdoga<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Typowe parametry watchdoga<\/strong><\/h3>\n\n\n\n<p>Typowa konfiguracja watchdoga polega przede wszystkim na ustaleniu warto\u015bci timeoutu licznika, po przekroczeniu kt\u00f3rej ma nast\u0105pi\u0107 reset. Dodatkowo, bardzo popularnym parametrem konfiguracyjnym jest warto\u015b\u0107 pocz\u0105tkowa okna watchdoga wykorzystywana w trybie okienkowym (<em>ang. window mode<\/em>). Ponadto, w rejestrach kontrolnych watchdog\u00f3w na niekt\u00f3rych platformach spotka\u0107 mo\u017cna np.:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>soft\/hard lock protection <\/em>\u2013 parametry definiuj\u0105ce mo\u017cliwo\u015b\u0107 ponownego nadpisania raz zapisanego rejestru kontrolnego,<\/li>\n\n\n\n<li><em>stop\/freeze mode handling<\/em> \u2013 parametry definiuj\u0105ce, czy licznik watchdoga jest zatrzymywany w momencie wej\u015bcia mikrokontrolera odpowiednio w Stop Mode \/ Debug Mode, co pozwala unikn\u0105\u0107 resetu podczas debuggowania,<\/li>\n\n\n\n<li><em>keyed trigger\/service mode<\/em> \u2013 parametry definiuj\u0105ce, jak\u0105 warto\u015b\u0107 nale\u017cy wpisywa\u0107 do rejestru odpowiedzialnego za cykliczne od\u015bwie\u017canie licznika watchdoga (np. ustalone w nocie katalogowej sta\u0142e warto\u015bci kluczy lub warto\u015bci zmienne obliczane na podstawie ustalonego algorytmu),<\/li>\n\n\n\n<li><em>clock selection<\/em> \u2013 zegar wewn\u0119trzny lub zewn\u0119trzny,<\/li>\n\n\n\n<li><em>timeout reaction<\/em> \u2013 domy\u015blnie reset, ale w niekt\u00f3rych przypadkach dost\u0119pne s\u0105 te\u017c opcje np. \u201e1.timeout-przerwanie, 2.timeout-reset\u201d.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Tryb okienkowy<\/strong><\/h3>\n\n\n\n<p>Window mode pozwala na zdefiniowanie w osobnym rejestrze minimalnej warto\u015bci licznika watchdoga, przy kt\u00f3rej jego od\u015bwie\u017canie jest dozwolone. W efekcie definiowany jest cykliczny przedzia\u0142 czasowy (okno), w kt\u00f3rym aplikacja powinna resetowa\u0107 licznik watchdoga. Pozwala to na bardziej precyzyjne monitorowanie zale\u017cno\u015bci czasowych w aplikacji.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/06\/1.png\"><img decoding=\"async\" width=\"605\" height=\"342\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/06\/1.png\" alt=\"Tryb normalny vs okienkowy watchdoga\" class=\"wp-image-22419\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/06\/1.png 605w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/06\/1-300x170.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 Tryb normalny vs okienkowy watchdoga<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Przyk\u0142adowa konfiguracja wewn\u0119trznego watchdoga<\/strong><\/h2>\n\n\n\n<p>Za\u0142\u00f3\u017cmy, \u017ce nasza aplikacja obs\u0142uguje sterownik \u0142adowarki baterii samochod\u00f3w elektrycznych. G\u0142\u00f3wn\u0105 funkcj\u0105 systemu jest pomiar, analiza i kontrola parametr\u00f3w elektrycznych \u0142adowania (pr\u0105d, napi\u0119cie). Pomiar napi\u0119cia dokonywany jest przez zewn\u0119trzny uk\u0142ad scalony <em>Xyz,<\/em> z kt\u00f3rego nasz mikrokontroler cyklicznie czyta dane pomiarowe. Uk\u0142ad ten posiada predefiniowane funkcje diagnostyczne pozwalaj\u0105ce na weryfikacj\u0119 na bie\u017c\u0105co w\u0142asnej sprawno\u015bci (np. <em>self-test<\/em>).<\/p>\n\n\n\n<p>W celu spe\u0142nienia zdefiniowanej poprzez analiz\u0119 bezpiecze\u0144stwa <a href=\"https:\/\/sii.pl\/blog\/wyszukiwarka\/asil\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">klasyfikacji ASIL<\/a> jedno z wymaga\u0144 brzmi nast\u0119puj\u0105co:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>SW musi wykonywa\u0107 istotne dla bezpiecze\u0144stwa funkcje diagnostyczne uk\u0142adu Xyz minimum co 100 ms.<\/em><\/li>\n\n\n\n<li><em>Funkcje diagnostyczne uk\u0142adu Xyz nie mog\u0105 by\u0107 wykonywane przez SW cz\u0119\u015bciej ni\u017c raz na 70ms.<\/em><\/li>\n<\/ul>\n\n\n\n<p>Dodatkowym za\u0142o\u017ceniem jest, \u017ce za kontrol\u0119 wymog\u00f3w czasowych wykonywania funkcji istotnych dla bezpiecze\u0144stwa uk\u0142adu scalonego <em>Xyz<\/em> odpowiada wewn\u0119trzny watchdog mikrokontrolera:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>SW musi monitorowa\u0107 kryteria czasowe wykonywania istotnych dla bezpiecze\u0144stwa funkcji diagnostycznych uk\u0142adu Xyz z wykorzystaniem watchdoga wewn\u0119trznego DWD (Digital Watchdog).<\/em><\/li>\n<\/ul>\n\n\n\n<p>Ponadto definiujemy, jakiej reakcji spodziewamy si\u0119 na niespe\u0142nienie kryteri\u00f3w czasowych. Dla przyk\u0142adu:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Je\u015bli DWD wykryje, \u017ce wykonywanie funkcji diagnostycznych uk\u0142adu Xyz przekroczy\u0142o kryteria czasowe SW powinien zapisa\u0107 kod b\u0142\u0119du w pami\u0119ci FLASH i zresetowa\u0107 system.<\/em><\/li>\n<\/ul>\n\n\n\n<p>Na podstawie wymienionych wy\u017cej wymaga\u0144 zak\u0142adamy, \u017ce nasza funkcja obs\u0142uguj\u0105ca wykonywanie mechanizm\u00f3w diagnostycznych uk\u0142adu Xyz b\u0119dzie wykonywana w tasku cyklicznym co 90 ms (np. co 9. wykonanie tasku 10 ms).<\/p>\n\n\n\n<p>Na podstawie powy\u017cszych za\u0142o\u017ce\u0144 mo\u017cna skonfigurowa\u0107 wewn\u0119trzny watchdog DWD (Digital Watchdog) mikrokontrolera RM57Lx w nast\u0119puj\u0105cy spos\u00f3b.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Krok 1: Ustaw warto\u015b\u0107 timeoutu (rejestr RTIDWDPRLD)<\/strong><\/h3>\n\n\n\n<p>Rejestr RTIDWDPRLD (pole DWDPRLD) przechowuje zdefiniowan\u0105 przez u\u017cytkownika warto\u015b\u0107 przepe\u0142nienia licznika (preload\/deadline). Do rejestru jest mo\u017cliwy zapis wy\u0142\u0105cznie przed w\u0142\u0105czeniem watchdoga.<\/p>\n\n\n\n<p>Czas przepe\u0142nienia licznika watchdoga mo\u017cna wyznaczy\u0107 z r\u00f3wnania:<\/p>\n\n\n\n<p>T<sub>exp<\/sub> = (DWDPRLD+1) x 2<sup>13<\/sup> \/ RTICLK1<\/p>\n\n\n\n<p>gdzie:<\/p>\n\n\n\n<p>DWDPRLD = 0&#8230;4095<br>RTICLK1 \u2013 cz\u0119stotliwo\u015b\u0107 zegara taktuj\u0105cego modu\u0142 RTI, przyjmijmy 8MHz<br><br>W naszym przypadku przyjmujemy:<\/p>\n\n\n\n<p>T<sub>exp<\/sub> = 100 ms<\/p>\n\n\n\n<p>Czyli:<\/p>\n\n\n\n<p><strong>DWDPRLD<\/strong> = T<sub>exp<\/sub>*RTICLK1\/2<sup>13<\/sup>-1 = 100 ms*8 MHz\/8192-1 = 96,66 = <strong>96<\/strong><\/p>\n\n\n\n<p>Dla warto\u015bci <strong>DWDPRLD<\/strong> = 96 finalnie otrzymujemy deadline watchdoga T<sub>exp <\/sub>= 99,33 ms<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Krok 2: Ustaw wielko\u015b\u0107 okna watchdoga (rejestr RTIWWDSIZECTRL)<\/strong><\/h3>\n\n\n\n<p>Rejestr RTIWWDSIZECTRL pozwala na zdefiniowanie rozmiaru okna watchdoga poprzez wyb\u00f3r jednej z warto\u015bci z tabeli:<\/p>\n\n\n\n<figure class=\"wp-block-table caption-align-center\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">WWDSIZE<\/td><td class=\"has-text-align-center\" data-align=\"center\">Wielko\u015b\u0107 procentowa okna w odniesieniu do warto\u015bci przepe\u0142nienia licznika (preload\/deadline)<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0000 0005h<\/td><td class=\"has-text-align-center\" data-align=\"center\">100% (w tym przypadku rozmiar okna jest r\u00f3wny okresowi licznika watchdoga)<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0000 0050h<\/td><td class=\"has-text-align-center\" data-align=\"center\">50%<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0000 0500h<\/td><td class=\"has-text-align-center\" data-align=\"center\">25%<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0000 5000h<\/td><td class=\"has-text-align-center\" data-align=\"center\">12.5%<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0005 0000h<\/td><td class=\"has-text-align-center\" data-align=\"center\">6.25%<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Pozosta\u0142e warto\u015bci<\/td><td class=\"has-text-align-center\" data-align=\"center\">3.125%<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Zgodnie z wymaganiami, licznik watchdoga powinien by\u0107 od\u015bwie\u017cany cyklicznie w przedziale czasowym [70 ms;100 ms]. W zwi\u0105zku z tym dobieramy warto\u015b\u0107 z tabeli:<\/p>\n\n\n\n<p><strong>WWDSIZE = 0x00000500<\/strong> (odp. Rozmiarowi okna 25%)<\/p>\n\n\n\n<p>Przy powy\u017cszych za\u0142o\u017ceniach faktycznie zdefiniowany przedzia\u0142 czasowy (okno) wygl\u0105da nast\u0119puj\u0105co:<\/p>\n\n\n\n<p>[99,33*75%; 99,33 ms] = <strong>[74,50 ms; 99,33ms]<\/strong><\/p>\n\n\n\n<p>Przedzia\u0142 ten pozwala spe\u0142ni\u0107 w\/w wymagania czasowe.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Krok 3: Ustaw reakcj\u0119 watchdoga na b\u0142\u0105d (rejestr RTIWWDRXNCTRL)<\/strong><\/h3>\n\n\n\n<p>W omawianym przez nas mikrokontrolerze istnieje mo\u017cliwo\u015b\u0107 wyboru, w jaki spos\u00f3b watchdog reaguje na b\u0142\u0105d, tj. na przepe\u0142nienie licznika lub pr\u00f3b\u0119 jego od\u015bwie\u017cenia poza zdefiniowanym oknem, poprzez ustawienia warto\u015bci rejestru RTIWWDRXNCTRL zgodnie z poni\u017csz\u0105 tabel\u0105:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">WWDRXN<\/td><td class=\"has-text-align-center\" data-align=\"center\">Reakcja na b\u0142\u0105d watchdoga<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x05<\/td><td class=\"has-text-align-center\" data-align=\"center\">Watchdog wygeneruje reset, je\u015bli obs\u0142uga licznika zostanie wykonana poza zdefiniowanym oknem czasowym lub nie zostanie wykonana w og\u00f3le.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x0A<\/td><td class=\"has-text-align-center\" data-align=\"center\">Watchdog wygeneruje przerwanie, je\u015bli obs\u0142uga licznika zostanie wykonana poza zdefiniowanym oknem czasowym lub nie zostanie wykonana w og\u00f3le.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>W naszym przypadku po wykryciu przekroczenia kryteri\u00f3w czasowych przez aplikacj\u0119 SW powinien zapisa\u0107 kod b\u0142\u0119du do pami\u0119ci nieulotnej, a nast\u0119pnie zresetowa\u0107 system. W zwi\u0105zku z tym wybieramy obs\u0142ug\u0119 b\u0142\u0119du w przerwaniu i ustawiamy warto\u015b\u0107<\/p>\n\n\n\n<p><strong>WWDRXN = 0x0A<\/strong><\/p>\n\n\n\n<p>W funkcji obs\u0142ugi przerwania zawarta b\u0119dzie obs\u0142uga zapisu kodu b\u0142\u0119du do pami\u0119ci FLASH oraz wywo\u0142anie wprost resetu systemu (software reset).<\/p>\n\n\n\n<p><strong>Uwaga!<\/strong> W przedstawionym wy\u017cej rozwi\u0105zaniu system nie zostanie zresetowany, je\u015bli aplikacja \u201ezawiesi si\u0119\u201d w trakcie wykonywania zdefiniowanej przez nas funkcji obs\u0142ugi przerwania (tj. podczas zapisywania kodu b\u0142\u0119du). Rozpatrywany przez nas modu\u0142 watchdoga daje mo\u017cliwo\u015b\u0107 zmiany konfiguracji rejestru RTIWWDRXNCTRL, nawet je\u015bli watchdog zosta\u0142 ju\u017c uprzednio w\u0142\u0105czony.<\/p>\n\n\n\n<p>W zwi\u0105zku z tym rozs\u0105dnym rozwi\u0105zaniem jest zmiana konfiguracji RTIWWDRXNCTRL na pocz\u0105tku funkcji obs\u0142ugi przerwania b\u0142\u0119du watchdoga <strong>WWDRXN = 0x05 <\/strong>(dzi\u0119ki temu watchdog zresetuje system, nawet je\u015bli funkcja obs\u0142ugi przerwania utknie w p\u0119tli niesko\u0144czonej). Alternatywnym rozwi\u0105zaniem przedstawionego problemu jest zastosowanie r\u00f3wnolegle watchdoga zewn\u0119trznego, kt\u00f3ry reagowa\u0142by na b\u0142\u0105d (przekroczenie timeoutu) resetem. W takim przypadku timeout watchdoga zewn\u0119trznego powinien by\u0107 odpowiednio d\u0142u\u017cszy i uwzgl\u0119dnia\u0107 deadline na wykonanie funkcji obs\u0142ugi przerwania watchdoga wewn\u0119trznego.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Krok 4: W\u0142\u0105cz watchdog (rejestr RTIDWDCTRL)<\/strong><\/h3>\n\n\n\n<p>Rejestr RTIDWDCTRL s\u0142u\u017cy do w\u0142\u0105czenia watchdoga poprzez zapis zdefiniowanego klucza. W mikrokontrolerze RM57Lx, po uprzednim w\u0142\u0105czeniu watchdoga, mo\u017cna go wy\u0142\u0105czy\u0107 jedynie poprzez system reset (aplikacja nie mo\u017ce wy\u0142\u0105czy\u0107 watchdoga). W celu w\u0142\u0105czenia watchdoga zapisujemy odpowiedni\u0105 warto\u015b\u0107 klucza:<\/p>\n\n\n\n<p><strong>DWDCTRL = 0xA98559DA<\/strong> (zapisz warto\u015b\u0107 klucza do w\u0142\u0105czania watchdoga).<\/p>\n\n\n\n<p>W\u0142\u0105czenie watchdoga powinno by\u0107 ostatnim krokiem jego inicjalizacji. Jak ju\u017c wcze\u015bniej wspomnia\u0142em, w wybranym mikrokontrolerze niekt\u00f3re parametry konfiguracyjne mog\u0105 by\u0107 modyfikowane ju\u017c po w\u0142\u0105czeniu watchdoga (np. wielko\u015b\u0107 okna lub reakcja na b\u0142\u0105d), jednak nie zaleca si\u0119 w\u0142\u0105cza\u0107 watchdoga, zanim warto\u015bci pocz\u0105tkowe tych parametr\u00f3w nie zostan\u0105 ustawione wprost przez aplikacj\u0119.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Watchdog a debuggowanie<\/strong><\/h2>\n\n\n\n<p>W poprzednich rozdzia\u0142ach om\u00f3wi\u0142em podstawowe kwestie zwi\u0105zane z watchdogiem oraz opisa\u0142em jego przyk\u0142adow\u0105 konfiguracj\u0119. W ostatnim punkcie tego artyku\u0142u chcia\u0142bym poruszy\u0107 zagadnienia zwi\u0105zane z debuggowaniem aplikacji z watchdogiem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Jak watchdog wp\u0142ywa na mo\u017cliwo\u015b\u0107 debuggowania programu?<\/strong><\/h3>\n\n\n\n<p>G\u0142\u00f3wnym problemem, kt\u00f3re nale\u017cy rozpatrzy\u0107 w kontek\u015bcie debuggowania aplikacji z watchdogiem, jest okre\u015blenie, jak ma pracowa\u0107 watchdog w momencie wstrzymania wykonywania instrukcji przez CPU na \u017c\u0105danie debuggera (czyli wej\u015bcie w tryb <em>Debug Suspend<\/em>).<\/p>\n\n\n\n<p>Je\u015bli zale\u017cy nam, \u017ceby debuggowanie by\u0142o mo\u017cliwe, musimy unikn\u0105\u0107 sytuacji, w kt\u00f3rej wykonywanie programu jest wstrzymane przez debugger, a licznik watchdoga kontynuuje prac\u0119. W przeciwnym wypadku ka\u017cdorazowe spotkanie naszego Program Countera z breakpointem sko\u0144czy si\u0119 przerwaniem lub resetem wygenerowanym przez watchdoga.<\/p>\n\n\n\n<p>Wi\u0119kszo\u015b\u0107 mikrokontroler\u00f3w daje u\u017cytkownikowi mo\u017cliwo\u015b\u0107 konfiguracji pracy watchdoga dla trybu <em>Debug Suspend<\/em>.<\/p>\n\n\n\n<p>Dla przyk\u0142adu:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dla omawianego w poprzednim rozdziale mikrokontrolera RM57Lx istnieje parametr konfiguracyjny COS (Continue on Suspend) w rejestrze RTIGCTRL, kt\u00f3ry definiuje zbiorczo zachowanie wszystkich licznik\u00f3w wchodz\u0105cych w sk\u0142ad modu\u0142u RTI (Real Time Interrupt) \u2013 w tym watchdoga DWD \u2013 na wej\u015bcie aplikacji w tryb <em>Debug Suspend<\/em> (<em>halting debug<\/em>):<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Warto\u015b\u0107 COS<\/td><td class=\"has-text-align-center\" data-align=\"center\">Zachowanie licznik\u00f3w RTI przy wej\u015bciu urz\u0105dzenia w tryb \u201e<em>halting debug<\/em>\u201d<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0<\/td><td class=\"has-text-align-center\" data-align=\"center\">Liczniki RTI zatrzymuj\u0105 si\u0119 w trybie \u201e<em>halting debug<\/em>\u201d<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">1<\/td><td class=\"has-text-align-center\" data-align=\"center\">Liczniki RTI kontynuuj\u0105 prac\u0119 w trybie \u201e<em>halting debug<\/em>\u201d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dla mikrokontrolera z rodziny MPC563X od NXP istnieje mo\u017cliwo\u015b\u0107 bezpo\u015bredniej konfiguracji zachowania licznika watchdoga w trybie <em>Debug Suspend<\/em> z poziomu rejestru SWT_CR (Software Watchdog Control Register), bit FRZ:<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table caption-align-center\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Warto\u015b\u0107 FRZ<\/td><td class=\"has-text-align-center\" data-align=\"center\">Zachowanie licznika watchdoga SWT przy wej\u015bciu urz\u0105dzenia w tryb \u201e<em>Debug Suspend<\/em>\u201d<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0<\/td><td class=\"has-text-align-center\" data-align=\"center\">Licznik SWT zatrzymuje si\u0119 w trybie \u201e<em>Debug Suspend<\/em>\u201d<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">1<\/td><td class=\"has-text-align-center\" data-align=\"center\">Licznik SWT kontynuuje prac\u0119 w trybie \u201e<em>Debug Suspend<\/em>\u201d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>R\u00f3wnie\u017c w sytuacji, kiedy nasza aplikacja korzysta z zewn\u0119trznego watchdoga, powinni\u015bmy uwzgl\u0119dni\u0107 jego wp\u0142yw na mo\u017cliwo\u015b\u0107 debuggowania. Najprostszym (i najcz\u0119\u015bciej jedynym) rozwi\u0105zaniem jest wy\u0142\u0105czenie watchdoga na czas debuggowania. Zwykle zewn\u0119trzne uk\u0142ady scalone z funkcj\u0105 watchdoga maj\u0105 osobne wej\u015bcie cyfrowe kontroluj\u0105ce jego stan (on\/off).<\/p>\n\n\n\n<p>Konfiguracja tych pin\u00f3w jest nadrz\u0119dna w stosunku do rejestr\u00f3w kontrolnych odpowiedzialnych za ustawienia watchdoga w danym uk\u0142adzie scalonym. Stan w\/w pin\u00f3w kontroluje si\u0119 przewa\u017cnie z pomini\u0119ciem aplikacji g\u0142\u00f3wnego mikrokontrolera np. poprzez zastosowanie zworki lub przeka\u017anika kontrolowanego przez zewn\u0119trzny tester.<\/p>\n\n\n\n<p><strong>Uwaga!<\/strong> Wszystkie w\/w mechanizmy nie wymagaj\u0105 wy\u0142\u0105czania watchdoga bezpo\u015brednio przez aplikacj\u0119 dla wersji software\u2019u przeznaczonej do debuggowania. Ma to oczywist\u0105 zalet\u0119 \u2013 w momencie uruchomienia takiej aplikacji na mikrokontrolerze bez po\u0142\u0105czenia z debuggerem (lub w przypadku watchdoga zewn\u0119trznego z odpowiednio ustawion\u0105 zwork\u0105) watchdog zareaguje resetem\/przerwaniem na b\u0142\u0105d.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Jak testowa\u0107\/debuggowa\u0107 dzia\u0142anie watchdoga?<\/strong><\/h3>\n\n\n\n<p>Na koniec warto przytoczy\u0107 kilka praktycznych wskaz\u00f3wek, jak podej\u015b\u0107 do debuggowania oraz testowania funkcjonalno\u015bci samego watchdoga.<\/p>\n\n\n\n<p>W fazie pisania\/konfiguracji sterownika watchdoga mo\u017cliwo\u015b\u0107 debuggowania z podgl\u0105dem jego rejestr\u00f3w wydaje si\u0119 niezb\u0119dna. W niekt\u00f3rych mikrokontrolerach w takich rejestrach wyszczeg\u00f3lniono flagi odpowiadaj\u0105ce r\u00f3\u017cnym typom b\u0142\u0119d\u00f3w, na kt\u00f3re watchdog reaguje resetem (<em>start\/end window violation, invalid register access<\/em> itd.).<\/p>\n\n\n\n<p>R\u00f3wnie\u017c ustawienie przerwania zamiast resetu jako reakcji na b\u0142\u0105d watchdoga (przynajmniej w SW testowym\/deweloperskim) mo\u017ce by\u0107 pomocne w debuggowaniu. Pozwala to zapisa\u0107 kod\/flag\u0119 b\u0142\u0119du w pami\u0119ci nieulotnej lub postawi\u0107 breakpoint w funkcji obs\u0142ugi przerwania w celu sprawdzenia kontekstu b\u0142\u0119du.<\/p>\n\n\n\n<p>Jednak przy debuggowaniu watchdoga nale\u017cy te\u017c mie\u0107 na uwadze <strong>ograniczenia<\/strong>, kt\u00f3re mo\u017cna spotka\u0107 w niekt\u00f3rych mikrokontrolerach. Przyk\u0142adowo w mikrokontrolerach z rodziny Aurix TC3xx watchdogi wewn\u0119trzne s\u0105 domy\u015blnie wy\u0142\u0105czone przy podpi\u0119tym debuggerze (czyli kiedy OCDS jest w\u0142\u0105czony) \u2013 ustawienia takie s\u0105 nadrz\u0119dne nad konfiguracj\u0105 rejestr\u00f3w watchdoga przez u\u017cytkownika. W takich przypadkach nale\u017cy wykona\u0107 kroki zgodnie z dokumentacj\u0105 mikrokontrolera w celu w\u0142\u0105czenia watchdoga dla trybu debug (je\u015bli takowe s\u0105 udost\u0119pnione). Nierzadko identyfikacja wp\u0142ywu debuggera na zachowanie watchdoga mo\u017ce by\u0107 k\u0142opotliwa z uwagi na <strong>poziom skomplikowania dokumentacji mikrokontrolera.<\/strong><\/p>\n\n\n\n<p>W zwi\u0105zku z powy\u017cszymi ograniczeniami zdecydowanie zalecan\u0105 praktyk\u0105 jest <strong>finalnie przeprowadzenie test\u00f3w funkcjonalnych watchdoga z od\u0142\u0105czonym debuggerem.<\/strong><\/p>\n\n\n\n<p>W celu przetestowania watchdoga bez udzia\u0142u debuggera nale\u017cy przygotowa\u0107 \u015brodowisko testowe pozwalaj\u0105ce na weryfikacj\u0119 wykonania resetu po b\u0142\u0119dzie watchdoga (np. dedykowana ramka CAN wysy\u0142ana w fazie start-up aplikacji). W celu sprawdzenia g\u0142\u00f3wnej funkcjonalno\u015bci watchdoga \u2013 czyli reakcji na przepe\u0142nienie licznika \u2013 warto zaimplementowa\u0107 prost\u0105 funkcj\u0119 testow\u0105 blokuj\u0105c\u0105 po okre\u015blonym czasie lub na \u017c\u0105danie testera (wys\u0142ane np. po magistrali CAN) wykonanie w\u0105tku odpowiedzialnego za cykliczne resetowanie tego licznika.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>W artykule om\u00f3wi\u0142em g\u0142\u00f3wne zagadnienia dotycz\u0105ce watchdoga. Opisa\u0142em jego funkcjonalno\u015b\u0107 oraz podzia\u0142 na watchdogi wewn\u0119trzne i zewn\u0119trzne. Wymieni\u0142em g\u0142\u00f3wne zastosowania oraz parametry konfiguracyjne. Na przyk\u0142adzie pokaza\u0142em typow\u0105 konfiguracj\u0119 rejestr\u00f3w watchdoga wewn\u0119trznego w oparciu o uproszczone wymagania. Na koniec poruszy\u0142em zagadnienia zwi\u0105zane z debuggowaniem aplikacji z watchdogiem.<\/p>\n\n\n\n<p>W praktyce, <strong>aby w pe\u0142ni wykorzysta\u0107 korzy\u015bci p\u0142yn\u0105ce z u\u017cywania watchdoga w aplikacji<\/strong>, tworzone s\u0105 specjalne komponenty software\u2019owe pozwalaj\u0105ce monitorowa\u0107 wykonanie w okre\u015blonym czasie wielu fragment\u00f3w kodu w aplikacji i reagowa\u0107 na wykryte b\u0142\u0119dy z wykorzystaniem jednego lub wielu watchdog\u00f3w (przyk\u0142ad: WdgM w standardzie Autosar). Jest to jednak temat na osobny artyku\u0142.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Bibliografia<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><a href=\"https:\/\/www.ti.com\/lit\/ug\/spnu562a\/spnu562a.pdf?ts=1685125143707&amp;ref_url=https%253A%252F%252Fwww.google\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >RM57Lx 16\/32-Bit RISC Flash Microcontroller Technical Reference Manual, Texas Instruments Incorporated, 2018-03<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.nxp.com\/files-static\/32bit\/doc\/ref_manual\/MPC563XMRM.pdf\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >MPC5634M Microcontroller Reference Manual, Freescale Semiconductor, 2012-09<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.infineon.com\/dgdl\/Infineon-AURIX_TC3xx_Part1-UserManual-v02_00-EN.pdf?fileId=5546d462712ef9b701717d3605221d96\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Infineon-AURIX_TC3xx_Part1-UserManual-v02_00-EN, Infineon Technologies AG, 2021-02<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.autosar.org\/fileadmin\/standards\/R22-11\/CP\/AUTOSAR_SWS_WatchdogManager.pdf\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Specification of Watchdog Manager AUTOSAR CP R22-11, AUTOSAR, 2022-11<\/a><\/li>\n<\/ol>\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;22417&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;14&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.8&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;4.8\\\/5 ( votes: 14)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Watchdog \u2013 czyli pies str\u00f3\u017cuj\u0105cy Twojej aplikacji&quot;,&quot;width&quot;:&quot;133.7&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: 133.7px;\">\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            4.8\/5 ( votes: 14)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Ka\u017cdy, kto na co dzie\u0144 zajmuje si\u0119 programowaniem system\u00f3w wbudowanych, spotka\u0142 si\u0119 pewnie nie raz z sytuacj\u0105, w kt\u00f3rej wykonywany &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/watchdog-czyli-pies-strozujacy-twojej-aplikacji\/\">Continued<\/a><\/p>\n","protected":false},"author":530,"featured_media":22427,"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":[1731,1546,563],"class_list":["post-22417","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-watchdog","tag-przeglad-narzedzi","tag-embedded"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/06\/Watchdog-\u2013-czyli-pies-strozujacy-Twojej-aplikacji.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/22417"}],"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\/530"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=22417"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/22417\/revisions"}],"predecessor-version":[{"id":22424,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/22417\/revisions\/22424"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/22427"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=22417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=22417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=22417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}