Konfiguracja Linuxa do współpracy z kartami wieloportowymi LB-240,
LB-280 produkcji LAB-EL
-
dla Linuxa w dystrybucji RedHat 6.0 Hedwig
|
 |
-
dokument powstał po instalacji karty LB-280 na komputerze z
Linuxem
w dystrybucji RedHat6.0 z jądrem 2.2.5 - istnieją różnice w
konfiguracji
portów szeregowych w różnych instalacjach Linuxa, więc nie jest to
stuprocentowo
dobry opis - w szczególności mogą wystąpić rożnice w sposobie wywołania
programu
setserial
oraz
sposobie
konfigurowania jądra przed kompilacją
-
pisząc ten dokument autor działał w dobrej wierze i nie
ponosi
odpowiedzialności
za żadne szkody wynikłe w skutek działalności Użytkownika
zainspirowanego
lekturą niniejszego dokumentu - w interesie Użytkownika jest więc
zapoznanie
się z dokumentacją do Jego instalacji i potraktowanie tego tekstu jako
jednej z możliwych dróg osiągnięcia celu
-
wykorzystany został program
setserial
w wersji 2.15
-
w przykładach odwołuję się do karty skonfigurowanej na adres
0x280,
irq 5 i posiadającej 8 portów szeregowych bez bufora FIFO czyli 16450
-
karty LB-240 i LB-280 są zgodne z kartami Hostess 550(TM)
produkcji
Comtrol
Corporation
OPIS
1. Pierwszym krokiem przy konfigurowaniu
linuksowego
komputera do współpracy z kartą wieloportową LB240 albo LB-280 (zwaną
dalej
kartą) jest sprawdzenie, czy jądro systemu posiada wkompilowaną obsługę
dla takiego urządzenia. Konieczne jest zawarcie następujących opcji
kompilacji
jądra:
-
CONFIG_SERIAL_EXTENDED
- opcja aktywująca obsługę niestandardowych funkcji portów szeregowych,
takich jak dzielenie przerwania przez kilka
UARTów
albo obsługę dodatkowych rejestrów zawartych na karcie. Opcja ta
otwiera
możliwość wybrania kolejnych szczegółowych opcji konfiguracji i jest
aktywowana
poprzez zaznaczenie pozycji
Extended
dumb
serial driver options w
programie
konfiguracji jądra.
-
CONFIG_SERIAL_MANY_PORTS -
konieczna
dla obsługi wiecej niż 4 standardowych portów PC - aktywowana poprzez
zaznaczenie
Support
more than 4 serial ports.
-
CONFIG_SERIAL_SHARE_IRQ -
konieczna
dla obsługi współdzielenia przerwania przez wszystkie
UARTy
karty - aktywowana przez zaznaczenie
Support
for sharing serial interrupts.
-
CONFIG_SERIAL_MULTIPORT -
konieczna
dla obsługi specjalnego rejestru umożliwiającego identyfikację
UARTa
zgłaszającego przerwanie - aktywowana przez zaznaczenie
Support
special multiport boards.
Jeśli aktualne jądro nie zostało skompilowane z ww. opcjami to należy
wygenerować
nowe i zainstalować je - opisu tych czynności niniejszy dokument nie
zawiera.
2. Drugi krok instalacji karty
wieloportowej
to stworzenie w systemie plików - plików urządzeń przez które możliwa
będzie
komunikacja oprogramowania użytkownika z procedurami jądra. Pliki
urządzeń
znajdują sie w katalogu
/dev
a ich nazwę (dotyczy urządzeń dla portów szeregowych) przez
konwencję
konstruuje sie z
ttyS
i unikalnego numeru, przy czym
ttyS0
do
ttyS3
przydzielane są zazwyczaj dla standardowych portów PC (oznaczanych
niekiedy
jako COM1..COM4). Dla każdego portu karty należy stworzyć odrębny plik
urządzenia, i niech to, w tym przykładzie, będą pliki od
ttyS16
do
ttyS23
(przykład dla karty 8-portowej). Posługujemy się programem
mknod,
który generuje pliki urządzeń - jako parametry podajemy: nazwę
specjalnego
pliku urządzenia, c (urządzenie znakowe), oraz dwie liczby: major
i minor - pozwalające na identyfikację urządzenia z zasobach
jądra.
Liczba major dla portu szeregowego (typu ttyS) jest równa 4,
liczbę
minor
uzyskujemy jako sumę 64+numer_przy_ttyS, czyli dla
ttyS16
będzie to 80. Można więc wykonać serię poleceń:
mknod /dev/ttyS16 c 4 80
mknod /dev/ttyS17 c 4 81
mknod /dev/ttyS18 c 4 82
mknod /dev/ttyS19 c 4 83
mknod /dev/ttyS20 c 4 84
mknod /dev/ttyS21 c 4 85
mknod /dev/ttyS22 c 4 86
mknod /dev/ttyS23 c 4 87
albo skorzystać ze skryptu dołączonego na końcu
dokumentu.
Wcześniejsze wersje systemu wykorzystywały
urządzenia typu
/dev/cua, dla których liczba major
ma
wartość 5 - obecnie autorzy systemu zalecają zaprzestanie korzystania z
tych plików urządzeń.
3. Trzecim
krokiem
jest stworzenie skryptów inicjujących tablice jądra wartościami
odpowiednimi
dla zainstalowanej karty - adres w przestrzeni I/O, przerwanie, typ
UARTów.
W tym celu posługujemy się programem
setserial.
Inicjacja tablic (w odróżnieniu od poprzednich kroków) jest konieczna
przy
każdym uruchomieniu systemu, należy więc, wykonywać ją ze skryptów
uruchamianych
automatycznie przy starcie. Program setserial wykonujemy oddzielnie dla
każdego portu karty, jako parametry podajemy: nazwę pliku urządzenia,
adres
bazowy poru, numer linii przerwań, typ
UARTa oraz
prędkość
transmisji. Adres bazowy kolejnego portu jest sumą adresu bazowego
karty
(ustawionego na zworkach) plus 8*numer_portu. Numer linii
przerwań
(również ustawiony na zworkach karty) jest taki sam we wszystkich
wywołaniach.
Typ
UARTa zależy w jakie układy wyposażona jest
karta,
zazwyczaj jest to: albo 16450 (niebuforowany), albo 16550
(bufor FIFO 16to bajtowy). Parametr określający prędkość transmisji ma
znaczenie jedynie wtedy, gdy oprogramowanie ustawia sobie transmisję
38400bps,
faktyczna predkość zależy od parametru który podamy
setserialowi,
i jeśli to będzie spd_normal, to uzyskamy faktyczną prędkość
38400bps,
dla spd_hi uzyskamy 57600bps a dla spd_vhi
115200bps.
Dla połączeń przy pomocy pętli prądowych nie zaleca się korzystania z
transmisji
szybszej niż 38400bps, ze względu na ograniczenia układów separacji
galwanicznej
kart LB-2?0. Przykładowy ciąg poleceń ustawiających paramerty tablic
jądra:
setserial /dev/ttyS16 port 0x280 irq 5 uart 16450 spd_normal
setserial /dev/ttyS17 port 0x288 irq 5 uart 16450 spd_normal
setserial /dev/ttyS18 port 0x290 irq 5 uart 16450 spd_normal
setserial /dev/ttyS19 port 0x298 irq 5 uart 16450 spd_normal
setserial /dev/ttyS20 port 0x2a0 irq 5 uart 16450 spd_normal
setserial /dev/ttyS21 port 0x2a8 irq 5 uart 16450 spd_normal
setserial /dev/ttyS22 port 0x2b0 irq 5 uart 16450 spd_normal
setserial /dev/ttyS23 port 0x2b8 irq 5 uart 16450 spd_normal
Po ustawieniu parametrów dla poszczególnych
portów
należy poinformować procedury jądra o istnieniu specjalnego rejestru
ułatwiającego
identyfikację
UARTa zgłaszającego przerwanie.
Rejestr
ten znajduje się w przestrzeni I/O pod adresem przesuniętym o 7 w
stosunku
do adresu bazowego karty. Posługujemy się znowu programem
setserial.
setserial /dev/ttyS16 set_multiport port1 0x287 mask1 0xff match1 0x00
Polecenia tego nie trzeba wykonywać dla
każdego
portu z osobna, ponieważ już wcześniej ustalono, że wszystkie posługują
się wspólną linią przerwań, a to wystarcza aby to samo ustawienie
dotyczyło
innych portów karty. Wyjaśnienia wymagają pozostałe parametry: port1
0x287 - jest to adres portu (rejestru) identyfikacji przerwania o
którym napisane jest powyżej, mask1 0xff - jest to wartość
maski
przykładanej do wartości wyczytanej z rejestru, dla każdego
UARTa
przydzielony jest 1 bit - jeśli więc korzystamy z karty 8mio portowej,
to maska powinna być ustawiona na 0xff czyli de facto nie
maskujemy
nic. Dla karty 4ro portowej maska powinna mieć wartość 0x0f.
Parametr:
match1
0x00 - ustala zawartość rejestru po ustaniu żądania obsługi, czyli
wartość jaką będzie zawierał rejestr po obsłużeniu żądań wszystkich
UARTów
karty.
Po wykonaniu ustawień można je skontrolować
wywołując
program:
setserial /dev/ttyS16 # wypisuje ustawienia dla konkretnego portu, tu ttyS16 setserial /dev/ttyS16
get_multiport # wypisuje ustawienia dla rejestru identyfikacji przerwania
4. Typowym
zastosowaniem
kart wieloportowych jest łączenie przy ich pomocy terminali znakowych z
hostem. Niezbędna konfiguracja obejmuje wypełnienie pozycji pliku
/etc/inittab
nakazujących procesowi
init
uruchamianie procesu
getty
dla każdej skonfigurowanej linii tty. Typowo wystarczy dodanie dla
każdego
nowego terminala jednej linii w inittabie tak jak w następującym
przykładzie:
16:2345:respawn:/sbin/getty ttyS16 DT19200 vt100
17:2345:respawn:/sbin/getty ttyS17 DT19200 vt100
18:2345:respawn:/sbin/getty ttyS18 DT19200 vt100
19:2345:respawn:/sbin/getty ttyS19 DT19200 vt100
20:2345:respawn:/sbin/getty ttyS20 DT19200 vt100
21:2345:respawn:/sbin/getty ttyS21 DT19200 vt100
22:2345:respawn:/sbin/getty ttyS22 DT19200 vt100
23:2345:respawn:/sbin/getty ttyS23 DT19200 vt100
Opis składni poleceń znaleźć można w manualu
do inittaba, ważne jest aby parametr definiujący parametry
transmisji
określał ją jako połączenie lokalne - nie wymagające synchronizacji
(handshake)
- w przykładzie określone jest to przez parametr DT19200
(wybrana
prędkość 19200bps). Definicja parametru DT19200 podana jest w
pliku
/etc/gettydefs i powinna ona wyglądać (mniej-więcej)
tak:
DT19200# B19200 CS8 CLOCAL # B19200 SANE -ISTRIP CLOCAL #@S login: #DT19200
Ważne jest podanie flagi
CLOCAL -
określającej
połączenie jako lokalne, opis formatu pliku znaleźć można w manualu do
gettydefs,
opis znaczenia flag w manualu do
stty. Po wypełnieniu pliku
inittab
należy zasygnalizować procesowi
init
zmianę ustawień wydając komendę:
init q
po czym na terminalach podłączonych do
uruchamianej
karty powinien pojawić się tekst zachęty do logowania.
Wyjaśnienia:
-
UART - universal
asynchronius receiver/transmiter, czyli układ (zazwyczaj scalony)
realizujący
funkcję nadajnika/odbiornika asynchronicznej transmisji szeregowej
-
program
konfiguracji jądra
- program wywoływany poleceniem: make menuconfig,
udostępniający
użytkownikowi interfejs (zestaw menu) do ustawiania opcji kompilacji
jądra
Bibliografia:
- manual: setserial, stty, getty, gettydefs, inittab, init, mknod
- HOWTO: Serial-HOWTO, Serial-Programming-HOWTO
- źródła jądra (2.2.5): /usr/src/linux/drivers/char/serial.c,
/usr/src/linux/include/linux/serial.h
-
www.comtrol.com - dokument
6252d.pdf
- Installation Reference Card for The Linux System with the Hostess
550(TM)
Series
#!/bin/bash
#
# skrypt ustawiajacy parametry jadra do wspolpracy z kartami LB-240 i LB-280
# produkcji LAB-EL, sprawdzony na jadrze 2.2.5, RedHat 6.0, z programem
# setserial 2.15
#
# JRS, 13.9.1999
#
# -- konfiguracja -----------------------------------------------------------
DEVSTART=16 # numer pierwszego ttyS przydzielonego karcie
PORTNUMB=8 # liczba uart-ow na karcie: 4 albo 8
BASE=0x280 # adres bazowy -- czyli adres pierwszego uart-a
IRQ=5 # numer linii irq
UART=16450 # typ uart-a: 16450 albo 16550
SPEED=spd_normal # spd_normal daje max bps=38400
# -- koniec konfiguracji ----------------------------------------------------
echo
echo -- tworzenie urzadzen --
PN=0 ; while (let $PN-$PORTNUMB) ; do
DN=$[$[$DEVSTART]+$[$PN]]
echo -n port $PN:
if (test -e /dev/ttyS$DN) ; then
echo /dev/ttyS$DN juz istnieje
else
echo /dev/ttyS$DN maj:4 min:$[64+$[$DN]]
mknod /dev/ttyS$DN c 4 $[64+$[$DN]]
fi
echo -n port $PN:
if (test -e /dev/cua$DN) ; then
echo /dev/cua$DN juz istnieje
else
echo /dev/cua$DN maj:5 min:$[64+$[$DN]]
mknod /dev/cua$DN c 5 $[64+$[$DN]]
fi
PN=$[$[$PN]+1]
done
echo
echo -- ustawienia portow --
PN=0 ; while (let $PN-$PORTNUMB) ; do
DN=$[$[$DEVSTART]+$[$PN]]
echo -n port $PN:
setserial -v /dev/ttyS$DN port $[$[$BASE]+$[PN]*8] \
irq $IRQ uart $UART $SPEED
PN=$[$[$PN]+1]
done
echo
echo -- ustawienia karty wieloportowej --
setserial /dev/ttyS$DEVSTART set_multiport port1 $[$[$BASE]+7] \
match1 0x00 \
mask1 `if (let $PORTNUMB-4) ; then echo 0xff ; else echo 0xf; fi`
setserial /dev/ttyS$DEVSTART get_multiport
#
# -- koniec skryptu ---------------------------------------------------------
14.9.1999