K U R S
Programowanie portu szeregowego
w systemach operacyjnych
Linux i Windows, część 3
Umiejętność programowej obsługi interfejsu
RS232 od strony komputera PC jest dziś
istotnym elementem elektronicznego rzemiosła.
W niniejszym kursie 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.
Aplikacja konsolowa używająca inny niż 0...9 to przez port zostanie otwiera port, po czym ustawia żąda-
portu szeregowego wysłany bajt o wartości równej kodo- ną przez użytkownika prędkość trans-
Aplikacja konsolowa została napi- wi ASCII tego znaku pomniejszonemu misji oraz wyłącza co tylko można
sana w języku C i skompilowana za o 0x30. Następnie program zasypia na z funkcjonalności obróbki danych wej-
pomocą kompilatora GCC, który spo- czas ok. 1 sekundy (break time), po ściowych i wyjściowych. Innymi sło-
tkamy w każdej dystrybucji Linuksa. czym sprawdza czy w buforze wej- wy, wybieramy wejście raw input
Składa się ona z trzech plików: ściowym portu znajdują się jakiekol- i wyjście raw output wyłączając wszel-
main.c główny plik aplikacji od- wiek dane (odpowiedz zestawu). Jeśli kie funkcje mapowania jednych zna-
powiedzialny za jej funkcjonalność tak jest są one odczytywane i w kon- ków na drugie, sprzętową i programo-
(list. 6); soli pojawia się zarówno ich interpre- wą kontrolę przepływu, itp..
LinuxRS232.h plik nagłówkowy tacja ASCII jak i wartości kolejnych List. 9 zawiera ciało funkcji Write
zawierający deklaracje funkcji ob- bajtów zapisane dziesiętnie. Pokazu- służącej do wysłania do portu Num-
sługi interfejsu RS232 (list. 7); je to rys. 4 zawierający zrzut z ekra- berOfBytesToWrite bajtów, począwszy
LinuxRS232.c plik zródłowy za- nu zrobiony podczas pracy aplikacji, od miejsca w pamięci określonego
wierający definicje (ciała) funk- gdy użytkownik jako daną do wysła- wskaznikiem Buffer. Funkcja ta zwra-
cji obsługi interfejsu RS232 nia wpisał liczbę 3. Zmienna InQue ca liczbę faktycznie wysłanych baj-
(list. 8...11). zawiera odczytaną za pomocą funkcji tów. W przypadku błędu zwraca 0.
Na list. 6 zamieściłem zawartość CheckCommInput liczbę bajtów ocze- List. 10 zawiera ciało funk-
pliku main.c. Działanie programu po- kujących w buforze wejściowym, zaś cji Read, za pomocą której możemy
lega na pobraniu jednej cyfry (je- zmienna BytesRead zawiera liczbę baj- wybrać z bufora wejściowego portu
den znak+Enter) z klawiatury i wysła- tów faktycznie wyjętych z tego bufora NumberOfBytesToRead bajtów. Specy-
niu przez port szeregowy /dev/ttyS0 za pomocą funkcji Read. fikujemy przy tym pewne ogranicze-
(COM1) bajta o wartości równej poda- List. 8 przedstawia implementację nie określone stałą cbInQueue zdefi-
nej cyfrze (0...9). Jeśli wpiszemy znak funkcji Open i Close. Funkcja Open niowaną w pliku LinuxRS232.h. Ogra-
niczenie to zapobiega próbie odczy-
List. 7. Plik nagłówkowy LinuxRS232.h tu wielu bajtów z portu. Wartość cbI-
//---------------------------------------------------------------------------
nQueue powinna być dobrana tak,
// File: LinuxRS232.h
// Description: Linux RS232 header file
aby podczas normalnej pracy aplika-
// Compiler: gcc
// Author: Arkadiusz Antoniak, 2005
cji w żadnym momencie nie zacho-
//---------------------------------------------------------------------------
#ifndef LinuxRS232H
dziła potrzeba odczytu z portu liczby
#define LinuxRS232H
#define cbInQueue 1024
bajtów większej od cbInQueue. Funk-
#define cbOutQueue 16
int Open(char *Port, unsigned long Baud);
cja Read zwraca 0 w przypadku błę-
void Close(void);
unsigned long Write(const void* Buffer, unsigned long NumberOfBytesToWrite);
du i 1, gdy odczyt zakończył się suk-
int Read(void * Buffer, unsigned long * lpNumberOfBytesRead, unsigned long NumberO-
fBytesToRead); cesem. Za pośrednictwem wskaznika
void CheckCommInput(unsigned long * lpInQue);
//--------------------------------------------------------------------------- lpNumberOfBytesRead zwracana jest
#endif
liczba faktycznie odczytanych bajtów.
Uwaga!
Ze wzgledu na objętość tekstu listingów 6 i 8, publikujemy je wyłącznie na CD-EP5/2006B oraz na stronie internetowej
w dziale Download.
Elektronika Praktyczna 5/2006
106
K U R S
dzeniem czy część sprzętowa na to
List. 9. Funkcja Write
unsigned long Write(const void* Buffer, unsigned long NumberOfBytesToWrite)
pytanie odpowiedziała, program od-
{
int iOutWrite;
czekuje pewien czas w naszym
if (fd<1) return 0;
iOutWrite = write(fd, Buffer, NumberOfBytesToWrite);
przykładzie jest to 1 sekunda. Czas
if (iOutWrite<0) return 0;
return iOutWrite; taki nazywany jest break time. Na-
}
leży w tym miejscu zwrócić uwagę
na różnicę w znaczeniu pojęć bre-
ak time i timeout używanych czę-
List. 10. Funkcja Read
int Read(void * Buffer, unsigned long * lpNumberOfBytesRead, unsigned long Numbe-
sto w opisach aplikacji komunika-
rOfBytesToRead)
{
cyjnych.
unsigned long nNumberOfBytesToRead;
int iInRead;
Otóż break time jest minimalnym
if (NumberOfBytesToRead>cbInQueue)
nNumberOfBytesToRead=cbInQueue;
czasem jaki aplikacja musi odczekać
else
nNumberOfBytesToRead=NumberOfBytesToRead; na wystąpienie pewnego zdarzenia.
if(fd<1) return 0;
Jeśli zdarzeniem tym jest odpowiedz
iInRead=read(fd, Buffer, nNumberOfBytesToRead);
if(iInRead<0)
układu pomiarowego dołączonego do
return 0;
else
komputera przez RS232, to break
*lpNumberOfBytesRead=iInRead;
return 1;
time jest wyznaczony przez czas do-
}
konania pomiaru i czas potrzebny na
przesłanie przez port szeregowy wy-
niku tego pomiaru. W naszym przy-
padku break time jest wyznaczony je-
dynie przez czas odpowiedzi oczy-
wiście 1 s jest czasem znacznie dłuż-
szym niż minimalny czas jaki należa-
łoby tutaj odczekać.
Czas timeout jest czasem przeter-
minowania (przedawnienia) pewnej
operacji. Jeśli po upływie tego czasu
chcemy ponownie wywołać tą opera-
cję, to musimy powtórzyć całą proce-
durę związaną z jej wywołaniem.
Podsumowanie
W tej części kursu pragnąłem za-
prezentować wykorzystanie omówio-
nych poprzednio funkcji na prostym
przykładzie, tak aby bez wgłębiania
się w szczegóły pokazać że to dzia-
Rys. 4. Okno aplikacji konsolowej ła . Proponuję Czytelnikom poekspe-
rymentować z opisanym zestawem
Wskaznik Buffer określa miejsce w pa- zechcą zapewne napisać własne funk- i oprogramowaniem ludzie wszak
mięci, gdzie zostaną zapisane odczy- cje obsługi portu szeregowego (byłoby uczą się najlepiej i najszybciej na
tane bajty. to nawet wskazane ze względów edu- przykładach. W następnej części zmie-
List. 11 przedstawia funk- kacyjnych). nimy nieco tematykę i zobaczymy jak
cję CheckCommInput, która pozwa- Całość kompilujemy za pomocą oprogramowanie portu szeregowego
la zapytać sterownik portu szerego- GCC używając standardowo programu wygląda w systemie Windows. Skupi-
wego ile bajtów aktualnie znajdu- make. Przykładowy plik makefile za- my się przy tym na tych cechach,
je się w buforze wejściowym. Ich mieściłem na list. 12. Jest to bardzo które są takie same lub podobne do
liczba zwracana jest przez wskaznik prosty plik, mówiący kompilatorowi ich odpowiedników występujących
lpInQue. jedynie co kompilować, zaś linkerowi w Linuksie. Wszystko to ma na celu
Oczywiście, funkcje przedstawio- z jakich plików *.o stworzyć plik stworzenie klasy obsługi RS232 w ję-
ne na list. 8...11 (plik LinuxRS232.c) wykonywalny o nazwie main. Aby zyku C++ identycznej w obu syste-
to tylko moja propozycja wykorzysta- otrzymać ten plik wystarczy wpi- mach co do interfejsu, więc przeno-
nia funkcji systemowych, a Czytelnicy sać make będąc w katalogu zawie- śnej. Klasę tą w wersji dla Win-
rającym pliki zródłowe aplikacji i plik dows stworzymy w następnej części
List. 11. Funkcja CheckCommInput
makefile. Program uruchamiamy wpi- cyklu. Oprócz tego, opiszemy też pro-
void CheckCommInput(unsigned long *
lpInQue) sując w konsoli ./main . stą aplikację GUI dla Windows, której
{
Jeśli do portu COM1 komputera funkcjonalność będzie taka sama jak
ioctl(fd, FIONREAD, lpInQue);
}
dołączony jest nasz zestaw, to bę- funkcjonalność opisanego dziś proste-
dziemy mogli obserwować działanie go programu konsolowego. W dalszych
List. 12. Plik makefile
całości. Polega ono na zadaniu py- częściach kursu aplikację tą przenie-
main: main.c LinuxRS232.c
gcc -g -c -Wall main.c -o main.o tania (wpisana przez użytkownika siemy na Linuksa.
gcc -g -c -Wall LinuxRS232.c -o
wartość) i obserwacji odpowiedzi. Arkadiusz Antoniak, EP
LinuxRS232.o
gcc LinuxRS232.o main.o -o main
Pomiędzy zadaniem pytania a spraw- arkadiusz.antoniak@ep.com.pl
Elektronika Praktyczna 5/2006
107
Wyszukiwarka
Podobne podstrony:
rs232 linux win32 cz2rs232 linux win32 cz6rs232 linux win32 cz1rs232 linux win32 cz8rs232 linux win32 cz7rs232 linux win32 cz4rs232 linux win32 cz5STM32 Butterfly RS232Linux 2000 DVB T Experimentslinux kobietycompilar linuxLinux IPCHAINS HOWTO Appendix Differences between ipchains and ipfwadmPrzystawka do spawania aluminium metoda TIG cz3systemy operacyjne cw linux apache mysqlLinux materialyLinux System PlikówAsembler linuxNauka słówek i memoryzacja na Puppy Linuxlinux 1 00więcej podobnych podstron