rs232 linux win32 cz4


K U R S
Programowanie portu szeregowego
w systemach operacyjnych Linux
i Windows, część 4
istotne jest jej typowe wykorzysta- Ważną rolę pełni funkcja Setup-
Umiejętność programowej obsługi
nie, pozwalające na otworzenie por- Comm() służąca do ustalenia rozmiaru
interfejsu RS232 od strony
tu do zapisu i odczytu, które przed- buforów: wejściowego i wyjściowego.
komputera PC jest dziś istotnym
stawiono na list. 13. Jest ona określona następująco:
elementem elektronicznego
BOOL SetupComm(
HANDLE hCommDev,
rzemiosła. W niniejszym
Konfiguracja portu
DWORD dwInQueue,
DWORD dwOutQueue
kursie piszemy jak w praktyce Po otwarciu, port musi zostać
);
skonfigurowany. Jego konfiguracja
oprogramować port szeregowy
odbywa się podobnie do modyfikacji Argumenty dwInQueue i dwOutQu-
w środowiskach Linux i Windows.
struktury termios w systemie Linux. eue zawierają rozmiary buforów wej-
Wiele miejsca poświęcamy
W systemie Windows modyfikowana ściowego i wyjściowego.
pisaniu przenośnych aplikacji
jest specjalna struktura DCB. Sche- Przykład konfiguracji portu szere-
GUI, które korzystają z interfejsu
mat konfiguracji polega na pobra- gowego w systemie Windows przed-
niu aktualnej wartości tej struktury stawiono na list. 14. Taka konfigura-
szeregowego i zachowują
za pomocą funkcji GetCommState(), cja pozwala na pracę z ramką typu
się tak samo w systemach
jej zmodyfikowaniu oraz zapisaniu 8N1 przy wyłączonej sprzętowej kon-
Windows jak i Linux. Wszystkie
nowej wartości za pomocą funk- troli przepływu i szybkości transmisji
omawiane zagadnienia poparte
cji SetCommState(). Prototypy tych 19200 bodów.
są szczegółowo opisanymi
funkcji są określone następująco:
BOOL GetCommState(
praktycznymi przykładami. Czytanie z portu
HANDLE hCommDev,
Czytanie z bufora wejściowego
LPDCB lpDCB
);
Po dłuższej przerwie wznawiamy portu szeregowego odbywa się za
kurs poświęcony programowaniu por- BOOL SetCommState( pomocą funkcji Win32 API określo-
HANDLE hCommDev,
tu szeregowego w systemach opera- nej następująco:
LPDCB lpDCB
BOOL ReadFile(
);
cyjnych Linux i Windows. W kolejnej
HANDLE hCommDev,
części poznamy sposób obsługi łącza Uchwyt hCommDev wskazuje na
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
RS232 w systemie Windows, oraz otwarty port szeregowy, zaś wskaz-
LPDWORD lpNumberOfBytesRead,
stworzymy przenośną klasę CCommIn- nik lpDCB wskazuje na strukturę LPOVERLAPPED lpOverlapped
);
terface, służącą do obsługi tego inter- DCB, do której mają zostać skopio-
fejsu w systemach Linux i Windows. wane dane o ustawie-
niach portu, lub z której
List. 13. Otwarcie portu do zapisu i odczytu
Obsługa łącza RS232 dane mają być pobrane hCommDev = CreateFile(lpFileName, GENERIC_READ |
GENERIC_WRITE, 0, NULL,
w systemie Windows w celu modyfikacji tych
OPEN_EXISTING, 0, NULL);
Sposoby obsługi portu RS232 są ustawień.
w dużej mierze podobne zarówno
w systemie Windows, jak i w sys- List. 14. Przykładowa konfiguracja portu szeregowego (ramka 8N1, 19200
temie Linux. Pewną różnicę stano- bodów)
if (hCommDev != INVALID_HANDLE_VALUE)
wi brak plików urządzeń systemie
{
dcb.DCBlength = sizeof(dcb);
Windows. Otwarcie portu polega
if(!GetCommState(hCommDev, &dcb))
na tymczasowym stworzeniu od-
return false;
dcb.BaudRate = 19200;
powiedniego pliku, zaś pózniejsze
//transmission parameters
jego używanie sprowadza się do
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
zapisywania i odczytywania danych
dcb.ByteSize = 8;
do/z utworzonego pliku. Podobnie //DCB flags
dcb.fParity = FALSE;
jest realizowana komunikacja z in-
dcb.fDtrControl = DTR_CONTROL_DISABLE;
//DTR line dislabled
nymi urządzeniami zewnętrznymi.
dcb.fRtsControl = RTS_CONTROL_DISABLE;
//RTS line disabled
dcb.fOutxCtsFlow = FALSE;
Otwieranie portu
dcb.fOutxDsrFlow = FALSE;
Otwieranie portu szeregowego od- dcb.fDsrSensitivity = FALSE;
dcb.fAbortOnError = FALSE;
bywa się za pomocą funkcji Win32
dcb.fOutX = FALSE;
API CreateFile(), która tworzy plik dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
związany z tym portem. Funkcja ta
dcb.fNull = FALSE;
if(!SetCommState(hCommDev,&dcb))
przyjmuje 7 parametrów i zapewnia
return false;
różnorakie opcje związane z otwie-
if(!SetupComm(hCommDev, cbInQueue, cbOutQueue))
return false;
raniem plików. Dla zagadnień zwią-
}
zanych z obsługą portu szeregowego
Elektronika Praktyczna 5/2007
89
K U R S
HANDLE hCommDev,
tu szeregowego (funkcja jednocze-
List. 15. Dyrektywy kompilacji warun- LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
śnie zeruje znacznik błędu) oraz
kowej dla biblioteki Qt
LPDWORD lpNumberOfBytesWritten,
#include
LPOVERLAPPED lpOverlapped odczytać stan portu, który jest
//...
);
#ifdef Q_WS_WIN umieszczany w specjalnej struktu-
//Code compiled on Windows OS
Uchwyt hCommDev wskazuje na rze COMSTAT, dostępnej poprzez
#endif
#ifdef Q_WS_X11 używany port szeregowy. Argument wskaznik lpStat. Jednym z pól tej
//Code compiled on Linux OS
lpBuffer jest wskaznikiem na po- struktury jest pole cbInQue za-
#endif
czątek obszaru pamięci, w którym wierające liczbę nie odczytanych
są umieszczone dane przeznaczone bajtów, jakie oczekują w buforze
Uchwyt hCommDev wskazuje na do wysłania do portu. Argument wejściowym portu szeregowego. Ar-
używany port szeregowy  jest to nNumberOfBytesToWrite specyfikuje gument hCommDev jest uchwytem
uchwyt zwracany podczas otwarcia ile bajtów ma być wysłanych do do używanego portu.
portu przez funkcję CreateFile(). Ar- portu, zaś argument lpNumberO-
gument lpBuffer jest wskaznikiem na fBytesWritten wskazuje na zmienną, Zamykanie portu
początek obszaru pamięci, w którym w której umieszczana jest liczba Zamykanie portu szeregowego od-
zostaną umieszczone dane odczyta- faktycznie wysłanych bajtów. Licz- bywa się za pomocą funkcji Win32
ne z portu. Argument nNumberOfBy- by te mogą się różnić, gdy nastąpił API określonej następująco:
BOOL CloseHandle(HANDLE *hCommDev);
tesToRead specyfikuje ile bajtów ma błąd zapisu. Ostatni argument funk-
być odczytanych z portu, zaś argu- cji WriteFile()  lpOverlapped  nie Funkcja zamyka port, a ściślej 
ment lpNumberOfBytesRead wskazuje jest w tym przypadku wykorzysty- związany z nim plik utworzony za
na zmienną, w której jest umiesz- wany i jego wartość podczas jej pomocą funkcji CreateFile(), wska-
czana liczba faktycznie odczytanych wywołania wynosi NULL. Funkcja zywany przez uchwyt hCommDev.
bajtów. Liczby te mogą się różnić WriteFile() zwraca wartość logiczną
wtedy, gdy w buforze wejściowym true, gdy zapis przebiegł prawidło- Klasa CCommInterface
znajduje się mniej bajtów niż poda- wo, zaś false, gdy wystąpił błąd. Klasa CCommInterface posiada
no w zmiennej nNumberOfBytesToRe- uniwersalne metody implementują-
ad, lub gdy nastąpił błąd odczytu. Sprawdzenie liczby bajtów ce podstawowe operacje na porcie
Ostatni argument funkcji ReadFile() oczekujących na odczyt szeregowym, a więc: otwarcie por-
 lpOverlapped  nie jest w tym w buforze wejściowym tu, zamknięcie portu, zapis ciągu
przypadku wykorzystywany i jego Sprawdzenie ile nie odczyta- bajtów, odczyt ciągu bajtów oraz
wartość podczas jej wywołania wy- nych bajtów oczekuje w buforze sprawdzenie liczby nie odczytanych
nosi NULL. Funkcja ReadFile() zwra- wejściowym odbywa się za pomo- bajtów znajdujących się w buforze
ca wartość logiczną true, gdy odczyt cą funkcji Win32 API określonej wejściowym. Oto lista prototypów
przebiegł prawidłowo, zaś false, gdy następująco: publicznych metod tej klasy:
BOOL ClearCommError( bool Open(string CommID, unsigned
wystąpił błąd.
HANDLE hCommDev, long Baud);
LPDWORD lpErrors,
LPCOMSTAT lpStat bool Close(void);
Pisanie do portu
);
Wysyłanie danych do bufora
unsigned long Write(const
void *Buffer, unsigned long
wyjściowego portu szeregowego od- Wywołanie tej funkcji pozwala
NumberOfBytesToWrite);
bywa się za pomocą funkcji Win32 poznać kod ostatniego błędu (wska-
bool Read(void *Buffer, unsigned
API określonej następująco: zywany przez argument lpErrors),
long *lpNumberOfBytesRead, unsigned
BOOL WriteFile(
jaki pojawił się podczas pracy por- long NumberOfBytesToRead);
List. 16. Plik nagłówkowy klasy CCommInterface
#ifndef CommInterfaceH
#define CommInterfaceH
#include
#include
using namespace std;
//---------------------------------------------------------------------------
class CCommInterface
{
private:
const char *lpFileName;
unsigned long BaudRate;
unsigned long cbInQueue;
unsigned long cbOutQueue;
#ifdef Q_WS_WIN
void *hCommDev;
#endif
#ifdef Q_WS_X11
int fd;
#endif
protected:
public:
CCommInterface();
bool Open(string CommID, unsigned long Baud);
void Close(void);
unsigned long Write(const void* Buffer, unsigned long NumberOfBytesToWrite);
bool Read(void * Buffer, unsigned long * lpNumberOfBytesRead, unsigned long NumberOfBytesToRead);
void CheckCommInput(unsigned long * lpErrors, unsigned long * lpInQue);
};
//---------------------------------------------------------------------------
#endif
Elektronika Praktyczna 5/2007
90
K U R S
fragmenty właściwe dla systemu W celu przekazania nazwy por-
bool CheckCommInput(unsigned long
*lpErrors, unsigned long *lpInQue);
Linux, gdy kompilacja będzie doko- tu ( COM1 ,  COM2 ) do funkcji
Nazwy poszczególnych argumen- nywana w systemie Linux. Dyrekty- Open() wykorzystano uniwersalny
tów jednoznacznie wskazują na ich wy kompilacji warunkowej opierają typ string z biblioteki STL (Stan-
znaczenie, nie ma więc potrzeby się na predefiniowanych stałych, dard Template Library). Dzięki
szczegółowego wyjaśniania roli każ- charakterystycznych dla używane- temu istnieje pewność co do prze-
dego z nich. Funkcja Write() zwra- go kompilatora czy biblioteki. Już kazywanych danych tekstowych
ca liczbę faktycznie zapisanych teraz zdradzę, że przykłady aplika- niezależnie od platformy, na której
bajtów (w przypadku błędu zwra- cji okienkowych omówione w kolej- dokonywana jest kompilacja. Bi-
ca 0). Funkcja Open() jako jedyne nych częściach kursu będą stworzo- blioteka ta jest przy tym tak bar-
argumenty przyjmuje identyfikator ne za pomocą rewelacyjnej i rozwo- dzo popularna, że jej implementa-
portu i szybkość transmisji  port jowej biblioteki Qt firmy Trolltech. cja dostarczana jest wraz z każdym
jest otwierany do pracy z ramką Dyrektywy kompilacji warunkowej szanującym się kompilatorem. Plik
8N1 przy wyłączonej sprzętowej charakterystyczne dla tej bibliote- nagłówkowy klasy CCommInterface
kontroli przepływu. Klasę tę moż- ki przedstawiono na list. 15. Stałe przedstawiono na list. 16.
na dowolnie zmodyfikować we- Q_WS_WIN i Q_WS_X11 są zde-
dług potrzeb, w celu zapewnienia finiowane w pliku QtGlobal. Plik Podsumowanie
innych ustawień portu, jeśli takie ten musi być wcześniej włączo- Wiemy już jak obsłużyć port
będą potrzebne. ny do kodu aplikacji (oczywiście, RS232 w systemach Linux i Win-
Implementacja metod klasy niekoniecznie w tym samym pliku dows, dysponujemy także uniwer-
CCommInterface polegała na zebra- zródłowym, w którym wykorzystuje salną klasą C++, która to umoż-
niu wiadomości dotyczących ob- się zdefiniowane w nim stałe). Dla liwia. Następne części kursu będą
sługi portu w obu systemach ope- innych bibliotek i kompilatorów ist- poświęcone tworzeniu prostych
racyjnych i połączeniu ich poprzez nieją inne stałe określające system aplikacji GUI wykorzystujących kla-
dyrektywy kompilacji warunkowej. operacyjny. Adaptacja klasy CCom- sę CCommInterface.
Dzięki temu, fragmenty właściwe mInterface do pracy z nimi polega Arkadiusz Antoniak, EP
dla systemu Windows będą kom- tylko i wyłącznie na zamianie tych arkadiusz.antoniak@ep.com.pl
pilowane, gdy kompilacja będzie stałych. Reszta kodu zródłowego www.antoniak.ep.com.pl
dokonywana w tym systemie, zaś pozostaje bez zmian.
1/8L
180x93 mm
Elektronika Praktyczna 5/2007
91


Wyszukiwarka

Podobne podstrony:
rs232 linux win32 cz2
rs232 linux win32 cz6
rs232 linux win32 cz1
rs232 linux win32 cz8
rs232 linux win32 cz7
rs232 linux win32 cz3
rs232 linux win32 cz5
STM32 Butterfly RS232
Linux 2000 DVB T Experiments
linux kobiety
compilar linux
Linux IPCHAINS HOWTO Appendix Differences between ipchains and ipfwadm
Pierwsze kroki w cyfrówce cz4
systemy operacyjne cw linux apache mysql
Linux materialy
Linux System Plików
Asembler linux
Nauka słówek i memoryzacja na Puppy Linux

więcej podobnych podstron