rs232_linux-win32_cz1.pdf

(515 KB) Pobierz
ep_03_089-095_rs232_cz1.indd
K U R S
Programowanie portu szeregowego
w systemach operacyjnych
Linux i Windows, część 1
Umiejętność programowej obsługi interfejsu
RS232 od strony komputera PC jest
dziś istotnym elementem elektronicznego
rzemiosła. W kolejnych częściach niniejszego
kursu piszemy jak w praktyce oprogramować
port szeregowy w środowiskach Linux
i Windows. Wiele miejsca poświęcamy pisaniu
przenośnych aplikacji GUI, które korzystają
z interfejsu szeregowego i zachowują się tak
samo w systemach Windows jak i Linux.
Wszystkie omawiane zagadnienia poparte
są szczegółowo opisanymi praktycznymi
przykładami.
Popularność Linuksa w ostat-
nich latach wyraźnie wzrosła i wie-
le wskazuje na to, że zjawisko to
będzie się z roku na rok nasilać.
Choć dla nas – elektroników – pod-
stawową platformą pozostaje Win-
dows, to powstaje coraz więcej pro-
gramów narzędziowych, kompilato-
rów dla mikrokontrolerów i innych
programów, które używamy w swo-
jej codziennej praktyce. Jednym
z najznamienitszych przykładów jest
słynny kompilator języka C dla mi-
krokontrolerów AVR (AVRGCC), czy
ARM. Być może w najbliższym cza-
sie Linux nie zawojuje zupełnie na-
szego świata, ale z pewnością sta-
nie się w nim bardziej obecny niż
dziś. Gdy elektronik decyduje się
napisać własne oprogramowanie,
to chyba najistotniejszym zagadnie-
niem z jakim musi się uporać sta-
je się oprogramowanie portów kom-
putera PC. W tym kursie bierzemy
pod lupę port szeregowy i patrzy-
my jak obsługuje się go w Linuksie
i pod Windows.
Cel niniejszego kursu jest dwo-
jaki. Po pierwsze, ma on na prak-
tycznych przykładach pokazać jak
można oprogramować port szere-
gowy w Linuksie oraz – niejako
przy okazji – w systemie Windows.
Nie twierdzę przy tym, że omó-
wię wszystkie szczegóły i szczególiki
związane z oprogramowaniem RS232
w każdym z tych systemów. Poka-
żę natomiast w praktyce jak wyko-
rzystać interfejs szeregowy kompu-
tera PC w najbardziej typowych za-
stosowaniach. Drugim istotnym za-
gadnieniem jakie przedstawię jest
pisanie aplikacji przenośnych, któ-
re korzystają z obsługi RS232 i po-
siadają graficzny interfejs użytkow-
nika ( GUI – Graphical User Interfa-
ce ). Jest to zagadnienie, które jest
obecnie „na topie” wśród zagad-
nień związanych z tematyką tworze-
nia oprogramowania. Istnieje wyraź-
ny trend, aby pisane aplikacje po-
siadały swoje wersje nie tylko dla
Windows, ale także dla Linuksa
i innych systemów operacyjnych. Po-
winny przy tym, w miarę możliwo-
ści, wyglądać i zachowywać się tak
samo pracując pod kontrolą każdego
z nich. Problem ten omówię w dal-
szych częściach kursu. Pisząc o nim
zachowam kierunek migracji z Win-
dows na Linuksa, gdyż właśnie
Windows pozostaje platformą „bazo-
wą”, w której większość z nas poru-
sza się znacznie sprawniej niż w Li-
nuksie. Innymi słowy, będziemy pi-
sać aplikacje GUI pod Windows ale
tak, aby dały się łatwo przenieść
na Linuksa, a potem je przeniesie-
my. Wszystko to będzie zilustrowa-
ne praktycznymi przykładami. Jed-
nym z nich będzie cyfrowy wolto-
mierz odczytywany przez interfejs
RS232C. Dodatkową korzyścią jaką
otrzymają Czytelnicy będzie przykła-
dowa klasa obsługująca RS232 zaim-
plementowana w języku C++, któ-
ra wystąpi w dwóch wersjach: dla
Windows i dla Linuksa. Klasa ta bę-
dzie miała identyczny interfejs dla
obu tych platform, dzięki czemu bę-
dzie ją można stosować w obu sys-
temach bez konieczności dokonywa-
nia jakichkolwiek zmian w programie
głównym (korzystającym z tej kla-
sy). Jej wykorzystanie będzie możli-
we w każdym środowisku programi-
stycznym zawierającym kompilator
C++, niezależnie od tego czy do
tworzenia GUI wykorzystamy MFC,
Qt, VCL/CLX,
dowolny tool-
kit C++, czy
też jakiekolwiek
inne oprogra-
mowanie.
Porty
w Linuksie
Nie jest
przesadą stwier-
dzenie, że w Li-
nuksie wszyst-
ko jest plikiem.
W istocie, nie-
mal wszystkie
„byty” z jakimi
mamy do czy-
nienia powią-
zane są w ten,
czy inny spo-
sób z jakimś pli-
kiem. Nie ina-
czej jest z por-
tami. Wszyst-
Rys. 1. Typowy cykl
pracy portu szere-
gowego (Linux)
Elektronika Praktyczna 3/2006
89
66534604.051.png 66534604.053.png
K U R S
Tab. 1. Pola struktury termios
Pole
Typ
Opis
trzecie 3 litery – prawa pozosta-
łych użytkowników ( o – other );
gdzie:
r – prawo do czytania ( Read );
w – prawo do pisania ( Write );
x – prawo do wykonywania
( eXecute ).
W nowo zainstalowanym syste-
mie zwykle jest tak, że właściciel
(w tym przypadku root ) ma pełne
prawa pisania i czytania rw– , zaś
zarówno grupa jak i pozostali użyt-
kownicy nie mają żadnych praw –
nie mogą ani pisać do portu, ani
z niego czytać. Sytuacja taka unie-
możliwia oczywiście uruchomienie
jakichkolwiek aplikacji korzystają-
cych z portu szeregowego w try-
bie zwykłego użytkownika. Aby to
zmienić, należy dodać im prawa
pisania i czytania. W tym celu lo-
c_cflag unsigned int
Opcje sterowania
c_lflag unsigned int
Opcje lokalne (dyscyplina linii)
c_iflag unsigned int
Opcje wejścia
c_oflag unsigned int
Opcje wyjścia
c_cc
unsigned char*
Tablica znaków specjalnych
c_ispeed unsigned int
Prędkość wejściowa
c_ospeed unsigned int
Prędkość wyjściowa
kie urządzenia zewnętrzne, do któ-
rych zaliczają się porty komputera,
reprezentowane są przez specjalne
pliki urządzeń znajdujące się w ka-
talogu /dev . Plików tych jest bardzo
dużo, ale nas interesuje tylko kilka
z nich. Przykładowo – porty rów-
noległe (o ile jest ich więcej niż
jeden, co się właściwie nie zda-
rza) reprezentowane są przez pliki
/dev/lp0 , /dev/lp1 itd.. Jeśli posiada-
my tylko jeden port równoległy, to
związany jest z nim plik /dev/lp0
(oczywiście przyporządkowanie to
może być zmienione). W przypadku
portów szeregowych domyślne przy-
porządkowanie jest następujące:
Oznacza to, że dostęp do reprezen-
towanego przez ten plik urządzenia
odbywa się „znak po znaku”, czy-
li „bajt po bajcie”. Następne 9 zna-
ków określa prawa dostępu, co ob-
jaśniono poniżej:
pierwsze 3 litery – prawa wła-
ściciela pliku ( u – user );
drugie 3 litery – prawa grupy
( g – group );
List. 1. Przykład otwarcia portu ttyS0
//**********************************************************
//
// Port ttyS0 (COM1) opening example
// Returns: 0 when error occured
// 1 when everything OK
//
//**********************************************************
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
COM1 (adres 0x3f8) – plik /dev/
ttyS0
COM2 (adres 0x2f8) – plik /dev/
ttyS1
COM3 (adres 0x3e8) – plik /dev/
ttyS2
COM4 (adres 0x2e8) – plik /dev/
ttyS3
//File descriptor
int fd;
int Open(void)
{
fd=open(„/dev/ttyS0”, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd<0)
{
//Opening error
return 0;
}
else
{
//Here port configuration
//...
}
return 1;
}
W niektórych starszych dystry-
bucjach Linuksa noszą one nazwy
cua0...cua3.
Aby dowiedzieć się o nich wię-
cej, przejdźmy do katalogu /dev
(komenda cd /dev z dowolnej loka-
cji) i wpiszmy ls ttyS0 –l . Komenda
ta pokaże nam podstawowe właści-
wości pliku ttyS0 . Oto przykładowy
wynik jej działania:
List. 2. Ogólny schemat konfiguracji portu szeregowego
//Copy of termios structure
struct termios options;
//Getting the current settings for the port
tcgetattr(fd, &options);
crw–rw–rw– 1 root uucp 4,
64 kwi 14 2001 ttyS0
//Setting baudrate (19200 for example)
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
Spójrzmy na pierwsze pole z le-
wej określające rodzaj pliku i prawa
dostępu do niego. Litera c wskazu-
je, że jest to plik znakowy ( char ).
//Modifying c_cflag by bitwise OR and AND
options.c_cflag &= ...;
options.c_cflag |= ...;
//Modifying c_lflag by bitwise OR and AND
options.c_lflag &= ...;
options.c_lflag |= ...;
Tab. 2. Opcje funkcji tcsetattr
Opcja Opis
TCSANOW Dokonaj zmiany natychmiast
//Modifying c_iflag by bitwise OR and AND
options.c_iflag &= ...;
options.c_iflag |= ...;
//Modifying c_oflag by bitwise OR and AND
options.c_oflag &= ...;
options.c_oflag |= ...;
TCSADRAIN
Dokonaj zmiany po zakończeniu
transmisji danych
TCSAFLUSH
Wyczyść ( flush ) bufory wej-
ściowy i wyjściowy, po czym
dokonaj zmiany
//Setting the new settings for the port immediately
tcsetattr(fd, TCSANOW, &options);
90
Elektronika Praktyczna 3/2006
66534604.054.png 66534604.055.png 66534604.001.png 66534604.002.png 66534604.003.png 66534604.004.png 66534604.005.png 66534604.006.png 66534604.007.png 66534604.008.png 66534604.009.png 66534604.010.png 66534604.011.png 66534604.012.png 66534604.013.png 66534604.014.png 66534604.015.png 66534604.016.png 66534604.017.png 66534604.018.png
K U R S
Tab. 3. Predefiniowane stałe dla
pola c_cflag
Stała Opis
Tab. 4. Predefiniowane stałe dla pola c_lflag
Stała Opis
ISIG Włącz wysyłanie sygnałów SIGINTR, SIGSUSP, SIGDSUSP i SIGQUIT
ICANON Flaga włączona: canonical input
Flaga wyłączona: raw input
XCASE Mapuj wielkie litery na małe (przestarzała)
ECHO Włącz wysyłanie odebranych znaków (echo)
ECHOE Po odebraniu znaku kasowania (erase) wyślij kombinację znaków BS-SP-BS.
ECHOK Wyślij znak NL (0x0A) po odebraniu znaku kasowania wiersza (kill)
ECHONL Odsyłaj znak NL (echo)
NOFLSH Wyłącz czyszczenie bufora wejściowego po przerwaniu lub odebraniu znaku przery-
wającego quit
IEXTEN Włącz rozszerzone funkcje portu (dot. dyscypliny linii)
ECHOCTL Odsyłaj znaki kontrolne (echo) jako kombinację ^znak
ECHOPRT Poprzedź usuwane znaki znakiem \\ (backslash)
ECHOKE Echem znaku kasowania wiersza jest odpowiednia kombinacja znaków SP i BS
Maska bitowa dla bitów określają-
cych prędkość (obecnie używanie
niezalecane)
B0 0 bodów (wyłącz DTR)
B50 50 bodów
B75 75 bodów
B110 110 bodów
B134 134 body
B150 150 bodów
B200 200 bodów
B300 300 bodów
B600 600 bodów
B1200 1200 bodów
B1800 1800 bodów
B2400 2400 bodów
B4800 4800 bodów
B9600 9600 bodów
B19200 19200 bodów
B38400 38400 bodów
B57600 57600 bodów
B76800 76800 bodów
B115200 115200 bodów
EXTA Zewnętrzny zegar taktujący
EXTB Zewnętrzny zegar taktujący
CSIZE Maska bitowa dla bitów określają-
cych liczbę bitów danych
CS5 5 bitów danych
CS6 6 bitów danych
CS7 7 bitów danych
CS8 8 bitów danych
CSTOPB Flaga włączona: 2 bity stopu
Flaga wyłączona: 1 bit stopu
CREAD Włącz odbiornik
PARENB Włącz kontrolę parzystości
Tab. 5. Predefiniowane stałe dla pola c_iflag
Stała Opis
INPCK Włącz kontrolę parzystości
IGNPAR Ignoruj błędy parzystości
PARMRK Zaznaczaj błędy parzystości
ISTRIP Zeruj bit parzystości (po kontroli parzystości)
IXON Włącz programową kontrolę przepływu (wychodzącą)
IXOFF Włącz programową kontrolę przepływu (wchodzącą)
IXANY Dowolny znak (nie tylko VSTART) włącza przepływ danych
IGNBRK Ignoruj znak przerwania
BRKINT Wyślij sygnał SIGINT gdy odebrano znak przerwania
INLCR Mapuj znak NL (0x0A) na CR (0x0D)
IGNCR Ignoruj znak CR
ICRNL Mapuj znak CR na NL
IUCLC Mapuj wielkie litery na małe (jeśli ustawiona flaga IEXTEN w c_lflag)
IMAXBEL Włącz sygnał dźwiękowy (bell) przy przepełnieniu bufora wejściowego
cze wiedzieć, co można z nimi ro-
bić, czyli jakie operacje wykonywa-
ne są na tych plikach w celu reali-
zacji transmisji pomiędzy PC, a do-
łączonym do niego urządzeniem. Na
rys. 1 przedstawiono typowy cykl
pracy portu szeregowego. Wyróż-
niłem na nim cztery główne fazy
pracy oraz związane z nimi słowa
kluczowe – nazwy funkcji, struktur
itp. Fazy te są następujące:
1. Otwarcie portu
Otwarcie portu równoznaczne
jest z otworzeniem pliku ttySx
do pisania i/lub czytania. My
rozważymy jedynie sytuacje,
w których port otwarty jest za-
równo do czytania jak i do pisa-
nia (transmisja dwukierunkowa).
2. Konfiguracja portu
Jest to niezwykle istotna faza
pracy z interfejsem szeregowym.
Tutaj konfigurujemy port tak,
aby spełniał wymagania jakie
nakłada na niego nasza aplika-
cja. Trzeba zaznaczyć, że w Li-
nuksie istnieje ogromna liczba
opcji konfiguracji, aod ich pra-
widłowego wybrania zależy po-
prawność pracy pisanego opro-
gramowania. W tej części kursu
omówię najistotniejsze z nich.
3. Używanie portu (pisanie, czyta-
nie, funkcje specjalne itp.)
W fazie „używania portu” realizu-
je się komunikację PC z urządze-
niem zewnętrznym, czyli proto-
kół komunikacyjny. Program po-
zostaje w tej fazie przez niemal
cały czas działania aplikacji.
4. Zamknięcie portu
Równoznaczne z zamknięciem
pliku ttySx.
PARODD
Flaga włączona: odd parity
Flaga wyłączona: even parity
HUPCL
Wystaw 0 na DTR przy zamknię-
ciu przez ostatni proces
CLOCAL
Linia lokalna – nie można zmienić
aktualnego właściciela portu
CNEW_
RTSCTS
CRTSCTS
Włącz sprzętową kontrolę przepły-
wu (hardware flow control)
gujemy się jako root (poleceniem
su ), po czym będąc w katalogu /dev
wpisujemy:
chmod go+rw ttyS0
Otwieranie portu
Port szeregowy, podobnie jak
każdy inny plik, może być otworzo-
ny za pomocą funkcji open . Przyj-
muje ona dwa argumenty:
– pierwszy argument zawiera peł-
ną ścieżkę dostępu do pliku
portu (w przypadku portu COM1
będzie to /dev/ttyS0 ),
– drugi argument określa opcje
otwierania portu, które można
zmieniać wykorzystując predefi-
niowane maski bitowe.
Wartością zwracaną jest deskryp-
Komenda ta dodaje prawa pi-
sania do portu i czytania z niego
wszystkim użytkownikom. Dopie-
ro teraz można uruchamiać progra-
my używające RS232, także w try-
bie zwykłego użytkownika.
Cykl pracy portu szeregowego
Wiemy już z grubsza jak w sys-
temie plików Linuksa reprezentowa-
ne są porty szeregowe. Trzeba jesz-
Elektronika Praktyczna 3/2006
91
CBAUD
66534604.019.png 66534604.020.png 66534604.021.png 66534604.022.png 66534604.023.png 66534604.024.png 66534604.025.png
K U R S
List. 3. Pobranie liczby bajtów pozo-
stających w buforze wejściowym
//**********************************
//
// Getting number of bytes
// available in inpu queue
//
//**********************************
#include <unistd.h>
#include <termios.h>
Tab. 6. Predefiniowane stałe dla pola c_oflag
Stała Opis
OPOST Przetwarzaj znaki przed wysłaniem
(Sposób przetwarzania określają pozostałe poniższe stałe. Są one ignorowane
gdy flaga OPOST nie jest ustawiona)
OLCUC Mapuj małe litery na wielkie
ONLCR Mapuj znak NL (0x0A) na parę CR-NL (0x0D-0x0A)
OCRNL Mapuj znak CR na znak NL
ONLRET Włączona: znak NL powoduje automatyczny powrót karetki
NLDLY Maska bitowa dla opóźnienia przy przejściu do nowego wiersza
(przestarzałe)
NL0 Brak opóźnienia
NL1 Odczekaj 100 ms po przejściu do nowej linii
CRDLY Maska bitowa dla flag CR0...CR3 – opcji opóźnień przy powrocie karetki
(przestarzałe)
CR0 Brak opóźnienia dla znaku CR
CR1 Opóźnienie po znaku CR zależy od aktualnej pozycji w kolumnie
CR2 Odczekaj 100 ms po wysłaniu znaku CR
CR3 Odczekaj 150 ms po wysłaniu znaku CR
TABDLY Maska bitowa dla flag TAB0...TAB3 – opcji opóźnień po znaku tabulacji
(przestarzałe)
TAB0 Brak opóźnienia
TAB1 Opóźnienie po znaku TAB zależy od aktualnej pozycji w kolumnie
TAB2 Odczekaj 100 ms po wysłaniu znaku TAB
TAB3 Rozszerz znaki tabulacji do znaków spacji (SP)
BSDLY Maska bitowa dla flag BS0...BS3 – opcji opóźnień po znaku backspace (BS)
(przestarzałe)
//File descriptor
int fd;
//Bytes available in input queue
int bytes;
//Get the number of bytes available
ioctl(fd, FIONREAD, &bytes);
tor pliku portu, który później (przy
czytaniu lub pisaniu) służy jako jego
identyfikator. Jeśli otwarcie przebie-
gło pomyślnie deskryptor ma war-
tość dodatnią. W przypadku błędu
otwarcia, którym może być brak od-
powiednich praw dostępu lub uży-
wanie portu przez inną aplikację,
funkcja open zwraca wartość mniej-
szą od 0. Przykład jej użycia znaj-
duje się na list. 1 . Znaczenie wyko-
rzystanych opcji jest następujące:
O_RDWR – otwarcie portu do
czytania i do pisania;
O_NOCTTY – nie ustawienie tej
opcji sprawi, że inne urządzenia
mogą mieć wpływ na pracę otwie-
ranego portu;
O_NDELAY – ustawienie tej fla-
gi oznacza, że program nie reaguje
na stan linii DCD. Nie ustawienie
tej flagi spowoduje, że program bę-
dzie uśpiony dopóki linia DCD nie
osiągnie stanu logicznego 0 ( space ).
W typowych zastosowaniach
otwieranie portu z innymi ustawie-
niami nie ma większego sensu. Nie
będziemy więc szczegółowo analizo-
wać znaczenia innych opcji. Oczy-
wiście, jeśli ktoś miałby potrzebę
skorzystania z nich (i wiedziałby co
robi), może ich użyć.
BS0
Brak opóźnienia
BS1
Odczekaj 50 ms po wysłaniu znaku BS
VTDLY
Maska bitowa dla flag VT0...VT3 – opcji opóźnień po znaku VT
(przestarzałe)
VT0
Brak opóźnienia
VT1
Odczekaj 2 s po wysłaniu znaku BS
FFDLY
Maska bitowa dla flag VT0...VT3 – opcji opóźnień po znaku 0xFF
(przestarzałe)
FF0
Brak opóźnienia
FF1
Odczekaj 2 s po wysłaniu znaku 0xFF
Tab. 7. Tablica znaków specjalnych c_cc (* – patrz opis)
Stała Opis
Kombinacja przycisków
VINTR Przerwanie (interrupt)
CTRL-C
VQUIT Koniec (quit)
CTRL-Z
VERASE Kasuj znak (erase)
Backspace (BS)
VKILL kasuj linię
CTRL-U
VEOF Koniec linii
CTRL-D
VEOL Koniec linii – powrót karetki
CR
Konfiguracjaportu
Gdy port szeregowy jest otwarty
należy go odpowiednio skonfiguro-
wać. Sterownik linuksowy zapewnia
nam ogromną liczbę opcji, z któ-
rych duża część służy do tego, aby
ułatwić używanie RS232 do przesy-
łania danych w sposób zorientowa-
ny liniowo (przydatne na przykład
w komunikacji z drukarkami). Dla
nas takie działanie jest niepożądane
– chcemy mieć pełną kontrolę nad
tym co wysyłamy, a także chcemy
mieć pewność, że to co odczytu-
jemy z bufora wejściowego jest na-
prawdę tym co zostało odebrane łą-
czem szeregowym. Na przykład, nie
VEOL2 Nowa linia
LF
VMIN Minimalna liczba bajtów do odczytania*
-
VSTART Wznów transmisję
CTRL-Q (XON)
VSTOP Wstrzymaj transmisję
CTRL-S (XOFF)
VTIME
Czas oczekiwania na blok danych (wyrażony w dziesiątych
częściach sekundy)*
-
zależy nam na tym, aby sterownik
ignorował znak powrotu karetki CR
(0x0D), gdyż dla nas może to być
istotna dana pomiarowa. Podobnie
nie chcemy, aby mapował małe li-
tery na wielkie i odwrotnie. Kolejną
przyczyną, dla której nie skorzysta-
my z większości opcji jakie zapew-
nia nam Linux jest fakt, że nie są
one dostępne pod Windows i jako
takie tylko przeszkadzałyby w prze-
noszeniu aplikacji okienkowych
z systemu Windows do Linuksa.
Obowiązuje tu oczywiście ta sama
zasada co przy otwieraniu portu –
kto chce może z nich skorzystać.
Konfiguracja portu odbywa się
poprzez modyfikowanie zawartości
pól struktury termios . Jest to struk-
tura zdefiniowana wpliku termios.h
92
Elektronika Praktyczna 3/2006
66534604.026.png 66534604.027.png 66534604.028.png 66534604.029.png 66534604.030.png 66534604.031.png
K U R S
Tab. 8. Wartości parametru cmd funkcji ioctl
Jeśli tego nie zrobimy, to pomi-
mo, że nie włączyliśmy tych opcji
może się zdarzyć, że nasza apli-
kacja zacznie wykazywać takie ce-
chy! Wystarczy, że wcześniej uży-
wana była aplikacja, która je włą-
czyła. Znaczenie stałych użytych
w powyższej instrukcji przedstawię
za chwilę.
Po drugie nie wolno zmieniać
pól struktury termios poprzez bez-
pośrednie przypisanie pewnej war-
tości, na przykład takiej
Funkcja POSIX
(options – struktura termios)
TCGETS Pobranie aktualnych ustawień portu tcgetattr
TCSETS Ustaw nowe ustawienia portu natychmiast tcsetattr(fd, TCSANOW, &options)
TCSETSF
Wyczyść (flush) bufory wejściowy i wyjścio-
wy po czym ustaw nowe ustawienia portu
tcsetattr(fd, TCSAFLUSH,
&options)
TCSETSW
Poczekaj na opróżnienie buforów wejściowego
i wyjściowego po czym ustaw nowe ustawie-
nia portu
tcsetattr(fd, TCSADRAIN, &options)
TCSBRK Wystaw sygnał break na zadany czas tcsendbreak, tcdrain
TCXONC Konfiguracja programowej kontroli przepływu tcflow
TCFLSH
Przepłukanie bufora wejściowego i/lub wyj-
ściowego
tcflush
options.c_iflag = 0;
TIOCMGET Pobranie stanu linii sterujących
-
TIOCMSET Zmiana stanu linii sterujących
-
Postępowanie takie może być
bardzo szkodliwe, gdyż inne apli-
kacje mogą korzystać z pewnych
opcji, których my nie powinniśmy
zmieniać.
Gdy już dokonamy wszystkich
niezbędnych zmian w zmiennej
options należy wpisać je do wła-
ściwej struktury termios w systemie.
Służy do tego funkcja tcsetattr , któ-
ra oprócz deskryptora pliku i adresu
zmodyfikowanej kopii termios przyj-
muje dodatkowy argument określa-
jący sposób jej działania. Możliwe
wartości tego argumentu przedsta-
wiono w tab. 2 .
Zauważmy, że ustawienie prędko-
ści transmisji (co ciekawe – osobno
dla nadajnika i odbiornika) nie od-
bywa się poprzez odpowiednie ope-
racje logiczne OR, lecz za pomocą
funkcji cfsetispeed i cfsetospeed . Ro-
bimy tak dlatego, że starsze wer-
sje systemów umieszczały informa-
cję o prędkości w polu c_cflag (patrz
następny punkt), zaś nowe umiesz-
czają ją w polach c_ispeed i c_ospe-
ed struktury termios . Użycie cfse-
tispeed i cfsetospeed uwalnia nas od
zastanawiania się nad tym, gdzie
w istocie informacje te się znajdują.
FIONREAD
Pobranie liczby bajtów znajdujących się w
buforze wejściowym (jeszcze nie odczytanych)
-
i odpowiada za przechowywanie in-
formacji konfiguracyjnych związa-
nych z urządzeniami terminalowy-
mi. Zawiera ona kilkadziesiąt flag,
które można modyfikować za po-
mocą specjalnych masek bitowych
i w ten sposób zmieniać ustawienia
portu szeregowego. Możemy decydo-
wać czy i jak dane wejściowe i wyj-
ściowe mają być przetwarzane, włą-
czać i wyłączać odbiornik i tak da-
lej. Struktura termios zawiera 7 pól
wymienionych w tab. 1 .
Ogólny schemat modyfikacji ter-
mios przedstawiony jest na list. 2 .
Modyfikacja polega na skopiowaniu
zawartości tej struktury do pewnej
zmiennej, stosownej modyfikacji tej
zmiennej, a następnie na skopiowa-
niu jej zawartości z powrotem do
struktury termios . W pierwszej kolej-
ności deklarujemy zmienną options
typu struct termios . Następnie po-
bieramy aktualne ustawienia por-
tu za pomocą funkcji tcgetattr , któ-
ra oprócz adresu zmiennej options
przyjmuje deskryptor pliku portu
zwrócony wcześniej przez funkcję
open . Teraz zmienna options zawie-
ra kopię aktualnej struktury termios
systemu. Możemy dowolnie mody-
fikować tę kopię (jej pola) poprzez
bitowe operacje OR i AND z odpo-
wiednimi stałymi charakterystyczny-
mi dla poszczególnych pól struk-
tury termios (omówię je za chwi-
lę). Wykonanie operacji OR ze sta-
łą oznacza włączenie odpowiadają-
cej jej opcji, zaś wykonanie operacji
AND z negacją tej stałej – wyłącze-
nie. Należy przy tym pamiętać, że:
Po pierwsze – nie wystarczy
nie włączyć jakiejś opcji przez OR,
aby nie była ona włączona! Nale-
ży ją w tym celu wyłączyć opera-
cją AND! Wynika to stąd, że struk-
tura termios dla danego portu jest
wspólna dla wszystkich aplikacji.
Przykładowo, jeśli nie chcemy aby
nasz program korzystał z mapowa-
nia znaku CR (0x0D) na znak NL
(0x0A) i odwrotnie, to musimy ko-
niecznie wyłączyć te funkcje pisząc
options.c_iflag & =~(ICRNL |
INLCR);
List. 4. Odczyt i modyfikacja stanu linii sterujących portu
//*******************************************
//
// Getting and setting the control signals
//
//*******************************************
#include <unistd.h>
#include <termios.h>
Konfiguracja:polec_cflag
– opcje sterowania
Zawartość pola c_cflag kontro-
luje liczbę bitów danych w ramce
RS232, steruje kontrolą parzystości,
określa liczbę bitów stopu oraz po-
//File descriprot
int fd;
Tab. 9. Stałe określające stan linii
sterujących portu
Stała Opis
TIOCM_DTR Sterowanie stanem DTR
TIOCM_RTS Sterowanie stanem RTS
TIOCM_CTS Sterowanie stanem CTS
TIOCM_CAR Sterowanie stanem DCD
TIOCM_CD Synonim dla TIOCM_CAR
TIOCM_DSR Sterowanie stanem DSR
//Variable for holding the control signals
int status;
//Getting the control signals
ioctl(fd, TIOCMGET, &status);
// Setting the control signals
// - logic 0 to DTR
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
Elektronika Praktyczna 3/2006
93
Wartość Opis
66534604.032.png 66534604.033.png 66534604.034.png 66534604.035.png 66534604.036.png 66534604.037.png 66534604.038.png 66534604.039.png 66534604.040.png 66534604.041.png 66534604.042.png 66534604.043.png 66534604.044.png 66534604.045.png 66534604.046.png 66534604.047.png 66534604.048.png 66534604.049.png 66534604.050.png 66534604.052.png
Zgłoś jeśli naruszono regulamin