J. Ułasiewicz Komputerowe systemy sterowania 1
Timery
1. Informacje podstawowe
Timer – mechanizm pozwalający na precyzyjne odmierzanie czasu i generowanie zdarzeń:
1. Sygnałów
2. Depozytów
Timer może być użyty do:
1. Precyzyjnego odmierzania odcinków czasu 2. Odblokowaniu procesu w ściśle określonym momencie czasu 3. Zabezpieczenia operacji blokujących.
Dalej będzie przedstawiona implementacja timerów według POSIX i UNIX (Open Group Specification)
Podstawowe funkcje dotyczące timerów:
timer_create
Tworzenie timera
timer_settime
Ustawienie timera
timer_gettime
Testowanie stanu timera
timer_delete
Kasowanie timera
sygnal
proxy
TIMER
blokada
Timer odblokowuje zablokowany proces
Instytut Cybernetyki Technicznej Politechniki Wrocławskiej PDF created with pdfFactory trial version www.pdffactory.com
J. Ułasiewicz Komputerowe systemy sterowania 2
2. Funkcje obsługi timera
2.1. Tworzenie timera
Przed użyciem timer powinien być utworzony. Tworzenie timera następuje poprzez wykonanie funkcji timer_create.
#include <time.h>
#include <signal.h>
timer_t timer_create(clockid_t clockid, struct sigevent * evp); Gdzie:
clockid
identyfikator źródła czasu (CLOCK_REALTIME) evp
struktura ze specyfikacją typu zdarzenia Gdzie:
sigevent.sigev_signo > 0
Specyfikacja numeru sygnału
sigevent.sigev_signo < 0
Specyfikacja numeru depozytu (proxy)
Funkcja zwraca:
> 0 Identyfikator timera
- 1 Błąd
Działanie funkcji polega na utworzeniu timera. Przy tworzeniu określa się czy timer ma generować sygnał czy depozyt. Nowo utworzony timer jest zablokowany. Trzeba go jeszcze ustawić przy pomocy funkcji timer_settime.
Przykłady:
a) sigevent.sigev_signo = SIGALRM
b) proxy = qnx_proxy_attach(0,0,0,-1)
sigevent.sigev_signo = - proxy;
2.2. Ustawienie timera
Ustawienie timera polega na określeniu:
- Trybu odmierzania czasu
- Czasu wyzwolenia
- Okresu repetycji
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
Gdzie:
timerid
Identyfikator timera
flags
Flagi (TIMER_ABSTIMER, TIMER_ADDREL)
Instytut Cybernetyki Technicznej Politechniki Wrocławskiej PDF created with pdfFactory trial version www.pdffactory.com
J. Ułasiewicz Komputerowe systemy sterowania 3
value
Nowa specyfikacja czasu generacji zdarzenia ovalue
Stara specyfikacja czasu generacji zdarzenia
Zamiast ovalue można użyć NULL.
struct itimerspec {
struct timespec it_value;
// pierwsze odpalenie
struct timespec it_interval;
// interwał
int notify_type;
// sygnał lub proxy
int timer_type;
// absolutny lub relatywny
}
struct timespec {
long tv_sec; // sekundy
long tv_nsec; // nanosekundy
}
Czas pierwszego
tv_sec
it_value
odpalenia
tv_nsec
Interwal
it_interval
tv_sec
notify_type
timer_type
tv_nsec
struct itimerspec
struct timespec
Czas T
Postać struktury itimerspec
Gdy it_interval = 0
to brak repetycji
Gdy it_value = 0
to timer zabroniony
Funkcja zwraca:
o
Sukces
-1
Błąd
Gdy bit flag TIMER_ABSTIMER jest ustawiony timer będzie wyzwolony gdy czas bieżący zrówna się z czasem wyspecyfikowanym w polu it_value.
Gdy bit flag TIMER_ADDREL jest ustawiony czas będzie liczony od chwili bieżącej (czas relatywny).
Instytut Cybernetyki Technicznej Politechniki Wrocławskiej PDF created with pdfFactory trial version www.pdffactory.com
J. Ułasiewicz Komputerowe systemy sterowania 4
2.3. Testowanie czasu do wyzwolenia timera
Do testowania czasu jaki pozostał do wyzwolenia timera używa się funkcji timer_gettime.
int timer_gettime(timer_t timerid, struct itimerspec *value);
Gdzie:
timerid
Identyfikator timera
value
Nowa specyfikacja czasu generacji zdarzenia
Funkcja zwraca:
o
Sukces
-1
Błąd
2.4. Kasowanie timera
Timer kasuje się za pomocą funkcji:
int timer_delete(timer_t timerid)
Gdzie:
timerid
Identyfikator timera
Funkcja zwraca:
o
Sukces
-1
Błąd
Instytut Cybernetyki Technicznej Politechniki Wrocławskiej PDF created with pdfFactory trial version www.pdffactory.com
J. Ułasiewicz Komputerowe systemy sterowania 5
3. Przykład zastosowania timera
W poniższym przykładzie timer generuje pierwszy depozyt po upływie 4 sekund.
Następne generuje co 1 sekundę.
// Demonstracja dzialania timera
// (C) J. Ulasiewicz 2005
#include <stdio.h>
#include <time.h>
#include <sys/kernel.h>
#include <sys/timers.h>
struct { int type; // typ
char text[64]; // pole tekstu
} msg;
main()
{ int res,i = 0;
timer_t id;
pid_t proxy;
struct itimerspec timer;
struct sigevent event;
/* Utworzenie proxy --------------------*/
proxy = qnx_proxy_attach(0,0,0,-1);
/* Utworzenie timera --------------------*/
event.sigev_signo = -proxy;
id = timer_create(CLOCK_REALTIME,&event);
/* Ustawienie timera --------------------*/
timer.it_value.tv_sec = 4L;
timer.it_value.tv_nsec = 0L;
timer.it_interval.tv_sec = 1L;
timer.it_interval.tv_nsec = 0L;
timer_settime(id,0,&timer,NULL);
while(1) {
Receive(proxy,&msg,sizeof(msg)); printf("Wyzwolenie: %d\n",i++);
};
/* Skasowanie timera ------*/
timer_delete(id);
exit(0);
}
Przykład zastosowania timera do cyklicznej generacji depozytu Instytut Cybernetyki Technicznej Politechniki Wrocławskiej PDF created with pdfFactory trial version www.pdffactory.com