2008.11_Mechanizmy czasu rzeczywistego w Linux_[Programowanie].pdf
(
1018 KB
)
Pobierz
439033276 UNPDF
Programowanie
Mechanizmy czasu rzeczywistego okiem programisty sterowników
rzeczywistego w Linux
Michał Strasburger
Jakiś czas temu na łamach magazynu Linux+ ukazał się artykuł o RTLinux opisujący mechanizmy czasu
rzeczywistego bazujące na mikrojądrze, w tym artykule opisane zostaną te dostarczane standardowo w
każdej dystrybucji linuksa z jądrem gałęzi 2.6, począwszy od wersji 2.6.9.
R
ozwój systemu operacyjnego linux w kierunku
korzystują systemy czasu rzeczywistego do przetwarza-
nia danych, symulowania przepływu informacji (ruchu sie-
ciowego) i testowania urządzeń sieciowych. Nawet produ-
cenci urządzeń multimedialnych audio i video korzystają
z usług systemów czasu rzeczywistego. Przykładowe apli-
kacje z wykorzystaniem systemu operacyjnego Linux i me-
chanizmów czasu rzeczywistego można znaleźć w [1], [2],
[3] (Ramka
W Sieci
).
Przykłady zastosowań
systemów czasu rzeczywistego
Systemy czasu rzeczywistego znajdują zastosowanie
w przemyśle, gdzie są wykorzystywane do precyzyjne-
go sterowania i nadzoru robotów, procesów technologicz-
nych i linii produkcyjnych. Spotkamy je w aplikacjach dla
środowisk dużego i podwyższonego ryzyka, takich jak ste-
rowanie elektrowni atomowych, systemy nawigacji i kon-
troli lotów, medyczne systemy podtrzymania życia pa-
cjentów. W przemyśle samochodowym systemy czasu rze-
czywistego realizują funkcje ABS, ESP i bezpośredniego
wtrysku paliwa. Nie wszystkie zadania systemów czasu
rzeczywistego są tak odpowiedzialne. Dostawcy usług te-
lekomunikacyjnych i producenci sprzętu sieciowego wy-
Systemy czasu rzeczywistego
System czasu rzeczywistego musi zagwarantować określo-
ny czas odpowiedzi na określone zjawiska zewnętrzne. Do-
stępny czas reakcji dzieli się na szereg czynności wykony-
wanych w ramach obsługi zdarzenia. I tak część czasu reak-
cji przypada z reguły:
• sensorowi, który wykrywa zjawisko,
• modułowi programu, który je analizuje i decyduje o
sposobie odpowiedzi,
• modułowi, który reaguje na zjawisko,
• nieprzewidzianym opóźnieniom (ok. 20-30% czasu re-
akcji)
54
listopad 2008
Mechanizmy czasu
wsparcia systemów wbudowanych (
embedded
)
i systemów czasu rzeczywistego (
realtime
)
osiągnął już bardzo dojrzały etap. Przyjrzyjmy
się, jakie mechanizmy można wykorzystać do zagwaranto-
wania szybkości pracy cząstki systemu czasu rzeczywistego,
jaką jest sterownik urządzenia.
Programowanie
Mechanizmy czasu rzeczywistego okiem programisty sterowników
W klasyikacji systemów czasu rzeczywi-
stego ocenia się rolę systemu w środowisku
jego pracy i potencjalne straty spowodowa-
ne przekroczeniem wymaganego czasu reak-
cji na bodziec. Pod tym względem dzielimy
je na dwie grupy. Pierwsza obejmuje syste-
my o bezwzględnych wymogach czasu reak-
cji (
hard
-
realtime
) a druga te, w których wy-
mogi czasu reakcji mogą być w wyjątkowych
sytuacjach przekraczane (
soft
-
realtime
). Przy-
kładem systemu
hard
-
realtime
będzie układ
wspomagania hamowania w samochodzie,
gdzie kilka milisekund dodatkowego opóźnie-
nia może spowodować utratę przyczepności
samochodu do nawierzchni i bezpośrednie za-
grożenie życia pasażerów. Przykładem sytemu
typu
soft
-
realtime
może być system nawiga-
cji satelitarnej, w którym opóźnienie wyświe-
tlanej informacji o trasie (nawet o kilkadzie-
siąt milisekund) nie zostanie w żaden sposób
odczute przez kierowcę. Dodatkowo systemy
typu
hard
-
realtime
charakteryzują się czasem
reakcji znacząco krótszym niż systemy typu
soft
-
realtime
. Do zastosowań typu hard-real-
time preferowane są rozwiązania dostarcza-
ne przez system operacyjny Linux z mikro-
jądrem, czyli wydzieloną częścią jądra, która
obsługuje tylko zadania o najwyższych prio-
rytetach. Do zastosowań soft-realtime z powo-
dzeniem można zastosować mechanizmy opi-
sane w tym artykule.
Twórca systemu czasu rzeczywistego za-
cznie od usunięcia z Linuksa niepotrzebnych
plików, programów, usług i modułów jądra;
my ograniczymy się tylko do tych modyika-
cji, które mają bezpośredni wpływ na nasz ste-
rownik. Po koniguracji jądra systemu opisane
zostaną mechanizmy, jakich możemy użyć w
procesie implementacji dla przyspieszenia do-
stępu do urządzenia i przyspieszenia wykony-
wania zadań sterownika. Prezentowane me-
chanizmy zakładają jednoprocesorową wersję
jądra, bazują na rozszerzeniach czasu rzeczy-
wistego posix1.b, posix1.c i innych mechani-
zmach dostarczanych w każdej dystrybucji Li-
nuksa, co gwarantuje przenośność kodu. Opisa-
ne mechanizmy poparte zostaną przykładami.
Zapraszam do lektury.
mie. Służy do tego zmienna HZ, zależna od ar-
chitektury i określająca częstotliwość przerwań
zegara systemowego. Dotychczas była ona
standardowo ustawiana na 100 powodując ge-
nerację przerwania zegarowego co 10 milise-
kund. Obecnie można jej wartość ustawić na-
wet na 1000, umożliwiając tym samym dzie-
sięciokrotnie częstsze przełączanie między pro-
cesami wykonywanymi w systemie. Oznacza
to szybsze dopuszczenie sterownika do pracy
w sytuacji, gdy ma on obsłużyć jakieś zdarze-
nie. Dodatkowo musimy się upewnić, że żad-
ne opcje oszczędzania energii nie są włączone,
a procesor będzie taktowany z najszybszą moż-
liwą częstotliwością.
Wydziedziczanie procesów wykonywa-
nych w trybie jądra (kernel preemption)
Zmiana częstotliwości przełączania proce-
sów w systemie nic nam nie da, jeżeli nie
zmusimy systemu operacyjnego do wydzie-
dziczania procesów wykonywanych w trybie
jądra. Standardowo w Linuksie proces uru-
chomiony wykonuje się aż skończy pewne
zadanie i sam decyduje o zwolnieniu proce-
sora. W takiej sytuacji czas odpowiedzi sys-
temu jest zdeterminowany przez czas wyko-
nywania najdłuższego zadania. Naszą inten-
cją jest wydziedziczenie procesu (odebranie
mu zasobów procesora), jeżeli jego czas wy-
konywania może spowodować przekroczenie
Tabela 1.
Klasyikacja systemów z uwzględnieniem czasu reakcji na pobudzenie
HARD-REALTIME
SOFT-REALTIME
WYMOGI CZASU REAKCJI
- jakość systemu określa najgorszy możliwy przy-
padek w opóźnieniu obsługi zdarzenia
- możliwość utraty części zdarzeń czasu reakcji
czyli pozostawienia ich bez obsługi
(niedopuszczalne zgubienie zdarzenia)
- jakość usługi określa statystyczny przypadek
- możliwość utraty części zdarzeń czyli pozostawie-
nia ich bez obsługi
- czas reakcji rzędu dziesiątek mikrosekund - czas reakcji rzędu dziesiątek/setek milisekund
SKUTKI PRZEKROCZENIA CZASU REAKCJI
- zagrożenie zniszczenia systemu lub zdrowia/życia
użytkownika
- pogorszenie jakości usług systemu (np. obra-
zu wideo)
Tabela 2.
Koniguracja jądra systemu linux do zastosowań w systemach czasu rzeczywistego
Lp Opcja
Sposób koniguracji
1. Częstotliwość przełącza-
nia zadań w systemie
Processor type and features → Timer frequency (250 HZ) -> (*) 1000
HZ
Processor type and features → [ ] Tickless System (Dynamic Ticks)
Power management options (ACPI, APM) ---> [*] CPU Frequency sca-
ling
[*] 'performance' governor
2. Wydziedziczanie pro-
cesów
Preemption Model ---> (*) Preemptible Kernel (Low-Latency Desktop)
[*] Voluntary Preemption
[*] Preempt The Big Kernel Lock
[*] Enable kernel irq balancing
3. Mechanizmy standardu
POSIX 1.b, 1.c
General setup → [*] System V IPC
[*] IPC Namespaces
[*] POSIX Message Queues
Processor type and features → [*] High Resolution Timer Support
[*] HPET Timer Support
Koniguracja jądra systemu
W Tabeli 2. zaprezentowano wybrane, omó-
wione poniżej opcje koniguracji jądra syste-
mu Linux do zastosowań w systemach czasu
rzeczywistego.
4. Optymalizacja obsługi
przerwań
Preemption Model ---> (*) Preemptible Kernel (Low-Latency Desktop)
[*] Enable kernel irq balancing
5. Opcje przydatne w pro-
cesie tworzenia aplikacji
(NIE MOGĄ BYĆ WŁĄ-
CZONE W DOCELO-
WYM SYSTEMIE)
Kernel hacking ---> Kernel debugging --->
[*] Collect scheduler statistics (NEW)
[*] Collect kernel timers statistics (NEW)
[*] RT Mutex debugging, deadlock detection
(NEW)
[*] Mutex debugging: basic checks (NEW)
[*] Write protect kernel read-only data struc-
tures (NEW)
Tajemnicza zmienna HZ.
Pierwszą rzeczą, jaką ma do dyspozycji projek-
tant sterownika jest koniguracja częstotliwości
potencjalnego przełączania procesów w syste-
www.lpmagazine.org
55
Programowanie
Mechanizmy czasu rzeczywistego okiem programisty sterowników
czasu reakcji systemu na bodziec zewnętrz-
ny. Do tego celu służy mechanizm zwany
kernel
preemption
.
Ta opcja narzuca nam styl programowa-
nia nazywany z ang.
reentant
coding
techni-
que
. Jest to sposób zabezpieczania się w pro-
gramach przed nieintencyjną zmianą danych
wykorzystywanych przez współbieżnie wyko-
nywane wątki aplikacji. Funkcja, która prze-
chowuje lokalny zbiór wartości dla każdego
wywołującego ją wątku jest funkcją tzw. wie-
lowejściową (
reentant
).
Niżej wymienione zasady skutecznie za-
bezpieczają nas przed korupcją danych:
Po włączeniu opcji wydziedziczania procesów
musimy jeszcze procesowi/wątkowi sterowni-
ka nadać odpowiednio wysoki priorytet, aby
mógł wydziedziczać inne procesy (w dalszej
części artykułu opisany zostanie sposób zmia-
ny priorytetu wątku).
• mechanizmy synchronizacji dostępu do
dzielonych zasobów: semafory i muteksy
• mechanizm komunikacji między wątkami
(message passing)
• pamięć dzielona między wątkami (shared
memory)
Rozszerzenia POSIX1.b i POSIX1.c
Dostrzegając chęć zastosowania Linuksa
w systemach
embedded
i
realtime
programi-
ści rozwijający system zaimplementowali dwie
grupy rozszerzeń systemowych mechanizmów
zdeiniowane w standardzie POSIX1.b i POSI-
X1.c Należą do nich:
POSIX1.c:
• wsparcie dla obsługi wielowątkowości w
obrębie jednego procesu obejmujące: two-
rzenie, kontrolę, synchronizację, prioryte-
ty i usuwanie wątków, jak również obsłu-
gę sygnałów przez wątki.
• użycie zmiennych lokalnych zamiast glo-
balnych,
• wyłączanie przerwań na czas wykonywa-
nia krytycznych operacji
• używanie systemowych mechanizmów
synchronizacji dostępu do dzielonych za-
sobów np. semafory czy muteksy
• kompilując kod naszego sterownika nale-
ży również użyć lagi
_REENTANT
POSIX1.b:
Zoptymalizowany
czas reakcji na przerwanie
Programista sterownika ma w tym przypadku
możliwość dwojakiego usprawnienia mechani-
zmu przerwań:
• algorytmy szeregowania procesów dla
systemów czasu rzeczywistego (np. Ro-
und Robin)
• wysokiej rozdzielczości zegary (high-reso-
lution timers)
• sygnały czasu rzeczywistego (realtime si-
gnals)
• zagwarantować niski czas opóźnienia re-
akcji na przerwanie, czyli minimalny czas
między zgłoszeniem przerwania i rozpo-
częciem jego obsługi (
low
interrupt
laten-
cy
)
• dodatkowo można jeszcze zoptymalizo-
wać czas reakcji na przerwanie pod wzglę-
dem powtarzalności czyniąc system bar-
dziej przewidywalnym – w tym przypad-
ku reakcja na przerwanie nie zawsze bę-
dzie tak błyskawiczna jak to możliwe, ale
czas do rozpoczęcia obsługi przerwania
będzie możliwie ujednolicony dla wszyst-
kich zdarzeń (
interrupt
balancing
)
Listing 1.
Prosty program sprawdzający wsparcie systemu dla wątków posix
#include “unistd.h”
#include “stdio.h”
int
main
(
void
)
{
long
rezultat
=
0L
;
printf
(
“\
n
Wsparcie
dla
w
ą
tk
ó
w
POSIX
:
“
);
rezultat
=
sysconf
(
_SC_THREADS
);
(
rezultat
>
0
?
printf
(
“
jest
.”
)
:
printf
(
“
brak
!
”
));
}
Opcje przydatne
podczas tworzenia aplikacji
W piątym wierszu Tabeli 2. pokazano opcje
koniguracji systemu pomocne w debugowaniu
i optymalizacji. Powinny one być wyłączone w
docelowym systemie, gdyż powodują dodatko-
we, znaczne opóźnienia w realizacji zadań sys-
temu operacyjnego.
Tabela 3.
Wybrane opcje standardu POSIX dla wsparcia aplikacji czasu rzeczywistego
OPCJA STANDARDU POSIX ZNACZENIE
_SC_THREADS
wsparcie dla wątków i muteksów w standardzie POSIX
_SC_THREAD_ THREADS_MAX
maksymalna ilość wątków możliwych do stworzenia w obrębie
jednego procesu
Mechanizm
komunikacji ze sprzętem
Standardowo sterowniki urządzenia to mo-
duły jądra, które komunikują się ze sprzę-
tem przez wywołania systemowe. Jest to
mechanizm wynikający z architektury sys-
temu i ze względów jego bezpieczeństwa,
czy jednak nadaje się do zastosowania w
systemach czasu rzeczywistego? Okazu-
je się, że nie zawsze! Jeżeli aplikacja mu-
si komunikować się z urządzeniem kilka-
krotnie zanim podejmie decyzję o reakcji,
to czas przełączania kontekstów jest zbyt
wysoką ceną za poprawną pracę urządzenia.
_SC_THREAD_ PRIORITY_SCHE-
DULING
wsparcie różnych algorytmów szeregowania i różnych warto-
ści priorytetów dla wątków w obrębie procesu
_SC_THREAD_ PRIO_INHERIT
wsparcie dla dziedziczenia priorytetów przez wątki
_SC_REALTIME_SIGNALS
wsparcie dla sygnałów czasu rzeczywistego
_SC_RTSIG_MAX
maksymalna liczba sygnałów czasu rzeczywistego dostęp-
nych dla jednej aplikacji
_SC_TIMERS
wsparcie dla zegarów czasu rzeczywistego
_SC_MONOTONIC_CLOCK
wsparcie dla źródła sygnału zegarowego napędzającego ze-
gary czasu rzeczywistego
_SC_SHARED_MEMORY_OBJECTS
wsparcie dla współdzielonych zasobów pamięci
_SC_MESSAGE_PASSING
wsparcie dla komunikacji międzywątkowej i międzyprocesoro-
wej (kolejek wiadomości)
56
listopad 2008
Programowanie
Mechanizmy czasu rzeczywistego okiem programisty sterowników
Wtedy pozostaje nam użycie mechanizmu
bezpośredniego dostępu do pamięci z apli-
kacji (z przestrzeni użytkownika!). Nie
każdy programista sterowników jest zwo-
lennikiem tej metody, ale znalazła ona po-
pularność i zastosowanie w tysiącach ste-
rowników dla urządzeń w systemach czasu
rzeczywistego i systemach wbudowanych.
Powszechnie znana jest jako metoda imple-
mentacji sterowników działających w prze-
strzeni użytkownika (
user
-
mode
drivers
). W
opinii autora jest nawet bardziej bezpieczną
metodą dostępu do urządzenia, gdyż niepo-
żądana próba dostępu do obszarów chronio-
nych pamięci z poziomu użytkownika skut-
kuje błędem aplikacji
segmentation
fault
a ten sam krok wykonany z przestrzeni ją-
dra może doprowadzić do niestabilności a
wręcz zawieszenia jądra systemu.
Listing 2.
Tworzenie wątku i deklaracja obsługi sygnału SIGINT
/* Adres początku pamięci sprzętowej urządzenia */
#deine POCZ_PAMIECI_URZADZENIA 0x0000
/* Rozmiar mapowanego obszaru pamięci */
#deine ROZMIAR_PAMIECI_URZADZENIA 0x1000
pthread_t
watek1_sterownika
=
(
pthread_t
)
0
;
pthread_t
watek2_sterownika
=
(
pthread_t
)
0
;
void
procedura_watku1
(
void
);
void
procedura_watku2
(
void
);
int
main
(
void
)
{
void
*
wsk_pamieci
=
(
void
*)
0
;
watek1_sterownika
=
pthread_self
();
if
(
signal
(
SIGINT
,
(
void
*)
wylacz_sterownik
)
=
=
SIG_ERR
)
{
printf
(
“\
n
Nie
udana
operacja
deklaracji
obs
ł
ugi
sygna
ł
u
”
);
}
Mechanizmy
komunikacji wątków sterownika
Aby zapewnić sterownikowi działającemu w
przestrzeni użytkownika szybkość pracy zakła-
damy implementację wielowątkową zamkniętą
w jednym procesie (POSIX1.c). Daje nam to
możliwość użycia zasobów dzielonych (
shared
memory
), mechanizmów przesyłania informa-
cji (
message
passing
) szybszych od IPC Syste-
mu V i synchronizacji za pomocą szybkich sy-
gnałów (
realtime
signals
), które umożliwiają
przekazywanie parametrów wraz z dostarcze-
niem sygnału do wątku.
wsk_pamieci
=
mapuj_pamiec
(
POCZ_PAMIECI_URZADZENIA
,
ROZMIAR_PAMIECI_URZADZENIA
);
if
(
wsk_pamieci
!=
0
)
{
printf
(
”\
n
Mapowanie
pami
ę
ci
nie
powiod
ł
o
si
ę”
);
return
(-
6
);
}
if
(
tworz_watki
()
<
0
)
{
printf
(
“\
n
Nie
udana
pr
ó
ba
stworzenia
w
ą
tk
ó
w
sterownika
”
);
return
(-
7
);
}
procedura_watku1
();
}
Mechanizmy
dostarczania przerwań do sterownika
• Sterownik informowany przerwaniem o
zmianie stanu urządzenia (
interrupt
-
dri-
ven
driver
). Ten akapit artykułu poświę-
cony został tak naprawdę jedynej sła-
bej stronie naszej koncepcji sterownika
pracującego w przestrzeni użytkowni-
ka. Tą słabą stroną jest brak szybkiego
i spójnego mechanizmu obsługi przerwań
z poziomu sterownika (przestrzeni użyt-
kownika). Prace nad stworzeniem takie-
go mechanizmu nadal trwają. Można so-
bie wyobrazić wykorzystanie mechani-
zmu obsługi przerwań w przestrzeni ją-
dra systemu i rejestrację obsługi prze-
rwania, w której jedynie generujemy sy-
gnał dostarczany do procesu sterowni-
ka aby poinformować go o przerwaniu.
W przypadku użycia sygnału czasu rze-
czywistego mamy gwarancję, że sygnał
dostanie dostarczony do procesu, ale nie
mamy gwarancji, że potrwa to tak krót-
ko jak tego oczekujemy. W 2006 roku
void
wylacz_sterownik
(
int
signo
)
{
puts
(
”
Sterownik
wylaczony
”
);
/* Zakończenie pracy wątków */
if
(
pthread_self
()
=
=
watek2_sterownika
)
{
/* Zwolnienie alokowanej pamięci */
puts
(
”\
nWatek
2
wylaczony
”
);
/* Unicestwienie wątku */
;
pthread_exit
((
void
*)
NULL
);
}
else
if
(
pthread_self
()
=
=
watek1_sterownika
)
{
puts
(
”\
nWatek
1
wylaczony
”
);
_exit
(
0
);
}
}
58
listopad 2008
Programowanie
Mechanizmy czasu rzeczywistego okiem programisty sterowników
pojawiła się idea zaprezentowana przez
Petera Chubb zrzeszonego w grupie ER-
TOS
1
(
Embedded
Real
-
Time
Operating
Systems
) polegająca na stworzeniu spe-
cjalnego pliku w systemie /proc, któ-
ry byłby odczytywany przez sterownik
aby sprawdzić czy wystąpiło przerwa-
nie. Koncepcja ta jednak nie gwarantuje
spójności. Biorąc pod uwagę brak gwa-
rancji, że procedura obsługi przerwania
kiedyś się skończy, jedynym sposobem
zabezpieczenia systemu przed zawiesze-
niem w takiej sytuacji jest wyłączenie
przerwania procesora i wymazanie la-
gi informującej o jego zgłoszeniu przed
rozpoczęciem obsługi przerwania. Spra-
wa komplikuje się dodatkowo, gdy nasz
sterownik ma obsłużyć kilka przerwań
o różnych priorytetach i dopuszczamy
ich zagnieżdżanie.
• Sterownik odpytujący o stan urządzenia
(
polling
-
driven
driver
). Sterownik urzą-
dzenia nie musi komunikować się ze
sprzętem wykorzystując przerwania (
in-
terrupt
-
driven
access
), większość urzą-
dzeń tego nie wymaga, alternatywą jest
cykliczne odpytywanie urządzenia o jego
stan (
polling
-
driven
access
). Możemy so-
bie wyobrazić, że urządzenie, do którego
piszemy sterownik generuje zdarzenie nie
częściej niż co 10 milisekund i informuje
o nim procesor, aby ten mógł je obsłużyć.
Procesor może mieć wyłączone przerwa-
Listing 3.
Funkcja mapuje obszar pamięci izycznej urządzenia do obszaru pamięci wirtualnej procesu sterownika
#include
<unistd.h>
#include
<sys/mman.h>
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<fcntl.h>
#include
<stdio.h>
printf
(
"Otwarcie /dev/mem nie powiodło się, kod
błędu: %d!
\n
"
,
dp
);
return
((
void
*)-
4
);
}
/* Mapowanie pamieci urzadzenia do przestrzeni
adresowej procesu */
mem_wsk
=
mmap
(
NULL
,
dlugosc_mapy
,
(
PROT_READ
|
PROT_WRITE
)
,
MAP_SHARED
,
dp
,
adres_izyczny
);
void
*
mapuj_pamiec
(
off_t
adres_izyczny
,
size_t
dlugosc_
mapy
)
{
int
dp
;
/* deskryptor pliku */
void
*
mem_wsk
;
/* wskaznik na zmapowany obszar
pamieci urzadzenia
(wirtualny adres w przestrzeni adresowej procesu)
*/
if
((
mem_wsk
==
MAP_FAILED
)
||
(
mem_wsk
==
NULL
))
{
printf
(
"Mapowanie pamięci urządzenia nie
powiodło się
\n
"
);
close
(
dp
);
return
((
void
*)-
5
);
}
/* Tylko root może otrzymać dostęp do /dev/mem */
if
(
geteuid
()
!=
0
)
{
printf
(
"Brak uprawnień do otwarcia /dev/mem!
(uruchom z uprawnieniami roota)
\n
"
);
return
((
void
*)-
1
);
}
/* Zamkniecie pliku odwzorowującego pamięć systemu
(/dev/mem) */
if
(
close
(
dp
)
!=
0
)
{
printf
(
"Zamkniecie /dev/mem nie powiodło się!
\
n
"
);
}
return
(
mem_wsk
);
}
/* Weryikacja adresu izycznego początku mapowanego
obszaru pamięci */
if
((
adres_izyczny
%
PAGE_SIZE
)
!=
0
)
{
printf
(
"Adres izyczny nie jest wielokrotnością
PAGE_SIZE)!
\n
"
);
return
((
void
*)-
2
);
}
/* przykłady dostępu do rejestrów urządzenia,
// zdeiniować jeden z poniższych trybów dostępu
// (uwaga, specyiczne dla kompilatora):
/* Weryikacja zakresu mapowanego obszaru pamieci */
if
((
dlugosc_mapy
%
PAGE_SIZE
)
!=
0
)
{
printf
(
"Długość mapowanego obszaru pamięci musi
być wielokrotnością PAGE_SIZE!
\n
"
);
return
((
void
*)-
3
);
}
//#deine ACCESS_MODE (unsigned int)
/* 32-bitowy */
//#
deine
ACCESS_MODE
(
unsigned
short
int
)
/* 16-bitowy */
//#
deine
ACCESS_MODE
(
unsigned
char
)
/* 8-bitowy */
/* Otwarcie pliku odwzorowujacego pamiec systemu (/
dev/mem) w trybie rw */
dp
=
open
(
"/dev/mem"
,
O_RDWR
|
O_SYNC
)
<
0
)
if
(
dp
<
0
)
{
//
Zapis
warto
ś
ci
do
rejestru
:
*((
volatile
ACCESS_MODE
*)(
adres_rejestru
))
=
wartosc
;
//
Odczyt
warto
ś
ci
rejestru
:
wartosc
=
(
ACCESS_MODE
)*((
volatile
ACCESS_MODE
*)(
adres_
rejestru
));
*
/
www.lpmagazine.org
59
Plik z chomika:
SOLARIX33
Inne pliki z tego folderu:
2006.01_Koder plików w formacie OGG_[Programowanie].pdf
(722 KB)
2007.06_Piękno fraktali_[Programowanie].pdf
(1778 KB)
2008.11_GanttProject_[Programowanie].pdf
(1014 KB)
2007.04_USB Device Explorer_[Programowanie].pdf
(1134 KB)
2006.09_QT, PyQT – szybkie tworzenie baz danych_[Programowanie].pdf
(1319 KB)
Inne foldery tego chomika:
Administracja
Aktualnosci
Audio
Bazy Danych
Bezpieczenstwo
Zgłoś jeśli
naruszono regulamin