Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 3.

Podobne prezentacje


Prezentacja na temat: "Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 3."— Zapis prezentacji:

1 Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 3

2 Typy procesów i wątków procesy i wątki asynchroniczne – aktywowane przerwaniami procesy i wątki synchroniczne – aktywowane układami odmierzania czasu procesy i wątki drugoplanowe – aktywowane gdy procesor ma wolne zasoby

3 Procesy i wątki asynchroniczne Zdarzenia są reprezentowane przez przerwania Przerwanie inicjuje ISR – procedurę obsługi przerwania i dodatkowo może się odbyć: odblokowanie wątku odblokowanie procesu pozostają w stanie zablokowania wznawiane przez przerwania (zdarzenia systemowe) po wykonaniu wracają do stanu zablokowania RTS mają reagować na zdarzenia (w restrykcyjnym czasie!)

4 ISR wykonuje proste czynności, które nie podlegają szeregowaniu W czasie ISR inne przerwania są zablokowane Następnie kod obsługi przerwania może przekazać działanie procesowi lub wątkowi Zwykle wątki (bo mają krótszy czas wznowienia) są utworzone dla przerwań i czekają gotowe na przerwanie Wystąpienie przerwania inicjuje: obsługę ISR aktywację wątku dla tego przerwania przejście wątku w stan oczekiwania

5 W1 ISR W2 odblokowanie wątku W2 przerwanie blokada wątek obsługi przerwania.. do problematyki wątków jeszcze wrócimy…. proces1 proces4 proces3 proces2 wątek

6 ISR wykona proste czynności ISR wykona proste czynności, resztę zleci procesowi lub wątkowi ISR od razu zleci czynności procesowi lub wątkowi …podsumowując, mogą być 3 sytuacje:

7 Trudność studiowania długich instrukcji, aby poznać docelową platformę. Analizowanie tabel pamięci, rejestrów i diagramów przedstawiających wewnętrzną strukturę sprzętową. Problemy: - jakie sposoby załadowania obrazu systemu -podział obszarów pamięci, w których poszczególne części systemu powinny się znaleźć -jakie metody inicjalizacji aplikacji -w jaki sposób pobierane będą dane wejściowe i generowane sygnały wyjściowe. Inicjacja RTS

8 Po uruchomieniu urządzenia, przejmuje nad nim kontrolę tzw. boot image (również obecny w ROM) oraz inicjalizuje sprzęt. Kiedy pamięć oraz podstawowe urządzenia są już zainicjalizowane, zaczyna wykonywać się loader - IPL, czyli właściwy program ładujący, który znajduje się na docelowym urządzeniu - zwykle w pamięci ROM - i służy do pobrania z komputera hosta obrazu systemu - współdziała z oprogramowaniem hosta. Obraz może też być w ROM. Używa się łącza szeregowego, chociaż programy ładujące potrafią korzystać z połączeń sieciowych oraz dokonywać operacji na pamięci flash.

9 Loader pobiera obraz bezpośrednio do pamięci RAM. Musi rozumieć format przesyłanego pliku - zawarte są w nim instrukcje określające pod jakimi adresami oraz w jakich częściach pamięci należy umieścić określone sekcje. Po zakończeniu transmisji, program ładujący przekazuje kontrolę do zainstalowanego obrazu.

10 Po uruchomieniu urządzenia, jego procesor zaczyna pobierać kolejne instrukcje z określonego systemowego obszaru pamięci. Znajduje się tam tzw. wektor resetujący, który ze względu na swoje ograniczone rozmiary, zawiera tylko instrukcję skoku do miejsca zawierającego właściwy kod inicjalizujący.

11

12 Zaraz po uruchomieniu urządzenia, rejestry jego procesora przyjmują wartości domyślne. Następnie, program ładujący: wyłącza procedury obsługi przerwań, inicjalizuje pamięć RAM, inicjalizuje pamięci podręczne procesora dokonuje bardzo podstawowego sprawdzenia sprzętu. Przyczyną wyłączenia obsługi przerwań jest brak gotowości systemu do ich obsługi. Pamięć RAM jest o wiele szybsza niż ROM, czy flash oraz dodatkowo umożliwia prostsze wykonanie operacji zapisu, dlatego też program ładujący kopiuje całość lub tylko część obrazu systemu do pamięci RAM. Później, następuje uruchomienie sprzętu, jak np. urządzenia wejścia - wyjścia oraz sterowanie przejmuje właściwy system operacyjny.

13 Obraz, który jest ładowany do maszyny docelowej, to zbiór wielu pakietów oprogramowania. Są to między innymi: moduły odpowiedzialne za obsługę płyty, liczne sterowniki, system czasu rzeczywistego, który dostarcza podstawowe usługi i umożliwia operacje wejścia - wyjścia

14 Board Support Packages

15 Wszystkie te komponenty, są odpowiedzialne za pełną inicjalizację urządzenia. inicjalizacja sprzętu, instalacja procedur obsługi przerwań i wyjątków, inicjalizacja samego systemu czasu rzeczywistego oraz poszczególnych jego aplikacji. Najbliżej sprzętu jest zbiór sterowników dla płyty głównej (BSP - board support packages – pakiety wspomagania płyty) - zazwyczaj są one pisane w języku niskiego poziomu oraz związane są z konkretną architekturą!

16 Pozostałe moduły implementowane w językach wysokiego poziomu - jak np. C. Uruchomienie samego systemu czasu rzeczywistego: inicjalizację jego obiektów i usług, jak np. procesy i wątki, kolejki, semafory, stworzenie stosu pamięci, obsługa komunikacji. Gdy zostanie uruchomiony moduł szeregujący procesy – (scheduler), użytkownik może uruchamiać wszelkie inne obecne w pamięci aplikacje. Wówczas system ma możliwość podziału dostępu do procesora oraz przekazywanie aplikacjom sterowania.

17 Advantech AIMB Intel® Core i7/i5/i3/Pentium® processor with Q57 chipset Advantech AIMB Intel® Core i7 and i5 mobile processor with Intel QM57 chipset Advantech PCM Embedded Intel® Atom processor N450 Single Core/D510 Dual Core 1.66 GHz + ICH8M Advantech SOM x Intel Atom Z5xx & System Controller Hub US15W with Fastboot IPL and BIOS Concurrent Technologies Specifications Intel Crown Beach CRB Intel Atom & System Controller Hub US15W Intel EP80579 aka "Tolopai" 6.4 Intel EP80579 SOC Kontron nanoETXexpress-SP 6.4.x Intel Atom Z5xx & System Controller Hub US15W with Fastboot IPL and BIOS MEN Intel Atom SP3 Intel Atom MEN Mikro Electronik Commercial Men Mikro Elektronik x86 BIOS SP2, 6.3.2, 6.4.x x Dell PowerEdge 840 BASE Desktop/Server x Dell Lattitude D820 Laptop SP3, x Dell Lattitude D830 Laptop 6.3.2, 6.4.x x86 …i wiele innych Hardware Database SDP info

18 Procesor wykonuje kod zapisany w BIOS'ie (albo ROM monitorze) BIOS przekazuje sterowanie do loadera - IPL. Tutaj ładowany jest do pamięci program startup Uruchamiany jest startup, ładowana jest pozostała część obrazu (OS boot image) Sterowanie przekazywane jest do procnto. Ten wykonuje skrypty startowe i kontynuuje pracę. Rozruch systemu QNX – podsumowanie

19 Integrated Developement Environment zintegrowane środowisko programistyczne QNX Momentics IDE Ułatwia szybkie tworzenie aplikacji RTS RAD – rapid application development Testowanie systemu: host aplikacji – wykonanie na QNX – target - cel

20 Kolejność czynności: Uruchomienie agenta qconn w VMPlayer Nowy QNX/C projekt – built variant x86 Kompilacja – (Built project) Ustawienie celu (target) – komunikacja z maszyną wirtualną, gdzie mamy QNX – Run configurations… Wykonanie – Run - ze środowiska IDE – target - IP maszyny wirtualnej - bezpośrednio z QNX – po udostępnieniu binariów programu z wykorzystaniem IP wirtualnej karty sieciowej VMNet (proces fs-cifs) Obserwacja działającego systemu – perspektywa QNX

21

22 int main(int argc, char *argv[]) { printf("Pierwszy proces\n"); printf("Arg0:%s\n",argv[0]); printf("Arg1:%s\n",argv[1]); …. Pierwszy proces Arg0:execl1ja Arg1:abc Argumenty procesu głównego

23 #include Pliki nagłówkowe #include i inne wykorzystamy niebawem

24 Każdy proces ma swój PID – identyfikator. Możemy go wyświetlić korzystając z funkcji: int getpid() Procesy tworzą hierarchię zależności, każdy proces ma swojego rodzica (za wyjątkiem procesu systemowego procnto o identyfikatorze 1). Identyfikator rodzica można uzyskać za pomocą funkcji: int getppid() PID – identyfikator procesu w systemie QNX polecenie: ps -A

25 …. int pid= getpid(); int ppid= getppid(); printf("Proces macierzysty: %u\n", pid); printf("Proces rodzic: %u\n", ppid); …. Przykład

26 int pid=fork() Proces potomny w momencie utworzenia posiada: własny segment kodu, własny segment danych i stosu. Wartości zmiennych w procesie potomnym są takie same jak w procesie macierzystym przed wykonaniem funkcji fork, lecz potem oba procesy mogą dokonywać ich zmiany. Funkcja zwraca: 0 - w kodzie procesu potomnego PID nowego procesu - w procesie macierzystym -1 gdy nowy proces nie może być utworzony Tworzenie kopii procesu macierzystego

27 Przykład int x=10; printf("x=%u\n", x); int pm = getpid(); printf("Proces macierzysty: %u\n", pm); int pp = fork(); printf("---%u---%u---\n",getpid(), getppid()); if (pp==0) { printf("To pisze potomny:"); x++; printf("---%u---%u---%u\n",getpid(), getppid(),x); sleep(2); } else { printf("To pisze macierzysty:"); x--; printf("---%u---%u---%u\n",getpid(), getppid(),x); sleep(2); } stworzenie kopii procesu macierzysty potomny x=10 Proces macierzysty: To pisze potomny: To pisze macierzysty:

28 int i,status; int x=10; printf("Proces MAIN start id====%u, x pocz=%u \n",getpid(),x); for (i=1;i<=2;i++) { printf("i: %u\n",i); int pp=fork(); if (pp==0) { x--; printf("Proces potomny odejmuje 1- id: %u id_ojca: %u, x=%u \n",getpid(),getppid(),x); } else { x+=4; printf("Proces macierzysty dodaje 4 - id: %u id_ojca: %u, x=%u\n",getpid(),getppid(),x); } printf(" OBYDWA : i: %u, x= %u\n",i,x); } Proces MAIN start id==== , x pocz=10 i: 1 Proces potomny odejmuje 1 - id: id_ojca: , x=9 Proces macierzysty dodaje 4 - id: id_ojca: , x=14 OBYDWA: i: 1, x= 9 OBYDWA: i: 1, x= 14 i: 2 Proces macierzysty dodaje 4 - id: id_ojca: , x=18 Proces macierzysty dodaje 4 - id: id_ojca: , x=13 Proces potomny odejmuje 1 - id: id_ojca: , x=13 Proces potomny odejmuje 1 - id: id_ojca: , x=8 OBYDWA: i: 2, x= 18 OBYDWA: i: 2, x= 13 OBYDWA: i: 2, x= Proces MAIN start id==== , x pocz=10 i: 1 Proces potomny odejmuje 1 - id: id_ojca: , x=9 Proces macierzysty dodaje 4 - id: id_ojca: , x=14 OBYDWA: i: 1, x= 9 OBYDWA: i: 1, x= 14 i: 2 Proces macierzysty dodaje 4 - id: id_ojca: , x=18 Proces macierzysty dodaje 4 - id: id_ojca: , x=13 Proces potomny odejmuje 1 - id: id_ojca: , x=13 Proces potomny odejmuje 1 - id: id_ojca: , x=8 OBYDWA: i: 2, x= 18 OBYDWA: i: 2, x= 13 OBYDWA: i: 2, x=

29 Proces MAIN start id==== , x pocz=10 i: 1 Proces macierzysty dodaje 4 - id: id_ojca: , x=14 Proces potomny odejmuje 1 - id: id_ojca: , x=9 OBYDWA: i: 1, x= 14 OBYDWA: i: 1, x= 9 i: 2 Proces potomny odejmuje 1 - id: id_ojca: , x=13 Proces macierzysty dodaje 4 - id: id_ojca: , x=18 OBYDWA: i: 2, x= 13 OBYDWA: i: 2, x= 18 Proces macierzysty dodaje 4 - id: id_ojca: , x=13 OBYDWA: i: 2, x= 13 Proces potomny odejmuje 1 - id: id_ojca: , x=8 OBYDWA: i: 2, x= czyli 4 procesy … ale czasem jest tak! ważne priorytety i szeregowanie

30 WAIT Funkcja wait umożliwia synchronizację procesów. W przypadku napotkania funkcji wait proces macierzysty oczekuje na zakończenie procesu potomnego (pierwszego, jeśli jest ich wiele) – wówczas dostępny jest status. Wcześniejsze zakończenie procesu macierzystego niż potomnego spowodowałoby, że potomny straciłby swojego przodka. Funkcja zwraca PID procesu potomnego. pid_t wait (int *status) Gdy status jest różny od NULL, stan procesu potomnego jest wskazywany przez zmienną status. Istnieją makro, jak np. WIFEXITED(status), umożliwiające odczytanie informacji ze zmiennej status: 1 – jeśli normalne zakończenie procesu 0 - jeśli błąd

31 int i,status,pid; int x=10; printf("Proces MAIN start id====%u, x pocz=%u \n",getpid(),x); for (i=1;i<=2;i++) { printf("i: %u\n",i); int pp=fork(); if (pp==0) { x--; printf("Proces potomny odejmuje 1- id: %u id_ojca: %u, x=%u \n",getpid(),getppid(),x); } else { x+=4; printf("Proces macierzysty dodaje 4 - id: %u id_ojca: %u, x=%u\n",getpid(),getppid(),x); pid=wait(&status); } printf(" OBYDWA : i: %u, x= %u\n",i,x); } Proces MAIN start id==== , x pocz=10 i: 1 Proces macierzysty dodaje 4 - id: id_ojca: , x=14 Proces potomny odejmuje 1 - id: id_ojca: , x=9 OBYDWA: i: 1, x= 9 i: 2 Proces macierzysty dodaje 4 - id: id_ojca: , x=13 Proces potomny odejmuje 1 - id: id_ojca: , x=8 OBYDWA: i: 2, x= 8 OBYDWA: i: 2, x= 13 OBYDWA: i: 1, x= 14 i: 2 Proces macierzysty dodaje 4 - id: id_ojca: , x=18 Proces potomny odejmuje 1 - id: id_ojca: , x=13 OBYDWA: i: 2, x= 13 OBYDWA: i: 2, x= wait potomny macierzysty

32 pid=wait(&status); printf("pid %u status: %u\n",pid,WIFEXITED(status)); pid status: 1

33 Przekształca bieżący proces w inny proces, którego kod wykonywalny zawarty jest w pliku fname, przekazuje mu parametry arg0, arg1,arg2, itd. execl(path/fname,arg0,arg1,...,NULL) execl czyli proces wywołujący jest zakończony

34 printf("Pierwszy proces\n"); int i; for (i=1;i<4;i++) { printf("i=%u\n",i); } execl("/mnt/tmp2/ex2/x86/o/execl2","execl2","10","20",NULL); printf("czy dziala?\n");// tego tekstu już nie będzie!!! return EXIT_SUCCESS; printf("To drugi\n"); int x; printf("ile arg=%u\n",argc); for (x=0;x

35 Po udostępnieniu fs-cifs…

36 Funkcja spawnl używana jest do tworzenia nowych procesów, z możliwością wyboru trybu pracy procesu macierzystego, który może być zakończony, wykonywany współbieżnie lub z oczekiwaniem na zakończenie potomnego. pid_t spawnl(int mode, char * path, arg0,arg1,..., argN,NULL) mode - tryb wykonania procesu: P_WAIT, P_NOWAIT, P_OVERLAY, P_NOWAITO, path – ścieżka z nazwą pliku wykonywalnego, arg0 - argument 0 przekazywany do funkcji main tworzonego procesu. Powinna być to nazwa pliku wykonywalnego ale bez ścieżki, arg1,...argN – argumenty przekazywane do funkcji main tworzonego procesu. Funkcja zwraca: PID (typ pid_t lub integer) utworzonego procesu -1 gdy wystąpi błąd. Tryby wykonania: P_WAIT - proces czeka na zakończenie procesu potomnego P_NOWAIT - proces potomny wykonywany jest współbieżnie P_OVERLAY - proces bieżący zastępowany jest przez proces potomny Tworzenie procesów współbieżnych spawnl

37 int pid,i,res,status,test; test=1234; char buf[10]; res = spawnl(P_WAIT,"/mnt/tmp2/spawnl2/x86/o/spawnl2","spawnl2","10",NULL); //res = spawnl(P_OVERLAY,"/mnt/tmp2/spawnl2/x86/o/spawnl2","spawnl2","10",NULL); // res = spawnl(P_NOWAIT,"/mnt/tmp2/spawnl2/x86/o/spawnl2","spawnl2","10",NULL); if(res < 0) { perror("SPAWN"); exit(0); } for(i=1;i < 10;i++) { printf("Macierzysty - krok %d \n",i); sleep(1); } pid = wait(status); printf("Proces %d zakonczony, status %d\n",pid,status); Potomny krok: 1 Potomny krok: 2 Potomny krok: 3 Potomny krok: 4 Potomny krok: 5 Potomny krok: 6 Potomny krok: 7 Potomny krok: 8 Potomny krok: 9 Potomny krok: 10 Potomny test: 0 Macierzysty - krok 1 Macierzysty - krok 2 Macierzysty - krok 3 Macierzysty - krok 4 Macierzysty - krok 5 Macierzysty - krok 6 Macierzysty - krok 7 Macierzysty - krok 8 Macierzysty - krok 9 Proces -1 zakonczony, status 0 int id, i,status,test ; for(i=1;i <= atoi(argv[1]);i++) { printf("Potomny krok: %d \n",i); sleep(1); } printf("Potomny test: %d \n",test); exit(i);

38 int getprio(pid_t pid) – pobranie priorytetu procesu, gdy argument pid=0 funkcja zwraca priorytet procesu macierzystego int setprio(pid_t pid, int prio) – ustawienie priorytetu procesu - funkcja zwraca poprzedni priorytet lub -1 gdy wystąpi błąd. Priorytet procesu Jednym z atrybutów procesu jest jego priorytet. Priorytet można uzyskać za pomocą funkcji: getprio() lub sched_getparam() a ustawić funkcjami: setprio() lub sched_setparam() Składnia funkcji getprio i setprio:

39 setprio(0,37); printf("Prio macierzysty:%u\n",getprio(0)); spawnl(P_NOWAIT,"/mnt/tmp/spawnl2/x86/o/spawnl2","spawnl2","10",NULL); for(i=1;i <= 10;i++) { printf("Macierzysty - krok %d \n",i); sleep(1); } setprio(getpid(),3); printf("Prio potomny:%u\n",getprio(getpid())); for(i=1;i <= atoi(argv[1]);i++) { printf("Potomny krok i=: %d \n",i); sleep(1); } Prio macierzysty:37 Macierzysty - krok 1 Prio pot:3 Potomny krok i=: 1 Macierzysty - krok 2 Potomny krok i=: 2 Macierzysty - krok 3 Potomny krok i=: 3 Macierzysty - krok 4 Potomny krok i=: 4 Prio macierzysty:3 Macierzysty - krok 1 Prio pot:38 Potomny krok i=: 1 Potomny krok i=: 2 Macierzysty - krok 2 Potomny krok i=: 3 Macierzysty - krok 3 Potomny krok i=: 4 Macierzysty - krok 4 współbieżne


Pobierz ppt "Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 3."

Podobne prezentacje


Reklamy Google