Systemy Czasu Rzeczywistego Autorzy



Pobieranie 386.64 Kb.
Strona1/5
Data06.05.2016
Rozmiar386.64 Kb.
  1   2   3   4   5

Systemu Czasu Rzeczywistego 2016-05-06

Systemy Czasu Rzeczywistego

Autorzy:

Wacław Kowalski

Rafał Krawczyk

Maciej Stojko

Tomasz Żyguła

Spis treści:



Zastosowanie podejścia środowiskowego UML w modelowaniu struktury systemu czasu rzeczywistego 4

Tytułem wstępu 5

Domena aplikacji 6

Używanie UML 7

Wprowadzenie 8

Modelowanie struktury 8

Porty 10

Konektory 17

Kapsuły 18

Zapis 21

Modelowanie zachowania 23

Protokoły 23

Zapis 24

Maszyny stanu 26

Wyzwalacze oparte na portach 26

Wzorzec abstrakcyjnego zachowania 27

Usługa oparta na czasie 31

Modelowanie UML 31

Zasady dobrego formułowania i dynamiczna składnia 31

Real – time UML - przykład 32

Analiza wymagań 41

Przypadki użycia 42

Scenariusze 45

Analiza przedmiotu 47

Diagramy klas 47

Relacje 53

Diagram stanów 59

Automatyczna weryfikacja modeli UML 62

Wstęp 63

Projekt RIVIERA 64

Źródło i metainformacje 64

PVF (Property Verification Framework) 65

PM (Property Manager) 66

Kontrolerzy 67

Hierarchia własności 68

Proces weryfikacji 69

Integrowanie PVF 70

Dodanie nowych własności 72

Struktura 73

Wzorce 73

Inne podobne narzędzia 75

I-Logix Raphsody 76

I-Logix Statement Magnum 76

Together 78

Teza PhD 78

DMS Toolkit 78

Visual Paradigm for UML Community Edition 3.1 79

Metamill 3.1 Visual UML CASE Tool 82

RationalRose 83

Argo 86


TESTY 87

Wyniki testów: 88

Metamill 3.1 88

RationalRose 91

Visual Paradigm 102



Zastosowanie podejścia środowiskowego UML w modelowaniu struktury systemu czasu rzeczywistego



Tytułem wstępu


Zagnieżdżone systemy oprogramowania czasu rzeczywistego spotykane w takich zastosowaniach jak telekomunikacja, aeronautyka i obrona, zwykle są duże i bardzo skomplikowane. W takich systemach niezwykle istotna jest solidna architektura. Nie tylko ułatwia ona początkową konstrukcję systemu, ale – co jest nawet ważniejsze – pozwala na wprowadzanie zmian związanych z nowymi celami stawianymi przed systemem. W tym referacie opiszemy zestaw tworów konstrukcyjnych, które ułatwiają projektowanie architektury oprogramowania w tej dziedzinie. Twory te, wywodzące się ze sprawdzonych w praktyce pomysłów pierwotnie zaimplementowanych w języku modelowania ROOM, opierają się na standardzie Unified Modeling Language – UML. Szczegółowo opisujemy, jak te konstrukty architektoniczne mogą być wyprowadzone z bardziej ogólnych sposobów modelowania UML przy użyciu potężnych mechanizmów rozszerzania UML.

Wprowadzenie

Wprowadzamy Jednolity Język Modelowania UML aby opisać zestaw konstruktów odpowiednich dla modelowania istotnej kategorii systemów oprogramowania czasu rzeczywistego. Pochodzą one z pomysłów pierwotnie zastosowanych w języku modelowania ROOM .

Domena aplikacji

Jedną z najważniejszych cech systemów czasu rzeczywistego jest zdolność do sprawnego reagowania na działania użytkownika w ciągu akceptowalnego okresu czasu. Ta prosta cecha definiuje szerokie spektrum różnych typów systemów od opartych na czasie do opartych na zadaniu, od miękkich do twardych systemów czasu rzeczywistego, itd. Z czasem każda z tych kategorii systemów wykształciła na podstawie doświadczeń zebranych w wielu projektach swoje własne środowisko, szablony i modele projektowania.

W tym referacie skupiamy się na największej kategorii systemów czasu rzeczywistego, które można określić jako skomplikowane, oparte na zadaniu i – potencjalnie – rozproszone. Takie systemy można najczęściej spotkać w telekomunikacji, aeronautyce, obronie i systemach automatycznej kontroli. Z powodu swej wielkości i stopnia złożoności systemy te wymagają początkowo dużych wysiłków, podejmowanych zwykle przez większe grupy, a następnie długiego okresu rozwoju i wzrostu. Przez ten czas pojawiają się nowe wymagania wobec systemu, który musi być odpowiednio modyfikowany, aby im sprostać.

W takich warunkach nadrzędnym problemem staje się architektura oprogramowania. Oznacza ona niezbędną strukturalną i behawioralną podstawę, na której opierają się wszystkie inne aspekty systemu. Odpowiednikiem architektury w budownictwie są ściany nośne – każda zmiana w ich rozmieszczeniu wymaga skomplikowanych i kosztownych modyfikacji. Dlatego też dobrze zaprojektowana architektura nie tylko upraszcza tworzenie systemu, ale też pozwala na łatwe wprowadzanie w nim zmian.

Aby poznać zasady tworzenia dobrej architektury, dobrze jest zapoznać się z szablonami projektowania, które oferują sprawdzoną jakość. Dlatego też do ROOM-u włączono pomysły, które tworzą specyficzny dla danej domeny język tworzenia architektury. Zasady te są używane od ponad dziesięciu lat i okazały się niezwykle przydatne w setkach różnorodnych projektach przemysłowych dużej skali. Okazało się, że to specyficzne dla domeny zastosowanie może być zaimplementowane przy użyciu ogólnego UML.

Używanie UML


Jak wspomniano wyżej, zasady te wprowadzono przy użyciu UML. Okazał się on dobrze spełniać swoje zadanie, a żadne dodatkowe sposoby modelowania nie były potrzebne. Swoje zastosowanie znalazły standardowe mechanizmy UML, takie jak stereotypy (ang. stereotype), wartości-etykiety (ang. tagged value) i warunki ograniczające (ang. constrains). Przykładowo istotę ROOM stanowią „kapsuły”, szczególny przypadek klasy w UML. Stereotyp ten rozszerza definicję klasy o specyficzną dla naszej dziedziny składnię. Kapsuły dostarczają skrótowy sposób odnoszenia się do zestawu dobrze opracowanych zasad, które określają tę składnię.

W efekcie sposoby modelowania opisane w tym referacie stanowią pewien rodzaj biblioteki UML, która znajduje zastosowanie w modelowaniu architektury dla skomplikowanych systemów czasu rzeczywistego. Biblioteka ta w połączeniu z innymi elementami UML tworzy obszerny zestaw narzędzi.

Wprowadzenie


Przeanalizujmy teraz najważniejsze zasady modelowania, które mają swoje zastosowanie w skomplikowanych systemach czasu rzeczywistego, a także opisujemy, jak można je wdrożyć przy użyciu UML. Zasady te można podzielić na dwie grupy: modelowanie struktury i modelowanie zachowania

Modelowanie struktury


Struktura systemu obejmuje elementy, które mają być modelowane oraz związki między nimi (np. związki komunikowania się, związki zawierania). UML dostarcza dwa komplementarne typy diagramów, które obejmują strukturę logiczną systemów: diagramy klasy (ang. class diagram) i diagramy współpracy (ang. collaboration diagram). Diagramy klasy przedstawiają uniwersalne związki pomiędzy klasami, czyli te związki, które istnieją w każdym kontekście istnienia klas. Diagramy współpracy przedstawiają związki, które istnieją tylko w pewnym ograniczonym kontekście – stanowią szablon dla konkretnego celu, który nie jest zawarty w definicji klasy. Dlatego też w diagramach współpracy rozróżnia się kolejne instancje tej samej klasy za pomocą roli. W sposobie modelowania prezentowanym w tym referacie zwracamy uwagę, aby diagramy współpracy UML przedstawiały jedynie współzależności pomiędzy jednostkami architektury. Zwykle kompletną specyfikację struktury skomplikowanych systemów czasu rzeczywistego tworzy kombinacja diagramów klasy oraz diagramów współpracy.

W szczególności możemy zdefiniować trzy zasadnicze konstrukty przy modelowaniu struktury:


  • kapsuły

  • porty

  • konektory

Kapsuły są to skomplikowane, fizyczne, potencjalnie rozproszone obiekty architektoniczne, które oddziaływają ze swoim otoczeniem poprzez jeden lub więcej sygnałowych1 obiektów brzegowych2 zwanych portami. Port jest fizyczną częścią kapsuły, która pośredniczy w komunikacji kapsuły ze światem zewnętrznym, jest obiektem, który zawiera specyficzny interfejs. Każdy port kapsuły odgrywa konkretną rolę we współpracy kapsuły z innymi obiektami. Semantyczną częścią tej współpracy zajmują się protokoły określające prawidłowy przepływ informacji (sygnałów) pomiędzy połączonymi portami kapsuł. Zmuszając kapsuły do komunikacji wyłącznie przez swoje porty, możemy oddzielić ich wewnętrzną strukturę od otaczającego je środowiska, co czyni je bardziej wszechstronnymi.

Konektory (ang. connectors), są abstrakcyjnym odzwierciedleniem kanałów komunikacji sygnałowej, które łączy dwa lub więcej portów. Połączone porty muszą pełnić w protokole wzajemnie uzupełniające się i kompatybilne role. Abstrahując od portów, to właśnie konektory zajmują się rzeczywistą komunikacją pomiędzy kapsułami. Zależności te mają dla architektury duże znaczenie, gdyż identyfikują, które kapsuły mogą się ze sobą bezpośrednio komunikować. Porty uwzględnia się, aby umożliwić kapsułom ukrywanie informacji i oddzielenie ich od świata zewnętrznego.

Możliwości kapsuł są realizowane przez połączoną z nią maszyną stanu (ang. state machine). Bardziej skomplikowane kapsuły obejmują wewnętrzną sieć pod-kapsuł (ang. sub-capsule), które współpracują przy użyciu konektorów. Te pod-kapsuły mogą również zawierać własne pod-kapsuły. Taki rodzaj dekompozycji może iść dowolnie daleko, umożliwiając modelowanie skomplikowanych struktur jedynie przy użyciu podstawowych zasad. Maszyna stanu (opcjonalnie), pod-kapsuły i ich sieć reprezentują części implementacji kapsuły i są niedostępne dla zewnętrznych obserwatorów.


Porty


Porty służą jako obiekty brzegowe dla każdej instancji kapsuły. Należą one do instancji kapsuły w tym sensie, że są tworzone razem z kapsułą i usuwane, gdy usuwana jest kapsuła. Każdy port ma swoją tożsamość i stan, które różnią się od tożsamości i stanu instancji kapsuły, do której należą (tak samo jak zawartość jest różna od swojego pojemnika).

Mimo, że porty działają jak interfejsy, nie odnoszą się bezpośrednio do interfejsów UML. Interfejs UML jest rzeczą czysto behawioralną i nie ma swojej struktury implementacyjnej. Port, z drugiej strony, zawiera zarówno strukturę, jak i własne zachowanie. Jest częścią składową struktury kapsuły, a nie tylko ograniczeniem jej zachowania. Realizuje on szablon architektoniczny, który możemy nazwać „interfejsem manifestu” (ang. manifest interface).

Jak już wspomniano, każdy port odgrywa rolę w jakimś protokole. Ta rola definiuje typ portu, czyli port realizuje sposób zachowania narzucony mu przez protokół.

Ponieważ porty znajdują się na obrzeżach kapsuły, mogą być widoczne zarówno z wnętrza, jak i z zewnątrz kapsuły. Patrząc od zewnątrz, wszystkie porty stanowią ten sam nieprzenikniony obiekt i nie mogą być rozróżniane inaczej, niż za pomocą swej tożsamości i roli jaką odgrywają w protokole. Patrząc natomiast od środka kapsuły, możemy rozróżnić dwa rodzaje portów: przekaźnikowe (ang. relay ports) i terminatory (ang. end ports). Różnią się one pomiędzy sobą wewnętrznymi powiązaniami – porty przekaźnikowe są połączone z pod-kapsułami, a terminatory z maszyną stanu kapsuły. Ogólnie porty przekaźnikowe „eksportują” interfejsy pod-kapsuł, a terminatory są obiektami brzegowymi dla maszyny stanu kapsuły. Zarówno przekaźniki, jak i kapsuły pojawiają się na obrzeżu kapsuły i – jak już wspomniano – nie są odróżnialne z zewnątrz.



Porty przekaźnikowe

Porty przekaźnikowe są portami, które przekazują dalej każdy sygnał. Stanowią one „otwór” w powłoce kapsuły i mogą być użyte przed pod-kapsuły do komunikacji ze światem zewnętrznym bez konieczności ujawniania się. Port przekaźnikowy jest połączony poprzez konektor do pod-kapsuły i – zwykle – do innej równoległej kapsuły. Otrzymują one sygnały pochodzące z każdej strony i zwyczajnie przekazują je drugiej stronie przy zachowaniu kierunku komunikacji. Nie wynika z tego jakiekolwiek opóźnienie lub strata informacji, chyba że po drugiej stronie nie ma podłączonego konektora. W takim wypadku sygnał zostaje utracony.

Porty przekaźnikowe umożliwiają bezpośrednie przekazywanie sygnałów i nie wymagają do swojego działania interwencji maszyny stanu kapsuły. Porty przekaźnikowe mogą się pojawiać jedynie na obrzeżu kapsuły i są zawsze publicznie widoczne.

Terminatory

Łańcuch konektorów musi być zawsze zakończony terminatorem, który komunikuje się z maszyną stanu kapsuły. Terminatory są obiektami brzegowymi dla maszyny stanu kapsuły (chociaż, mogą również służyć jako obiekty brzegowe dla samej kapsuły). Terminatory są ostatecznym źródłem i końcem każdego sygnału wysyłanego przez kapsuły. Sygnały te są generowane przez maszyny stanu kapsuł. Aby wysłać sygnał, maszyna stanu wywołuje operację nadawania lub odbioru w jednym ze swoich terminatorów. Sygnał jest następnie przekazywany przez konektor, (potencjalnie) przez jeden lub więcej portów przekaźnikowych aż w końcu natrafia na drugi terminator, zwykle w innej kapsule. Ponieważ komunikacja sygnałowa może być asynchroniczna, terminator zawiera kolejkę, w której przetrzymuje wiadomości otrzymane, ale jeszcze nie przetworzone przez maszynę stanu (przypomina to skrzynkę pocztową). Odbiór i odsyłanie sygnału jest realizowany zgodnie ze standardem składni UML .

Podobnie do portów przekaźnikowych, terminatory mogą pojawiać się na obrzeżu kapsuły i być publicznie widoczne. Takie porty nazywane są terminatorami publicznymi i mają postać obiektów zarówno maszyny stanu, jak i kapsuły.3 Jednakże terminatory mogą pojawiać się także w środku kapsuły jako części jej wewnętrznej struktury. Porty są używane przez maszynę stanu do komunikacji ze swoimi pod-kapsułami albo z zewnętrznymi warstwami implementacji i wspomagania4. Te wewnętrzne terminatory są nazywane chronionymi terminatorami, gdyż są niewidoczne.

Należy zauważyć, że ten rodzaj portu jest całkowicie określony przez swoją wewnętrzną możliwość łączenia się i widoczność na zewnątrz kapsuły; różne możliwe określenia (port przekaźnikowy, publiczny terminator, prywatny terminator) stanowią jedynie skrótową terminologię. Publiczny port, który nie jest połączony wewnętrznie może się stać albo portem przekaźnikowym albo terminatorem w zależności od swojego późniejszego połączenia, może także nie zostać podłączonym i stanowić kosz dla nadchodzących sygnałów.



Modelowanie UML

Używając terminologii UML, port jako obiekt jest modelowany przez stereotyp „portu”, który jest stereotypem klasy UML. Jak już wspomniano, typ portu jest definiowany przez rolę protokołu, którą odgrywa. Ponieważ role protokołu są klasami abstrakcyjnymi, konkretna klasa odwołująca się do tej instancji jest tą, która implementuje rolę protokołu powiązaną z tym portem. W zależnościach UML pomiędzy portem a protokołem rola jest identyfikowana jako zrealizowana zależność. Zapisuje się to za pomocą kreski z trójkątną strzałką na końcu specyfikacji. Jest to forma uogólnienia, gdzie element źródłowy – port – dziedziczy jedynie zachowanie specyficzne dla celu – roli protokołu – ale nie dla jego struktury.

Kapsuła jest w szczególnej relacji ze swoimi portami. Jeżeli końcowa część tej relacji jest większa niż jeden, oznacza to, że istnieje wiele instancji portu, a każdy z nich bierze udział w innej instancji protokołu. Jeżeli końcowa część relacji jest zakresem wartości, oznacza to, że liczba portów może być zmienna w czasie i że porty są dynamicznie tworzone i niszczone (może to podlegać ograniczeniom).

Rysunek 1. Porty, protokoły i role protokołów

Rysunek 1 pokazuje przykład pojedynczego portu b należącego do klasy kapsuł CapsuleClassA. Port ten realizuje nadrzędną rolę protokołu identyfikowanego przez klasę protokołów ProtocolA. Należy zauważyć, że właściwa klasa portów PortClassX, będąca implementacją klasy, która może się różnić w poszczególnych realizacjach, zwykle nie interesuje modelującego aż do fazy implementacji. Informacją mającą znaczenie jest rola protokołu, którą implementuje ten protokół. Z tego powodu, a także dla ułatwienia oznaczania, oznaczenia użyte na rysunku 1 nie jest zwykle używane i są zastępowane bardziej zwięzłą formą opisaną w dalszej części referatu .

Zapis (oznaczanie)

W diagramach klasy, porty kapsuły są wymienione w specjalnie oznaczonej liście, jak to przedstawiono na rysunku 2. Lista portów zwykle pojawia się po atrybucie i operatorze listy. Taki sposób zapisu wykorzystuje funkcję UML pozwalającą na dodawanie list o specjalnych nazwach.



Rysunek 2. Oznaczanie portów – reprezentacja diagramu klasy

Wszystkie porty zewnętrzne (porty przekaźnikowe i publiczne terminatory) są widoczne z zewnątrz, podczas gdy porty wewnętrzne są ukryte (np. port b2 na rysunku 2). Rolę protokołu określa się zwykle za pomocą ścieżki dostępu, ponieważ nazwa roli protokołu jest unikatowa jedynie w pewnym ograniczonym obszarze. Przykładowo, na rysunku 2 port b odgrywa nadrzędną rolę zdefiniowaną w klasie protokołu ProtocolA. Dla portów binarnych często stosuje się zapis skrótowy: symbol tyldy (~) używany jest dla koniugacyjnych5 (ang. conjugated) roli protokołów (np. port b2) natomiast konkretna nazwa nie wymaga dodatkowych adnotacji (np. port b1). Porty o ilości instancji (ang. multiplicity) różnej od jeden zawierają ilość instancji w nawiasach kwadratowych. Przykładowo, port b1[3] ma trzy instancje, a b5[0..2] oznaczałoby port o zmiennej liczbie instancji nie większej od dwóch.

Rysunek 2 pokazuje jak porty są przedstawiane w diagramach klasy. Porty można także przedstawiać na diagramach współpracy, które opisują wewnętrzny podział kapsuły. W takich diagramach obiekty są reprezentowane przez odpowiadające im role, pod-kapsuły przez role kapsuł, a porty przez role portów. Aby rysunek nie był zbyt zagmatwany role portów przedstawia się zwykle za pomocą ikon (biały lub czarny kwadrat). Porty publiczne mają postać ikony, która znajduje się na obramowaniu kapsuły (zob. rysunek 3). Taki skrótowy zapis jest dobrze zrozumiały i pozwala uniknąć rysowania niepotrzebnych przecinających się linii.



Rysunek 3. Sposób zapisu portów – diagram współpracy

Można zauważyć, że etykiety na rysunku 3 są jedynie dodatkiem do roli portów i nie należy ich mylić nazwami konektorów.6 Ponieważ porty posiadają unikatowe nazwy, nie ma znaczenia graficzna kolejność portów na brzegu kapsuły. Dzięki temu unika się rysowania krzyżujących się linii.

Dla protokołów binarnych może być użyta dodatkowa ikona: port pełniący rolę koniugacyjną jest oznaczony białym kwadratem (w odróżnieniu od czarnych kwadratów). W takim przypadku należy użyć przedrostek w postaci tyldy oraz nazwę protokołu, aby oznaczyć rolę koniugacyjną; nazwa roli protokołu jest tutaj zbędna i można ją pominąć. Analogicznie, sama nazwa protokołu na czarnym kwadracie oznacza rolę bazową protokołu. Np. jeżeli podstawową rolą protokołu ProtQ jest rola nadrzędna, to rysunki 3 i 4 są ekwiwalentne. Taka konwencja zapisu pozwala łatwo zobaczyć, kiedy komplementarne protokoły są połączone.



Rysunek 4. Konwencje zapisu dla protokołów binarnych

Porty o większej liczbie instancji również można zaznaczać graficznie, używając standardowego sposobu zapisu UML (Rysunek 5). Nie jest to konieczne (wystarcza jedynie odpowiednie oznaczenie w nawiasach kwadratowych), ale podkreśla możliwość istnienia większej liczby instancji danego portu.

Rysunek 5. Porty o większej liczbie instancji

Opisane tutaj przykłady graficznego przedstawiania portów na diagramach współpracy opierają się na widoku kapsuł z zewnątrz. W takich wypadkach nie jest możliwe bądź pożądane określenie, czy dany port jest portem przekaźnikowym, czy terminatorem. Kiedy jednak pokazujemy wewnętrzną strukturę kapsuły, takie rozróżnienie musi być graficznie dokonane (rysunek 6).

Rysunek 6. Zapis portów – diagram współpracy (widok od wewnątrz)

W tym wypadku terminatory są pokazane jako połączone z figurą przypominającą stadion, która symbolizuje maszynę stanu kapsuły. Przykładowo port x1 jest publicznym (koniugacyjnym) terminatorem, a port x3 jest chronionym terminatorem. (Można zauważyć, że chociaż na rysunku zaznaczono wiele maszyn stanu, w rzeczywistości jedna kapsuła może zawierać najwyżej jedną maszynę stanu. Terminatory można graficznie podłączać do jednej maszyny stanu, co jednak zaciemniało by obraz rysunku). Porty przekaźnikowe oznacza się przez ich połączenie z portem pod-kapsuły (np. port x2). Porty, które nie są połączone ani z ikoną „stadionu”, ani z portem pod-kapsuły, tak jak port x4, są portami nieokreślonymi (ang. indeterminate). Oznacza to, że nie określa się, czy są one przekaźnikami czy terminatorami, lecz tworzy się dla nich specjalną podklasę.

Konektory


Konektor reprezentuje kanał komunikacyjny, który udostępnia funkcję transportu dla danego protokołu sygnałowego. Podstawową cechą konektorów jest to, że potrafią one połączyć jedynie te porty, które pełnią wzajemnie komplementarne role w protokole danego konektora. Zasadą jest, że rola protokołu nie musi koniecznie przynależeć do tego samego protokołu, ale wtedy musi być kompatybilna z protokołem konektora.7

Podobieństwo pomiędzy konektorami a protokołami może sugerować, że są to identyczne pojęcia. Nie jest to jednak prawdą, gdyż protokoły są abstrakcyjną specyfikacją zachowania, podczas gdy konektory oznaczają obiekty fizyczne, których jedynym zadaniem jest przekazywanie sygnałów między jednym portem a drugim. Zwykle konektory mają postać pasywnego kanału. (W praktyce fizyczne konektory mogą czasem odbiegać od założonego zachowania. Przykładowo, w wyniku wewnętrznego błędu, konektor może wykasować, zmieniać kolejność lub duplikować wiadomości. Ten typ błędu ma często miejsce w rozproszonych kanałach komunikacji).



Modelowanie UML

W UML konektor jest modelowany za pomocą związku (ang. association) i jest definiowany poprzez rolę związku na diagramie współpracy przedstawiającym kapsułę. Ten związek może istnieć pomiędzy dwoma lub więcej portami odpowiednich klas kapsuły. (W zaawansowanych zastosowaniach, w których konektor ma fizyczne właściwości, stosuje się klasę związku, gdyż konektor jest zwykle obiektem o określonej tożsamości). Relacja konektora z odpowiednim protokołem jest realizowana poprzez podłączone porty. Nie są potrzebne żadne rozszerzenia UML dla reprezentowania konektorów.



Zapis

Ponieważ konektory nie wymagają żadnych specjalnych stereotypów, nie są konieczne dodatkowe oznaczenia. Na diagramie klasy konektor może być przedstawiony poprzez jego związek. Niezależnie od tego, czy konektor jest rysowany na diagramie klasy, musi on być pokazany na diagramie kooperacji kapsuły, do której przynależy. Konektor protokołu binarnego przedstawia się za pomocą linii pomiędzy dwoma komplementarnymi rolami protokołu.

Konektory dla protokołów trzeciego i wyższego rzędu są reprezentowane przy użyciu standardowego zapisu UML – figury w kształcie diamentu dla powiązań n-tego stopnia.

Kapsuły


Kapsuły są jedną z najważniejszych konstrukcji modelowania. Używa się ich, aby przedstawiać ważniejsze elementy architektoniczne skomplikowanych systemów czasu rzeczywistego. Zazwyczaj kapsuła posiada jeden lub więcej portów, za pomocą których komunikuje się z innymi kapsułami. Kapsuły nie posiadają innych publicznych części niż porty i wszystkie operacje ze światem zewnętrznym są dokonywane przez porty. Jak już wspomniano, kapsuła może zawierać jedną lub więcej pod-kapsuł połączonych ze sobą za pomocą konektorów. Taką wewnętrzną strukturę nazywa się współpracą UML (ang. collaboration). Kapsuła może posiadać maszynę stanu, która wysyła i odbiera sygnały poprzez terminatory kapsuły i która sprawuje kontrolę nad niektórymi elementami wewnętrznej struktury. Maszyna stanu może być zatem rozumiana jako część odpowiedzialna za zachowanie kapsuły i kontrolująca jej operacje.

Oprócz portów, kapsuły posiadają pewne specyficzne ograniczenia statyczne i dynamiczne na swoje procedury, dzięki czemu konkretne jej instancje odróżniają się od ogólnej definicji klasy.



Wewnętrzna struktura

Całkowity wewnętrzny podział kapsuły, czyli jej implementacja, jest przedstawiany za pomocą współpracy (ang. collaboration). Współpraca ta zawiera specyfikację wszystkich jej portów, pod-kapsuł i konektorów. Podobnie jak porty, pod-kapsuły i konektory przynależą do kapsuły i nie mogą istnieć poza nią. Są one tworzone razem z kapsułą i razem z nią kasowane.

Niektóre pod-kapsuły mogą nie być tworzone w tym samym czasie, co zawierające ja kapsuła. Są one tworzone w zależności od potrzeb przez maszynę stanu kapsuły. Maszyna stanu może także usuwać kapsuły w dowolnym czasie. Jest to zgodne z zasadami składania (ang. composition) UML.

Struktura kapsuły może zawierać tzw. role-wtyczki (ang. plug-in roles). Są to specjalne przestrzenie dla pod-kapsuł, które mogą być dynamicznie przydzielane. Takie rozwiązanie jest konieczne, ponieważ nie zawsze z góry wiadomo, które obiekty będą pełniły jakie role podczas działania systemu. Kiedy ta informacja jest już dostępna, odpowiednia instancja kapsuły (która przynależy do innej kapsuły) może być „podłączona” (ang. plugged) do slotu8, w wyniku czego automatycznie tworzone są konektory łączące porty z innymi pod-kapsułami. Jeżeli takie przydzielenie zasobów nie jest już konieczne, kapsuła jest usuwana ze slotu, a wraz z nią odpowiadające jej konektory.

Dynamicznie tworzone pod-kapsuły i wtyczki pozwalają na modelowanie dynamicznie zmieniających się struktur przy jednoczesnym zapewnieniu poprawnej komunikacji i wzajemnych relacji pomiędzy kapsułami. Jest to klucz do osiągnięcia pełnej integralności architektonicznej w skomplikowanych systemach czasu rzeczywistego.



Maszyna stanu

Maszyna stanu opcjonalnie powiązana z kapsułą jest jedynie kolejną częścią implementacji kapsuły. Niesie ona jednak ze sobą szczególne właściwości, które odróżniają je od innych elementów kapsuły:



  • Maszyny stanu nie mogą się składać z innych pod-kapsuł. Określają one zachowanie bezpośrednio. Mogą one być jednak dzielone hierarchicznie na prostsze maszyny stanu, używając standardowych możliwości UML.

  • Może istnieć maksymalnie jedna maszyna stanu na kapsułę (mimo, że pod-kapsuły mogą zawierać własne maszyny stanu). Kapsuły, które nie zawierają maszyn stanu, są pojemnikami dla pod-kapsuł.

  • Maszyny stanu potrafią obsługiwać sygnały docierające do każdego terminatora kapsuły, a także wysyłać sygnały za ich pomocą.

  • Maszyny stanu są jedyną jednostką, która może uzyskać dostęp do chronionych wewnętrznych elementów kapsuły. Oznacza to, że pełnią one funkcję kontrolującą względem wszystkich innych pod-kapsuł9. Mogą one tworzyć i usuwać wszystkie dynamiczne pod-kapsuły oraz podłączać i odłączać zewnętrzne pod-kapsuły zgodnie z zapotrzebowaniem.

Modelowanie UML

W UML kapsuła jest reprezentowana przez stereotyp klasy „kapsuła”. Kapsuła jest połączone strukturalnie ze swoimi portami, pod-kapsułami (wyłączając dynamiczne pod-kapsuły) oraz wewnętrznymi konektorami. Oznacza to, że części te mogą istnieć dopiero podczas powstania konkretnej instancji kapsuły. Nie licząc portów publicznych, wszystkie części kapsuły, takie jak pod-kapsuły i konektory, są ukryte.

Wewnętrzna struktura kapsuły jest modelowana za pomocą współpracy UML. Pod-kapsuły są oznaczane za pomocą odpowiednich ról pod-kapsuł. Również sloty są identyfikowane przez role pod-kapsuł. Typ pod-kapsuły określa z kolei zestaw roli protokołów, które muszą być spełnione przez kapsuły, mające być podłączone do slotów. Aby odróżnić pod-kapsuły wtyczki (ang. plug-in sub-capsules), określa się specjalną wartość-etykietę (ang. tagged value) dla każdej roli pod-kapsuły:


  • isPlugIn – wartość booleanowska; jeżeli jest prawdą oznacza slot, w przeciwnym razie – normalną pod-kapsułę

Dynamicznie tworzone pod-kapsuły są oznaczane przez zmienny czynnik ilości instancji. Podobnie do slotów, mogą one być także określane typem interfejsu. Daje to dużą ogólność w tworzeniu specyfikacji.

Pomimo dodatkowych ograniczeń maszyna stanu powiązana z kapsułą jest modelowana przy pomocy standardowego połączenia między Klasyfikatorem UML (ang. UML Classifier) i Maszyną Stanu. Implementacja/dekompozycja kapsuły jest modelowana poprzez standardowy element współpracy UML powiązany z klasyfikatorem.

Zapis

Zapis na diagramie klasy dla kapsuł używa standardowych konwencji UML. Ponieważ jest stereotypem, nazwa stereotypu może pojawiać się ponad nazwą klasy w prostokącie klasy. Opcjonalna specjalna ikona powiązana ze stereotypem może się pojawić w prawym górnym rogu prostokąta. Oba sposoby notacji są widoczne na rysunku 7. Ponadto, jeżeli kapsuła posiada porty, zapis może także zawierać część z listą portów, jak to pokazano na rysunku 2.

Pod-kapsuły w diagramie klasy mogą być przedstawione za pomocą zależności kompozycji (ang. composition relationship), a pod-kapsuły wtyczki poprzez zależności agregacji (ang. aggregation relationship), co zostało uwidocznione na rysunku 7.

Rysunek 7. Zapis kapsuły na diagramie klasy

Dekompozycja kapsuły może być także przedstawiona przy użyciu zapisu UML dla obiektów składowych, jak to pokazano na rysunku 6 i rysunku 8 poniżej. Poza informacją przekazywaną przez diagram klasy, ten sposób zapisu określa także precyzyjnie wzajemne połączenia topologiczne pomiędzy pod-kapsułami, czyli konektory. Maszyna stanu jako taka nie jest pokazana na tych diagramach (ani na żadnych innych diagramach klasy UML), ale pośrednio poprzez małe białe figury w kształcie stadionu znajdujące się przy terminatorach. Pod-kapsuły wtyczki są przedstawione za pomocą słowa kluczowego „{plugin}” (np. pod kapsuła b na rys. 8).

Rysunek 8. Diagram współpracy odpowiadający diagramowi klasy z rysunku 7


Modelowanie zachowania


Zachowanie jest opisywane na poziomie architektonicznym przy użyciu pojęcia protokołu. Standardowe maszyny stanu UML są używane do modelowania maszyn stanu kapsuł, w połączeniu z dziedziczeniem, jest możliwość ponownego ich zastosowania.


Protokoły


Protokół jest specyfikacją pożądanego zachowania, które ma miejsce przy użyciu konektora – będącego specyfikacją konkretnego uzgodnienia pomiędzy uczestnikami protokołu. Protokół składa się z szeregu uczestników, z których każdy pełni określoną rolę w protokole. Każda taka rola protokołu jest określona przez unikatową nazwę, zestaw sygnałów, które są dobierane przez tę rolę, oraz zestaw sygnałów wysyłanych przez tę rolę (każdy z tych zestawów może być pusty). Opcjonalnie protokół może zawierać specyfikację prawidłowych sekwencji komunikacyjnych; może ją także definiować maszyna stanu. W końcu protokół może również posiadać zestaw sekwencji pierwotnych interakcji (ang. prototypical interactions sequence), które mogą być przedstawiane jako diagramy sekwencji. Diagramy sekwencji muszą być zgodne z protokołem maszyny stanu, jeżeli został taki zdefiniowany.

Protokoły binarne, uwzględniające jedynie dwóch uczestników, są najbardziej pospolite i najłatwiejsze do analizy. Jedną z zalet tego typu protokołów jest fakt, że wystarczy dla nich określenie tylko jednej roli, roli podstawowej. Inna rola, zwana rolą koniugacji, może być wyprowadzona z roli podstawowej poprzez proste odwrócenie zestawów sygnałów przychodzących i wychodzących. Taka operacja inwersji zwana jest właśnie koniugacją.

Modelowanie UML

Rola protokołu jest modelowana przez stereotyp «protocolRole» roli klasyfikatora (ang. ClassifierRole). Ten stereotyp posiada dwie zależności (ang. dependencies) względem sygnału: jedną dla przychodzących a drugą dla wychodzących sygnałów. (Jest to ogólna właściwość klas UML). Podobnie jak każdy inny klasyfikator, rola protokołu może zawierać maszynę stanu, która przechwytuje lokalne zachowanie roli protokołu. Ta maszyna stanu nie musi koniecznie odpowiadać protokołowi maszyny stanu.

Protokół jest modelowany przez stereotyp «protocol» współpracy UML wraz z relacją zawierania względem każdej swojej roli protokołu; odpowiada to zwykłej relacji posiadania własnych elementów. Współpraca nie ma żadnej wewnętrznej struktury (tzn. nie posiada powiązanych ról). Podobnie jak inne elementy podlegające uogolnieniu, protokół może być wzbogacony przy pomocy dziedziczenia. Maszyna stanu i klasy współpracy powiązane z danym protokołem dziedziczą bezpośrednio od klasyfikatora.

Zapis

Role protokołów można przedstawiać, używając standardowego zapisu dla klasyfikatorów z konkretnie wymienioną etykietą stereotypu i dwoma opcjonalnymi listami dla przychodzących i wychodzących zestawów sygnałów, jak to ilustruje rysunek 9. Maszyna stanu i diagram interakcji roli protokołu są reprezentowane za pomocą standardowego zapisu UML.

Rysunek 9. Zapis roli protokołu – diagram klasy

Specjalnego skrótowego sposobu zapisu używa się dla protokołów binarnych, ponieważ występują one zdecydowanie najczęściej. Jak już wcześniej wspomniano, protokoły binarne muszą mieć określoną jedynie rolę podstawową. Ponadto, ponieważ rola maszyny stanu i protokół maszyny stanu są w tym wypadku tym samym, jedynie protokół maszyny stanu musi być określony. Z tego powodu zapis dla protokołów binarnych łączy elementy zapisu roli protokołu poprzez bezpośrednie dołączenie list sygnałów przychodzących i wychodzących z klasą protokołu. Stereotyp protokołu i odpowiadająca mu ikona (rysunek 10) pozwala na rozróżnienie go od zapisu protokołu roli.

Rysunek 10. Zapis protokołów binarnych – diagram klasy


Maszyny stanu


Specyfikacja maszyny stanu jako części kapsuły, tak jak specyfikacja prawidłowych sekwencji protokołu, jest dokonywana przy użyciu standardowych maszyn stanu UML. W tej części pokazujemy niektóre sposoby, przy pomocy których maszyny stanu mogą być użyte do strukturalnego modelowania konstruktów, które już opisaliśmy.

Wyzwalacze oparte na portach

W praktyce często się zdarza, że dwa lub więcej portów tej samej kapsuły używa jednego protokołu, ale są różne w sensie składniowym. Ponadto ten sam sygnał może się pojawiać w więcej niż jednej roli protokołu wspomaganej przez różne porty kapsuły. W każdym z tych przypadków, konieczne może być rozróżnienie pomiędzy konkretnymi terminatorami odbierającymi dany sygnał. Pozwala to aplikacjom na obróbkę tego samego sygnału w różny sposób, w zależności od źródła tego sygnału i jego stanu. Taki sposób wyzwalacza nazwany jest wyzwalaczem opartym na portach (ang. port-based trigger).



Modelowanie UML

Zakłada się, że implementacja dostarcza informacji o tym, który port otrzymał sygnał w postaci jednego z przekazywanych parametrów dotyczących zdarzenia. W takim wypadku wyzwalacze oparte na portach mogą być łatwo modelowane w UML przy użyciu warunków, które sprawdzają port źródłowy. Nie są do tego potrzebne żadne rozszerzenia koncepcyjne.


Wzorzec abstrakcyjnego zachowania


Część ta opisujemy powszechną i bardzo przydatną heurystykę, która wykorzystuje w swoim działaniu hierarchiczną naturę maszyn stanu UML. Po raz pierwszy użyto jej w ROOMcharts10, wariancie ROOM schematów stanu (ang. state chart). Nazywana jest wzorcem abstrakcyjnego zachowania (ang. abstract behavior pattern).



Rysunek 11. Abstrakcyjna maszyna stanu

Rozważmy abstrakcyjną maszynę stanu przedstawioną na rysunku 11. Termin „abstrakcyjny” oznacza, że ta maszyna stanu musi być doprecyzowana przed jej praktycznym zastosowaniem. Przykładowo, prosta maszyna czasu z rysunku 11 jest przedstawicielem najbardziej abstrakcyjnego poziomu zachowania (automatyzacja kontroli) pośród wielu różnych typów elementów w systemach czasu rzeczywistego. Mimo, że wszystkie one dzielą tę samą wysokopoziomową strukturę, różne typy elementów mogą być zupełnie odmienne w swoim zachowaniu w zależności od stawianego przed nimi celu. Dlatego też ta maszyna stanu może służyć jako pewna klasa abstrakcyjnych kapsuł, które są podstawą dla innych, bardziej wyspecjalizowanych klas kapsuł.

Zdefiniujmy teraz dwa różne sposoby uszczegółowienia (ang. refinement) kapsuły, które opierają się na dziedziczeniu. Te dwa sposoby, R1 i R2, przedstawiono na rysunku 12. Dla zachowania jasności rysunku, elementy dziedziczone od klasy-rodzica zaznaczono szarym kolorem.



Rysunek 12. Dwa sposoby uszczegółowienia maszyny stanu z rysunku 11.

Dwa sposoby różnią się pomiędzy metodą dekompozycji stanu „Running” oraz rozszerzenia pierwotnego etapu „start”. Takie metody mogą być stosowane dopiero, gdy sposoby uszczegółowienia są już znane i nie byłyby możliwe w pojedynczej klasie abstrakcyjnej z etapem (ang. transition) typu 1-1.

Modelowanie UML

Możliwość kontynuowania zarówno etapów nadchodzących, jak i wychodzących jest podstawą tego typu uszczegółowień. Może się wydawać, że punkty startowe i ostateczne są wystarczające dla ich opisu. Niestety taka metoda nie wystarcza, jeżeli musimy rozszerzać wiele różnych etapów.

Dla wzorca abstrakcyjnego zachowania potrzebny jest sposób na połączenie dwóch lub więcej segmentów przejścia, które są wykonywane w jednym ciągu od uruchomienia do zatrzymania. Oznacza to, że przychodzące etapy hierarchiczne są dzielone na część, która kończy swoje działanie na brzegu stanu (ang. state boundary) i na jej rozszerzenie, które działa dalej. Analogicznie, hierarchiczne etapy wychodzące są rozkładane na część która przestaje istnieć na brzegu stanu oraz na część, która kontynuuje działanie od granicy stanu do stanu docelowego. Ten efekt może być uzyskany przy pomocy koncepcji stanu łańcucha (ang. chain state). Modeluje się to poprzez stereotyp «chainState» Stanu UML. Jest to stan, którego jedynym zadaniem jest łączenie dalszych automatycznych etapów w jeden etap. Stan łańcucha nie posiada wewnętrznej struktury, żadnego działania początkowego, wewnętrznej aktywności, ani działania wyjściowego. Nie posiada również etapów wywoływanych przez zdarzenia. Może obsługiwać każdą liczbę etapów początkowych (ang. input transition). Może posiadać etapy końcowe (ang. output transition) bez żadnego wyzwalacza; taki etap jest automatycznie realizowany, kiedy etap początkowy aktywuje stan. Zadaniem stanu jest podłączenie etapu początkowego do osobnego etapu kończącego. Przedstawienie stanu łańcucha ma na celu oddzielenie wewnętrznej specyfikacji stanu od jego zewnętrznego środowiska, czyli zamknięcie w kapsule.

W efekcie łańcuch stanu stanowi pewien stan przejściowy, który łączy etapy z ich kontynuacjami. Jeżeli nie zdefiniowano żadnego kolejnego etapu, kończy się proces łączenia, a cały etap jest realizowany.

Przykładowa maszyna stanu przedstawiona na rysunku 13 przedstawia stany łańcucha i ich zapis. Stany łańcucha są reprezentowane na diagramie przez małe białe kółka umieszczone wewnątrz odpowiedniego stanu hierarchicznego (jest to zapis podobny do przedstawiania stanów początkowych i końcowych, które mu odpowiadają). Kółka są ikonami stereotypu i zwykle rysuje się je blisko obrzeży..

Rysunek 13. Stan łańcucha i etapy połączone

Połączone przejście składa się w tym przykładzie z trzech połączonych etapów-segmentów e1/a11/a12/a13. Po otrzymaniu sygnału e1, wykonywane są kolejno etapy e1/a11, a11 aż do osiągnięcia stanu c1. Następnie realizowany jest etap c1 i c2, a na końcu przejście od c2 do S21. Jeżeli na tej ścieżce postępowania wszystkie stany mają działania początkowe i kończące, sekwencja wykonywania ma następującą postać:


  • działanie kończące S11

  • działanie a11

  • działanie kończące S1

  • działanie a12

  • działanie początkowe S2

  • działanie a13

  • działanie początkowe S21

Wszystkie te etapy są wykonywane w jednym ciągu od uruchomienia do zatrzymania.

Możemy to porównać z sekwencją działań wykonywanych przy etapie bezpośrednim e2/a2, które są następujące:



  • działanie kończące S11

  • działanie kończące S1

  • działanie a2

  • działanie początkowe dla stanu S2

  • działanie początkowe dla stanu S21


Usługa oparta na czasie


Tak jak można się spodziewać, w większości systemów czasu rzeczywistego najważniejszym czynnikiem jest czas. Ogólnie można modelować dwie sytuacje oparte na czasie: możliwość wyzwalania działań w określonym momencie i możliwość wywoływania działań po upłynięciu określonego czasu od danego momentu.

Większość systemów czasu rzeczywistego wymaga konkretnej i bezpośrednio dostępnej (podlegającej kontroli) właściwości – usługi opartej na czasie. Usługa ta jest dostępna przy pomocy standardowego portu (serwisowy punkt dostępowy) i zamienia czas w zdarzenia, które są następnie obsługiwane tak samo jak zdarzenia oparte na sygnale. Przykładowo, za pomocą takiej usługi maszyna stanu może zażądać informacji, że osiągnięto pewien moment bądź upłynął określony odcinek czasu.

Modelowanie UML

Idea usługi opartej na czasie nie wymaga żadnych rozszerzeń UML lub specjalnego sposobu zapisu. Serwisowe punkty dostępowe są oznaczane jako chronione terminatory, których typ określa się jako „TimeServiceSAP” (rola definiowana przez system).

Zasady dobrego formułowania i dynamiczna składnia


Bardzo przydatne jest określenie zarówno statycznej składni (tj. zasad dobrego formułowania) jak i składni dynamicznej (realizowanej podczas pracy) dla opisanych tu konstruktów czasu rzeczywistego. Dzięki pełnej i spójnej definicji w połączeniu z również kompletnym i spójnym językiem wykonującym (np. C++ lub Ada), za pomocą którego określa się szczegóły przejść między stanami i metod obiektowych, uzyskany model jest wykonywalny i sprawny. Ponadto, jeżeli w modelu zawarto wszystkie niezbędne detale, będzie on mógł automatycznie generować kompletne implementacje..

  1   2   3   4   5


©absta.pl 2016
wyślij wiadomość

    Strona główna