CPU-metr.pdf

(241 KB) Pobierz
CPU-meter do PC-ta
P R O J E K T Y
CPU−meter do PC−ta
Przedstawiony tutaj
sprzÍtowy wskaünik obci¹øenia
procesora PC-ta wykorzystuje
prosty i†³atwo dostÍpny
sprzÍt (port Centronics) oraz
dosyÊ z³oøony niskopoziomowy
software w†Delphi. Na
szczÍúcie wiÍkszoúÊ pracy
zosta³a juø wykonana i†tylko
czeka na po³¹czenie
w†dzia³aj¹c¹ ca³oúÊ...
Rekomendacje : dla osÛb
chc¹cych rozbudowaÊ swÛj
komputer o†prosty, lecz
efektowny wskaünik
obci¹øenia, bÍd¹cy rÛwnieø
doskona³¹ baz¹ dla dalszych
eksperymentÛw.
Miernik obci¹øenia procesora
jest obecny w†niemal kaødym sys-
temie operacyjnym, czÍsto bywa
wrÍcz zintegrowany z†pow³ok¹, jak
w†przypadku Sun Solaris. Popu-
larne Windowsy rÛwnieø standar-
dowo wyposaøone s¹ w† Monitor
Systemu i† Miernik ZasobÛw . Pro-
ponujemy tutaj pewn¹ alternaty-
wÍ dla typowego, programowego
wyúwietlania czasu zajÍtoúci pro-
cesora przez przeniesienie aktual-
nego wskazania wraz z†wykresem
na zewn¹trz komputera. Idealnym
rozwi¹zaniem wydaje siÍ zastoso-
wanie powoli odchodz¹cego
w†niepamiÍÊ interfejsu Centronics
do sterowania wyúwietlaczem al-
fanumerycznym LCD. Ma to tym
wiÍkszy sens, øe port rÛwnoleg³y
bardzo czÍsto bywa niewykorzys-
tany, jako øe jego rolÍ przejmuje
powoli USB. Ca³oúÊ projektu zo-
sta³a przygotowana dla wyúwiet-
laczy LCD kompatybilnych ze
standardem HD44780. DostÍpnoúÊ
tego typu wyúwietlaczy obecnie
nie jest øadnym problemem. Tak
wiÍc kluczem obwodu elektrycz-
nego jest interfejs portu rÛwnoleg-
³ego z†wyúwietlaczem. SposÛb re-
alizacji tego interfesju pokazano
na rys. 1 . Jak widaÊ, schemat nie
jest szczegÛlnie skomplikowany,
komentarz do niego nie musi byÊ
zbyt obszerny.
Magistrala danych D0...D7 jest
sterowana bezpoúrednio przez wyj-
úcia danych portu Centronics. Bit
prze³¹czaj¹cy miÍdzy zapisem
i†odczytem z†wyúwietlacza (R/!W)
zosta³ sprzÍtowo ustawiony na
zapis. Powodem tego jest brak
moøliwoúci prostego odczytu da-
nych z†wyúwietlacza, poniewaø
z†magistrali danych portu rÛwno-
leg³ego w†standardowym trybie
(SPP) nie moøna czytaÊ. Dlatego
implementacja odczytu danych
z†LCD (w tym rÛwnieø dosyÊ
przydatnej flagi zajÍtoúci) bardzo
by siÍ skomplikowa³a i†zosta³a
od³oøona na przysz³oúÊ. Pozosta³e
bity steruj¹ce prac¹ wyúwietlacza,
tzn. prze³¹czanie dane/komenda
(RS) oraz taktowanie (E), s¹ ob-
s³ugiwane przez odpowiednie syg-
na³y portu rÛwnoleg³ego (SELECT
IN oraz STROBE). Standardowy
wyúwietlacz alfanumeryczny LCD
wymaga jeszcze podania dodatko-
wego napiÍcia steruj¹cego kontra-
stem na wejúcie oznaczone Vo.
W†niektÛrych modelach wystarcza
napiÍcie bliskie 0V, a†w†innych
niezbÍdne jest wrÍcz napiÍcie
ujemne. W†tym celu do obwodu
elektrycznego dodany zosta³ op-
cjonalny modu³ zasilania -5 V†zbu-
dowany w†oparciu o†przetwornicÍ
ICL7660. Potencjometr 10 k
umoøliwia p³ynn¹ regulacjÍ na-
Elektronika Praktyczna 5/2003
35
CPU−meter do PC−ta
32578018.029.png 32578018.030.png
CPU−meter do PC−ta
List. 1. Program odpowiedzialny
za wysyłanie danych do portu
I/O
procedure prt(portn: word; val: byte);
begin
asm
mov al,val
mov dx,portn
out dx,al
end;
end;
List. 2. Procedura wysyłająca
dane i polecenia do sterownika
wyświetlacza LCD
procedure write_LPT(a: byte; sterowanie:boo-
lean);
begin
if sterowanie=TRUE then
begin
prt(LPT+$02,$09); { RS=0, E=0 }
prt(LPT+$00,a); { rozkaz }
prt(LPT+$02,$01); { RS=0, E=1 }
prt(LPT+$02,$09); { RS=0, E=0 }
end else
begin
prt(LPT+$02,$08); { RS=1, E=0 }
prt(LPT+$00,a); { dana }
prt(LPT+$02,$00); { RS=1, E=1 }
prt(LPT+$02,$08); { RS=1, E=0 }
end;
end;
List. 3. Procedury realizujące:
konfigurację podczas inicjalizacji,
czyszczenie ekranu, powrót
kursora, przesunięcie kursora,
wpisywanie znaków do CGRAM
procedure
lcd_define(d0,d1,d2,d3,d4,d5,d6,d7:byte);
{ definicja znaku do CGRAM }
begin
sleep(10);
write_LPT(d0,FALSE);
sleep(10);
write_LPT(d1,FALSE);
sleep(10);
write_LPT(d2,FALSE);
sleep(10);
write_LPT(d3,FALSE);
sleep(10);
write_LPT(d4,FALSE);
sleep(10);
write_LPT(d5,FALSE);
sleep(10);
write_LPT(d6,FALSE);
sleep(10);
write_LPT(d7,FALSE);
sleep(10);
end;
procedure lcd_init;
{ inicjalizacja wyswietlacza LCD }
begin
sleep(10);
write_LPT(32+16+8,TRUE);
sleep(10);
write_LPT(16+4,TRUE);
sleep(10);
write_LPT(8+4,TRUE);
sleep(10);
write_LPT(4+2,TRUE);
sleep(10);
write_LPT(1,TRUE);
sleep(1000);
write_LPT(64,TRUE);
sleep(10);
lcd_define(0,0,0,0,0,0,0,31);
lcd_define(0,0,0,0,0,0,31,31);
lcd_define(0,0,0,0,0,31,31,31);
lcd_define(0,0,0,0,31,31,31,31);
lcd_define(0,0,0,31,31,31,31,31);
lcd_define(0,0,31,31,31,31,31,31);
lcd_define(0,31,31,31,31,31,31,31);
lcd_define(31,31,31,31,31,31,31,31);
sleep(10);
end;
procedure lcd_clear;
{ czyszczenie ekranu wyswietlacza }
begin
write_LPT(1,TRUE);
end;
piÍcia kontrastu pomiÍdzy -5 V
a†+5 V. W†przypadku pominiÍcia
przetwornicy naleøy drugi zacisk
potencjometru zewrzeÊ zwork¹ do
masy. W†tym wypadku oczywiúcie
nie jest moøliwa generacja napiÍÊ
ujemnych, ale w†wielu nowych
typach wyúwietlaczy nie ma to
znaczenia.
Podstawow¹ procedur¹ przy
obs³udze portu jest wys³anie da-
nej wartoúci na port I/O (odpo-
wiada za to program pokazany na
list. 1 ), zaimplementowany dla
jÍzykÛw Pascal firmy Borland (np.
Turbo Pascal i†Delphi) dziÍki
wbudowanemu asemblerowi. Pa-
rametrami tej procedury s¹ oczy-
wiúcie konkretna wartoúÊ oraz
adres I/O, na ktÛry wartoúÊ ta ma
zostaÊ wys³ana.
DziÍki powyøszej procedurze
moøna wysy³aÊ dane lub rozkazy
do wyúwietlacza. Wys³anie danej
od rozkazu rÛøni siÍ de facto
tylko stanem sygna³u steruj¹cego
RS, w†zwi¹zku z†czym warto zin-
tegrowaÊ obie te funkcje w†jedn¹
procedurÍ, pokazan¹ na list. 2 .
W†procedurze tej zmienna global-
na LPT oznacza adres bazowy
wybranego portu.
Jak juø stwierdzono wczeúniej,
dzia³anie portu rÛwnoleg³ego
w†trybie podstawowym nie po-
Teraz oprogramowanie
Po omÛwieniu prostego w†re-
alizacji obwodu elektrycznego po-
ra zaj¹Ê siÍ ìinteligencj¹î urz¹-
dzenia, ktÛra oczywiúcie zosta³a
zaszyta w†oprogramowaniu. Op-
rogramowanie to moøna podzieliÊ
na dwie czÍúci: procedury steru-
j¹ce wyúwietlaczem oraz modu³
pomiaru obci¹øenia procesora.
Podstaw¹ obs³ugi wyúwietlacza
jest oczywiúcie umiejÍtnoúÊ pro-
gramowania poszczegÛlnych syg-
na³Ûw steruj¹cych. W†tym przy-
padku moøna to osi¹gn¹Ê przez
pisanie do przestrzeni adresowej
portu LPT. PrzestrzeÒ ta rozci¹ga
siÍ przez kilka kolejnych bajtÛw
adresu bazowego, typowo 278h
lub 378h i†jest krÛtko podsumo-
wana w† tab. 1 .
procedure lcd_home;
{ powrot kursora }
begin
write_LPT(2,TRUE);
end;
procedure lcd_shift;
{ przesuniecie zawartosci wyswietlacza }
begin
write_LPT(16+8+4+1,TRUE);
end;
Rys. 1. Schemat elektryczny interfejsu
zwala na odczyt danej przez
magistralÍ D0...D7. Nie moøna
w†zwi¹zku z†tym odczytaÊ statusu
sterownika wyúwietlacza, a†kon-
kretnie czy jest gotowy do przy-
jÍcia kolejnej danej (bit BF). Roz-
wi¹zano ten problem w†nieco pry-
mitywny, aczkolwiek skuteczny
sposÛb, mianowicie przez opÛü-
nienie o†ustalanej programowo
d³ugoúci. D³ugoúÊ tego opÛünienia
moøna zoptymalizowaÊ w†ostat-
niej fazie testÛw dla konkretnego
komputera. OpÛünienie to nie jest
jednak obci¹øeniem dla systemu
(nie wliczaj¹c inicjalizacji), bo-
wiem jest zrealizowane w†Delphi
za pomoc¹ timerÛw, ktÛre uak-
tywniaj¹ siÍ tylko w†okreúlonych
interwa³ach czasowych.
36
Elektronika Praktyczna 5/2003
32578018.031.png 32578018.032.png 32578018.001.png 32578018.002.png 32578018.003.png 32578018.004.png 32578018.005.png 32578018.006.png 32578018.007.png 32578018.008.png 32578018.009.png 32578018.010.png 32578018.011.png 32578018.012.png 32578018.013.png 32578018.014.png 32578018.015.png 32578018.016.png 32578018.017.png 32578018.018.png 32578018.019.png 32578018.020.png 32578018.021.png 32578018.022.png 32578018.023.png
CPU−meter do PC−ta
List. 4. Najważniejsze fragmenty programu
{ zmienne globalne }
var
TestForm: TTestForm;
buffer: string;
akt,LPT,bufl: integer;
.
.
.
procedure TTestForm.TimerTimer(Sender: TObject);
{ procedura obslugi timera glownego, okres ustawiany przez użytkownika }
var i : Integer;
j : Double;
s : string;
begin
CollectCPUData;
j := GetCPUUsage(0)*100;
s := Format(‘%1.0f%% ‘,[j]);
TestForm.Caption:=’CPU Usage ‘+s;
Application.Title:=’CPU Usage ‘+s;
for i := 1 to 4 do buffer[i]:= s[i];
for i := bufl+6 downto 6 do buffer[i]:= buffer[i-1];
buffer[5]:= chr(trunc(j/13)+8);
lcd_home;
akt:= 1;
Timer1.Enabled:= true;
end;
procedure TTestForm.FormCreate(Sender: TObject);
{ procedura przy inicjalizacji programu }
var i : Integer;
f : TIniFile;
begin
f := TIniFile.Create(‘CpuUsage.Ini’);
with f do
begin
LPT:= ReadInteger(‘Configuration’,’Address’,$278);
bufl:= ReadInteger(‘Configuration’,’Buffer’,20);
Timer.Interval:= ReadInteger(‘Configuration’,’Refresh’,5000);
end;
akt:= 0;
lcd_init;
SpinEdit1.Value:= bufl;
SpinEdit2.Value:= Timer.Interval div 1000;
buffer:= ‘ ‘;
if LPT = $278 then RadioButton1.Checked:= true
else RadioButton1.Checked:= false;
if LPT = $378 then RadioButton2.Checked:= true
else RadioButton2.Checked:= false;
f.Free;
end;
procedure TTestForm.CzasNaZnak(Sender: TObject);
{ procedura obslugi timera taktowania LCD, okres np. 10ms }
begin
if (akt < bufl+6) then
begin
write_LPT(ord(buffer[akt]),FALSE);
akt:=akt+1;
end else Timer1.Enabled:= false;
end;
procedure TTestForm.set278(Sender: TObject);
{ procedura obslugi przycisku 278h }
begin
LPT:=$278;
lcd_init;
end;
procedure TTestForm.set378(Sender: TObject);
{ procedura obslugi przycisku 378h }
begin
LPT:=$378;
lcd_init;
end;
procedure TTestForm.buf_change(Sender: TObject);
{ procedura przy zmianie wartosci SpinEdita długości bufora }
begin
bufl:=SpinEdit1.Value;
end;
procedure TTestForm.refresh_change(Sender: TObject);
{ procedura przy zmianie wartosci SpinEdita interwału pomiaru }
begin
Timer.Interval:= SpinEdit2.Value * 1000;
end;
procedure TTestForm.FormClose(Sender: TObject; var Action: TCloseAction);
{ procedura przy zakończeniu aplikacji }
var
f : TIniFile;
begin
f := TIniFile.Create(‘CpuUsage.Ini’);
with f do
begin
WriteInteger(‘Configuration’,’Address’,LPT);
WriteInteger(‘Configuration’,’Buffer’,bufl);
WriteInteger(‘Configuration’,’Refresh’,Timer.Interval);
end;
f.Free;
end;
a)
b)
Rys. 2. Wygląd interfejsu aplikacji
sterującej
Przyk³ady procedur realizuj¹-
cych powyøsze operacje przedsta-
wiono na list. 3 .
Internetowe open-source s¹ nie-
przebranym ürÛd³em pomys³Ûw
i†niemal gotowych projektÛw.
RÛwnieø dziÍki tej idei uda³o siÍ
prosto i†bezboleúnie zrealizowaÊ
pomiar obci¹øenia procesora. Klu-
czem okaza³ siÍ tutaj gotowy
komponent do Delphi realizuj¹cy
tego typu pomiar. SpoúrÛd paru
testowanych modu³Ûw najlepiej
chyba w†tej roli spisa³ siÍ pakiet
Alexeya Dynnikova ( aldyn@-
chat.ru ) o†nazwie adCPU . Modu³
ten jest dostÍpny jako freeware
pod adresem http://www.aldyn.ru .
Instalacja modu³u praktycznie
ogranicza siÍ do do³¹czenia pliku
ürÛd³owego do projektu. Dostaje-
my do dyspozycji trzy funkcje do
pomiaru obci¹øenia dowolnego
procesora w†systemie:
- GetCPUCount - zwraca liczbÍ
procesorÛw w†systemie,
- CollectCPUData - zbiera infor-
macje o†aktualnym obci¹øeniu
kaødego procesora,
- GetCPUUsage(n) - zwraca po-
przednio zebrany pomiar obci¹-
øenia dla procesora n.
Tab. 1. Przestrzeń adresowa portu
Centronics
Offset
Odczyt/ Numer
Numer Opis
Opis
Zapis bitu
bitu
!
" #$ %
"
%$$$
&'(
$$
$$
) $$
$$
"$*
Za pomoc¹ przytoczonych pro-
cedur moøna ³atwo realizowaÊ
podstawowe funkcje wyúwietlacza
LCD, takich jak:
- konfiguracja podczas inicjali-
zacji,
- czyszczenie ekranu,
- powrÛt kursora,
- przesuniÍcie,
- definicja znakÛw do CGRAM
(niezbÍdna do wykresu s³upko-
wego).
$
%+ &'(
" &
&
,
"$+
Elektronika Praktyczna 5/2003
37
Offset
Offset Odczyt/
Odczyt/
Numer
Zapis
32578018.024.png 32578018.025.png 32578018.026.png
CPU−meter do PC−ta
Rys. 3. Przykładowe wskazanie na
wyświetlaczu
d³ugoúÊ bufora (przydatne przy
wyúwietlaczach o†rÛønej liczbie
znakÛw), adres portu oraz inter-
wa³ cyklu pomiarowego.
Po kaødorazowym pomiarze ob-
ci¹øenia procesora, aktualizowany
jest bufor, w†ktÛrym znajduj¹ siÍ
poprzednie wartoúci pomiarÛw. Na-
stÍpnie aktualna wartoúÊ pomiaru
jest transmitowana do wyúwietlacza
w†postaci numerycznej (np. 56%)
oraz poprzednie wartoúci z†bufora
w†postaci wykresu s³upowego (dziÍ-
ki znakom zdefiniowanym do
CGRAM). Przyk³adowe wskazanie
na wyúwietlaczu mog³oby wiÍc
wygl¹daÊ jak na rys. 3 . D³ugoúÊ
wykresu jest oczywiúcie zaleøna od
d³ugoúci bufora oraz iloúci dostÍp-
nych pÛl na wyúwietlaczu.
Jak juø wspomniano, kluczowe
fragmentu kodu ürÛd³owego pro-
jektu przedstawiono na list. 4.
Kod ten zawiera rÛwnieø wiele
dodatkowych elementÛw, ktÛre
z†punktu widzenia tego projektu
s¹ mniej istotne, a†s³uø¹ g³Ûwnie
ergonomii uøycia aplikacji. S¹ to
m.in. zapamiÍtywanie i†odtwarza-
nie poprzednich ustawieÒ w†pliku
CpuUsage.Ini oraz formatowanie
bufora i†tytu³u aplikacji. Czytelni-
cy bardziej zainteresowani stron¹
programistyczn¹ z†pewnoúci¹ ³at-
wo zrozumiej¹ sens tego kodu
i†byÊ moøe wzbogac¹ go o†w³asne
pomys³y. AplikacjÍ tÍ moøna
w†prosty sposÛb rozbudowaÊ o†ko-
lejne elementy, jak chociaøby wy-
úwietlanie innych danych w†dru-
giej linijce wyúwietlacza (np. ak-
tualny czas systemowy). Dodatko-
wo moøna j¹ rozbudowaÊ o†moø-
liwoúÊ pracy w†systemie wielo-
procesorowym, np. przez cyklicz-
ne wyúwietlanie wskazaÒ dla ko-
WYKAZ ELEMENTÓW
Rezystory
P1: 10k
Nie wnikaj¹c w†zasadÍ dzia³a-
nia procedur autorstwa Alexeya
Dynnikova (ktÛre moøna poznaÊ,
analizuj¹c niezbyt d³ugi kod ürÛd-
³owy), moøna w†prosty sposÛb
zmierzyÊ obci¹øenie procesora.
Praktyczna realizacja w†projekcie
Delphi sk³ada³aby siÍ z†czÍúci ini-
cjalizacyjnej oraz cyklicznie wy-
wo³ywanej procedury pomiaru
i†wyúwietlania. Kluczem jest cyk-
liczny pomiar wartoúci obci¹øenia,
ktÛry moøe byÊ wywo³ywany syg-
na³em timera. Po zebraniu danych
naleøy rÛwnieø zaktualizowaÊ bu-
for poprzednich wartoúci w†celu
stworzenia wykresu. By³aby to
bardzo dobra koncepcja, gdyby nie
koniecznoúÊ stosowania sztywnych
opÛünieÒ przy sterowaniu wyúwiet-
laczem. Taki czas bezczynnoúci
by³by duøym obci¹øeniem dla sys-
temu. W†zwi¹zku z†tym wprowa-
dzono drugi timer, ktÛry z†czÍstot-
liwoúci¹ wielokrotnie wiÍksz¹ tak-
tuje dane dla wyúwietlacza po
pomiarze obci¹øenia. Timer ten
jest aktywny przez parÍ cykli po
pomiarze, po czym po przetrans-
mitowaniu ca³oúci danych sam siÍ
deaktywuje. Realizacja programo-
wa nie jest skomplikowana i†moø-
na j¹ natychmiast zrozumieÊ spo-
jrzawszy w†kod ürÛd³owy projektu
(kluczowe fragmenty s¹ przedsta-
wione na list. 4 ).
Na rys. 2 przedstawiono wy-
gl¹d formy surowego projektu
w†Delphi oraz gotowej aplikacji
po skompilowaniu. Jak widaÊ,
z†poziomu GUI moøna zmieniaÊ
µ
F/16V
F/16V
Półprzewodniki
U1: ICL7660/7660S
Różne
W1: dowolny wyświetlacz LCD
2x20 znaków
Zl1: wtyk DB25
JP1: goldpiny 1x2 + jumper
µ
lejnych procesorÛw. W†niektÛrych
komputerach rÛwnieø adres portu
rÛwnoleg³ego nie jest ustawiony
na øadn¹ z†ìhistorycznychî war-
toúci 278h lub 378h. W†zwi¹zku
z†tym, sposÛb ustawiania adresu
moøna rÛwnieø ³atwo zmodyfiko-
waÊ. Delphi daje w†tym wzglÍdzie
wrÍcz nieograniczone moøliwoúci.
Montaø i†uruchomienie urz¹dze-
nia nie powinny przysparzaÊ øad-
nych trudnoúci. Ca³y uk³ad bez
wyúwietlacza mieúci siÍ wewn¹trz
obudowy z³¹cza DB25. Otwart¹
kwesti¹ pozostaje zasilanie, ktÛre
niestety nie jest wyprowadzone na
port Centronics, w†zwi¹zku z†czym
niezbÍdne jest do³¹czenie zasilacza
zewnÍtrznego. Aby tego unikn¹Ê,
moøna zastosowaÊ sztuczkÍ polega-
j¹c¹ na ìpodczepieniuî siÍ do
zasilania komputera na z³¹czu kla-
wiaturowym, gameporcie lub USB.
W†praktyce polecam rzadko wyko-
rzystywany gameport (zasilanie na
wszystkich skrajnych stykach - na-
piÍcie +5†V wystÍpuje na stykach
1, 8, 9 i†15, masa to styki 4 i†5).
Jarek Paluszyñski
jarekp@ict.pwr.wroc.pl
38
Elektronika Praktyczna 5/2003
Kondensatory
C1: 100
C2: 10
32578018.027.png 32578018.028.png
Zgłoś jeśli naruszono regulamin