{"id":28089,"date":"2024-06-17T05:00:00","date_gmt":"2024-06-17T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=28089"},"modified":"2024-06-17T14:25:14","modified_gmt":"2024-06-17T12:25:14","slug":"protokol-xcp-w-systemach-wbudowanych","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/protokol-xcp-w-systemach-wbudowanych\/","title":{"rendered":"Protok\u00f3\u0142 XCP w systemach wbudowanych"},"content":{"rendered":"\n<p>Pracuj\u0105c nad oprogramowaniem dla bran\u017cy automotive, w pewnym momencie stykamy si\u0119 z konieczno\u015bci\u0105 dost\u0119pu do wewn\u0119trznych zmiennych ECU (ang. Electronic Control Unit). Pierwszym naszym pomys\u0142em mo\u017ce by\u0107 oczywi\u015bcie debugger (np.: Lauterbach TRACE32, iSYSTEM WinIdea), nierzadko jednak zdarzaj\u0105 si\u0119 sytuacje, gdy jest on niewystarczaj\u0105cy.<\/p>\n\n\n\n<p>Dzieje si\u0119 tak:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>gdy dysponujemy jedynie plikami wykonywalnymi (skompilowanym kodem \u017ar\u00f3d\u0142owym aplikacji), np.: .exe, .dll, .bin, .hex, .elf bez symboli),<\/li>\n\n\n\n<li>gdy fizycznie nie jeste\u015bmy w stanie podpi\u0105\u0107 debuggera (np.: podczas test\u00f3w w samochodzie),<\/li>\n\n\n\n<li>podczas prac nad prototypowaniem urz\u0105dzenia (ang. Rapid Control Prototyping)<\/li>\n\n\n\n<li>podczas kalibracji i pomiar\u00f3w r\u00f3\u017cnorodnych parametr\u00f3w ECU (np.: za pomoc\u0105 symulacji rzeczywistego urz\u0105dzenia w programie Vector CANoe) w systemach HIL (Hardware-in-the-loop) \/SIL (Software-in-the-loop),<\/li>\n\n\n\n<li>w analizie problem\u00f3w wyst\u0119puj\u0105cych sporadycznie.<\/li>\n<\/ul>\n\n\n\n<p>We wspomnianych powy\u017cej sytuacjach z pomoc\u0105 mo\u017ce nam przyj\u015b\u0107 protok\u00f3\u0142 XCP (ang. Universal Measurement and Calibration Protocol), kt\u00f3ry z powodzeniem jest stosowany w \u015bwiecie automotive, a nawet szerzej \u2013 po prostu w systemach wbudowanych.<\/p>\n\n\n\n<p>W poni\u017cszym artykule chcia\u0142bym przedstawi\u0107 <strong>podstawowe za\u0142o\u017cenia teoretyczne tego protoko\u0142u oraz dost\u0119pne funkcjonalno\u015bci w praktyce.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wprowadzenie do protoko\u0142u XCP<\/strong><\/h2>\n\n\n\n<p>Protok\u00f3\u0142 XCP zosta\u0142 ustandaryzowany w 2003 roku przez ASAM (ang. Association for Standardization of Automation and Measuring Systems). Za\u0142o\u017ceniami nowego protoko\u0142u zosta\u0142y przede wszystkim:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>bazowanie na architekturze typu Master \u2013 Slave,<\/li>\n\n\n\n<li>niezale\u017cno\u015b\u0107 od rodzaju fizycznej magistrali.<\/li>\n<\/ul>\n\n\n\n<p>Podstawowym za\u015b celem nowego standardu sta\u0142o si\u0119 umo\u017cliwienie dostosowania (odczyt i\/lub zapis) parametr\u00f3w wewn\u0119trznych ECU \u2013 pomiar i kalibracja, w taki spos\u00f3b, aby z jednej strony zmniejszy\u0107 restrykcyjne wymagania dotycz\u0105ce korzystania z zasob\u00f3w ECU, z drugiej jednak zapewni\u0107 maksymaln\u0105 pr\u0119dko\u015b\u0107 transmisji.<\/p>\n\n\n\n<p>W praktyce opracowano standard podstawowy opisuj\u0105cy za\u0142o\u017cenia i komunikacj\u0119 samego protoko\u0142u oraz kilka dodatkowych, skupionych na warstwach transportowych konkretnych magistrali \u2013 CAN, FlexRay, Ethernet (UDP\/IP oraz TCP\/IP), USB, SPI, SCI.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-1.png\"><img decoding=\"async\" width=\"921\" height=\"203\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-1.png\" alt=\"XCP \u2013 model warstwowy\" class=\"wp-image-28091\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-1.png 921w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-1-300x66.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-1-768x169.png 768w\" sizes=\"(max-width: 921px) 100vw, 921px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 XCP \u2013 model warstwowy<\/figcaption><\/figure>\n\n\n\n<p>Zdefiniowano r\u00f3wnie\u017c, \u017ce dost\u0119p do parametr\u00f3w i zmiennych wewn\u0105trz ECU zostanie zapewniony za pomoc\u0105 informacji o ich adresach w pami\u0119ci, za\u015b wszystkie informacje niezb\u0119dne do uzyskania do nich dost\u0119pu oraz pozosta\u0142a konfiguracja b\u0119d\u0105 zawarte w znormalizowanych plikach w standardzie ASAM MCD-2 MC, czyli plikach z rozszerzeniem .a2l. Szerzej o tych plikach opowiem w ostatniej cz\u0119\u015bci tego artyku\u0142u. <\/p>\n\n\n\n<p>Najnowsz\u0105 dost\u0119pn\u0105 wersj\u0105 protoko\u0142u XCP jest wersja 1.5 wprowadzona w roku 2017.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Protok\u00f3\u0142 XCP \u2013 model komunikacji<\/strong><\/h2>\n\n\n\n<p>W tym artykule nie mam zamiaru przedstawia\u0107 ca\u0142o\u015bciowo protoko\u0142u XCP, gdy\u017c s\u0105 do tego stosowne dokumentacje. Chcia\u0142bym jednak pokr\u00f3tce opisa\u0107 podstawy XCP, aby\u015bcie \u0142atwiej zrozumieli dalsze zagadnienia.<\/p>\n\n\n\n<p>Komunikacja XCP opiera si\u0119, tak jak wspomnia\u0142em powy\u017cej, na wymianie pakiet\u00f3w (ang. XCP Packets) pomi\u0119dzy uk\u0142adami Master \u2013 Slave. Wyr\u00f3\u017cniamy dwie grupy pakiet\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CTO (ang. Command Transfer Object) do transmisji podstawowych komend (ang. <strong>C<\/strong>o<strong>M<\/strong>man<strong>D<\/strong>), odpowiedzi na te komendy (ang. <strong>RES<\/strong>ponse), zg\u0142aszania b\u0142\u0119d\u00f3w podczas wykonywania komend (ang. <strong>ERR<\/strong>or), obs\u0142ugi sytuacji specjalnych (ang. <strong>EV<\/strong>ent) oraz obs\u0142ugi pakiet\u00f3w serwisowych (ang. <strong>SERV<\/strong>ice Request Processor).<\/li>\n\n\n\n<li>DTO (ang. Data Transfer Object) do transmisji danych DAQ (ang. Data AcQuisition) i STIM (ang. Data STIMulation), o kt\u00f3rych b\u0119dzie jeszcze mowa.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Ramka XCP<\/strong><\/h2>\n\n\n\n<p>Ramka XCP sk\u0142ada si\u0119 z 3 cz\u0119\u015bci:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>nag\u0142\u00f3wka (XCP Header),<\/li>\n\n\n\n<li>g\u0142\u00f3wnej cz\u0119\u015bci pakietu (XCP Packet),<\/li>\n\n\n\n<li>zako\u0144czenia (XCP Tail).<\/li>\n<\/ul>\n\n\n\n<p>Warto zauwa\u017cy\u0107, \u017ce pakiet XCP sam w sobie jest niezale\u017cny od warstwy transportowej, co oznacza de facto, \u017ce ka\u017cdorazowo zostaje on obudowany informacjami specyficznymi dla danej magistrali (CAN\/FlexRay\/etc.). Poni\u017cszy rysunek prezentuje to w nieco bardziej przyst\u0119pny spos\u00f3b:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2.jpg\"><img decoding=\"async\" width=\"958\" height=\"275\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2.jpg\" alt=\"Ramka XCP\" class=\"wp-image-28093\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2.jpg 958w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-300x86.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-768x220.jpg 768w\" sizes=\"(max-width: 958px) 100vw, 958px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 <a href=\"https:\/\/dev.to\/arvind_b_n_luxoft\/xcp-universal-measurement-and-calibration-protocol-part-2-gcd\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Ramka XCP<\/a><\/figcaption><\/figure>\n\n\n\n<p>W celu zrozumienia, jakie informacje s\u0105 przekazywane w poszczeg\u00f3lnych polach pakietu, poni\u017cej zamieszczam ich opis:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Identyfikator pakietu (PID) \u2013 pozwala na identyfikacj\u0119 przesy\u0142anej wiadomo\u015bci.<\/li>\n\n\n\n<li>Wyr\u00f3wnanie (FILL) \u2013 pole opcjonalne, kt\u00f3re mo\u017cna wykorzysta\u0107 do wype\u0142nienia, je\u015bli nie ma wystarczaj\u0105cej ilo\u015bci danych do przes\u0142ania.<\/li>\n\n\n\n<li>Absolutna liczba list DAQ (DAQ).<\/li>\n\n\n\n<li>Znacznik czasu (Timestamp) jest to pole opcjonalne wykorzystywane do przesy\u0142ania informacji o czasie systemowym. Mo\u017ce by\u0107 u\u017cyty przez komend\u0119 GET_DAQ_CLOCK lub jako informacja dodatkowa przy korzystaniu z DAQ\/STIM.<\/li>\n\n\n\n<li>Pole danych przy transmisji pakiet\u00f3w CTO (zawiera specyficzne parametry) lub DTO (zawiera dane DAQ\/STIM).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>XCP funkcjonalno\u015bci<\/strong><\/h2>\n\n\n\n<p>XCP oferuje szereg przydatnych funkcjonalno\u015bci. Cz\u0119\u015b\u0107 z nich jest konieczna do implementacji, natomiast inne s\u0105 jedynie opcjonalne, w zale\u017cno\u015bci od potrzeb czy wymaga\u0144 funkcjonalnych projektu. W tym miejscu chcia\u0142bym om\u00f3wi\u0107 najwa\u017cniejsze z nich.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Nawi\u0105zanie po\u0142\u0105czenia<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/gif-3.gif\"><img decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/gif-3.gif\" alt=\"\" class=\"wp-image-28184\"\/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 XCP \u2013 nawi\u0105zanie po\u0142\u0105czenia <\/figcaption><\/figure>\n\n\n\n<p>Nawi\u0105zanie po\u0142\u0105czenia z XCP Slave polega na wys\u0142aniu komendy CONNECT (kod 0xFF). W polu MODE wybra\u0142em tryb Normalny (zdefiniowanym przez standard), cho\u0107 istnieje mo\u017cliwo\u015b\u0107 zdefiniowania w\u0142asnej implementacji nawi\u0105zywania po\u0142\u0105czenia.<\/p>\n\n\n\n<p>Informacje zwrotne m\u00f3wi\u0105 nam, \u017ce:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>b\u0119dziemy mieli do dyspozycji DAQ i STIM (pole RESOURCE),<\/li>\n\n\n\n<li>do transmisji danych zosta\u0142 wybrany format Intel, rozmiar elementu pod jednym adresem to 1 Bajt, Slave Block Mode jest dost\u0119pny, komenda GET_COMM_MOD_INFO zapewnia dodatkowe informacje (pole COMM_MODE_BASIC),<\/li>\n\n\n\n<li>maksymalny rozmiar pakietu CTO to 0x96 (pole MAX_CTO),<\/li>\n\n\n\n<li>maksymalny rozmiar pakietu DTO to 0x2C (pole MAX_DTO),<\/li>\n\n\n\n<li>wersja protoko\u0142u XCP to 1.0 (pole XCP Protocol Layer Version Number),<\/li>\n\n\n\n<li>wersja warstwy transportowej XCP to 1.0 (pole XCP Transport Layer Version Number).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Zako\u0144czenie po\u0142\u0105czenia<\/strong><\/h3>\n\n\n\n<p>Aby zako\u0144czy\u0107 po\u0142\u0105czenie, nale\u017cy wys\u0142a\u0107 komend\u0119 DISCONNECT:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4.gif\"><img decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4.gif\" alt=\"XCP \u2013 zako\u0144czenie po\u0142\u0105czenia\" class=\"wp-image-28097\"\/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4 XCP \u2013 zako\u0144czenie po\u0142\u0105czenia <\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pomiar metod\u0105 odpytywania (ang. Polling Measurement)<\/strong><\/h3>\n\n\n\n<p>Jest to podstawowa funkcjonalno\u015b\u0107 pozwalaj\u0105ca na odczytywaniu warto\u015bci zmiennej za pomoc\u0105 pojedynczego \u017c\u0105dania, u\u017cywaj\u0105c komendy SHORT_UPLOAD lub sekwencji komend SET_MTA i UPLOAD.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5.gif\"><img decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5.gif\" alt=\"XCP \u2013 metoda odpytywania\" class=\"wp-image-28099\"\/><\/a><figcaption class=\"wp-element-caption\">Ryc. 5 XCP \u2013 metoda odpytywania <\/figcaption><\/figure>\n\n\n\n<p>W powy\u017cszej animacji widzimy wys\u0142anie komendy SHORT_UPLOAD (0xF4) do odczytania warto\u015bci zmiennej zlokalizowanej pod adresem 0x12345678 o rozmiarze 2 Bajt\u00f3w. W odpowiedzi uzyskujemy informacj\u0119, \u017ce zmienna ma warto\u015b\u0107 0x0C07.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pomiar cykliczny<\/strong><\/h3>\n\n\n\n<p>Ten rodzaj pomiaru umo\u017cliwia odczyt (DAQ) i\/lub zapis (STIM) warto\u015bci zmiennych w spos\u00f3b cykliczny. W por\u00f3wnaniu do poprzedniego mechanizmu konfiguracja jest troch\u0119 bardziej skomplikowana i wymaga zrozumienia kilku technicznych kwestii.<\/p>\n\n\n\n<p>Po pierwsze potrzebujemy informacji o adresach zmiennych oraz ich rozmiarach (wyra\u017conych w Bajtach). Korzystaj\u0105c z DAQ\/STIM, b\u0119dziemy chcieli cz\u0119sto odczytywa\u0107 lub zmienia\u0107 warto\u015bci wi\u0119kszej ilo\u015bci zmiennych, wi\u0119c de facto b\u0119dziemy tworzy\u0107 tablic\u0119 takich par (adres + rozmiar w Bajtach) (ang. Object Descriptor Table (ODT)).<\/p>\n\n\n\n<p>Po drugie, utworzone w powy\u017cszy spos\u00f3b tablice mo\u017cemy nast\u0119pnie grupowa\u0107 w listy DAQ\/STIM. Listy te mo\u017cna tworzy\u0107 na 3 sposoby:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Predefiniowa\u0107 w ECU (listy DAQ\/STIM oraz tablice ODT s\u0105 predefiniowane; ze wzgl\u0119du na brak elastyczno\u015bci ta metoda rzadko jest u\u017cywana).<\/li>\n\n\n\n<li>Definiowa\u0107 statycznie (listy DAQ\/STIM oraz tablice ODT s\u0105 predefiniowane, ale zmienne mo\u017cna edytowa\u0107).<\/li>\n\n\n\n<li>Definiowa\u0107 dynamicznie, by mie\u0107 pe\u0142n\u0105 kontrol\u0119 na listami, tablicami ODT oraz samymi zmiennymi w czasie rzeczywistym.<\/li>\n<\/ol>\n\n\n\n<p>Ostatni\u0105 cz\u0119\u015bci\u0105 konfiguracji s\u0105 zdarzenia (Eventy). S\u0105 one niczym innym jak cyklicznymi funkcjami, w kt\u00f3rych mo\u017cna uruchamia\u0107 DAQ \/STIM. Na etapie tworzenia zdarze\u0144 definiuje si\u0119 ich cykliczno\u015b\u0107, priorytet, przypisanie funkcji DAQ, STIM lub DAQ\/STIM. Warto te\u017c zaznaczy\u0107, \u017ce Eventy mog\u0105 by\u0107 powi\u0105zane z wi\u0119ksz\u0105 ilo\u015bci\u0105 list.<\/p>\n\n\n\n<p>Poni\u017cszy rysunek przedstawia przyk\u0142ad zale\u017cno\u015bci pomi\u0119dzy definicjami opisanymi wy\u017cej. Utworzy\u0142em zdarzenie XCP_TestEvent z jedn\u0105 list\u0105 typu DAQ, kt\u00f3ra zawiera jedn\u0105 tablic\u0119 ODT z trzema zmiennymi.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-1.png\"><img decoding=\"async\" width=\"787\" height=\"593\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-1.png\" alt=\"XCP \u2013 zale\u017cno\u015bci pomi\u0119dzy zdarzeniem, DAQ list\u0105 i tablic\u0105 ODT\" class=\"wp-image-28101\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-1.png 787w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-1-300x226.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-1-768x579.png 768w\" sizes=\"(max-width: 787px) 100vw, 787px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6 XCP \u2013 zale\u017cno\u015bci pomi\u0119dzy zdarzeniem, DAQ list\u0105 i tablic\u0105 ODT<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>DAQ+STIM (ang. bypassing)<\/strong><\/h3>\n\n\n\n<p>Gdy omawia\u0142em parametry okre\u015blaj\u0105ce XCP Event, wspomnia\u0142em, \u017ce mo\u017ce on by\u0107 nie tylko typu DAQ lub STIM, ale r\u00f3wnie\u017c typu DAQ\/STIM. W takiej sytuacji m\u00f3wimy o tzw. bajpasie \u2013 pobieramy dane z ECU, przetwarzamy je poza ECU i nast\u0119pnie zapisujemy z powrotem do ECU. W tym mechanizmie wa\u017cne jest oczywi\u015bcie zapewnienie pe\u0142nej integralno\u015bci danych oraz spe\u0142nienie warunk\u00f3w synchronizacji odczytu i zapisu do pami\u0119ci.<\/p>\n\n\n\n<p>Z punktu widzenia konfiguracji b\u0119dziemy potrzebowa\u0107 dwie listy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>jedn\u0105 typu DAQ,<\/li>\n\n\n\n<li>jedn\u0105 typu STIM.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Programowanie pami\u0119ci (ang. Flash programming)<\/strong><\/h3>\n\n\n\n<p>Programowanie za pomoc\u0105 protoko\u0142u XCP oznacza mo\u017cliwo\u015b\u0107 zapisu danych pod wskazany obszar w pami\u0119ci nieulotnej Flash. Proces zapisu lub czyszczenie pami\u0119ci wygl\u0105da nast\u0119puj\u0105co:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Przygotowanie istotnych parametr\u00f3w z punktu widzenia zarz\u0105dzania pami\u0119ci\u0105 (np.: kontrolowanie wersji danych, kt\u00f3re chcemy nadpisa\u0107, sprawdzenie, czy ECU zezwala na zapis pod konkretnymi adresami, etc.).<\/li>\n\n\n\n<li>Wykonanie operacji przesy\u0142ania danych do ECU.<\/li>\n\n\n\n<li>Sprawdzenie, czy zapis lub czyszczenie pami\u0119ci powiod\u0142y si\u0119 (np.: sprawdzenie sumy kontrolnej).<\/li>\n<\/ul>\n\n\n\n<p>Warto wi\u0119c zauwa\u017cy\u0107, \u017ce standard XCP definiuje jedynie szkielet mechanizmu oraz podstawowy zestaw komend realizuj\u0105cych zapis lub czyszczenie pami\u0119ci, natomiast spos\u00f3b w jaki ostatecznie zostanie on zaimplementowany, zale\u017cy od wymaga\u0144 danego projektu.<\/p>\n\n\n\n<p>Ze wzgl\u0119du na ograniczone mo\u017cliwo\u015bci bezpiecze\u0144stwa operacji programowania pami\u0119ci za pomoc\u0105 protoko\u0142u XCP <strong>mechanizm ten powinien by\u0107 u\u017cywany jedynie w fazie prac rozwojowych oprogramowania<\/strong>, a nie w produkcie ko\u0144cowym.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Mechanizm ochronny XCP<\/strong><\/h3>\n\n\n\n<p>Podczas prac nad standardem XCP pomy\u015blano r\u00f3wnie\u017c o zabezpieczeniu dost\u0119pu do funkcjonalno\u015bci XCP w spos\u00f3b nieautoryzowany. Do tego celu wykorzystano mechanizm seed-and-key.<\/p>\n\n\n\n<p>Podczas pr\u00f3by po\u0142\u0105czenia XCP Master otrzymuje od XCP Slave wygenerowan\u0105 przez niego liczb\u0119 pseudolosow\u0105 (ang. seed). Nast\u0119pnie Master przy pomocy algorytmu generuje klucz (ang. key), po czym wysy\u0142a go do XCP Slave. Slave r\u00f3wnie\u017c przy pomocy tego samego algorytmu generuje w\u0142asny klucz i por\u00f3wnuje go z tym otrzymanym od Mastera. Je\u017celi klucze s\u0105 identyczne, XCP Slave pozwala na rozpocz\u0119cie komunikacji. Graficzne uj\u0119cie tego procesu przedstawiono na animacji poni\u017cej.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7.gif\"><img decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7.gif\" alt=\"XCP \u2013 mechanizm seed-and-key\" class=\"wp-image-28103\"\/><\/a><figcaption class=\"wp-element-caption\">Ryc. 7 XCP \u2013 mechanizm seed-and-key<\/figcaption><\/figure>\n\n\n\n<p>Chcia\u0142bym r\u00f3wnie\u017c wspomnie\u0107 o wzgl\u0119dach bezpiecze\u0144stwa zwi\u0105zanych z obecno\u015bci\u0105 sterownika XCP w kodzie produkcyjnym. Jest to zagadnienie \u015bci\u015ble zwi\u0105zane z danym projektem i wymaganiami klienta. Spotyka si\u0119 r\u00f3\u017cne podej\u015bcia do niego \u2013 od najbardziej rygorystycznego, w kt\u00f3rym XCP w og\u00f3le nie jest brane pod uwag\u0119 w procesie kompilacji wyda\u0144 produkcyjnych, po bardziej liberalne, gdzie XCP, co prawda jest dezaktywowane, ale z pozostawion\u0105 \u201efurtk\u0105\u201d do ponownej aktywacji za pomoc\u0105 unikalnych sekwencji diagnostycznych. <\/p>\n\n\n\n<p>Tak wi\u0119c nie mamy w tym temacie jednego rozwi\u0105zania, lecz ka\u017cdy przypadek wymaga <strong>indywidualnej analizy.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zarz\u0105dzanie pami\u0119ci\u0105 podczas komunikacji z XCP<\/strong><\/h2>\n\n\n\n<p>Wa\u017cnym zagadnieniem jest prawid\u0142owe zarz\u0105dzanie pami\u0119ci\u0105 podczas komunikacji z XCP.<\/p>\n\n\n\n<p>Podczas normalnej pracy ECU operuje na pami\u0119ci Flash. Mamy zatem ograniczon\u0105 mo\u017cliwo\u015b\u0107 modyfikacji pojedynczych obiekt\u00f3w w niej zapisanych. Jest to podyktowane jej okre\u015blon\u0105 \u017cywotno\u015bci\u0105 (maksymalna ilo\u015b\u0107 operacji zapisu\/kasowania). Co wi\u0119c w sytuacji, gdy w kodzie produkcyjnym konieczne jest cz\u0119ste wykonywanie kalibracji ECU, np.: w systemie czujnik\u00f3w LiDAR? W jaki spos\u00f3b dokonywa\u0107 takich cyklicznych zapis\u00f3w w czasie rzeczywistym (ang. at runtime)?<\/p>\n\n\n\n<p>Z pomoc\u0105 najcz\u0119\u015bciej przychodzi nam <strong>wykorzystanie pami\u0119ci RAM<\/strong>, kt\u00f3ra co prawda wymaga zasilania, by m\u00f3c przechowywa\u0107 informacje, ale za to oferuje \u0142atwy odczyt i zapis. Nie wyst\u0119puje tu r\u00f3wnie\u017c problem z jej \u017cywotno\u015bci\u0105.<\/p>\n\n\n\n<p>B\u0119dzie wi\u0119c chodzi\u0142o o przechowywanie parametr\u00f3w w pami\u0119ci RAM podczas ich modyfikacji. Mo\u017cna zatem u\u017cy\u0107 cz\u0119\u015bci RAM-u jako bufora dla danych odczytanych z Flash. Owo odczytanie zawarto\u015bci i skopiowanie jej do pami\u0119ci RAM zazwyczaj dokonywane jest podczas startu aplikacji, za\u015b podczas wy\u0142\u0105czania nast\u0119puje ca\u0142o\u015bciowy lub cz\u0119\u015bciowy (zmiany mog\u0105 by\u0107 wykrywane za pomoc\u0105 sum kontrolnych) \u201epowrotny\u201d zapis do pami\u0119ci Flash.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Pliki konfiguracyjne A2l<\/strong><\/h2>\n\n\n\n<p>Ostatnim zagadnieniem, kt\u00f3re chcia\u0142bym poruszy\u0107, s\u0105 pliki a2l. Tak jak wspomnia\u0142em, konfiguracja XCP i symboliczne przypisanie zmiennych do ich adres\u00f3w w pami\u0119ci ECU odbywa si\u0119 w\u0142a\u015bnie za pomoc\u0105 plik\u00f3w a2l.<\/p>\n\n\n\n<p>Oto kilka wycink\u00f3w z plik\u00f3w a2l ukazuj\u0105cych szereg parametr\u00f3w konfiguracyjnych niezb\u0119dnych do poprawnego dzia\u0142ania konkretnych funkcjonalno\u015bci:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Konfiguracja protoko\u0142u XCP:<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n       \/begin PROTOCOL_LAYER\n        0x0101 \t\t\t           \/* XCP protocol layer version *\/\n        20\t\t\t\t           \/* T1 &#x5B;ms] Time-out of the standard CTO *\/\n        20000\t\t\t           \/* T2 &#x5B;ms] Time-out of the checksum calculation *\/\n        20000\t\t\t           \/* T3 &#x5B;ms] Time-out of the non-volatile memory programming: eg.  PROGRAM_START *\/\n        20000\t\t\t           \/* T4 &#x5B;ms] Time-out of the non-volatile memory programming: PROGRAM_CLEAR *\/\n        20000\t\t\t           \/* T5 &#x5B;ms] Time-out of the non-volatile memory programming: PROGRAM *\/\n        20000\t\t\t           \/* T6 &#x5B;ms] Time-out of the command CONNECT(USER_DEFINED) *\/\n        20000\t\t\t           \/* T7 &#x5B;ms] Time-out of the pre-action *\/\n        100 \t\t\t           \/* MAX_CTO: Indicates the maximum length of a CTO packet in bytes. *\/\n        50 \t\t\t\t           \/* MAX_DTO: Indicates the maximum length of a DTO packet in bytes. *\/\n        BYTE_ORDER_MSB_LAST\t       \/* Byte Order *\/\n        ADDRESS_GRANULARITY_BYTE   \/*The address granularity indicates the size of an element at a single address. *\/\n        OPTIONAL_CMD GET_ID\t\t   \/* XCP-Code of optional command supported by the slave *\/\n        OPTIONAL_CMD SHORT_UPLOAD\n      \/end PROTOCOL_LAYER\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Konfiguracja Eventu DAQ XCP:<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n     \/begin EVENT\n        Xcp_TestEvent         \/* EVENT_CHANNEL_NAME *\/\n        Xcp_Test              \/* EVENT_CHANNEL_SHORT_NAME *\/\n        0                     \/* EVENT_CHANNEL_NUMBER *\/\n        DAQ \n        1                     \/* MAX_DAQ_LIST *\/\n        1                     \/* TIME_CYCLE *\/\n        1                     \/* TIME_UNIT *\/ \n        0                     \/* PRIORITY *\/\n      \/end EVENT\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Konfiguracja DAQ XCP:<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n   DYNAMIC\t                            \/* The flag indicates whether the DAQ lists that are not PREDEFINED shall be     \n\t                                        configured statically or dynamically *\/\n      5                                     \/* MAX_DAQ: Total number of available DAQ lists *\/ \n      5                                     \/* MAX_EVENT_CHANNEL: Total number of available event channels *\/\n      0                                     \/* MIN_DAQ: Total number of predefined DAQ lists*\/\n      OPTIMISATION_TYPE_DEFAULT             \/* Type of Optimisation Method the master preferably should use. *\/\n      ADDRESS_EXTENSION_FREE                \/* ADDRESS_EXTENSION *\/\n      IDENTIFICATION_FIELD_TYPE_ABSOLUTE    \/* IDENTIFICATION_FIELD *\/\n      GRANULARITY_ODT_ENTRY_SIZE_DAQ_BYTE   \/* GRANULARITY_ODT_ENTRY_SIZE_DAQ *\/\n      7                                     \/* MAX_ODT_ENTRY_SIZE_DAQ *\/\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Konfiguracja dost\u0119pu do odczytu i zapisu zmiennej <em>XCP_TestVar <\/em>typu unsigned word i znajduj\u0105cej si\u0119 pod adresem 0x12345678:<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n    \/begin CHARACTERISTIC XCP_TestVar &quot;&quot;\n      VALUE 0x12345678 __UWORD_Z 0 NO_COMPU_METHOD 0 65535\n      SYMBOL_LINK &quot; XCP_TestVar &quot; 0\n    \/end CHARACTERISTIC\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>Moim celem w powy\u017cszym artykule by\u0142o przyjrzenie si\u0119 kluczowym zagadnieniom i zastosowaniom protoko\u0142u XCP. Przede wszystkim zale\u017ca\u0142o mi na podkre\u015bleniu jego uniwersalno\u015bci i elastyczno\u015bci. Cechy te bowiem uczyni\u0142y go jednym z ulubionych narz\u0119dzi in\u017cynier\u00f3w rozwijaj\u0105cych zaawansowane systemy motoryzacyjne czy te\u017c in\u017cynier\u00f3w test\u00f3w. <\/p>\n\n\n\n<p>Mam nadziej\u0119, \u017ce po przeczytaniu wpisu znajd\u0105 si\u0119 osoby zainteresowane dalszym zg\u0142\u0119bianiem temat\u00f3w zwi\u0105zanych z XCP i r\u00f3wnie\u017c takie, kt\u00f3re b\u0119d\u0105 chcia\u0142y w praktyce wykorzysta\u0107 szereg przydatnych funkcji oferowanych przez ten protok\u00f3\u0142.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Bibliografia<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ASAM e.V. (2008). XCP Version 1.1: The Universal Measurement and Calibration Protocol Family.<\/li>\n\n\n\n<li><a href=\"https:\/\/cdn.vector.com\/cms\/content\/application-areas\/ecu-calibration\/xcp\/XCP_Book_V1.5_EN.pdf\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >XCP \u2013 The Standard Protocol for the Embedded Development<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.autosar.org\/fileadmin\/standards\/R18-10_R4.4.0_R1.5.0\/CP\/AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >AUTOSAR \u2013 Layered Software Architecture<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.autosar.org\/fileadmin\/standards\/R18-10_R4.4.0_R1.5.0\/CP\/AUTOSAR_SWS_XCP.pdf\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >AUTOSAR \u2013 Specification of Module XCP<\/a><\/li>\n<\/ul>\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;28089&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;27&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: 27)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Protok\u00f3\u0142 XCP w systemach wbudowanych&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: 27)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Pracuj\u0105c nad oprogramowaniem dla bran\u017cy automotive, w pewnym momencie stykamy si\u0119 z konieczno\u015bci\u0105 dost\u0119pu do wewn\u0119trznych zmiennych ECU (ang. Electronic &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/protokol-xcp-w-systemach-wbudowanych\/\">Continued<\/a><\/p>\n","protected":false},"author":645,"featured_media":28114,"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":[2216,1589,563,864],"class_list":["post-28089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-xcp","tag-automotive","tag-embedded","tag-autosar"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/Protokol-XCP-w-systemach-wbudowanych.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28089"}],"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\/645"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=28089"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28089\/revisions"}],"predecessor-version":[{"id":28205,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/28089\/revisions\/28205"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/28114"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=28089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=28089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=28089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}