Architektura Systemów Wbudowanych
|
|
- Elżbieta Cybulska
- 5 lat temu
- Przeglądów:
Transkrypt
1 Architektura Systemów Wbudowanych Laboratorium 6 Wieloprocesowość, wielowątkowość szeregowanie, synchronizacja, komunikacja IPC 2018
2 Spis treści Wstęp wątki, procesy Przygotowanie platform docelowej Przygotowanie środowiska programistycznego QNX Momentics IDE Przełączanie perspektyw... 9 Tworzenie projektu Kompilacja projektu Uruchomienie aplikacji Debugowanie aplikacji Wątki przygotowanie platformy programistycznej QNX Momentics Wątki szeregowanie Przeanalizuj poniższy kod. Zwróć uwagę na wynik działania funkcji update_thread() Synchronizacja wątków Przygotowanie platformy i środowiska IDE Przeanalizuj poniższy kod programu Mutex Przeanalizuj poniższy kod programu Condvar Przeanalizuj poniższy kod programu SEMEX Komunikacja IPC Inter-Procces Communication Przygotowanie platformy i środowiska IDE Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Sprawozdanie
3 Wstęp wątki, procesy. Procesy są komponentami składowymi systemu, które widoczne dla każdego innego procesu oraz mogą komunikować się z każdym procesem. Proces: program załadowany do pamięci; identyfikowany przez id procesu, zwykle nazywany jako pid; wspólne zasoby procesu: pamięć, włączając kod i dane, otwarte pliki, identyfikatory : id użytkownika, id grupy, timery. Zasoby należące do jednego procesu są chronione przed innymi procesami. Wątki są szczegółową implementacją danego procesu ukrytą w jego wnętrzu. Uruchamiane są wewnątrz procesów. Każdy uruchomiony proces musi posiadać przynajmniej jeden wątek. Wątki należące do jednego procesu współdzielą wszystkie jego zasoby. Wątek wątek jest pojedynczym strumieniem wykonania; wątek posiada pewne atrybuty: priorytet, algorytm kolejkowania, zestaw rejestrów, maska CPU dla SMP, maska sygnałów, i inne
4 Przygotowanie platform docelowej. Uruchom VMware Player dwuklik na ikonie: Ikonka aplikacji VMware Player. Na ekranie pojawi się okno główne programu: Główne okno programu VMware Player. Po lewej stronie okna znajduje się lista obrazów systemów. Wybierz z niej obraz system QNX Neutrino - Neurino650Target. Okno zmieni swój wygląd na poniższy
5 VMware Player okno po wybraniu obrazu systemu. Następnie wybierając Play virtual machine lub wykonując dwuklik na nazwie obrazu uruchamiamy system QNX Neutrino. Na ekranie pojawi się okno konsoli systemu. Okno konsoli systemu QNX Neutrino. Zaloguj się jako administrator systemu login: root
6 Poleceniem pidin sprawdź czy uruchomiony jest proces qconn - QNX connection. Okno konsoli po wykonaniu polecenia pidin. Jeżeli nie ma go na liście uruchomionych procesów wykonaj poniższe polecenie. Polecenie qconn. Ponownie sprawdź czy uruchomiony jest proces qconn. W następnej kolejności sprawdź adres IP uruchomionej platformy docelowej poleceniem ifconfig. Zapamiętaj adres IP będzie on potrzebny do zestawienia połączenia pomiędzy platformą docelową, a hostem środowiska IDE. Przełączanie pomiędzy oknem maszyny wirtualnej a systemem Windows: CTRL+G przejście z OS Windows do maszyny wirtualnej; CTRL+ALT przejście z maszyny wirtualnej do OS Windows
7 Przygotowanie środowiska programistycznego QNX Momentics IDE. Uruchom środowisko QNX Momentics IDE używając ikonki: Na ekranie pojawi się okno Workspace Launcher pozwalające wybrać przestrzeń roboczą Workspace. Wybierz przestrzeń roboczą wskazaną w instrukcji lub podaną przez prowadzącego. Okno Workspace Launcher Po wybraniu przestrzeni roboczej na ekranie pojawi się okno główne środowiska
8 Okno główne środowiska programistycznego 8
9 Importowanie projektów do przestrzeni roboczej Po lewej stronie okna środowiska deweloperskiego znajduje się okno Project Explorer, w którym wyświetlane są projekty znajdujące się w aktualnie wybranej przestrzeni roboczej. Jeżeli w oknie nie są widoczne żadne projekty należy je zaimportować. Okno Project Explorer Aby zaimportować projekty do przestrzenia roboczej należy prawym klawiszem myszy otworzyć menu kontekstowe okna Project Explorer, a następnie wybrać opcję Import, rysunek na następnej stronie. 9
10 Menu kontekstowe okna Project Explorer Na ekranie pojawia się okno Import. Okno Import 10
11 Wybieramy z grupy Select an import source, opcję General, a następnie Existing Projects into Workspace na ekranie pojawi się poniższe okno. Okno Import W polu Select root directory wskazujemy główny katalog naszej przestrzeni roboczej, używając klawisza Browse. Katalog wybieramy w oknie poniżej. Okno wyboru folderu przestrzeni roboczej 11
12 Na ekranie pojawi się okno z listą dostępnych projektów. Środowisko domyślnie wybierze te projekty, które nie są dołączone do aktualnej przestrzeni roboczej. Okno Import Projects Po wciśnięciu klawisza Finish projekty zostaną dodane automatycznie do aktualnej przestrzenia roboczej rysunek na następnej stronie. 12
13 Widok okna platformy programistycznej z zaimportowanymi projektami. 13
14 Przełączanie perspektyw Perspektywy pozwalają zorganizować widok okna głównego zgodnie z aktualnie wykonywaniami zadaniami. Okno główne w trakcie debugowania kodu powinno zawierać zupełnie inne widoki niż te, których używamy podczas pisania kodu. Perspektywy przełączamy używając kluczy, które znajdują się po prawej stronie paska narzędzi. Klucze perspektyw Klucz perspektywy C/C++ Perspektywy C/C++ używamy do: tworzenia projektu; dodawania plików nagłówkowych i źródłowych; edytowania kodu; kompilacji projektu. Klucz perspektywy Debug Perspektywy Debug używamy do: analizowania krok po kroku poprawności działania oprogramowania; poszukiwania błędów logicznych; sprawdzania poprawności danych; śledzenia ścieżki wykonywanego kodu. Klucz perspektywy QNX System Information Perspektywy QNX System Information używamy do: dodawania i usuwania platformy docelowej; sprawdzenia stanu platformy docelowej; sprawdzenia stanu uruchomionych procesów i wątków; analizy zasobów procesów; analizy wzajemnych powiązań pomiędzy procesami i wątkami. 14
15 Tworzenie projektu. Wybieramy z menu głównego opcję: File->New->QNX C Project. Na ekranie pojawi się okno dialogowe New Project. Okno dialogowe New Project 15
16 Po wpisaniu nazwy projektu w okienku Project name: wciskamy klawisz Next pojawi się okno dialogowe. W zakładce Build Variants wybieramy platformę sprzętową, na którą będziemy kompilować nasze oprogramowanie. Po dokonaniu wyboru wciskamy klawisz Finish. Na ekranie pojawi się okno główne środowiska z perspektywą C/C++ i z wstępnie przygotowanym projektem. 16
17 Kompilacja projektu. Wybieramy z menu głównego opcję Project->Build Project. Wynik kompilacji pojawi się w zakładce Console. W zakładce Problems wyświetlone zostaną ewentualne błędy i problemy. Menu Project 17
18 Uruchomienie aplikacji. Z menu głównego wybieramy opcję za pierwszym razem Run->Run Configuration, przy kolejnych uruchomieniach Run->Run. Okno Run Configurations W polu po lewej stronie tworzymy nową konfigurację uruchamiania C/C++ QNX QConn IP. W polu Project Browse wybieramy projekt z przestrzeni roboczej. W polu C/C++ Application Search Project wybieramy aplikację do uruchomienia. W zakładce Arguments możemy prowadzić argumenty wejściowe aplikacji. Run uruchamia aplikację na platformie docelowej. W polu Taget Option wybieramy odpowiednią platformę docelową. 18
19 Debugowanie aplikacji. Podobnie jak w pkt 3. używamy opcji Run->Debug Configuration przy pierwszym uruchomieniu debugera w kolejnych uruchomieniach Run->Debug. Okno Debug Configurations W menu głównym opcja Run/Debug w czasie debugowania kodu posiada następujące polecenia. Menu Run/Debug 19
20 Wątki przygotowanie platformy programistycznej QNX Momentics. Przed uruchomieniem własnego kodu zwiększ priorytet procesu qconn z poziomu środowiska IDE, do poziomu 12. W tym celu wybierz perspektywę QNX System Information. Wybierz zakładkę Process Information. Następnie z listy procesów uruchomionych na platformie docelowej wybierz proces qconn. W zakładce Process Information wciśnij prawy klawisz myszy na nazwie procesu głównego qconn. Pojawi się menu kontekstowe rysunek poniżej. Wybierz opcję Set Process Priority/Scheduling Algorithm na ekranie pojawi okno. 20
21 W polu Priority wpisz wartość 12. Algorytm szeregowania pozostaw bez zmian. Wciśnij klawisz OK zatwierdzając zmiany. Wynik zmian powinien być widoczny w zakładce Process Information, jak na poniższym rysunku. Zmianę ustawień możesz sprawdzić również w wirtualnej maszynie używając polecenia pidin. 21
22 Wątki szeregowanie Przeanalizuj poniższy kod. Zwróć uwagę na wynik działania funkcji update_thread(). #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/neutrino.h> #include <pthread.h> #include <sched.h> The number of threads that we want to have running simultaneously. #define NumThreads 4 volatile int volatile int var1; var2; The header of the main function of thread. Thread starts its job in this function. void *update_thread (void *); char *progname = "threads"; int main(int argc, char *argv[]) { pthread_t threadid [NumThreads]; // a place to // hold the thread // ID's pthread_attr_t attrib; // scheduling // attributes struct sched_param param; // for setting // priority int i, policy; int oldcancel; setvbuf (stdout, NULL, _IOLBF, 0); var1 = var2 = 0; initialize to known values printf ("%s: starting; creating threads\n", progname); We want to create the new threads using Round Robin scheduling, and a lowered priority, so set up a thread attributes structure. We use a lower priority since these threads will be hogging the CPU pthread_getschedparam( pthread_self(), &policy, ¶m ); pthread_attr_init(&attrib); 22
23 pthread_attr_setinheritsched(&attrib, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy (&attrib, SCHED_RR ); param.sched_priority -= 5; // change priority a couple // levels pthread_attr_setschedparam (&attrib, ¶m); pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, &oldcancel); Create the threads. As soon as each pthread_create call is done, the thread has been started. for (i = 0; i < NumThreads; i++) { pthread_create( &threadid [i], &attrib, &update_thread, (void *) i); Let the other threads run for a while sleep (120); and then kill them all printf ("%s: stopping; cancelling threads\n", progname); for (i = 0; i < NumThreads; i++) { pthread_cancel (threadid [i]); printf ("%s: all done, var1 is %d, var2 is %d\n", progname, var1, var2); fflush (stdout); sleep (1); return EXIT_SUCCESS; void *update_thread (void *i) { while (1) { if(var1!= var2) { printf ("thread %d, var1 (%d)!= var2 (%d)!\n",(int) i, var1, var2); var1 = var2; var1++; //sched_yield(); for faster processors, to cause problem to happen var2++; return (NULL); 1. Jaki jest wynik działania powyższego programu, czy wartości zmiennych var1 i var2 będą sobie równe, czy też różne? 23
24 2. Uzupełnij kod projektu Threads, tak aby uruchomiony został jeden wątek o priorytecie o pięć niższym niż priorytet procesu głównego, algorytm szeregowania Round Robin. W helpie sprawdź funkcje, których wywołania należy uzupełnić. 3. Sprawdź wynik działania uruchomionego kodu. Czy wynik jest zgodny z przewidywaniami z pkt 3. Do sprawdzeń użyj perspektywy QNX System Information. Wynik działania programu przedstaw prowadzącemu. 4. Zmodyfikuj kod programu tak, aby proces główny tworzył 16 wątków, które będą rozpoczynały pracę w funkcji update_thread(). Jaki będzie wynik działania programu, czy wartości zmiennych var1 i var2 będą sobie równe, czy też różne? 5. Sprawdź wynik działania uruchomionego kodu. Do sprawdzeń użyj perspektywy QNX System Information. Wynik działania programu przedstaw prowadzącemu. 6. Jakie może być rozwiązanie ewentualnych problemów? 7. Zmodyfikuj kod w taki sposób, aby proces główny tworzył trzy wątki, które będą rozpoczynały pracę w różnych funkcjach, będą miały różny priorytet oraz różny sposób szeregowania. 8. Sprawdź wynik działania uruchomionego kodu. Do sprawdzeń użyj perspektywy QNX System Information. Wynik działania programu przedstaw prowadzącemu. 24
25 Synchronizacja wątków W systemach wielowątkowych wspólne zasoby procesu takie, jak: pamięć: kod programu; dane; otwarte pliki; identyfikatory: id użytkownika, id grupy; timery, są współdzielone przez wszystkie wątki należące do procesu. Wątki konkurują pomiędzy sobą o dostęp do poszczególnych zasobów. Może to prowadzić do niepożądanych sytuacji, w których wielokrotne zapisy tego samego obszaru pamięci mogą nadpisywać oczekiwane dane. W takich sytuacjach wątki czytające nie wiedzą kiedy dane są stabilne. Operowanie na niewłaściwych danych prowadzi do wypracowywania błędnych wyników, a w konsekwencji może być przyczyną podejmowania niewłaściwych decyzji, które mogą mieć katastrofalne skutki. Rozwiązaniem w/w problemów jest stosowanie metod synchronizacji pracy wątków. QNX Neutrino dostarcza wielu metod synchronizacji wątków. Do najważniejszych możemy zaliczyć wymienione poniżej: mutex wzajemne wykluczenie wątków; condvar oczekiwanie na zmienną; semaphore oczekiwanie na licznik; rwlock synchronizacja wątków piszących i czytających; join synchronizacja do zakończenia wątku; spinlock oczekiwanie na alokację pamięci; sleepon podobnie do condvars, z dynamiczną alokacją; barrier oczekiwanie na określoną liczbę wątków. Na laboratorium będziemy badać działanie trzech pierwszych metod. Przygotowanie platformy i środowiska IDE Uruchom QNX Neutrino za pomocą maszyny wirtualnej. Sprawdź poleceniem pidin czy jest uruchomiony proces qconn. Jeśli nie ma go na liście pracujących procesów uruchom go poleceniem qconn #.Sprawdź adres IP poleceniem ifconfig. Następnie uruchom środowisko QNX Momentics IDE. Wybierz przestrzeń roboczą wskazaną przez prowadzącego. Przeanalizuj poniższy kod programu Mutex. The exercise is to use the mutex construct that we learned about to modify the source to prevent our access problem. #include <stdio.h> #include <sys/neutrino.h> #include <pthread.h> #include <sched.h> 25
26 The number of threads that we want to have running simultaneously. #define NumThreads 4 The global variables that the threads compete for. To demonstrate contention, there are two variables that have to be updated "atomically". With RR scheduling, there is a possibility that one thread will update one of the variables, and get preempted by another thread, which will update both. When our original thread runs again, it will continue the update, and discover that the variables are out of sync. volatile int volatile int var1; var2; void *update_thread (void *); char *progname = "mutex"; pthread_mutex_t var_mutex; main (){ pthread_t threadid [NumThreads]; // a place to hold // the thread ID's pthread_attr_t attrib; // scheduling // attributes struct sched_param param; // for setting // priority int i, policy; setvbuf (stdout, NULL, _IOLBF, 0); var1 = var2 = 0; initialize to known values printf ("%s: starting; creating threads\n", progname); Mutex initialization pthread_mutex_init(&var_mutex, NULL ); We want to create the new threads using Round Robin scheduling, and a lowered priority, so set up a thread attributes structure. We use a lower priority since these threads will be hogging the CPU. pthread_getschedparam( pthread_self(), &policy, ¶m ); pthread_attr_init (&attrib); pthread_attr_setinheritsched (&attrib, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy (&attrib, SCHED_RR); param.sched_priority -= 2; // drop priority a couple // levels 26
27 pthread_attr_setschedparam (&attrib, ¶m); attrib.flags = PTHREAD_CANCEL_ASYNCHRONOUS; Create the threads. As soon as each pthread_create call is done, the thread has been started. for(i = 0; i < NumThreads; i++) { pthread_create(&threadid [i], &attrib, &update_thread, (void*)i); Let the other threads run for a while sleep(20); And then kill them all printf("%s: stopping; cancelling threads\n", progname); for(i = 0; i < NumThreads; i++) { pthread_cancel (threadid [i]); printf("%s: all done, var1 is %d, var2 is %d\n", progname, var1, var2); fflush (stdout); sleep(1); exit(0); The actual thread. The thread ensures that var1 == var2. If this is not the case, the thread sets var1 = var2, and prints a message. Var1 and Var2 are incremented. Looking at the source, if there were no "synchronization" problems, then var1 would always be equal to var2. Run this program and see what the actual result is... void do_work(){ static int var3; var3++; For faster/slower processors, may need to tune this program by modifying the frequency of this printf -- add/remove a 0 27
28 if(!(var3 % ) ) printf ("%s: thread %d did some work\n", progname, pthread_self()); void * update_thread (void *i){ while (1) { pthread_mutex_lock(&var_mutex); if (var1!= var2) { int lvar1, lvar2; lvar1 = var1; lvar2 = var2; var1 = var2; pthread_mutex_unlock(&var_mutex); printf("%s: thread %d, var1 (%d) is not equal to var2 (%d)!\n", progname, (int) i, lvar1, lvar2); else pthread_mutex_unlock(&var_mutex); do some work here do_work(); pthread_mutex_lock(&var_mutex); var1++; var2++; pthread_mutex_unlock(&var_mutex); return (NULL); 9. Uruchom program z projektu Mutex. Sprawdź jego działanie. Jaki jest wynik działania programu? 10. Uzupełnij kod projektu Mutex, tak aby praca wątków była synchronizowana przy pomocy mutexa. 11. Sprawdź wynik działania zmodyfikowanego kodu. Sprawdź w jakim stanie są inne wątki, gdy jeden z nich wykonuje kod sekcji krytycznej. Do sprawdzeń użyj perspektywy QNX System Information. Wynik działania programu przedstaw prowadzącemu. 28
29 Przeanalizuj poniższy kod programu Condvar. Objectives: This code was a two-state example. The producer (or state 0) did something which caused the consumer (or state 1) to run. State 1 did something which caused a return to state 0. Each thread implemented one of the states. This example will have 4 states in its state machine with the following state transitions: State 0 -> State 1 State 1 -> State 2 if state 1's internal variable indicates "even" State 1 -> State 3 if state 1's internal variable indicates "odd" State 2 -> State 0 State 3 -> State 0 And, of course, one thread implementing each state, sharing the same state variable and condition variable for notification of change in the state variable. #include <stdio.h> #include <unistd.h> #include <sys/neutrino.h> #include <pthread.h> #include <sched.h> Our global variables. volatile int state; // which state we are in Our mutex and condition variable pthread_mutex_t mutex ; pthread_cond_t cond ; void *state_0 (void *); void *state_1 (void *); void *state_2 (void *); void *state_3 (void *); char *progname = "condvar"; main (){ setvbuf (stdout, NULL, _IOLBF, 0); pthread_mutex_init( &mutex, NULL ); pthread_cond_init( &cond, NULL ); state = 0; pthread_create (NULL, NULL, state_1, NULL); pthread_create (NULL, NULL, state_0, NULL); 29
30 pthread_create (NULL, NULL, state_2, NULL); pthread_create (NULL, NULL, state_3, NULL); sleep (20); // let the threads run printf ("%s: main, exiting\n", progname); State 0 handler (was producer) void * state_0 (void *arg){ while (1) { pthread_mutex_lock (&mutex); while (state!= 0) { pthread_cond_wait (&cond, &mutex); printf ("%s: transit 0 -> 1\n", progname); state = 1; don't chew all the CPU time delay(100); pthread_cond_broadcast(&cond); pthread_mutex_unlock (&mutex); return (NULL); State 1 handler (was consumer) void * state_1 (void *arg){ int i; //int new_state = 2; while (1) { pthread_mutex_lock (&mutex); while (state!= 1) { pthread_cond_wait (&cond, &mutex); if( ++i & 0x1 ){ state = 3; else{ state = 2; // "clever" ways to set next state // state = (++i & 0x1)? 3:2; // // state = new_state ^= 0x1; // 30
31 printf ("%s: transit 1 -> %d\n", progname, state); pthread_cond_broadcast (&cond); pthread_mutex_unlock (&mutex); return (NULL); void * state_2 (void *arg){ while (1) { pthread_mutex_lock (&mutex); while (state!= 2) { pthread_cond_wait (&cond, &mutex); printf ("%s: transit 2 -> 0\n", progname); state = 0; pthread_cond_broadcast (&cond); pthread_mutex_unlock (&mutex); return (NULL); void * state_3 (void *arg){ while (1) { pthread_mutex_lock (&mutex); while (state!= 3) { pthread_cond_wait (&cond, &mutex); printf ("%s: transit 3 -> 0\n", progname); state = 0; pthread_cond_broadcast (&cond); pthread_mutex_unlock (&mutex); return (NULL); 12. Uruchom program z projektu Condvar. Sprawdź jego działanie. Jaki jest wynik działania programu? 13. Zmodyfikuj kod programu Condvar w taki sposób, aby wszystkie wątki consumer, wykonały pracę po zmianie stanu zmiennej warunkowej. 14. Sprawdź wynik działania uruchomionego kodu z pkt 11. Do sprawdzeń użyj perspektywy QNX System Information. Wynik działania programu przedstaw prowadzącemu. 31
32 Przeanalizuj poniższy kod programu SEMEX. This module demonstrates POSIX semaphores. Operation: A counting semaphore is created, primed with 0 counts. Five consumer threads are started, each trying to obtain the semaphore. A producer thread is created, which periodically posts the semaphore, unblocking one of the consumer threads. #include <stdio.h> #include <sys/neutrino.h> #include <pthread.h> #include <semaphore.h> #include <fcntl.h> #include <sys/stat.h> #include <malloc.h> Our global variables, and forward references sem_t *mysemaphore; void *producer (void *); void *consumer (void *); char *progname = "semex"; #define SEM_NAME "/Semex" main (){ int i; setvbuf (stdout, NULL, _IOLBF, 0); // #define Named #ifdef Named mysemaphore = sem_open (SEM_NAME, O_CREAT, S_IRWXU, 0); not sharing with other process, so immediately unlink sem_unlink( SEM_NAME ); #else // Named mysemaphore = malloc (sizeof (sem_t)); sem_init (mysemaphore, 1, 0); #endif // Named for(i = 0; i < 5; i++){ pthread_create (NULL, NULL, consumer, (void *) i); pthread_create (NULL, NULL, producer, (void *) 1); sleep (20); // let the threads run printf ("%s: main, exiting\n", progname); 32
33 Producer void * producer (void *i){ while (1) { sleep (1); printf ("%s: (producer %d), posted semaphore\n", progname, (int) i); sem_post (mysemaphore); return (NULL); Consumer void * consumer (void *i){ while (1) { sem_wait (mysemaphore); printf ("%s: (consumer %d) got semaphore\n", progname, (int) i); return (NULL); 15. Uruchom program z projektu Semex. Sprawdź jego działanie. Jaki jest wynik działania programu? Jakiego rodzaju semafora używa program? 16. Zmodyfikuj kod programu Semex w taki sposób, aby wątki do synchronizacji swojej pracy używały innego rodzaju semafora. 17. Uruchom i sprawdź działanie zmodyfikowanego kodu. 33
34 Komunikacja IPC Inter-Procces Communication QNX Neutrino wspiera różnorodne mechanizmy komunikacji IPC: rodzima komunikacja QNX Neutrino (API unikalne dla QNX): komunikaty QNX Neutrino; pulsy QNX Neutrino; mechanizmy zgodne z POSIX/UNIX (API przenośne): sygnały; pamięć dzielona; potoki (wymagany proces pipe); kolejki komunikatów POSIX (wymagany proces mqueue lub mq); gniazda TCP/IP (wymagany proces io-net) Na laboratorium zapoznamy się z rodzimą komunikacją QNX Neutrino. Komunikacja bazująca na komunikatach QNX Neutrino oparta jest na modelu klient-serwer. Jest dwukierunkowa i synchroniczna. Oznacza to iż klient po wysłaniu komunikatu do serwera czeka na jego odpowiedź. Dopiero po otrzymaniu informacji zwrotnej może kontynuować pracę. W trakcie przesyłania komunikatów mamy do czynienia z fizycznym kopiowaniem danych pomiędzy obszarami pamięci. Do komunikacji asynchronicznej używane są pulsy krótkie powiadomienia. 34
35 Zalety pulsu: nieblokujący dla nadawcy; ustalony rozmiar: 32-bitowa wartość, 8-bitowy kod(-128 do 127); jednokierunkowe (nie wymagają odpowiedzi); szybkie i niedrogie Przygotowanie platformy i środowiska IDE Uruchom QNX Neutrino za pomocą maszyny wirtualnej. Sprawdź poleceniem pidin czy jest uruchomiony proces qconn. Jeśli nie ma go na liście pracujących procesów uruchom go poleceniem qconn #.Sprawdź adres IP poleceniem ifconfig. Następnie uruchom środowisko QNX Momentics IDE. Wybierz przestrzeń roboczą wskazaną przez prowadzącego. Zadanie 1. Przeanalizuj kod źródłowy poniższego programu server. Odszukaj w nim fragmenty odpowiedzialne za zestawienie połączenia po stronie serwera. Wypisz odpowiednie funkcje w sprawozdaniu. server.c A QNX msg passing server. It should receive a string from a client, calculate a checksum on it, and reply back the client with the checksum. The server prints out its pid and chid so that the client can be made aware of them. Using the comments below, put code in to complete the program. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/neutrino.h> #include <process.h> #include "msg_def.h" //layout of msg's should always defined by //a struct, here's it's definition int calculate_checksum(char *text); int main(void) { int chid; int pid; int rcvid; cksum_msg_t msg; int status; int checksum; 35
36 setvbuf (stdout, NULL, _IOLBF, 0); //set IO to stdout to be line buffered chid = ChannelCreate(0); //PUT CODE HERE to create a channel if(-1 == chid) { //was there an error creating the channel? perror("channelcreate()"); //look up the errno code and print exit(exit_failure); pid = getpid(); //get our own pid //print our pid/chid so client can be told where to connect printf("server's pid: %d, chid: %d\n", pid, chid); while(1) { //PUT CODE HERE to receive msg from client rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL); if(rcvid == -1) { //Was there an error receiving msg? perror("msgreceive"); //look up errno code and print break; //try receiving another msg checksum = calculate_checksum(msg.string_to_cksum); //PUT CODE HERE TO reply to client with checksum status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum) ); if(-1 == status) { perror("msgreply"); return 0; int calculate_checksum(char *text){ char *c; int cksum = 0; for (c = text; *c!= NULL; c++) cksum += *c; return cksum; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu server tak, aby mógł odbierać komunikaty od klienta. Po modyfikacjach uruchom program server. 36
37 Zadanie 2. Przeanalizuj kod źródłowy poniższego programu client. Odszukaj w nim fragmenty odpowiedzialne za zestawienie połączenia po stronie klienta. Wypisz odpowiednie funkcje w sprawozdaniu. client.c A QNX msg passing client. It's purpose is to send a string of text to a server. The server calculates a checksum and replies back with it. The client expects the reply to come back as an int. This program program must be started with commandline args. See if(argc!= 4) below. To complete the exercise, put in the code, as explained in the comments below. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/neutrino.h> #include <sys/netmgr.h> // #define for ND_LOCAL_NODE is in here #include "msg_def.h" int main(int argc, char* argv[]) { int coid; //Connection ID to server cksum_msg_t msg; int incoming_checksum; //space for server's reply int status; //status return value used for ConnectAttach and MsgSend int server_pid; //server's process ID int server_chid; //server's channel ID setvbuf (stdout, NULL, _IOLBF, 0); if(4!= argc) { printf("this program must be started with commandline arguments, for example:\n\n"); printf(" cli abcdefghi \n\n"); printf(" 1st arg(482834): server's pid\n"); printf(" 2nd arg(1): server's chid\n"); printf(" 3rd arg(abcdefghi): string to send to server\n"); //to make it easy, let's not bother handling spaces exit(exit_failure); 37
38 server_pid = atoi(argv[1]); server_chid = atoi(argv[2]); printf("attempting to establish connection with server pid: %d, chid %d\n", server_pid, server_chid); //PUT CODE HERE to establish a connection to the server's channel coid = ConnectAttach(ND_LOCAL_NODE, server_pid, server_chid, _NTO_SIDE_CHANNEL, 0); if(-1 == coid) { //was there an error attaching to server? perror("connectattach"); //look up error code and print exit(exit_failure); msg.msg_type = CKSUM_MSG_TYPE; strcpy(msg.string_to_cksum, argv[3]); printf("sending string: %s\n", msg.string_to_cksum); //PUT CODE HERE to send message to server and get the reply status = MsgSend(coid, &msg, sizeof(msg), &incoming_checksum, sizeof(incoming_checksum) ); if(-1 == status) { //Was there an error sending to server? perror("msgsend"); exit(exit_failure); printf("received checksum=%d from server\n", incoming_checksum); printf("msgsend return status: %d\n", status); return EXIT_SUCCESS; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu client tak, aby mógł wysyłać komunikaty do serwera. Po modyfikacjach uruchom program client. Zadanie 3. Zmień kod programu client tak, aby komunikat do serwera nadawany był cyklicznie. Zastanów się, jak zmodyfikować kody powyższych programów server i client, aby odpowiedzieć na następujące pytania: W jakim stanie jest client nim server gotowy będzie do odbierania komunikatów? 38
39 W jakim stanie jest client gdy server odbierze komunikat? W jakim stanie jest server nim klient wyśle do niego komunikat? Dokonaj odpowiednich modyfikacji kodu i udziel odpowiedzi na wyżej postawione pytania. Zaprezentuj wyniki prowadzącemu w perspektywie QNX System Information. Zadanie 4. Przeanalizuj kod źródłowy poniższego programu pulse_server. pulse_server.c A QNX msg passing server. It should receive a string from a client, calculate a checksum on it, and reply back the client with the checksum. The server prints out its pid and chid so the client can be made aware of them. Using the comments below, put code in to complete the program. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/neutrino.h> #include <process.h> #include "msg_def.h" //layout of msg's should always defined by a struct, here's //it's definition int calculate_checksum(char *text); int main(void) { int chid; int pid; int rcvid; msg_buf_t msg; int status; int checksum; setvbuf (stdout, NULL, _IOLBF, 0); buffered //set IO to stdout to be line 39
40 chid = ChannelCreate(0); //PUT CODE HERE to create a channel if(-1 == chid) { //was there an error creating the channel? perror("channelcreate()"); //look up the errno code and print exit(exit_failure); pid = getpid(); //get our own pid //print our pid/chid so client can be told where to connect printf("server's pid: %d, chid: %d\n", pid, chid); while(1) { //PUT CODE HERE to receive msg from client rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL); if(rcvid == -1) { //Was there an error receiving msg? perror("msgreceive"); //look up errno code and print continue; //try receiving another msg else if (rcvid == 0) { printf("a pulse was received, its code is %d, its value is %d\n", msg.pulse.code, msg.pulse.value.sival_int); continue; checksum = calculate_checksum(msg.cksum.string_to_cksum); //PUT CODE HERE TO reply to client with checksum status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum) ); if(-1 == status) { perror("msgreply"); return 0; int calculate_checksum(char *text) { char *c; int cksum = 0; for (c = text; *c!= NULL; c++) cksum += *c; return cksum; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu pulse_server tak, aby mógł odbierać pulsy do klienta. Po modyfikacjach uruchom program pulse_server. 40
41 Zadanie 5. Przeanalizuj kod źródłowy poniższego programu pulse_client. pulse_client.c A QNX msg passing client. It's purpose is to send a string of text to a server. The server calculates a checksum and replies back with it. The client expects the reply to come back as an int This program program must be started with commandline args. See if(argc!= 4) below. To complete the exercise, put in the code, as explained in the comments below. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/neutrino.h> #include <sys/netmgr.h> // #define for ND_LOCAL_NODE is in here #include "msg_def.h" #define MY_PULSE_CODE _PULSE_CODE_MINAVAIL #define MY_OTHER_PULSE_CODE _PULSE_CODE_MINAVAIL + 7 int main(int argc, char* argv[]) { int coid; //Connection ID to server int status; //status return value used for ConnectAttach and MsgSend int server_pid; //server's process ID int server_chid; //server's channel ID int some_value = 25; //make up some kind of number for a value setvbuf (stdout, NULL, _IOLBF, 0); if(4!= argc) { printf("this program must be started with commandline arguments, for example:\n\n"); printf(" cli abcdefghi \n\n"); printf(" 1st arg(482834): server's pid\n"); printf(" 2nd arg(1): server's chid\n"); printf(" 3rd arg(abcdefghi): string to send to server\n"); //to make //it easy, let's not bother handling spaces exit(exit_failure); server_pid = atoi(argv[1]); server_chid = atoi(argv[2]); 41
42 printf("attempting to establish connection with server pid: %d, chid %d\n", server_pid, server_chid); //PUT CODE HERE to establish a connection to the server's channel coid = ConnectAttach(ND_LOCAL_NODE, server_pid, server_chid, _NTO_SIDE_CHANNEL, 0); if(-1 == coid) { //was there an error attaching to server? perror("connectattach"); //look up error code and print exit(exit_failure); status = MsgSendPulse(coid, getprio(0), MY_PULSE_CODE, 0); if(status == -1) { perror("problmem with 1st MsgSendPulse"); status = MsgSendPulse(coid, getprio(0), MY_OTHER_PULSE_CODE, some_value); if(status == -1) { perror("problmem with 2nd MsgSendPulse"); return EXIT_SUCCESS; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu pulse_client tak, aby mógł wysyłać pulsy do serwera. Po modyfikacjach uruchom program pulse_client. Zadanie 6. Zmodyfikuj program pulse_client tak aby pulsy wysyłane były cyklicznie. Dodaj własny pulse. Sprawdź w jakim stanie jest proces pulse_client po wysłaniu pulsu. 42
43 Zadanie 7. Przeanalizuj kod źródłowy poniższego programu name_lookup_server. Odszukaj w nim fragmenty odpowiedzialne za zestawienie połączenia po stronie serwera. Zamieść odpowiednie funkcje w sprawozdaniu. name_lookup_server.c A QNX msg passing server. It should receive a string from a client, calculate a checksum on it, and reply back the client with the checksum. The server prints out its pid and chid so that the client can be made aware of them. Using the comments below, put code in to complete the program. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/neutrino.h> #include <process.h> #include <sys/iofunc.h> #include <sys/dispatch.h> #include "msg_def.h" //layout of msg's should always defined by a struct, // here's it's definition int calculate_checksum(char *text); int main(void) { int rcvid; msg_buf_t msg; int status; int checksum; name_attach_t* attach; setvbuf (stdout, NULL, _IOLBF, 0); //set IO to stdout to be line buffered //PUT CODE HERE to attach a name attach = name_attach(null, SERVER_NAME, 0); if(null == attach) { //Was there an error creating the channel? perror("name_attach()"); //look up the errno code and print exit(exit_failure); 43
44 while(1) { //PUT CODE HERE to receive msg from client, store the receive id in rcvid rcvid = MsgReceive(attach->chid, &msg, sizeof msg, NULL); if(rcvid == -1) { //was there an error receiving msg? perror("msgreceive"); //look up errno code and print continue; //try receiving another msg else if(rcvid == 0) { printf("received pulse, code = %d\n", msg.pulse.code); continue; printf("received msg: %s\n", msg.cksum.string_to_cksum); checksum = calculate_checksum(msg.cksum.string_to_cksum); //PUT CODE HERE TO reply to client with checksum, store the return status //in status status = MsgReply(rcvid, EOK, &checksum, sizeof checksum); if(-1 == status) { perror("msgreply"); return 0; int calculate_checksum(char *text) { char *c; int cksum = 0; for (c = text; *c!= NULL; c++) cksum += *c; return cksum; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu name_lookup_server tak, aby mógł odbierać komunikaty do klienta. Po modyfikacjach uruchom program name_lookup_server. 44
45 Zadanie 8. Przeanalizuj kod źródłowy poniższego programu name_lookup_client. Odszukaj w nim fragmenty odpowiedzialne za zestawienie połączenia po stronie klienta. Wypisz odpowiednie funkcje w sprawozdaniu. name_lookup_client.c A QNX msg passing client. It's purpose is to send a string of text to a server. The server calculates a checksum and replies back with it. The client expects the reply to come back as an int. This program program must be started with commandline args. See if(argc!= 4) below To complete the exercise, put in the code, as explained in the comments below. Look up function arguments in the course book or the QNX documentation. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/neutrino.h> #include <sys/netmgr.h> #include <sys/iofunc.h> #include <sys/dispatch.h> // #define for ND_LOCAL_NODE is in here #include "msg_def.h" int main(int argc, char* argv[]) { int coid; //Connection ID to server msg_buf_t msg; int incoming_checksum; //space for server's reply int status; //status return value used for ConnectAttach and //MsgSend setvbuf (stdout, NULL, _IOLBF, 0); if(2!= argc) { printf("this program must be started with commandline arguments, for example:\n\n"); printf(" client abcdefghi \n\n"); printf(" where (abcdefghi) is string to send to server\n"); //to make //it easy, let's not bother handling spaces exit(exit_failure); 45
46 printf("client: attempting to establish connection with server %s\n", SERVER_NAME); //PUT CODE HERE to establish a connection to the server's channel, store the connection id in the variable 'coid' coid = name_open(server_name, 0); if(-1 == coid) { //was there an error attaching to server? perror("connectattach"); //look up error code and print exit(exit_failure); msg.cksum.msg_type = CKSUM_MSG_TYPE; strcpy(msg.cksum.string_to_cksum, argv[1]); printf("sending string: %s\n", msg.cksum.string_to_cksum); //PUT CODE HERE to send message to server and get the reply status = MsgSend(coid, &msg, sizeof msg, &incoming_checksum, sizeof(incoming_checksum); if(-1 == status) { //was there an error sending to server? perror("msgsend"); exit(exit_failure); printf("received checksum=%d from server\n", incoming_checksum); printf("msgsend return status: %d\n", status); return EXIT_SUCCESS; Na podstawie powyższego kodu zmodyfikuj kod źródłowy projektu name_lookup_client tak, aby mógł wysyłać komunikaty do serwera. Po modyfikacjach uruchom program name_lookup_client. Zadanie 9. Zmodyfikuj kody programów name_lookup_client i name_lookup_server tak aby komunikaty były wysyłane i odbierane cyklicznie. 46
47 Sprawozdanie. Grupa: 47
48 48
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: QNX Neutrino IPC native Mariusz Rudnicki 2016 Wstęp QNX Neutrino wspiera różnorodne mechanizmy komunikacji IPC: rodzima komunikacja QNX Neutrino
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: THREADS Mariusz Rudnicki 2016 1. Przygotowanie platformy i środowiska IDE. Przed uruchomieniem własnego kodu zwiększ priorytet procesu qconn
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: THREADS SYNCHRONIZATION METHODS Mariusz Rudnicki 2016 1. Wstęp W systemach wielowątkowych wspólne zasoby procesu takie, jak: pamięć: kod programu;
Programowanie Systemów Czasu Rzeczywistego
Programowanie Systemów Czasu Rzeczywistego Laboratorium Wprowadzenie Mariusz RUDNICKI mariusz.rudnicki@eti.pg.gda.pl 2016 Spis treści Przygotowanie platform docelowej.... 3 Przygotowanie środowiska programistycznego
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: QNX Neutrino Interrupts Mariusz Rudnicki 2016 Wstęp W QNX Neutrino wszystkie przerwania sprzętowe przechwytywane są przez jądro systemu. Obsługę
1. Tworzenie nowego projektu.
Załącznik do Instrukcji 1. Tworzenie nowego projektu. Wybieramy opcję z menu głównego New->QNX C Project. Wprowadzamy nazwę przechodzimy do następnego kroku NEXT. Wybieramy platformę docelową oraz warianty
Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.4
Mariusz Rudnicki mariusz.rudnicki@eti.pg.gda.pl PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.4 Synchronizacja wątków Omawiane zagadnienia Czym jest synchronizacja wątków? W jakim celu stosuje się mechanizmy
Warsztaty AVR. Instalacja i konfiguracja środowiska Eclipse dla mikrokontrolerów AVR. Dariusz Wika
Warsztaty AVR Instalacja i konfiguracja środowiska Eclipse dla mikrokontrolerów AVR Dariusz Wika 1.Krótki wstęp: Eclipse to rozbudowane środowisko programistyczne, które dzięki możliwości instalowania
Ćwiczenia 2 IBM DB2 Data Studio
Ćwiczenia 2 IBM DB2 Data Studio Temat: Aplikacje w Data Studio 1. Projekty Tworzenie procedur, UDF, trygerów zaczynamy od utworzenia projektu File -> New -> Project wybieramy Data Development Project.
1.Wstęp. 2.Generowanie systemu w EDK
1.Wstęp Celem niniejszego ćwiczenia jest zapoznanie z możliwościami debuggowania kodu na platformie MicroBlaze oraz zapoznanie ze środowiskiem wspomagającym prace programisty Xilinx Platform SDK (Eclipse).
Pobieranie argumentów wiersza polecenia
Pobieranie argumentów wiersza polecenia 2. Argumenty wiersza polecenia Lista argumentów Lista argumentów zawiera cały wiersz poleceń, łącznie z nazwą programu i wszystkimi dostarczonymi argumentami. Przykłady:
Informatyka I : Tworzenie projektu
Tworzenie nowego projektu w programie Microsoft Visual Studio 2013 Instrukcja opisuje w jaki sposób stworzyć projekt wykorzystujący bibliotekę winbgi2 w programie Microsoft Visual Studio 2013. 1. Otwórz
1. Uruchom poniższy program tworzący pojedynczy wątek:
9 Wątki 1. Uruchom poniższy program tworzący pojedynczy wątek: #include #include #include void* worker(void* info) int i; for(i=0; i
Mariusz Rudnicki PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.4
Mariusz Rudnicki mariusz.rudnicki@eti.pg.gda.pl PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.4 Synchronizacja wątków Omawiane zagadnienia Czym jest synchronizacja wątków? W jakim celu stosuje
Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.2
Mariusz Rudnicki mariusz.rudnicki@eti.pg.gda.pl PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.2 Architektura - Procesy Proces program załadowany do pamięci; identyfikowany przez id procesu, zwykle nazywany
w odróżnieniu od procesów współdzielą przestrzeń adresową mogą komunikować się za pomocą zmiennych globalnych
mechanizmy posix Wątki w odróżnieniu od procesów współdzielą przestrzeń adresową należą do tego samego użytkownika są tańsze od procesów: wystarczy pamiętać tylko wartości rejestrów, nie trzeba czyścić
Programowanie obiektowe zastosowanie języka Java SE
Programowanie obiektowe zastosowanie języka Java SE Wstęp do programowania obiektowego w Javie Autor: dr inŝ. 1 Java? Java język programowania obiektowo zorientowany wysokiego poziomu platforma Javy z
Temat zajęć: Tworzenie i obsługa wątków.
Temat zajęć: Tworzenie i obsługa wątków. Czas realizacji zajęć: 180 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: Tworzenie wątków, przekazywanie parametrów do funkcji wątków i pobieranie
Sieciowa komunikacja procesów - XDR i RPC
*** abc.x Przyklad pliku RPCGEN Obliczanie sumy, roznicy i iloczynu dwoch liczb calkowitych *** ************************************ Wywolanie procedury odleglej dopuszcza tylko jeden argument wywolania
Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.
Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych. 1. Przygotowanie środowiska programistycznego. Zajęcia będą
Driver interfejsu szeregowego dla systemu QNX Neutrino
Architektura Systemów Wbudowanych Laboratorium 9 i 10 Juny 2015 Driver interfejsu szeregowego dla systemu QNX Neutrino Imię Nazwisko Nr indeksu 1.Wstęp Co to jest manager zasobów? program rozszerzający
MeetingHelper. Aplikacja Android ułatwiająca przekazywanie materiałów pomiędzy uczestnikami spotkania. Instrukcja obsługi dla programisty
MeetingHelper Aplikacja Android ułatwiająca przekazywanie materiałów pomiędzy uczestnikami spotkania Instrukcja obsługi dla programisty W tej części został zawarty opis uruchamiania projektu programistycznego,
I - Microsoft Visual Studio C++
I - Microsoft Visual Studio C++ 1. Nowy projekt z Menu wybieramy File -> New -> Projekt -> Win32 Console Application w okienku Name: podajemy nazwę projektu w polu Location: wybieramy miejsce zapisu i
dynamiczny przydział pamięci calloc() memset() memcpy( ) (wskaźniki!! )
dynamiczny przydział pamięci malloc() free() realloc() calloc() memset() memcpy( ) mempcpy( ) memmove() (wskaźniki!! ) 1 dynamiczny przydział pamięci void * memccpy (void * to, void * from, int c, int
Materiały oryginalne: ZAWWW-2st1.2-l11.tresc-1.0kolor.pdf. Materiały poprawione
Materiały oryginalne: ZAWWW-2st1.2-l11.tresc-1.0kolor.pdf Materiały poprawione Rozwiązanie zadania w NetBeans IDE 7.4: Jarosław Ksybek, Adam Miazio Celem ćwiczenia jest przygotowanie prostej aplikacji
Camspot 4.4 Camspot 4.5
User manual (addition) Dodatek do instrukcji obsługi Camspot 4.4 Camspot 4.5 1. WiFi configuration 2. Configuration of sending pictures to e-mail/ftp after motion detection 1. Konfiguracja WiFi 2. Konfiguracja
WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.
WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM NetBeans Wykonał: Jacek Ventzke informatyka sem. VI 1. Uruchamiamy program NetBeans (tu wersja 6.8 ) 2. Tworzymy
Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project
Aplikacja Sieciowa Jedną z fundamentalnych właściwości wielu aplikacji jest możliwość operowania pomiędzy jednostkami (np. PC), które włączone są do sieci. W Windows operacja ta jest możliwa przy wykorzystaniu
Ćwiczenie 1. Kolejki IBM Message Queue (MQ)
Ćwiczenie 1. Kolejki IBM Message Queue (MQ) 1. Przygotowanie Przed rozpoczęciem pracy, należy uruchomić "Kreator przygotowania WebSphere MQ" oraz przejść przez wszystkie kroki kreatora, na końcu zaznaczając
Instrukcja konfiguracji usługi Wirtualnej Sieci Prywatnej w systemie Mac OSX
UNIWERSYTETU BIBLIOTEKA IEGO UNIWERSYTETU IEGO Instrukcja konfiguracji usługi Wirtualnej Sieci Prywatnej w systemie Mac OSX 1. Make a new connection Open the System Preferences by going to the Apple menu
Programowanie Współbieżne
Programowanie Współbieżne Pthread http://www.unix.org/version2/whatsnew/threadsref.html Oraz strony podręcznika systemowego man 1 Wątki W tradycyjnym modelu w systemie Unix, jeżeli proces wymaga, by część
Instrukcja pomocnicza
Programowanie lokalnych aplikacji.net 2013/2014 Instrukcja pomocnicza Debugowanie procesów potomnych w Visual Studio 2012 Prowadzący: Tomasz Goluch Wersja: 3.0 I. Debugowanie procesów potomnych w Visual
Politechnika Gdańska Katedra Optoelektroniki i Systemów Elektronicznych
Laboratorium OiOSE. Programowanie w środowisku MS Visual C++ 1 Politechnika Gdańska Katedra Optoelektroniki i Systemów Elektronicznych Organizacja i Oprogramowanie Systemów Elektronicznych Michał Kowalewski
Problemy techniczne SQL Server
Problemy techniczne SQL Server Jak utworzyć i odtworzyć kopię zapasową bazy danych za pomocą narzędzi serwera SQL? Tworzenie i odtwarzanie kopii zapasowych baz danych programów Kadry Optivum, Płace Optivum,
Zaawansowane aplikacje internetowe laboratorium
Zaawansowane aplikacje internetowe laboratorium Web Services (część 2). Celem ćwiczenia jest przygotowanie prostej aplikacji prezentującej technologię usług sieciowych (ang. Web Services). Przygotowana
Viszio. SZARP v3.1. Adam Smyk. 1. Uruchamianie programu. SZARP http://www.szarp.org
SZARP http://www.szarp.org Viszio SZARP v3.1 Adam Smyk Program viszio wykorzystywany jest wyświetlania wartości paramterów w transparentnych oknach. Głównymi danymi dla viszio są: nazwa serwera, numer
Dynamiczny DNS dla usług typu Neostrada przykład konfiguracji
W usłudze Neostrada TP czy Net24 (Netia) router otrzymuje jeden publiczny adres IP, który zapewnia globalną osiągalność routera z dowolnego miejsca w Internecie. Niestety adres ten ulega losowej wymianie
SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)
Program my_ping: wysłanie komunikatu ICMP z żądaniem echa Struktura icmp (plik netinet/ip_icmp.h) 0 7 8 15 16 31 TYP (icmp_type) KOD (icmp_code) IDENTYFIKATOR (icmp_id) SUMA KONTROLNA (icmp_cksum) NUMER
Katowice, plan miasta: Skala 1: = City map = Stadtplan (Polish Edition)
Katowice, plan miasta: Skala 1:20 000 = City map = Stadtplan (Polish Edition) Polskie Przedsiebiorstwo Wydawnictw Kartograficznych im. Eugeniusza Romera Click here if your download doesn"t start automatically
Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.
Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu. Dr inż. Zofia Kruczkiewicz Dwa sposoby tworzenia apletów Dwa sposoby
Wprowadzenie do laboratorium. Zasady obowiązujące na zajęciach. Wprowadzenie do narzędzi wykorzystywanych podczas laboratorium.
Wprowadzenie do laboratorium. Zasady obowiązujące na zajęciach. Wprowadzenie do narzędzi wykorzystywanych podczas laboratorium. Prowadzący Dr inż. Zofia 1 La1 La2 Forma zajęć - laboratorium Wprowadzenie
Problemy techniczne SQL Server
Problemy techniczne SQL Server Jak utworzyć i odtworzyć kopię zapasową za pomocą narzędzi serwera SQL? Tworzenie i odtwarzanie kopii zapasowych baz danych programów Kadry Optivum, Płace Optivum, MOL Optivum,
namespace HostedReceiver { public class Receiver: IConfigureThisEndpoint, AsA_Server {
Pobranie i instalacja: - http://www.nservicebus.com/ - download v3.0 now - rozpakować - MSMQ powinno być zainstalowane (Panel Sterowania -> Dodaj/Usuń programy -> Składniki systemu Windows -> Kolejkowanie
Shared memory and messages. Functions. process 0. process 1. program 0. program 0. data 0. data 1. program 1. data 0. data 1.
Shared memory and messages Shared memory vs message passing Shared memory - C functions Shared memory - example program Message queues - C functions Message queues - example program process 0 process 1
Zadanie1. Wykorzystując serwis internetowy Wikipedii wyjaśnij następujące pojęcia: wirtualizacja, VirtualBox, Vmware, KVM, Virtual PC, Hyper-V.
T: Wirtualizacja instalacji serwera Windows. Zadanie1. Wykorzystując serwis internetowy Wikipedii wyjaśnij następujące pojęcia: wirtualizacja, VirtualBox, Vmware, KVM, Virtual PC, Hyper-V. VirtualBox to
Wykład 3: Implementacja programów wbudowanych
Systemy wbudowane Wykład 3: Implementacja programów wbudowanych Problemy implementacji oprogramowania wbudowanego Szeregowanie zadań System operacyjny Obsługa przerwań 10/16/2010 S.Deniziak:Systemy wbudowane
Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak
Katedra Elektrotechniki Teoretycznej i Informatyki wykład 12 - sem.iii M. Czyżak Język C - preprocesor Preprocesor C i C++ (cpp) jest programem, który przetwarza tekst programu przed przekazaniem go kompilatorowi.
Programowanie w Javie
Programowanie w Javie Andrzej Czajkowski Lista nr 0 Debugger w Javie Celem ćwiczenia jest poznanie podstawowych funkcji narzędzia debugera (odpluskwiacz) w środowisku Eclipse. Po ukończeniu ćwiczenia student
Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.5
Mariusz Rudnicki mariuszrudnicki@etipggdapl PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ5 Komunikacja IPC Omawiane zagadnienia Czym jest komunikacja międzyprocesowa? W jakim celu stosuje się komunikację
Krótkie wprowadzenie do korzystania z OpenSSL
Krótkie wprowadzenie do korzystania z OpenSSL Literatura: http://www.openssl.org E. Rescola, "An introduction to OpenSSL Programming (PartI)" (http://www.linuxjournal.com/article/4822) "An introduction
Jak skonfigurować bezpieczną sieć bezprzewodową w oparciu o serwer RADIUS i urządzenia ZyXEL wspierające standard 802.1x?
Jak skonfigurować bezpieczną sieć bezprzewodową w oparciu o serwer RADIUS i urządzenia ZyXEL wspierające standard 802.1x? Przykład autoryzacji 802.1x dokonano w oparciu serwer Microsoft Windows 2003 i
Krótka instrukcja instalacji Adobe Acrobat Reader
Krótka instrukcja instalacji Adobe Acrobat Reader Program Adobe Acrobat Reader jest niezbędny do otwarcia dokumentu e-faktury tp. Jeżeli nie posiadają go Państwo w swoim komputerze, należy go zainstalować.
FAQ: 00000042/PL Data: 3/07/2013 Konfiguracja współpracy programów PC Access i Microsoft Excel ze sterownikiem S7-1200
Spis treści 1 Opis zagadnienia omawianego w dokumencie.. 2 2 Wstęp do nowego projektu..... 3 2.1 Nowy projekt... 3 2.2 Dodanie nowego urządzenia... 4 3 Program w main... 6 4 Program PC Access.... 8 4.1
Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 Zofia Kruczkiewicz
Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 http://www.junit.org/ Zofia Kruczkiewicz 1. Aby utworzyć test dla jednej klasy, należy kliknąć prawym przyciskiem myszy w oknie Projects na wybraną
How to share data from SQL database table to the OPC Server? Jak udostępnić dane z tabeli bazy SQL do serwera OPC? samouczek ANT.
Jak udostępnić dane z tabeli bazy SQL do serwera OPC? samouczek ANT How to share data from SQL database table to the OPC Server? ANT tutorial Krok 1: Uruchom ANT Studio i dodaj do drzewka konfiguracyjnego
Laboratorium - Poznawanie FTP
Cele Część 1: Korzystanie z usługi FTP z wiersza poleceń. Część 2: Pobranie pliku z serwera FTP za pomocą WS_FTP LE Część 3: Korzystanie z usługi FTP w przeglądarce Scenariusz File Transfer Protocol (FTP)
7. Szeregowanie procesów w systemie QNX6 Neutrino
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 7. Szeregowanie procesów w systemie QNX6 Neutrino 7.1 PRIORYTETY Każdy z procesów wykonywanych w systemie RTS ma przyporządkowany priorytet. W systemie
Tworzenie projektu asemblerowego dla środowiska Visual Studio 2008.
Dwiczenie 5. TEMAT: CEL: Tworzenie projektu asemblerowego dla środowiska Visual Studio 2008. Celem dwiczenia jest poznanie możliwości VS 2008 w zakresie tworzenia i uruchamiania aplikacji z kodem mieszanym
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka 1. Kompilacja aplikacji konsolowych w środowisku programistycznym Microsoft Visual Basic. Odszukaj w menu startowym systemu
Konfiguracja połączenia VPN w systemie Windows 7 z serwerem rozgrywki wieloosobowej gry Medal Of Honor: Wojna na Pacyfiku: Pacyfik.
Windows 7 Konfiguracja połączenia VPN w systemie Windows 7 z serwerem rozgrywki wieloosobowej gry Medal Of Honor: Wojna na Pacyfiku: Pacyfik.net... 1 Configuration of VPN connection in Window 7 system
QNX Neutrino (v 6.3)
QNX Neutrino (v 6.3) System operacyjny czasu rzeczywistego Wielozadaniowy, architektura z mikrojądrem API zgodne ze standardem POSIX Rozproszony, przezroczysta praca w sieci Mechanizmy wykrywania/tolerowania
Signals + Threads: Qt vs. Boost
Signals + Threads: Qt vs. Boost Adam Bujalski 2014-04-01 Adam Bujalski Signals + Threads: Qt vs. Boost 2014-04-01 1 / 22 Spis Treści 1 2 Wątki 3 Qt::QueuedConnection w boost Adam Bujalski Signals + Threads:
PROGRAMOWANIE SYSTEMÓW WBUDOWANYCH INTER-PROCESS COMMUNICATION
PROGRAMOWANIE SYSTEMÓW WBUDOWANYCH INTER-PROCESS COMMUNICATION Mariusz Rudnicki mariuszrudnicki@etipgedupl Programowanie Systemów Wbudowanych 1/91 KOMUNIKACJA MIĘDZYPROCESOWA IPC Omawiane zagadnienia Czym
USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian
1 / 12 Content list / Spis Treści 1. Hardware and software requirements, preparing device to upgrade Wymagania sprzętowe i programowe, przygotowanie urządzenia do aktualizacji 2. Installing drivers needed
SubVersion. Piotr Mikulski. SubVersion. P. Mikulski. Co to jest subversion? Zalety SubVersion. Wady SubVersion. Inne różnice SubVersion i CVS
Piotr Mikulski 2006 Subversion is a free/open-source version control system. That is, Subversion manages files and directories over time. A tree of files is placed into a central repository. The repository
Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne
Zdalne wywołania procedur Jarosław Kuchta Programowanie Współbieżne Podstawy RPC Remote Procedure Call Wywołanie procedur jednego procesu z innego procesu. Proces wywoływany serwer Proces wywołujący -
7. Szeregowanie procesów w systemie QNX6 Neutrino
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 7. Szeregowanie procesów w systemie QNX6 Neutrino 7.1 Priorytety Każdy z procesów wykonywanych w systemie RTS ma przyporządkowany priorytet. W systemie
Instrukcja instalacji i konfiguracji Karty EDGE/GPRS SonyEricsson GC85
Instrukcja instalacji i konfiguracji Karty EDGE/GPRS SonyEricsson GC85 SPIS TREŚCI SPIS TREŚCI...2 WSTĘP...2 INSTRUKCJA INSTALACJI I KONFIGURACJI...3 SCHEMAT INSTALACJI KARTY SIM W SE GC85...3 INSTALACJA
podstawowa obsługa panelu administracyjnego
podstawowa obsługa panelu administracyjnego Poniższy dokument opisuje podstawowe czynności i operacje jakie należy wykonać, aby poprawnie zalogować się i administrować środowiskiem maszyn wirtualnych usługi
Zdalny dostęp SSL. Przewodnik Klienta
Zdalny dostęp SSL Przewodnik Klienta Spis treści 1. WSTĘP... 3 2. DOSTĘP DO SSL VPN Z KOMPUTERA Z SYSTEMEM WINDOWS... 3 2.1. INSTALACJA CERTYFIKATÓW SIGNET... 3 2.2. INSTALACJA TOKENA W SYSTEMIE WINDOWS
https://portal.clusterix.pl:8443 trainxx tramxx
Logowanie 1. Otworzyć w oknie przeglądarki adres: https://portal.clusterix.pl:8443 2. Zalogować się używając konta, użytkownik: trainxx, hasło: tramxx Delegacja certyfikatu proxy 1. Zalogować poprzez ssh
Projekt procesora NIOSII w strukturze programowalnego układu logicznego CYCLONEII EP2C35F672C6 podłączenie i obsługa wyświetlacza LCD.
LAB. 2 Projekt procesora NIOSII w strukturze programowalnego układu logicznego CYCLONEII EP2C35F672C6 podłączenie i obsługa wyświetlacza LCD. Laboratorium Mikroprocesorowych Układów Sterowania instrukcja
Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1).
Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1). Celem ćwiczenia jest przygotowanie prostej aplikacji internetowej wykorzystującej technologię usług sieciowych (ang. Web Services).
Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1
Tworzenie programów równoległych Krzysztof Banaś Obliczenia równoległe 1 Tworzenie programów równoległych W procesie tworzenia programów równoległych istnieją dwa kroki o zasadniczym znaczeniu: wykrycie
Wymagania do zdalnej instalacji agentów firmy StorageCraft
Wymagania do zdalnej instalacji agentów firmy StorageCraft Sytuacja Te wymagania są rekomendowane do zrealizowania przed wykonaniem zdalnej instalacji agentów ShadowProtect. Pomogą one także rozwiązad
Laboratorium 1. I. Zainstaluj program Eclipse (wersja C/C++ w odpowiednim systemie operacyjnym
Laboratorium 1 I. Zainstaluj program Eclipse (wersja C/C++ http://www.eclipse.org/downloads/) w odpowiednim systemie operacyjnym II. Zainstaluj narzędzia Windows CDT (w Eclipse jako software site dodajemy
Zadania: 1. Funkcja przeliczająca F na C: float FtoC(float f){ return (f 32.0) * 5.0 / 9.0; }
Zadania: 1. Funkcja przeliczająca F na C: float FtoC(float f){ return (f 32.0) * 5.0 / 9.0; 2. Utworzyć dodatkową funkcję, która przelicza F na K, na bazie poprzedniej F to C (z poprzednich zajęć), wg
Strona 1 NUMPAGES INSTRUKCJA OBSŁUGI KARTY DARK. CENTRUM USŁUG ZAUFANIA SIGILLUM Wersja 1.0
Strona 1 INSTRUKCJA OBSŁUGI KARTY DARK CENTRUM USŁUG ZAUFANIA SIGILLUM Wersja 1.0 Strona 2 Spis treści 1. Wstęp... 3 2. Instalacja oprogramowania... 4 3. Korzystanie z oprogramowania... 7 3.1. IDProtect
Konfiguracja i przygotowanie środowiska do współpracy z infrastrukturą PL-Grid
geclipse dla PL-Grid Instalacja środowiska: 1. Upewnij się, że masz zainstalowane środowisko Java, 2. Rozpakuj archiwum geclipse-plgrid_.zip do wybranego przez siebie katalogu, np.: D:\PL-Grid
Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.
Przykład: $ ls more Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi. Tworzenie łącza #include int pipe(int filedes[2]); Przykład: int
Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania
Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania Przemysłowe układy sterowania PID Układy regulacji PID w strukturze sprzętowej Pytania i zadania do zajęć
Programowanie Proceduralne
Programowanie Proceduralne Struktury Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 10 Co dziś będzie: Definiowanie struktury Deklarowanie zmiennych bȩda cych strukturami
Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego
Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego 1 /24 Pisanie pojedynczych znaków z klawiatury do pliku #include void main(void) { FILE *fptr; // wkaznik do pliku, tzw. uchwyt
Aplikacje WWW - laboratorium
Aplikacje WWW - laboratorium JavaServer Pages Celem ćwiczenia jest zbudowanie kilku prostych stron internetowych z użyciem technologii JSP. Podczas ćwiczenia wykorzystany zostanie algorytm sortowania bąbelkowego
BACKUP BAZ DANYCH MS SQL
BACKUP BAZ DANYCH MS SQL SPIS TREŚCI Informacje ogólne... 2 Tworzenie projektu... 2 Krok 1: Informacje Podstawowe... 2 Krok 2: Dane... 3 Krok 3: Planowanie... 4 Krok 4: Zaawansowane... 5 Przywracanie baz
Problemy czytelników i pisarzy oraz 5 ucztujących filozofów
Problemy czytelników i pisarzy oraz 5 dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
Microsoft.NET: ASP.NET MVC + Entity Framework (Code First)
Microsoft.NET: ASP.NET MVC + Entity Framework (Code First) Do realizacji projektu potrzebne jest zintegrowane środowisko programistyczne Microsoft Visual Studio 2012. W ramach projektu budowana jest prosta
Załącznik 1 instrukcje instalacji
Załącznik 1 instrukcje instalacji W poniższym załączniku przedstawione zostaną instrukcje instalacji programów wykorzystanych w trakcie tworzenia aplikacji. Poniższa lista przedstawia spis zamieszczonych
Java pierwszy program w Eclipse «Grzegorz Góralski strona własna
Strona 1 z 9 «Przykładowe zadania do cz. III ćwiczeń z genetyki Java pierwsze kroki w programowaniu (01)» Kategoria: java, Tagi: eclipse - java - programowanie. Autor: Grzegorz, napisał dnia: February
MentorGraphics ModelSim
MentorGraphics ModelSim 1. Konfiguracja programu Wszelkie zmiany parametrów systemu symulacji dokonywane są w menu Tools -> Edit Preferences... Wyniki ustawień należy zapisać w skrypcie startowym systemu
Programowanie sterowników
Programowanie sterowników Wydział Elektrotechniki, Informatyki i Telekomunikacji 1 Strona 1 Ćwiczenie 1: Usuwanie projektu 1. Uruchom Windows Explorer. 2. Usuń projekt z lokalizacji na dysku: D:\Automation
Zaawansowane aplikacje internetowe - laboratorium Web Services (część 2).
Zaawansowane aplikacje internetowe - laboratorium Web Services (część 2). Celem ćwiczenia jest przygotowanie prostej aplikacji prezentującej technologię usług sieciowych (ang. Web Services). Przygotowana
Pracownia internetowa w szkole ZASTOSOWANIA
NR ART/SBS/07/01 Pracownia internetowa w szkole ZASTOSOWANIA Artykuły - serwery SBS i ich wykorzystanie Instalacja i Konfiguracja oprogramowania MOL Optiva na szkolnym serwerze (SBS2000) Artykuł opisuje
Konfiguracja oprogramowania w systemach MS Windows dla kont z ograniczonymi uprawnieniami
Konfiguracja oprogramowania w systemach MS Windows dla kont z ograniczonymi uprawnieniami Dotyczy programów opartych na bazie BDE: Menedżer Pojazdów PL+ Ewidencja Wyposażenia PL+ Spis treści: 1. Wstęp...
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka 1. Kompilacja aplikacji konsolowych w środowisku programistycznym Microsoft Visual Basic. Odszukaj w menu startowym systemu
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO. Mariusz RUDNICKI: pok. 753 tel.:
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO Mariusz RUDNICKI: mariusz.rudnicki@eti.pg.gda.pl pok. 753 tel.: 347 26 39 Zagadnienia Pojęcia podstawowe SCR Architektura QNX Neutrino Procesy, wątki i synchronizacja
COMMAX CDV-70UX - USTAWIENIE PRACY URZĄDZEŃ MOBILNYCH
2017.03.07 COMMAX CDV-70UX - USTAWIENIE PRACY URZĄDZEŃ MOBILNYCH Monitor CDV-70UX występuje w dwóch wersjach sprzętowych: Wersja 1: - numery seryjne 2015.06S1506., 2015.07S1507., - dioda informacyjna LED
Zaawansowane aplikacje internetowe - laboratorium Architektura CORBA.
Zaawansowane aplikacje internetowe - laboratorium Architektura CORBA. Celem ćwiczenia jest przygotowanie prostej aplikacji wykorzystującej architekturę CORBA. Aplikacja składa się z usługodawcy (serwera)
Instrukcja podstawowego uruchomienia sterownika PLC LSIS serii XGB XBC-DR20SU
Instrukcja podstawowego uruchomienia sterownika PLC LSIS serii XGB XBC-DR20SU Spis treści: 1. Instalacja oprogramowania XG5000 3 2. Tworzenie nowego projektu i ustawienia sterownika 7 3. Podłączenie sterownika