Urządzenia peryferyjne RS-232 oprogramowanie pod WINDOWS Wykład 3
WINDOWS - struktura System Processes Server Processes Environment Subsystem User Applications RegDB Subsystem DLLs Executive Graphics (Win32k) Device Drivers. Kernel Hardware Abstraction Layer (HAL) User mode Kernel mode 2
Windows 2000/XP Architektura System Processes Services Subsystems Applications File server Logon Session manager Other Other Replicator RPC Alerter Event logger Win32 LPC LPC LPC LPC Windows 2000 System I/O manager File systems Security monitor Executive Power Management Memory Management Object management/executive run time Process support Device drivers Hardware abstraction layer Kernel Platform interface I/O devices DMA control Bus mapping Clocks/ timers Cache control Interrupt dispatch Privileged architecture 3
Wywołanei Win32 API Environment Subsystem User Applications Subsystem DLLs NTDLL.DLL LPC Executive Device Drivers. Kernel Graphics (Win32k) Hardware Abstraction Layer (HAL) 4
C# and.net programming Use inpout32.dll - Lake View Research (www.lvr.com). Provides direct read and write of the I/O [DllImport("inpout32.dll", EntryPoint = "Out32")] public static extern void Output(int adress, int value); [DllImport("inpout32.dll", EntryPoint = "Inp32")] public static extern int Input(int address); Use: Output(port, data); temp = Input(port); // writes data to port // read port, puts data in temp 5
Sterowniki DOS or Win16 application Virtual device driver VDM Win32 API DLLs Win32 application User mode Win32 subsystem GDI (graphics engine) Display driver Printer driver Spooler Kernel mode Windows NT Executive services Executive and kernel Video port driver DOS application dedicated service (KDD) Kernel device driver Video miniport KDD Parallel port KDD 6
Odwołanie się do sterownika call ReadFile application ReadFile: call NtReadFile return to caller Kernel32.DLL user mode NtReadFile: int 0x2E return to caller NtDll.DLL kernel mode call NtReadFile dismiss int 0x2E NtOskrnl.EXE check parameters call driver block, or not return to caller NtOskrnl.EXE initiate I/O return to caller driver.sys 7
Praca ze sterwonikami pod Windows Pobiera od systemu tzw. uchwyt urządzenia zwracany przez funkcję CreateFile. Jako parametr podawana jest nazwa urządzenia. Przy pomocy specjalistycznych funkcji API dotyczących danego urządzenia program steruje urządzeniem, lub używa to tego celu funkcji IOCTL, lub nowszej DeviceIOCtl. W systemie Windows wszystkie porty wejściawyjścia są reprezentowane jako pliki Zatem używamy: CreateFile, CloseHandle, ReadFile, ReadFileEx, WriteFile i WriteFileEx 8
Współpraca z portem szerogowym Pobranie uchwytu urządzenia portu szeregowego Zmiana konfiguracji portu Czytanie i wysyłanie danych poprzez port Kontrolowanie reakcji programu na wystąpienie określonych zdarzeń portu 9
Otwieranie urządzenia HANDLE CreateFile(LPCTSTR lpfilename, DWORD dwdesiredaccess, DWORD dwsharemode, LPSECURITY_ATTRIBUTES lpsecurityattributes, HANDLE htemplatefile) lpfilename wskaźnik do nazwy, COMx, \\\\.\\COMx, gdy x>9). dwdesiredaccess flagi trybu dostępu do pliku: 0 - nie możliwy zapis ani odczyt, jednakże program może wysyłać sygnały sterujące GENERIC_READ obiekt jest otwierany w trybie odczytu i będzie możliwy tylko odczyt GENERIC_WRITE obiekt jest otwierany w trybie zapisu i będzie możliwy tylko zapis Kombinacja GENERIC_READ i GENERIC_WRITE otwarcie obiektu w trybie odczyt-zapis. 10
Otwieranie urządzenia dwsharemode flagi dotyczące współużytkowania, 0 lpsecurityattributes wskaźnik do struktury określającej prawa bezpieczeństwa, NULL dwcreationdistribution zbiór flag definiujących sposób otwarcia pliku. W przypadku portu szeregowego jest to zawsze OPEN_EXISTING dwflagsandattributes FILE_FLAG_OVERLAPPED i FILE_FLAG_NO_BUFFERING htemplatefile NULL Zamykanie: BOOL CloseHandle(HANDLE File); 11
Otwieranie i zamykanie urządzenia HANDLE hcom = CreateFile( COM1, GENERIC_WRITE GENERIC_READ,0,NULL, FILE_FLAG_OVERLAPPED,NULL); if (hcom!=invalid_handle_value){ CloseHandle(hCOM); } else cout << Błąd otwarcia portu << endl 12
Ustalanie wielkości bufora portu BOOL SetupComm(HANDLE hfile, DWORD dwinqueue, DWORD dwoutqueue); hfile uchwyt do portu zwrócony przez CreateFile dwinqueue wielkość bufora na przychodzące z zewnątrz dane w bajtach dwoutqueue - wielkość bufora na dane do wysłania w bajtach If (!SetupComm(hCom,2000,2000)) cout << Błąd bufora << endl; 13
Ustalanie parametrów transmisji DCB (Device Control Block). BOOL BuildCommDCB(LPCTSTR lpdef, LPDCB lpdcb); DCB dcb; ZeroMemory(&dcb, sizeof(dcb); char Buffer[100]; strcpy(buffer, baud=9600 parity=n data=8 stop=1 ); BuildCommDCB((char*)&buffer,&dcb); BOOL GetCommState(HANDLE hfile, LPDCB lpdbc); BOOL SetCommState(HANDLE hfile, LPDCB lpdbc); 14
Ustalanie parametrów transmisji if(getcommstate(hcom,&dcb)){ dcb.baudrate = CBR_1200; dcb.bytesize=7; dcb.parity=2; dcb.stopbits=0; SetCommState(hCom,&dcb); } 15
Przesyłanie danych BOOL ReadFile(HANDLE hfile, LPVOID lpbuffer, DWORD nnumberofbytestoread, LPDWORD lpnumberofbytesread, LPOVERLAPPED lpoverlapped) BOOL WriteFile(HANDLE hfile, LPVOID lpbuffer, DWORD nnumberofbytestowrite, LPDWORD lpnumberofbyteswritten, LPOVERLAPPED lpoverlapped) lpoverlapped wskaźnik na strukturę o nazwie OVERLAPPED w której przechowywane są dane o łączności asynchronicznej 16
Monitorowanie działania ClearCommError(HANDLE hfile, LPDWORD lperror, LPCOMSTATE lpcomstate); Funkcja ta zapala nam flage lperror w momencie wystąpienia błędu, oraz wypełnia specjalistyczną strukturę COMSTATE, w której znajdują się aktualne dane dotyczące stanu portu szeregowego. 17
Ustawienie zdarzenia DWORD dwstoredflags; dwstoredflags = EV_BREAK EV_CTS EV_DSR EV_ERR EV_RING \ EV_RLSD EV_RXCHAR EV_RXFLAG EV_TXEMPTY ; SetCommMask(hComm, dwstoredflags)) 18
Czekanie na zdarzenie BOOL WaitCommEvent(HANDLE hfile, LPDWORD lpevtmask, LPOVERLAPPED lpoverlapped) EV_BREAK zapalana w momencie wystąpienia sygnału break EV_CTS zapalana w momencie zmiany wartości sygnału CTS EV_DSR - zapalana w momencie zmiany wartości sygnału DSR EV_ERR zapalana przy wystąpieniu błędu transmisji EV_EVENT1, EV_EVENT2 pojawia się w momencie specyficznym dla danego sterownika EV_PERR błąd drukarki EV_RING zapalenie sygnału RING EV_RLSD flaga pojawia się w momencie, gdy urządzenie rozpoczęło transmisję EV_RX80FULL zapełnienie bufora w 80% EV_RXCHAR- odebranie znaku i umieszczenie go w buforze EV_RXFLAG odebranie znaku zgodnego z maską w strukturze DCB, zastosowanie wykrywanie znaku sterującego 19 EV_TXEMPTY zakończenie wysyłania danych z bufora wyjściowego
Przykład funkcji czytającej COMSTAT Stat; DWORD Errors; DWORD nnumberofbytestoread; ClearCommError(hCommDev, &Errors, &Stat); if (Stat.cbInQue > 0) { if (Stat.cbInQue > Buf_Size) nnumberofbytestoread = Buf_Size; else nnumberofbytestoread = Stat.cbInQue; ReadFile(hCommDev, lpbuffer, nnumberofbytestoread, lpnumberofbytesread, NULL); } 20
Inne funkcje BOOL FlushFileBuffers(HANDLE hcommdev); BOOL PurgeComm(HANDLE hcommdev, DWORD fdwaction); PURGE_TXABORT wszelkie operacje zapisu (transmisji) do portu identyfikowanego przez hcommdev zostaną natychmiast przerwane, nawet jeżeli nie zostały zakończone. PURGE_RXABORT wszelkie operacje odczytu z portu zostaną natychmiast przerwane, nawet jeżeli nie zostały zakończone. PURGE_TXCLEAR bufor wyjściowy zostanie wyczyszczony; nastąpi skasowanie zawartości. PURGE_RXCLEAR bufor wejściowy zostanie wyczyszczony, nastąpi skasowanie zawartości. 21
C# SerialPort Properties / Events
C# Needs: using System.IO.Ports; Set properties serialport1.baudrate = 9600; serialport1.databits = 8; serialport1.parity = (Parity)Enum.Parse(typeof(Parity), "None"); serialport1.stopbits = (StopBits)Enum.Parse(typeof(StopBits), "One"); Open device serialport1.open(); 23
C# and.net programming Hardware 24 Send and receive data serialport1.writeline(textbox1.text); listbox1.items.add(serialport1.readline()); Or use DataReceived event private void serialport1_datareceived (object sender, SerialDataReceivedEventArgs e) { } listbox1.items.add(serialport1.readline()); 24
C# Serial Program