Linux_embedded_cz2.pdf
(
525 KB
)
Pobierz
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
Wprowadzenie do Linux’a embedded
KURS
Wprowadzenie do
Linux’a embedded (2)
Klawiatura matrycowa,
podsystem input,
zaawansowana obsługa
wejścia – wyjścia
Dodatkowe materiały
na CD/FTP
W poprzednim odcinku zapoznaliśmy się z obsługą portów GPIO
w Linuksie za pomocą aplikacji użytkownika wykorzystując interfejs
sysfs-gpio. Sprawdzenia stanu wciśnięcia klawisza dokonywaliśmy
poprzez cyklicznie odczytywanie stanu, co powodowało, że proces
zupełnie niepotrzebnie był co chwilę aktywowany, w celu wykrycia
zbocza na linii wejściowej. W środowiskach wielozadaniowych
powinniśmy unikać cyklicznego odpytywania, aby procesor był
dostępny dla innych procesów. Poza tym, jak wspomniano
poprzednio, porty GPIO nie są same w sobie funkcjonalnym
urządzeniem, służą one jedynie do podłączenia innych układów np.
diod LED itp. W bieżącym odcinku pokażemy zatem jak w jaki
sposób obsłużyć klawiaturę, oraz diody LED zgodnie z i lozoi ą
jądra Linuksa.
Dodatkowe materiały na CD/FTP:
ftp://ep.com.pl
, user:
12147
, pass:
2e7u6a2a
• pierwsza część kursu
jest możliwy za pomocą kilku interfejsów
które stanowią: intefejs klawiatury, Inter-
fejs myszy, Interfejs Joysticka oraz Interfejs
zdarzeń. Dostęp do poszczególnych interfej-
sów aplikacjom zapewniają pliki urządzeń.
(Jak mawia stare powiedzenie w linuksie
wszystko jest plikiem). Interfejs klawiatury
myszy i joysticka jest dedykowany obsłudze
wyżej wspomnianych urządzeń i jego zasto-
sowanie nie wymaga dodatkowego komen-
tarza. Interfejs Event służy do podłączania
innych rodzajów przycisków czy klawiszy,
(np. przycisk zamknięcia obudowy laptopa,
przyciski głośności itp.), i umożliwia gene-
rowanie zdarzeń, możliwych do odczytania
z aplikacji użytkownika. Może się wydawać,
że interfejs event, a interfejs klawiatury to
w zasadzie to samo, jednak różnica jest taką,
że interfejs klawiatury mapuje bezpośrednio
klawiaturę do konsoli, Interfejs event z kolei
umożliwia odczytywanie stanu pozostałych
klawiszy istotnych dla danej platformy.
Aby urozmaić przykład zamiast pojedyn-
czego przycisku podłączymy klawiaturę ma-
trycową w roli której wykorzystamy moduł
KAMODKBD4x4 i rmy Kamami. Klawiaturę
tą podłączymy do podsystemu Input jądra,
za pomocą odpowiedniego sterownika, nato-
miast do sterowania diodami LED użyjemy
interfejsu leds, który jest przeznaczony do
sterowania diodami LED.
nuksa przedstawiono na
rysunku 4
zaczerp-
niętym z czasopisma „The Linux Journal”
(
http://www.linuxjournal.com
).
Interfejs ten składa się z jądra podsyste-
mu (Input core), które od strony niskopozio-
mowej komunikuje się ze sterownikami urzą-
dzeń, które są odpowiedzialne za bezpośred-
nią komunikację z urządzeniami. Natomiast
od strony aplikacji użytkownika zapewnia
jednolity interfejs. Od strony aplikacji dostęp
Zagadnienia teoretyczne
Podsystem wejścia (
Linux Input Sub-
system
).
Podsystem wejścia jądra systemu
linuks, zapewnia jednolity interfejs dla ob-
sługi wszelkich urządzeń wejściowych, ta-
kich jak klawiatury, myszki, joysticki, oraz
inne urządzenia. Zapewnia on obsługę urzą-
dzeń z wykorzystaniem, zdarzeń. Zapewnia
on również sterowanie, np. diodami LED
klawiatury, wibracjami joysticka itp. Mecha-
nizm dostarcza warstwę abstrakcji unieza-
leżniającą aplikację użytkownika od sprzętu,
magistrali do której zostało urządzenie pod-
łączone. np. USB, PS2, GPIO itp. Schemat
blokowy podsystemu wejścia w jądrze Li-
Rysunek 4. Schemat blokowy podsystemu wejścia w jądrze Linuksa
95
ELEKTRONIKA PRAKTYCZNA 5/2011
KURS
sterowniki dla większości typo-
wych urządzeń dołączanych do
portów GPIO. W poprzednim od-
cinku wspominaliśmy o sterow-
niku gpio_buttons dla pojedyn-
czych przycisków. W przypadku
klawiatury matrycowej odpo-
wiednim sterownikiem będzie
matrix_keypad
, a jedyną rzeczą
jaką będziemy musieli wykonać
to zdei niować kilka struktur
oraz zarejestrować opis urządze-
nia w odpowiednich strukturach
przechowujących koni gurację, za pomocą
funkcji
platform_register_device()
, w pliku
inicjalizującym daną płytkę.
Sterowanie klawiatura matrycową od-
bywa się za pomocą przemiatania poprzez
wystawienie odpowiednich stanów na linii
wierszy (ROW), oraz sprawdzania stanów
na liniach kolumn (COL). Przy czym spraw-
dzanie stanów może się odbywać za pomo-
cą aktywnego odpytywania, lub za pomocą
przerwań. Sterownik
matrix-keypad
, został
napisany, z wykorzystaniem tego drugiego
sposobu, i do prawidłowej pracy wymaga li-
nii
GPIO,
które potrai ą zgłaszać przerwania.
Na szczęście porty
GPIO
naszego mikrokon-
trolera RM9200 posiadają taką możliwość,
zatem bez problemu możemy wykorzystać
sterownik
matrix_keypad
. Aby sterownik
mógł działać poprawnie musimy w struktu-
rach przechowujących koni gurację maszy-
ny, określić rodzaj klawiatury, oraz sposób
jej dołączenia co jest realizowane za pomocą
struktury z
listingu
1
.
Pole
keymap_data
wskazuje na kolejną
strukturę
matrix_keymap_data
, która za-
wiera wskaźnik do tablicy dei niującej przy-
pisania kodów klawiszy do poszczególnych
wierszy i kolumn. Pole
row_gpios
, wskazuje
na tablicę zawierającą numery porządkowe
portów GPIO (poprzedni artykuł), określa-
jące i zyczne linie GPIO, które będą użyte
w roli linii wierszy, podobnie pole
col_gpios
,
określa linie GPIO, które będą użyte w roli li-
nii kolumn. Pola
num_row_gpios
oraz
num_
col_gpios
, określają ilość linii kolumn, oraz
linii wierszy klawiatury matrycowej. Pole
col_scan_delay_us
określa, czas opóźnienia
pomiędzy ustawieniem linii stanu linii wier-
szy, a odczytywaniem stanu linii kolumn.
Pole
debounce_ms
określa czas potrzebny
do wyeliminowania drgań zestyków. Pole
active_low
określa, czy stanem aktywnym
jest sygnał 1 czy 0. Pole
wakeup
, określa czy
klawiatura umożliwia wybudzanie systemu
ze stanu uśpienia. Pole
no_autorepeat
, okre-
śla że klawiatura nie generuje kodów powtó-
rzeń podczas ciągłego trzymania klawisza,
a jedynie eventy wciśnięcia oraz zwolnienia
klawisza. Wypełnienie struktury
matrix_
keypad_platform
, zapewnia sterownikowi
matrix-keypad
, wszystkie niezbędne dane
potrzebne do działania, oraz informuje ste-
rownik o obecności klawiatury matrycowej
dołączonej do portów GPIO.
Dostęp do klawiatury z aplikacji użyt-
kownika, z wykorzystaniem interfejsu
event.
Dostęp do zdarzeń podsystemu in-
put realizowany jest za pomocą pliku /dev/
input/eventX (gdzie X określa kolejny numer
urządzenia). Po otwarciu urządzenia dane
o zdarzeniach od urządzenia, będzie można
odczytywać za pomocą wywołania systemo-
wego read(). Ponieważ domyślnie funkcja
read(), jest blokująca (usypiająca proces),
wywołanie funkcji read spowoduje uśpienie
wywołującego procesu do momentu wystą-
pienia zdarzenia od podsystemu input. Zda-
rzenia zostały zdei niowane w postaci struk-
tury umieszczonej na
listingu
2
.
Pole
timeval
, zawiera znacznik czasu
wystąpienia zdarzenia, pole
type
określa typ
zdarzenia, w przypadku klawiatury, będą to
zdarzenia typu
EV_KEY
, natomiast pole
va-
lue
, określa wartość dla danego zdarzenia.
Dla zdarzenia
EV_KEY
, wciśnięcie klawisza
będzie sygnalizowane zwróceniem wartości
1
w polu
value
, zwolnienie klawisza sygna-
lizowane będzie zwróceniem wartości
0
, na-
tomiast wciśnięcie i przytrzymanie klawisza
będzie powodowało generowanie cyklicz-
nych zdarzeń powtórzonych, które będą sy-
gnalizowane wartością
2.
Pole
code
zawiera
kod klawisza który został wciśnięty. Zatem
odczytując zdarzenia za pomocą funkcji
read()
, spowodujemy uśpienie wywołujące-
go procesu do momentu wystąpienia zdarze-
nia.
Lisitng 1. Struktura służąca do obsługi klawiatury
struct
matrix_keypad_platform_data {
const
struct
matrix_keymap_data *keymap_data;
const
unsigned
int
*row_gpios;
const
unsigned
int
*col_gpios;
unsigned
int
num_row_gpios;
unsigned
int
num_col_gpios;
unsigned
int
col_scan_delay_us;
/* key debounce interval in milli-second */
unsigned
int
debounce_ms;
unsigned
int
clustered_irq;
unsigned
int
clustered_irq_fl ags;
bool
active_low;
bool
wakeup;
bool
no_autorepeat;
};
Dane platform device, umożliwiające
określenie koni guracji maszyny.
Klasyczne
komputery PC mają ściśle określoną archi-
tekturę oraz podsystem BIOS umożliwiają-
cy, określenie urządzeń zewnętrznych i we-
wnętrznych będących częścią komputera.
Aby dowiedzieć się w jakie urządzenia wy-
posażony jest komputer, wystarczy odpytać
BIOS, lub urządzenia PnP (Plug and Play).
W przypadku innych architektur, a szczegól-
nie w przypadku urządzeń wbudowanych,
mamy do czynienia z wieloma różnymi kon-
strukcjami sprzętowymi, zawierającymi róż-
ne komponenty i podzespoły. Najczęściej nie
istnieje również żaden jednolity interfejs sta-
nowiący funkcjonalny odpowiednik syste-
mu BIOS, który umożliwia zapytanie o listę
dostępnego sprzętu. Jedynym zatem sposo-
bem sprawdzenia, listy dostępnych kompo-
nentów danej platformy jest zdei niowanie
listy podzespołów bezpośrednio w kodzie.
W linuksie kod zdei niowany jest w postaci
struktur danych
platform_data
zawierają-
cych listę podzespołów danej maszyny. Lista
ta dei niowana jest w jądrze w pliku odpo-
wiedzialnym za koni gurację danej maszyny.
W przypadku
BF210
plikiem odpowiedzial-
nym za inicjalizację jest plik w kodzie jądra
znajdujący się w następującej lokalizacji:
arch/arm/mach-at91/board-boff210.c
Lista
uradzeń dostępnych na danej platformie zor-
ganizowana jest w postaci dei nicji struktur
struct platform_device
, które następnie są ini-
cjalizowane za pomocą funkcji
platform_de-
vice_register()
...
Sterownik klawiatury matrycowej ma-
trix-keypad.
Aby urządzenie było widocz-
ne przez podsystem wejścia, musi posiadać
sterownik dla podsystemu. Dołączenie
odpowiedniego urządzenia wymaga zatem
napisania sterownika jądra, co może być za-
daniem stosunkowo skomplikowanym dla
początkującego użytkownika. W głowach
czytelników rodzi się pytanie, czy aby do-
łączyć tytułową klawiaturę KAMOD4x4
będziemy musieli się zmagać z napisaniem
odpowiedniego sterownika dla podsystemu
input? Wiadomość jest bardzo optymistycz-
na i brzmi NIE. Dzięki warstwie abstrakcji
obsługi portów GPIO istniejącym w kerne-
lu, oraz danych koni guracyjnych, dla danej
platformy (
platform data
), istnieją gotowe
Przykład praktyczny KAMOD4x4
ze sterownikiem matrix-keypad.
Diody LED sterowane przez leds-
gpio
Wstęp, schemat ideowy.
Po zapoznaniu
się z częścią teoretyczną przejdziemy do pre-
zentacji, przykładu w którym wykorzystamy
klawiaturę matrycowa
KAMODKBD4x4
,oraz
minimoduł
KAMODLED8
produkcji
KAMAMI
.
Będzie to bardzo prosty przykład, w którym
wciśnięcie i trzymanie klawisza, będzie zapa-
lało diody
LED
D0-D3
, odpowiadające wciśnię-
temu klawiszowi, natomiast zwolnienie klawi-
sza powodować będzie wyłączenie wszystkich
diod. Klawiatura matrycowa będzie dołączona
do podsystemu input, z wykorzystaniem ste-
rownika
matrix-keypad
, co umożliwi nam cał-
kowicie pasywne sprawdzanie stanu klawiszy.
Diody LED będą dołączone do podsystemu
LED
za pomocą sterownika
leds-gpio
. Aplika-
cja przestrzeni użytkownika będzie używać in-
terfejsu
evdev
, do odczytywania stanu klawia-
Listing 2. Struktura defi niująca
zdarzenia
struct
input_event {
struct
timeval time;
__u16 type;
__u16 code;
__s32 value;
};
96
ELEKTRONIKA PRAKTYCZNA 5/2011
Wprowadzenie do Linux’a embedded
kolumn, które zostało zdeiniowane na 10 us.
Pole
debounce_time
, zawiera opóźnienie eli-
munujące drgania zestyków, które zostało usta-
wione na 10 ms. Pole
active_low
informuje że
skanowanie wierszy i kolumn odbywa się za
pomocą stanu niskiego, dzięki czemu możliwe
jest wykorzystanie wewnętrznych rezystorów
podciągających. Pole
wake_up=1
, określa że
możliwe jest wybudzanie urządzenia ze sta-
nu uśpienia w wyniku wciśnięcia klawisza.
Tak przygotowana struktura informacyjna dla
sterownika
matrix_keypad
, jest następnie przy-
pisywana do struktury
platform_device
, która
następnie jest rejestrowana w systemie w funk-
cji inicjalizującej maszyne
bf_board_init()
za
pomocą wywołania p
latform_device_register(
&keypad_device)
Tablica struktur
gpio_leds
zdeiniowana
jako LEDS zawiera informację o koniguracji
diod LED, i sprowadza się ona do przypisa-
nia nazwy poszczególnych diod LED w polu
name
, oraz przypisania odpowiadającej jej
linii GPIO. Nazwy te następnie będą widocz-
ne w przestrzeni użytkownika w katalogu
/sys/class/led.
Zaprezentowany przykład jest dostępny
w postaci kompletnego obrazu karty, przy-
gotowanego do testów, jednak w przypadku
samodzielnego konigurowania urządzeń, ko-
nieczna będzie modyikacja kodu jądra Linuk-
sa, chociaż w minimalnie opisanym zakresie,
dlatego w dalszej części tekstu opiszemy w jaki
sposób dokonywać zmian we własnym zakre-
sie. Mniej dociekliwi czytelnicy mogą pominąć
niniejszy fragment.
W świecie Open Source, zmiany w kodzie
źródłowym dla istniejącego kodu dołączane
są w postaci plików patch. Są to proste pliki
tekstowe, które zawierają różnice pomiędzy
oryginalnym, a zmodyikowanym kodem,
obsługiwane przez program
patch
. Plik l
eds-
keypad.patch
, zawiera patch dla jądra linuxa,
zawierający wcześniej opisany fragment kodu,
konigurującego klawiaturę oraz diody. Po-
nieważ do kompilacji jądra nie są potrzebne
żadne biblioteki zewnętrzne możemy w zasa-
dzie wykorzystać dowolną wersję kompilatora
gcc,
która zawiera obsługę
EABI
. Na przykład
w Ubuntu 10.10, wystarczy zainstalować pa-
kiet
gcc-4.5-arm-linux-gnueabi
(polecenie
sudo apt-get install gcc-4.5-arm-linux-gnueabi
)
Następnie aby skompilować przykład należy
ściągnąć źródła jądra 2.6.37 ze strony
http://
www.kernel.org/
rozpakować je, a następnie za-
stosować patch dla maszyny BF210 który jest
dostępny tutaj
http://www.boff.pl/content/iles/
id5/2.6.37-boff-bf210.patch
(po
lecenie patch
-p1 -d linux-2.6.37 < 2.6.37-boff-210.patch
).
Kolejną czynnością jest zastosowanie patcha,
który dodaje opisane wcześniej struktury
plat-
form-data
, za pomocą polecenia:
patch -p1 -d
linux-2.6.37 < leds_keypad.patch
. Gdy już
mamy odpowiednio skonigurowane źródła
możemy przystąpić koniguracji jądra. W tym
celu do katalogu
linux-2.6.37
, należy skopio-
KAMODLED8: (+5V – J2PIN1, GND – J2PIN2, D0 – J2PIN7, D1 – J2PIN9,
D2 – J2PIN17, D3 – J2PIN19, D4-J2PIN4, D5-J2PIN6, D6-J2PIN8, D7-J2PIN10)
KAMODKB4x4: ( ROW1 – J3PIN9, ROW2 – J3PIN15, ROW3- J3PIN27, ROW4-J3PIN29,
COL1-J3PIN17, COL2-J3PIN19, COL3-J3PIN21, COL4-J3PIN23)
Rysunek 5. Schemat ideowy dołączenia modułów do płyty prototypowej BF210
tury. Schemat ideowy dołączenia modułów do
płyty prototypowej BF210 przedstawiono na
rysunku 5
.
Linie LED-ów zostały dołączone odpo-
wiednio do linii portów PB1, PB2, PB6, PB7,
natomiast linie wierszy i kolumn odpowiednio
do linii PB26, PB29, PC5, PC6, PC0, PC1, PC2,
PC3. Dzięki możliwości włączenia wbudowa-
nych w linie GPIO rezystorów podciągających,
nie będą potrzebne dodatkowe rezystory, a po-
łączenie wszystkich modułów możemy doko-
nać np. za pomocą przewodów CAB, do naby-
cia w irmie Kamami.
Konigurowanie jądra.
Jak już wcześniej
wspomniano, lista dostępnych urządzeń na
danej maszynie determinowana jest za pomo-
cą struktur
platform-device.
BF210 jest płytą
prototypową zatem z uwagi na niemożliwość
określenia przeznaczenia a zatem przypisa-
nia linii GPIO, nie jest możliwe dostarczenie
gotowego binarnego jądra, które nadaje się
do wykorzystania we wszystkich projektach.
W związku z tym w przypadku dołączenia
urządzeń które nie są Plug&Play (u nas tylko
USB), i wykorzystaniu sterowników jądra, bę-
dziemy zmuszeni do edycji kodu źródłowego
jądra, a konkretnie pliku odpowiedzialnego za
konigurację maszyny, oraz rekompilację jądra.
W przypadku płyty prototypowej BF210, kod
linuxa jest zdeiniowany w pliku a
rch/arm/
mach-at91/board-boff210.c
. Na
listingu
3
prze-
stawiono fragment struktur, odpowiedzialnych
za informację, o dołączeniu klawiatury matry-
cowej, oraz diod LED.
Na początku tworzona jest tablica, zawie-
rająca przypisanie poszczególnych wierszy
i kolumn, do odpowiedniego kodu klawiszy.
Następnie na podstawie tablicy mapy two-
rzona jest struktura
matrix_keypad_data
, do
której przypisujemy mapę stworzonych klawi-
szy. Mapa ta określa kod klawisza, zwrócony
w wyniku wykrycia wciśnięcia na przecięciu
odpowiedniej kolumny i odpowiedniego wier-
sza. Następnie tworzone są dwie tablice zawie-
rające mapę przypisań linii
GPIO
, do wierszy,
oraz kolumn. Następnie na bazie wcześniej
zdeiniowanych struktur tworzona jest struk-
tura
matrix_keypad_platform_data
stanowią-
ca informację dla sterownika
matrix-keypad
.
Pole
keymap_data
, zawiera przypisanie wcze-
śniej utworzonej koniguracji klawiszy. Pola
row_gpios
,
num_row_gpios
zawierają odpo-
wiednio przypisania mapy linii GPIO, które
stanowią linie kolumn, oraz ilość linii. Podob-
nie sytuacja wygląda w przypadku przypisania
linii GPIO wierszy. Pole
con_scan_delay_us
,
określa opóźnienie pomiędzy wystawieniem
stanu na linii wierszy, a odczytaniem stanu
97
ELEKTRONIKA PRAKTYCZNA 5/2011
KURS
wać koni gurację jądra
ex2_coni g
do pliku
.coni g
w katalogu
linux-2.6.37
(
polecenie cp
ex2_coni g linux-2.6.37/.coni g
) . Następnie
należy zmienić bieżącą ścieżkę aby znaleźć
się w katalogu
linux 2.6.37,
a następnie wy-
wołać polecenie
make oldconi g ARCH=arm
,
co spowoduje skoni gurowanie jądra według
załączonego pliku .coni g. Po skoni gurowaniu
jądra możemy przystąpić do jego kompilacji za
pomocą polecenia:
make uImage ARCH=arm
.
Po dłużej chwili w katalogu
uImage
pojawi się
gotowy plik binarny z jądrem. Tak przygoto-
wane jądro możemy wgrać do katalogu
/boot
na karcie docelowej. Kolejną czynnością jest
kompilacja modułów jądra, która odbywa się
z wykorzystaniem polecenia
make modules
ARCH=arm
. Podobnie moduły jądra należy
wgrać na kartę docelową np. poprzez zamo-
towanie karty w katalogu
/mnt
, a następnie
wydanie polecenia make
modules_install IN-
STALL_MOD_PATH=/mnt/
Aplikacja przestrzeni użytkownika matri-
xkbd.
Aby zademonstrować użycie klawiatury
matrycowej, oraz diod LED z wykorzystaniem
podsystemów
input
, oraz
led
, napisano bardzo
prostą aplikację przestrzeni użytkownika, któ-
ra w momencie wciśnięcia klawisza, będzie za-
palała diody
LED
przypisane do danego klawi-
sza, oraz powodowała wyłączenie diod w mo-
mencie puszczenia klawisza. Jednocześnie na
standardowym wyjściu (konsoli) wypisywane
będą komunikaty informujące o otrzymywa-
nych zdarzeniach klawiatury typu
EV_KEY
.
(Kod źródłowy aplikacji znajduje się w pliku
matrixkbd.c
) Klawiatura widoczna będzie jako
plik
/dev/input/event0
, natomiast diody
D0..
D3
, widoczne będą jako katalogi
/sys/class/ledX
(gdzie X=0-3)
. Włączanie oraz wyłączanie
diod LED realizowane jest za pomocą funkcji
led_ctl
(
listing
4
).
Funkcja ta jako argument
no
przyjmuje
numer porządkowy diody (0–3), określająca nr
diody, natomiast jako argument
value
, przyj-
muje wartość oznaczająca czy ma być ona włą-
czona czy wyłączona. Jej działanie jest bardzo
proste i sprowadza się do wpisania za pomocą
funkcji write() do pliku
brightness
odpowied-
niej diody, wartości 0 lub 1.
Program zaczyna wykonywanie od funk-
cji
main
w której realizowany jest odczyt sta-
nu kodów klawiszy (
listing
5
).
Na początku za pomocą wywołania sys-
temowego
open()
, jest otwierane urządzenie
/dev/input/event0
reprezentujące klawiaturę.
Następnie za pomocą funkcji
ioctl()
pobierana
jest nazwa klawiatury, co może być użyteczne
w przypadku gdy mamy do czynienia z więk-
szą ilością urządzeń wejściowych. (W naszym
przypadku mamy jedno urządzenie, więc po
prostu otwieramy
/dev/input/event0
), a na-
stępnie wypisujemy nazwę jaka została przy-
pisana urządzeniu klawiatury matrycowej.
Następnie program wchodzi do pętli nieskoń-
czonej, gdzie zdarzenia od klawiatury odczy-
tywane są za pomocą wywołania systemowe-
go
read()
. Wywołanie to spowoduje uśpienie
procesu, do momentu wystąpienia zdarzenia,
na interfejsie
event0
. W przypadku wystąpie-
nia zdarzenia tablica struktur events zostanie
wypełniona. Następnie w pętli
for()
odczyty-
wane są wszystkie zdarzenia. W przypadku
Listing 3. Fragmenty struktur odpowiedzialnych za informację o dołączeniu
klawiatury matrycowej oraz diod LED
static
const
uint32_t
keymap[] =
{
KEY(0, 0, KEY_1),
KEY(0, 1, KEY_4),
KEY(0, 2, KEY_7),
KEY(0, 3, KEY_ENTER),
KEY(1, 0, KEY_2),
KEY(1, 1, KEY_5),
KEY(1, 2, KEY_8),
KEY(1, 3, KEY_0),
KEY(2, 0, KEY_3),
KEY(2, 1, KEY_6),
KEY(2, 2, KEY_9),
KEY(2, 3, KEY_ESC),
KEY(3, 0, KEY_A),
KEY(3, 1, KEY_B),
KEY(3, 2, KEY_C),
KEY(3, 3, KEY_D),
};
static
const
struct
matrix_keymap_data keymap_data =
{
.keymap = keymap,
.keymap_size = ARRAY_SIZE(keymap)
};
static
const
uint32_t
row_gpios[] =
{
AT91_PIN_PC0, AT91_PIN_PC1, AT91_PIN_PC2, AT91_PIN_PC3
};
//PB26 PB29 PC5 PC6
static
const
uint32_t
col_gpios[] =
{
AT91_PIN_PB26, AT91_PIN_PB29, AT91_PIN_PC5, AT91_PIN_PC6
};
static
struct
matrix_keypad_platform_data keypad_confi g =
{
.keymap_data = &keymap_data,
.row_gpios = row_gpios,
.num_row_gpios = ARRAY_SIZE(row_gpios),
.col_gpios = col_gpios,
.num_col_gpios = ARRAY_SIZE(col_gpios),
.col_scan_delay_us = 10,
.debounce_ms = 10,
.active_low = 1, /* pull up realization */
.no_autorepeat = 0,
.wakeup = 1
};
static
struct
platform_device keypad_device =
{
.name = “matrix-keypad”,
.id = -1,
.dev =
{
.platform_data = &keypad_confi g,
},
};
static
struct
gpio_led leds[] =
{
{
.name = “led0”,
.gpio = AT91_PIN_PB1
},
{
.name = “led1”,
.gpio = AT91_PIN_PB2
},
{
.name = “led2”,
.gpio = AT91_PIN_PB6
},
{
.name = “led3”,
.gpio = AT91_PIN_PB7
}
};
Listing 4. Funkcja led_ctl
//Led enable disable
static
void
led_ctl(
int
no,
bool
value )
{
char
name_buf[128];
//Create led by name
snprintf(name_buf,sizeof(name_buf),”/sys/class/leds/led%i/brightness”,no);
int
led_fd = open(name_buf, O_WRONLY); //Open the led fi le
error( led_fd );
int
led_wr = write( led_fd, value?”1”:”0”,1); //Write the led value
error( led_wr );
close( led_fd ); //Close the led handle
}
98
ELEKTRONIKA PRAKTYCZNA 5/2011
Wprowadzenie do Linux’a embedded
Listing 5. Odczyt stanu kodów klawiszy
//Main loop
int
main(
void
)
{
//Input event device0
int
input_fd = open(“/dev/input/event0”,O_RDONLY);
error(input_fd);
//Get device name
{
char
buf[128];
int
ioctl_ret = ioctl(input_fd,EVIOCGNAME(sizeof(buf)),buf);
error(ioctl_ret);
printf(“Input device name: %s\n”,buf);
}
//Handle input events
struct
input_event event[MAX_KEY_MSGS];
for(;;)
{
int
input_rd = read(input_fd,event,sizeof(event));
error(input_rd);
for (
size_t
i=0; i< input_rd/sizeof (
struct
input_event);i++)
if( event[i].type == EV_KEY ) //Interested only with key event
on_key(&event[i]);
}
close( input_fd );
return
0;
}
Listing 7. Przykładowe komunikaty
wyświetlane przez konsolę Linux
root@bf210-at91:~# matrixkbd
Input device name: matrix-keypad
Got key scancode 10 value PRESSED
Got key scancode 10 value RELEASED
Got key scancode 10 value PRESSED
Got key scancode 10 value RELEASED
Got key scancode 48 value PRESSED
Got key scancode 48 value RELEASED
Got key scancode 30 value PRESSED
Got key scancode 30 value RELEASED
Got key scancode 4 value PRESSED
Got key scancode 4 value RELEASED
Got key scancode 3 value PRESSED
Got key scancode 3 value RELEASED
Got key scancode 9 value PRESSED
Got key scancode 9 value RELEASED
Got key scancode 48 value PRESSED
Got key scancode 48 value REPEAT
Got key scancode 48 value REPEAT
Got key scancode 48 value REPEAT
Got key scancode 48 value REPEAT
Got key scancode 48 value REPEAT
Got key scancode 48 value RELEASED
systemem Linux, oraz jądrem dostosowanym
do potrzeb bieżącego odcinka jest dostarcza-
ny w postaci pliku obrazu
example2.img.
Przykład można nagrać na czystą kartę SD,
w sposób analogiczny jak opisano w poprzed-
nim artykule, a następnie tak nagraną kartę
umieścić w złączu BF210 i włączyć napięcie
zasilające. Po uruchomieniu linuksa należy
zalogować się do konsoli jako root, a następ-
nie uruchomić program wpisując polecenie
matrixkbd
. Teraz wciskając i zwalniając kla-
wisze klawiatury matrycowej, będziemy mo-
gli obserwować zapalanie odpowiednich diod
LED w minimodule
KAMODLED8
, oraz ob-
serwować komunikaty w konsoli Linux’owej,
na której jest uruchomiony program. Przykła-
dowy fragment komunikatów umieszczono
na
listingu
7
.
W komunikatach aplikacji możemy zo-
baczyć początkową nazwę urządzenia wej-
ściowego, które zostało ustalone w strukturze
platform-data, następnie widzimy informację
o kolejnych wciśnięciach i zwolnieniach kla-
wisza, oraz w przypadku trzymania klawisza
możemy obserwować ciągłe komunikaty, ge-
nerowane przez mechanizm auto powtarza-
nia.
Listing 6. Funkcja on_key obsługująca zdarzenie naciśnięcia klawisza
//Handle input event
static void on_key(const
struct
input_event *ev)
{
printf( “Got key scancode %d value %s\n”,ev->code, ch_keyval(ev->value) );
if
( ev->value == KEYV_PRESS)
//MAP keyboyard scancodes to key
switch
( ev-> code)
{
case
KEY_1: led_bitmask(1);
break
;
case
KEY_2: led_bitmask(2);
break
;
case
KEY_3: led_bitmask(3);
break
;
case
KEY_4: led_bitmask(4);
break
;
case
KEY_5: led_bitmask(5);
break
;
case
KEY_6: led_bitmask(6);
break
;
case
KEY_7: led_bitmask(7);
break
;
case
KEY_8: led_bitmask(8);
break
;
case
KEY_9: led_bitmask(9);
break
;
case
KEY_0: led_bitmask(10);
break
;
case
KEY_A: led_bitmask(11);
break
;
case
KEY_B: led_bitmask(12);
break
;
case
KEY_C: led_bitmask(13);
break
;
case
KEY_D: led_bitmask(14);
break
;
case
KEY_ENTER: led_bitmask(15);
break
;
default
: led_bitmask(0);
break
;
}
else
if
( ev->value == KEYV_RELEASE) led_bitmask(0);
}
otrzymania zdarzenia typu
EV_KEY
, wywo-
ływana jest funkcja
on_key()
, która jako argu-
ment przyjmuje wskaźnik na strukturę
input_
event
reprezentującą zdarzenie (
listing
6
).
Funkcja ta na początku wypisuje kod wci-
śniętego klawisza, oraz jego stan (wciśnięty,
zwolniony, autopotarzanie). W przypadku
gdy mamy do czynienia z wciśnięciem kla-
wisza, w zależności od numeru klawisza wy-
woływana jest funkcja
led_bitmask()
, która
powoduje włączenie odpowiednich diod LED
przypisanych do danego klawisza. W przy-
padku, wystąpienia zdarzenia od zwolnienia
klawisza, wywoływana jest funkcja
led_bit-
mask(0)
, co powoduje wyłączenie wszystkich
diod LED.
Uruchomienie przykładu na BF210.
Skompilowany przykład, wraz z kompletnym
Lucjan Bryndza, EP
lucjan.bryndza@ep.com.pl
REKLAMA
99
ELEKTRONIKA PRAKTYCZNA 5/2011
Plik z chomika:
IZOPROPYL
Inne pliki z tego folderu:
Wentylatory.pdf
(1666 KB)
Star Wars. Katalizator. Wprowad - James Luceno.pdf
(1665 KB)
Gordon R. Dickson - Smoczy rycerz T2.pdf
(1663 KB)
LOKOMOTYWA TOWAROWA EMD JT42CWRM(Class66).pdf
(1662 KB)
Greer Luanshya - Kto sieje wiatr 02 - Po burzy spokój.pdf
(1660 KB)
Inne foldery tego chomika:
- - 2025--FULL---
- - 2024 FILMY NOWE
- WIN DROID IOS - HASŁO ARHIWÓW I FOLD - 1111
█ DUŻY MIX █
12.000 FILMÓW
Zgłoś jeśli
naruszono regulamin