Driver interfejsu szeregowego dla systemu QNX Neutrino

Podobne dokumenty
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

1. Tworzenie nowego projektu.

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Pobieranie argumentów wiersza polecenia

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Programowanie Proceduralne

Sieciowa komunikacja procesów - XDR i RPC

Programowanie Systemów Czasu Rzeczywistego

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

dynamiczny przydział pamięci calloc() memset() memcpy( ) (wskaźniki!! )

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Shared memory and messages. Functions. process 0. process 1. program 0. program 0. data 0. data 1. program 1. data 0. data 1.

LabVIEW PLATFORMA EDUKACYJNA Lekcja 5 LabVIEW i Arduino konfiguracja środowiska i pierwszy program

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

Informatyka. Wy-03 Dynamiczna alokacja pamięci, wyjątki. mgr inż. Krzysztof Kołodziejczyk

Wykład 3: Implementacja programów wbudowanych

QNX Neutrino (v 6.3)

Uzupełnienie dot. przekazywania argumentów

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Krótkie wprowadzenie do korzystania z OpenSSL

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Ćwiczenia 2 IBM DB2 Data Studio

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

Iteracyjny serwer TCP i aplikacja UDP

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

1.Wstęp. 2.Generowanie systemu w EDK

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

Informatyka I : Tworzenie projektu

1: ////////// 2: // test.c. 3: ssize_t ret = read(fd, buf, nbytes);

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Rev Źródło:

EC4P Pierwszy program w 6 krokach

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

4.2 Sposób korzystania z l acza

Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.2

Języki i metody programowania Java Lab1 Zofia Kruczkiewicz

Co nie powinno być umieszczane w plikach nagłówkowych:

Wstęp do programowania 1

Wstęp do programowania

Zakopane, plan miasta: Skala ok. 1: = City map (Polish Edition)

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Politechnika Gdańska Katedra Optoelektroniki i Systemów Elektronicznych

FAQ: /PL Data: 3/07/2013 Konfiguracja współpracy programów PC Access i Microsoft Excel ze sterownikiem S7-1200

inode instalacja sterowników USB dla adaptera BT 4.0

3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);

Wykład 1

Gniazda BSD. komunikacja bezpołączeniowa

Konfigurowanie modułu BK9050 firmy Beckhoff wprowadzenie

Architektura Systemów Wbudowanych

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Instrukcja obsługi User s manual

Projekt procesora NIOSII w strukturze programowalnego układu logicznego CYCLONEII EP2C35F672C6 podłączenie i obsługa wyświetlacza LCD.

Instrukcja instalacji sterowników USB dla urządzeń Posnet Polska S.A.

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Tychy, plan miasta: Skala 1: (Polish Edition)

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Jedrzej Ułasiewicz Komputerowe systemy sterowania 1

Camspot 4.4 Camspot 4.5

Programowanie obiektowe zastosowanie języka Java SE

RS868v3 module configuration

Obsługa plików Procesy

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.

Modelowanie numeryczne w fizyce atmosfery Ćwiczenia 3

METHOD 2 -DIAGNOSTIC OUTSIDE

ECLIPSE wnioski z dwóch pierwszych laboratoriów

Linux Kernel. Wprowadzenie

Realizacja systemów wbudowanych (embeded systems) w strukturach PSoC (Programmable System on Chip)

Wprowadzenie do laboratorium. Zasady obowiązujące na zajęciach. Wprowadzenie do narzędzi wykorzystywanych podczas laboratorium.

Grzegorz Cygan. Wstęp do programowania mikrosterowników w języku C

Visual Basic Debugging and Error Handling

Wstęp do Programowania, laboratorium 02

Linux Kernel III. Character devices

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

Instrukcja konfiguracji usługi Wirtualnej Sieci Prywatnej w systemie Mac OSX

Rodzina protokołów TCP/IP. Aplikacja: ipconfig.

Architektura typu klient serwer: przesyłanie pliku tekstowo oraz logowania do serwera za pomocą szyfrowanego hasła

Programowanie w Javie

Tworzenie aplikacji w języku Java

Jzyk C++ cz 3. Jarosław Gramacki Instytut Informatyki i Elektroniki ( $)*)+' *, - ( ' )*'.' '',*/ *, ','*0) 1 / ) %*+ 2'' 2" ( $%%) )'20 )*0) 1 / )

Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 Zofia Kruczkiewicz

Laboratorium Programowania Kart Elektronicznych

SQL 4 Structured Query Lenguage

4 bity zarezerwowane dla przyszłych zastosowań 11 bitów określających źródło błędu 16 bitów określających rodzaj błędu.

Programowanie Systemów Wbudowanych

Sterowniki urządzeń w systemie operacyjnym RTEMS

Instrukcja podstawowego uruchomienia sterownika PLC LSIS serii XGB XBC-DR20SU

Konfigurowanie sterownika BC8150 firmy Beckhoff wprowadzenie

OpenPoland.net API Documentation

Funkcje zawarte w bibliotece < io.h >

Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Zadania: 1. Funkcja przeliczająca F na C: float FtoC(float f){ return (f 32.0) * 5.0 / 9.0; }

Zarządzanie sieciami telekomunikacyjnymi

LabVIEW PLATFORMA EDUKACYJNA Lekcja 6 LabVIEW i Arduino programy wykorzystujące wyświetlacz LCD, czujnik temperatury, PWM i diodę LED

Transkrypt:

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 system operacyjny poprzez: tworzenie i zarządzanie nazwami w przestrzeni nazw dostarczenie klientom interfejsu zgodnego ze standardem POSIX (np. open(), read(), write(),...) może być połączony ze sprzętem hardware (takim jak port szeregowy albo sterownik dysku, itp.) albo może być po prostu encją oprogramowania (jak /dev/mqueue) Mapowanie nazw QNX Writing a Resource Manager QNX Software Systems LTD. 1

QNX Writing a Resource Manager QNX Software Systems LTD. QNX Writing a Resource Manager QNX Software Systems LTD. 2

Manager zasobów wykonuje następujące kroki: tworzy kanał, przejmuje część przestrzeni nazw, oczekuje na komunikaty i zdarzenia, przetwarza komunikaty i zwraca wyniki. Spojrzenie na ogólną koncepcję menedżera zasobów. QNX Writing a Resource Manager QNX Software Systems LTD. 2005 QNX Writing a Resource Manager QNX Software Systems LTD. 2005 3

2.Przygotowanie do wykonania zadań. Uruchom środowisko QNX Momentics IDE ze wskazaną przez prowadzącego przestrzenią roboczą. Zapoznaj się z podstawowymi widokami środowiska. Sprawdź dostępne perspektywy. Przydatne perspektywy to: C/C++ perspective ; Debug perspective ; QNX System Information perspective ; Przejdź do perspektywy QNX System Information - klucz na pasku narzędzi w górnej prawej części ekranu. W oknie Target Navigator ustaw połączenie z platformą docelową. Wciskając prawy klawisz myszy i wybierając opcję New QNX Target. Pojawi się okno: W polu Hostname or IP wprowadź adres IP platformy docelowej. Upewnij się że na platformie docelowej uruchomiony jest proces qconn. Jeśli nie wykonaj polecenie: qconn #. Wróć do perspektywy C/C++. Otwórz wskazany plik źródłowy. Kompilacja projektu wybierz z menu głównego opcję Project->Build Project. Przejdź do realizacji zadań. 4

3.Zadania do zrealizowania Zad.3.1. Opracowanie API dla zasobu sprzętowego. W środowisku w pliku źródłowym uzupełnij kod odpowiedzialny za: Inicjowanie portu szeregowego wyznaczonego przez prowadzącego; Wysyłanie danych łączem szeregowym; Odbieranie danych łączem szeregowym; Uwaga: Nadawanie i odbiór powinny być zorganizowane w oparciu o przerwania. Załącznik 3. Materiały pomocnicze w załączniku 1. Po napisaniu kodu sprawdź działanie opracowanych funkcji prostym programem przesyłając i odbierając dane z inną grupą laboratoryjną. Zad.3.2. Opracowanie menedżera zasobu. Bazując na plikach źródłowych z zadania 3.1 uzupełnij kod, który zamieni program do sprawdzenia komunikacji po łączu szeregowym w menedżera zasobu. Etapy postępowania: 1. Przygotowanie prototypów funkcji, które będą pełniły rolę funkcji POSIX open(), write(), read(). 2. Zadeklarowanie zmiennych odpowiedzialnych za: strukturę dispatch ; listę komunikatów połączenia; listę komunikatów I/O; atrybuty urządzenia; atrybuty managera zasobów; dispatch context. 3. Alokacja zasobów i inicjalizacja struktury dispatch. 4. Inicjowanie funkcji połączenia i tablicy funkcji wejścia-wyjścia. 5. Podmiana standardowych funkcji handlera na własne funkcje. 6. Inicjowanie struktury opisującej urządzenie. 7. Powiadomienie menedżera procesów o sposobie połączenia i podpięcie funkcji wejścia-wyjścia. 8. Alokacja struktury kontekstowej menedżera. 9. Pętla główna programu menedżera zasobu. rejestrujemy ścieżkę dostępu w głównej pętli: blokowanie w oczekiwaniu na komunikat 5

wywołanie funkcji obsługi; funkcja obsługi obsługuje nadchodzące zapytania i wykonuje odpowiednie fragmenty kodu, w zależności od zapytania. 10. Przygotowanie kodu własnych funkcji io_open(), io_write(), io_read(). Poszczególne kroki zaznaczone są w przykładowym kodzie w załączniku 2. Po napisaniu kodu. Należy skompilować projekt i uruchomić menedżera zasobu. Sprawdź działanie opracowanego menedżera prostym programem wymieniając dane z inną grupą laboratoryjną, która korzysta z innego portu szeregowego. 6

Załącznik 1. Several example functions for serial interface programming /* Initializing serial interface: bound rate, frame parameters */ void SET_RS232(){ unsigned char temp,licz; out8(port1+3, 0x80); /* SET DLAB ON */ out8(port1+0, 0x06); /* SET BAUND RATE - 19200 BPS */ out8(port1+1, 0x00); /* */ out8(port1+3, 0x1B); /* PARITY, 1 STOP BIT, 8 BITS */ out8(port1+2, 0xC7); /* FIFO CONTROL */ out8(port1+4, 0x0B); /* TURN ON DTR, RTS and OUT2 */ licz=16; /* just in case */ do{ licz--; if(!licz) break; while(read_rs232((unsigned char*)&temp)); /* Enabling interrupt source */ void SET_INT_SOURCE(unsigned char INT_SOURCE){ out8(port1+1, INT_SOURCE); /* Disabling interrupt source interrupt mask*/ void CLR_INT_SOURCE(unsigned char INT_SOURCE){ out8(port1+1, INT_SOURCE); /* Sending char */ void SEND_COMMAND(unsigned char COMM_TRANS){ out8(port1, COMM_TRANS); 7

Załącznik 2. /* resmgr.c This module contains the source code for the /dev/example device developed as part of the Neutrino "Writing a Resource Manager" section. If using a shared target, please change EXAMPLE_NAME to something unique for you, so to avoid testing somebody else's code. This module contains all of the functions necessary. */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/iofunc.h> #include <sys/dispatch.h> #include <sys/neutrino.h> #include <sys/resmgr.h> /* default name for this device: /dev/rs232 */ #define EXAMPLE_NAME "/dev/rs232" /* change to something else if sharing a target */ // #define EXAMPLE_NAME "/dev/dagexample" void options (int argc, char *argv[]); 1.Przygotowanie prototypów funkcji, które będą pełniły rolę funkcji POSIX open(), write(), read(). int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra); int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb); int io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb); 2. Zadeklarowanie zmiennych odpowiedzialnych za: strukturę typu dispatch; strukturę funkcji połączenia; strukturę funkcji wejścia-wyjścia; kontekst menedżera zasobów; atrybuty menedżera zasobów; 8

atrybuty funkcji wejścia-wyjścia. /* our connect and I/O functions */ resmgr_connect_funcs_t connect_funcs; resmgr_io_funcs_t io_funcs; /* our dispatch, resource manager and iofunc variables */ dispatch_t *dpp; resmgr_attr_t rattr; dispatch_context_t *ctp; iofunc_attr_t ioattr; char *progname = "rs232"; int optv; // -v for verbose operation main (int argc, char *argv[]){ int pathid; setvbuf (stdout, NULL, _IOLBF, 0); printf ("%s: starting...\n", progname); options (argc, argv); /* allocate and initialize a dispatch structure for use by our main loop */ 3. Alokacja zasobów i inicjalizacja struktury dispatch. dpp = dispatch_create (); if (dpp == NULL) { fprintf (stderr, "%s: couldn't dispatch_create: %s\n", progname, strerror (errno)); exit (1); /*Set up the resource manager attributes structure, we'll use this as a way of passing information to resmgr_attach(). For now, we just use defaults. */ memset (&rattr, 0, sizeof (rattr)); /* using the defaults for rattr */ /* intialize the connect functions and I/O functions tables to their defaults by calling iofunc_func_init(), connect_funcs, and io_funcs variables are already declared. */ 4. Inicjowanie funkcji połączenia i tablicy funkcji wejścia-wyjścia. iofunc_func_init (_RESMGR_CONNECT_NFUNCS, &connect_funcs, _RESMGR_IO_NFUNCS, &io_funcs); /*over-ride the connect_funcs handler for open with our io_open, and over-ride the io_funcs handlers for read and write with our io_read and io_write handlers. */ 9

5. Podmiana standardowych funkcji handlera na własne funkcje. connect_funcs.open = io_open; io_funcs.read = io_read; io_funcs.write = io_write; /* initialize our device description structure*/ 6. Inicjowanie struktury opisującej urządzenie. iofunc_attr_init (&ioattr, S_IFCHR 0666, NULL, NULL); /* call resmgr_attach to register our prefix with the process manager, and also to let it know about our connect and I/O functions. On error, returns -1 and errno is set. */ 7. Powiadomienie menedżera procesów o sposobie połączenia i podpięcie funkcji wejścia-wyjścia. pathid = resmgr_attach (dpp, &rattr, EXAMPLE_NAME,_FTYPE_ANY, 0, &connect_funcs, &io_funcs, &ioattr); if (pathid == -1) { fprintf (stderr, "%s: couldn't attach pathname: %s\n", progname, strerror (errno)); exit (1); 8. Alokacja struktury kontekstowej menedżera. ctp = dispatch_context_alloc (dpp); 9. Pętla główna programu menedżera zasobu. while (1) { if ((ctp = dispatch_block (ctp)) == NULL) { fprintf (stderr, "%s: dispatch_block failed: %s\n", progname, strerror (errno)); exit (1); dispatch_handler (ctp); 10. Przygotowanie kodu własnych funkcji io_open(), io_write(), io_read(). /* * io_open we are called here when the client does an open. It is up to us to establish a context (in this case NULL will do just fine), and return a status code. */ 10

int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra){ if (optv) { printf ("%s: in io_open\n", progname); return (iofunc_open_default (ctp, msg, handle, extra)); /* io_read At this point, the client has called their library "read" function, and expects zero or more bytes. Currently our /dev/example resource manager returns zero bytes to indicate EOF -- no more bytes expected. After our exercises, it will return some data. */ intio_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb){ int status; static char data[] = "hello"; int nb; if (optv) { printf ("%s: in io_read\n", progname); if ((status = iofunc_read_verify(ctp, msg, ocb, NULL))!= EOK) { if (optv) printf("read failed because of error %d\n", status ); return (status); // No special xtypes if ((msg->i.xtype & _IO_XTYPE_MASK)!= _IO_XTYPE_NONE) { return(enosys); nb = strlen(data ); nb = min( nb, msg->i.nbytes ); _IO_SET_READ_NBYTES (ctp, nb); SETIOV( ctp->iov, data, nb ); if (nb > 0) ocb->attr->flags = IOFUNC_ATTR_ATIME; return (_RESMGR_NPARTS (1)); 11

/* * io_write * At this point, the client has called their library "write" function, and expects that our resource manager will write the number of bytes that they have specified to some device. Currently, for /dev/example, all of the clients writes always work -- they just go into Deep Outer Space.*/ int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb){ int status; int nb; if (optv) { printf ("%s: in io_write, of %d bytes\n", progname, msg->i.nbytes); if ((status = iofunc_write_verify(ctp, msg, ocb, NULL))!= EOK) return (status); // No special xtypes if ((msg->i.xtype & _IO_XTYPE_MASK)!= _IO_XTYPE_NONE) { return(enosys); if( msg->i.nbytes == ctp->info.msglen - (ctp->offset + sizeof(*msg) )){ /* have all the data */ char *buf; buf = (char *)(msg+1); #if 0 #else else { nb = write( STDOUT_FILENO, buf, msg->i.nbytes ); // fd 1 is stdout if( -1 == nb ) return errno; char *buf; buf = malloc( msg->i.nbytes ); if (NULL == buf ) return ENOMEM; nb = resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(*msg)); nb = write(1, buf, nb ); // fd 1 is stdout free(buf); if( -1 == nb ) return errno; char buf[1000]; // my hardware buffer int count, bytes; count = 0; 12

while ( count < msg->i.nbytes ){ bytes = resmgr_msgread( ctp, buf, 1000, count + sizeof(*msg )); if( bytes == -1 ) return errno; bytes = write( 1, buf, bytes ); // fd 1 is standard out if( bytes == -1 ){ if (!count ) return errno; else break; count += bytes; nb = count; #endif _IO_SET_WRITE_NBYTES (ctp, nb); if (msg->i.nbytes > 0) ocb->attr->flags = IOFUNC_ATTR_MTIME IOFUNC_ATTR_CTIME; return (_RESMGR_NPARTS (0)); /* options This routine handles the command line options. For our simple /dev/example, we support: -v verbose operation */ Void options (int argc, char *argv[]){ int opt; optv = 0; while ((opt = getopt (argc, argv, "v"))!= -1) { switch (opt) { case 'v': optv++; break; 13

Załącznik 3. /*intsimple.c This module demonstrates will contain code for handling an interrupt. To test is, simply run it. Note that you may have to do something to cause the interrupts to be generated (e.g. press a key if handling the keyboard interrupt). */ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/neutrino.h> #include <sys/syspage.h> char *progname = "intsimple"; struct sigevent int_event; // the event to wake up the thread const struct sigevent *hdlr( void *blah, int id ){ static int count = 0; if (++count > 1500 ){ count = 0; return &int_event; return NULL; main (int argc, char **argv){ int id; setvbuf (stdout, NULL, _IOLBF, 0); printf ("%s: starting...\n", progname); // request I/O privity ThreadCtl(_NTO_TCTL_IO, 0 ); /* set up an event for the handler or the kernel to use to wake up this thread. Use whatever type of event and event handling you want */ SIGEV_INTR_INIT( &int_event ); // either register an interrupt handler or the event id = InterruptAttach(0, hdlr, NULL, 0, _NTO_INTR_FLAGS_TRK_MSK ); 14

while (1) { // block here waiting for the event InterruptWait(0, NULL ); // if using a high frequency interrupt, don't print every interrupt printf ("%s: we got an event after 1500 timer ticks and unblocked\n", progname); 15