Echtzeit Timer



  • Hallo zusammen,

    ich arbeite momentan an einer Aufgabe, bei der es das Ziel ist das Programm so zu starten, dass die Funktion setperiodic() in dem von mir unten beigefügten Code so erweitert werden soll, dass es mit einer Startzeit von 3 Sekunden gestartet wird und mit einer Zykluszeit von 2.5 Sekunden aufgerufen wird:

    #include <errno.h>
    #include <signal.h>
    #include <stdio.h>
    #include <time.h>
    #include <unistd.h>
    
    /* Prototypes */
    static void interrupthandler();
    static int  setinterrupt();
    static int  setperiodic();
    int         main();
    
    /* Defines */
    
    #define BILLION 1000000000L
    #define TIMER_MSG "Received Timer Interrupt"
    
    /* File-local Variables */
    
    int 	  i_r_counter=1;
    timer_t timerid;
    
    static void interrupthandler(int signo, siginfo_t *info, void *context)
    {
    	int errsave;
    
    	errsave = errno;
    	printf("%s %d\n",TIMER_MSG, i_r_counter++);
    	errno = errsave;
    }
    
    static int setinterrupt(void) 
    {
    	struct sigaction act;
    
    	act.sa_flags = SA_SIGINFO;
    	act.sa_sigaction = interrupthandler;
    	if ((sigemptyset(&act.sa_mask) == -1) ||
    	    (sigaction(SIGALRM, &act, NULL) == -1)) {
    		return -1;
    	}
    	return 0;
    }
    
    static int setperiodic(double sec) 
    {
    	struct itimerspec value;
    
    	if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) {
    		return -1;
    	}
    	value.it_value.tv_sec = (long)sec;
    	value.it_value.tv_nsec = (sec - value.it_value.tv_sec)*BILLION;
    	if (value.it_value.tv_nsec >= BILLION) {
    		value.it_value.tv_sec++;
    		value.it_value.tv_nsec -= BILLION;
    	}
    	value.it_interval = value.it_value;
    	return timer_settime(timerid, 0, &value, NULL);
    }
    
    int main(void) 
    {
    int loopcounter;
    	if (setinterrupt() == -1) {
    		perror("Fehler SIGALRM Händler Anbindung");
    		return 1;
    	}
    	if (setperiodic(2.0) == -1) {
    		perror("Fehler bei Start des periodischen Timers");
    		return 1;
    	}
    	for (loopcounter=0; loopcounter < 5; loopcounter++){
    		pause();
    	}
    	timer_delete(timerid);	
    }
    

    Das Programm muss mit der Realtime-Bibliothek zusammen kompiliert werden, also z.B:
    gcc -o timer timer.c -lrt

    Wie kann ich es nun erreichen, dass value.it_interval und value.it_value unterschiedliche Werte haben können, da ja value.it_interval für den Intervall zuständig ist in dem der Timer aufgerufen wird wenn er ausgelaufen ist und value.it_value den Zeitraum des Timers festlegt wie lange er läuft.
    Muss ich die Funktion dafür mit einem weiteren Parameter erweitern?

    Dazu noch eine kleine Nebenfrage zum reinen Verständnis:

    Die Funktion setperiodic() bekommt ja einen double Wert als Argument übergeben, woraus dann durch

    value.it_value.tv_sec = (long)sec;
    

    .tv_sev durch den expliziten Cast den vollen Sekundenanteil erhält und durch

    value.it_value.tv_nsec = (sec - value.it_value.tv_sec)*BILLION;
    

    .tv_nsec den Nanosekundenanteil erhält.

    Nun stellt sich mir bei dieser Zeile folgende Frage:

    if (value.it_value.tv_nsec >= BILLION)
    

    Gilt nicht immer, dass tv_nsec < BILLION ist?

    Ich wäre für jede Hilfe dankbar und bedanke mich für die Mühe und die Zeit, die ihr euch genommen habt.

    Liebe Grüße

    zOption



  • zOption schrieb:

    Wie kann ich es nun erreichen, dass value.it_interval und value.it_value unterschiedliche Werte haben können, da ja value.it_interval für den Intervall zuständig ist in dem der Timer aufgerufen wird wenn er ausgelaufen ist und value.it_value den Zeitraum des Timers festlegt wie lange er läuft.

    Ist das eine Scherzfrage? In Zeile 63 setzt du sie doch gleich.

    zOption schrieb:

    Muss ich die Funktion dafür mit einem weiteren Parameter erweitern?

    Wohl eher mit zwei weiteren.

    static int setperiodic(double sec, interval_type_t it_interval, value_typte_t it_value );
    

    Mit den Typen interval_type_t, value_typte_t deiner Wahl.


Anmelden zum Antworten