Systemy czasu rzeczywistego (QNX)
IV rok informatyki, studia dzienne magisterskie
rok akademicki 2006/2007, semestr zimowy


Poniżej znajduje się opis zadań do zrealizowania w semestrze. Opis dotyczy zadania A.

Część A, czyli system działający lokalnie

Wykorzystując mechanizmy systemowe zaprojektować i uruchomić zadany przez prowadzącego zajęcia system.

Zasady działania systemu:
  1. Wszystkie procesy systemu uruchamiamy na jednym procesorze, czyli na jednym komputerze, ale tak, by każdy proces był uruchomiony na innej konsoli.
  2. Do synchronizacji procesów wykorzystujemy komunikaty.
  3. Każdy proces kończąc pracę informuje o normalnym lub awaryjnym zakończeniu pracy (procesy 'klienci informują, który serwer uległ uszkodzeniu).
  4. Procesy nie pobierają danych z plików.
  5. W programach nie można wykorzystywać funkcji fork() oraz wątków.
  6. Własne funkcje definiujecie Państwo tylko wtedy, kiedy rzeczywiście są Wam potrzebne - gdy będziecie wywoływać je kilka razy.
  7. Programy piszecie Państwo ze względu na czas ich działania - ważny jest każdy cykl procesora. QNX jest systemem czasu rzeczywistego - proszę mieć to na względzie!
  8. Nie można wprowadzać żadnych danych do procesów "ręcznie": do tego służyć ma lista parametrów wywołania (argv, argc). Dlaczego? Otóż, gdybyśmy wprowadzili możliwość wpisywania parametrów przez użytkownika ręcznie i czekali potem długo na jego reakcję (aż klepnie te kilka klawiszy) - to wprowadzamy duże zakłócenia - nasza aplikacja nie będzie "sama się kręcić", zbyt dużo będzie zależało od szybkości "klepania" w klawiaturę przez użytkownika.
  9. Wykorzystujemy funkcje preprocesora C do wyświetlania dodatkowych informacji na ekranie monitora (np. DEBUG). Innymi słowy, gdybyście przypadkiem Państwo  w trakcie pisania programu odczuwali potrzebę wypisywania na ekran mnóstwa komunikatów, to a). pohamować ją :)  b). wykorzystać preprocesor w sposób pokazany powyżej.
  10. Należy przygotować skrypty shell'owe (dla pojazdów: czyli samochodów/pociągów/barek) pokazujące prawidłowe działanie systemu, czyli skrypty mają uruchamiać procesy Państwa systemu.
W systemie istnieją następujące procesy (zadania):

1. Proces wizualizacji systemu
2. Proces przechowujący zasoby systemu
3. Proces zarządzający szlabanami i światłami
4. Proces klienta: samochód/pociąg/barka


Szczegółowo:


1. Proces wizualizacji systemu
Proces ten pracuje w trybie tekstowym. I w trybie tekstowym realizuje grafikę. W kolorkach. Z wykorzystaniem biblioteki ncurses.
Schemat, czyli jak ma wyglądać ekran obsługiwany przez ten proces - macie Państwo na wylosowanych karteczkach z zadaniem.

Proces wizualizacji pokazuje liczbę procesów pojazdów oczekujących na poszczególnych wjazdach.
Proces ten posiada odpowiednio 3 liczniki zainicjowanych procesów pojazdów, liczniki nie są widoczne na ekranie.
Wjazdy są trzy, odpowiednio ponumerowane.

Proces wizualizacji wyświetla na ekranie znaki ASCII począwszy od miejsca, określonego przez procesy pojazdów.
Proces ten nie pamięta poprzednich wykonywanych operacji i nie przechowuje w pamięci żadnej współrzędnej ekranu.

Format danych dla komunikatu tego procesu ma następującą strukturę: char z1 x1 y1 z2 x2 y2.
Można również użyć struktury zawierającej: char z1, int x1, int y1, char z2, int x2, int y2.
 
Proces wizualizacji analizuje z1 oraz z2 niezależnie.

Po otrzymaniu komunikatu od procesu zarządcy, proces wizualizacji dla zmiennej z1 równej znakowi:

Po otrzymaniu komunikatu od procesu pojazdu, proces wizualizacji dla zmiennej z1 równej znakowi:

Po otrzymaniu komunikatu, dla zmiennej z1 równej znakowi:


Po otrzymaniu komunikatu od procesu zarządcy lub procesu pojazdu, proces wizualizacji dla zmiennej z2 równej znakowi:

Litery S oraz C symulują pola świateł dla pojazdów:
S : pole jest na krawędzi jezdni, tło czerwone lub zielone,
C : tło czerwone (mrugające) lub czarne.

UWAGA!
Proces ten nie pamięta poprzednio wykonanych operacji! W przypadku wykonania dowolnej błędnej operacji kończy działanie!

powrót

2. Proces przechowujący zasoby systemu
Tylko ten proces ma dostęp do klawiatury (pozostałe procesy mają zablokowany).
Odebranie przez ten proces sygnału CTRL-Z powoduje zakończenie pracy pozostałych procesów systemu w następujący sposób: proces zasobów informuje procesy klienckie o zakończeniu pracy, ostatni z klientów informuje proces wizualizacji (ponieważ proces zasobów systemu nie komunikuje się z procesem wizualizacji).
Proces zasobów odpowiada na zapytania dotyczące zajętości jednego odcinka drogi. Odpowiedź jest pozytywna, jeśli ten odcinek drogi jest wolny. Podobne odpytywanie następuje dla stanu świateł.
Proces ten przechowuje również stan licznika klientów (pojazdów) obecnych na przejeździe kolejowym (LS) oraz stan liczników zgłoszeń pojazdów (pojazdy zgłaszają się przed skrzyżowaniem).

Struktura odbieranego komunikatu: numer_polecenia dana typu char
Struktura wysyłanego komunikatu:  potwierdzenie, dana1, dana2, dana3 typu char

Potwierdzenie przyjmuje wartości:
0 : gdy odpowiedź jest pozytywna,
1 : gdy informujemy klienta o zakończeniu pracy, wtedy dana1 przyjmuje wartość równą 0,
     gdy dana1 przyjmuje inną wartość, proces klienta informuje proces wizualizacji o zakończeniu pracy
     i sam również kończy pracę.

w programie zdefiniowane są następujące funkcje: awaria(), obsuga_sygnalu(), main().

Schemat oprogramowania sygnałów:

w procesie serwera zasobów:
- przechwytujemy sygnał CTRL-Z, czyli SIGSTOP (ang. signal interrupt),
- jako obsługę sygnału wykonujecie Państwo co tam trzeba, i koniecznie rozsyłacie sygnał do pozostałych procesów.

void obsuga_sygnalu()
{
   ...
   kill (0, SIGURG);
   ...
}

void main ()
{
   ...
   signal (SIGINT,
obsuga_sygnalu() );
   ...
}



W pozostałych procesach:
 - obsługujemy otrzymany z procesu serwera zasobów sygnał:

void
procedura_obsługi_sygnału ()
{
   ...
   ...
}

void main ()
{
   ...
   signal (SIGURG, procedura_obsługi_sygnału );
   ...
}
powrót

3. Proces klienta: zarządca przejazdu kolejowego i świateł - dróżnik
Proces dróżnika po uruchomieniu aktualizuje stan zadania zgodnie z zadanymi warunkami (z kierunkami jazdy opisanymi w nawiasach przy wjazdach, nawiasy kwadratowe oznaczają drogi z pierwszeństwem przejazdu.
Proces ten w zadanych odstępach czasu odczytuje z serwera zasobów stan zgłoszeń pojazdów i na ich podstawie odpowiednio steruje szlabanem i światłami.
W trakcie przełączania szlabanu nie analizujemy stanu zgłoszeń od pojazdów.
Proces dróżnika po zmianie świateł na "zielone", po uzyskaniu potwierdzenia wjazdu pojazdu w strefę skrzyżówania, wraca do analizy zgłoszeń.
Obok 'opuszczonego' szlabanu ma 'mrugać' światło czerwone (dwa cykle z czerwonym tłem, dwa cykle z czarnym).
Szlabany mają się zmieniać jednocześnie z pojazdami opuszczającymi skrzyżowanie.
W programie zarządcy zdefiniowane są następujące funkcje:
awaria_wizji(), awaria_zasobów(), koniec(), main().

powrót


4. Proces klienta: samochód/pociąg/barka
Przykładowy sposób wywołania procesu klienta, plik wykonywalny o nazwie ppp:

....$ ppp p1 p2 p3 p4 &
....$ ppp A  30 1  2  &

gdzie poszczególne parametry oznaczają:
parametr p1:
znak ASCII z przedziału 'A'..'Z', który będzie nazwą procesu klienta (wyświetlaną na ekranie przez odpowiedni proces),
parametr p2: czas opóźnienia startu procesu COP, równy wartości z przedziału [0..40] razy 1 sekunda, do generowania czasu nalezy wykorzystać funkcje systemowe,
parametr p3
: wjazd, z którego zaczyna się proces klienta. Wjazdów mamy 3, są ponumerowane. Parametr ten przyjmuje wartość [1..3],
parametr p4: czas jazdy pojazdu (po "kratce", funkcja opozn() ), parametr ten przyjmuje wartość z przedziału [1..30] razy DT, czas DT=0.25 sek wygenerować programowo.

Samochody mają dwa znaki ASCII, zaś pociągi trzy znaki ASCII.
Pojazdy zgłaszają


& - oznacza, że dany proces będzie wywoływany "w tle".

Po uruchomieniu, proces pojazdu wykonuje następujące czynności:

- wykonuje funkcję sleep() o wartości COP,
- wybiera drogę,
- wysyła komunikat o zwiększeniu odpowiedniego licznika procesów oczekujących na wizualizację na odpowiednim wjeździe
  (wjazd) do procesu wizualizacji (liczba ta jest wyświetlana na odpowiednim wjeździe, numer wjazdu to parametr p2),
- wysyła zapytanie o pierwszy odcinek drogi do serwera zasobów,
- wysyła komunikat o zmniejszeniu odpowiedniego licznika pojazdów oczekujących i wyświetleniu znaku ASCII na ekranie (pojazd wyjeżdża),
- funkcja opozn(),
- ...
- wysyła komunikat o
wyświetleniu 2-ch znaków ASCII do serwera wizji,
- wysyła komunikat o zwolnieniu odcinka drogi do serwera zasobów,
- funkcja opozn(),
- ...
- wysyła komunikat o zwiększeniu licznika zgłoszeń przy skrzyżowaniu do serwera zasobów,
- ...
- wysyła komunikat o wyświetleniu 2-ch znaków ASCII do serwera wizji,
- wysyła komunikat o zwolnieniu odcinka drogi do serwera zasobów,
- funkcja opozn(),
- wysyła komunikat z zapytaniem o stan światła do serwera zasobów,
- wysyła komunikat o zmniejszeniu licznika zgłoszeń i jednocześnie o zwiększeniu licznika zajętości skrzyżowania do serwera zasobów,
- wysyła komunikat z zapytaniem o odcinek drogi do serwera zasobów,
- wysyła komunikat o wyświetleniu 2-ch znaków ASCII do serwera wizji,


-- po przejechaniu całej planszy - pojazd kończy działanie

powrót