Results 1 to 10 of 10
I am making trying to set up code that can start and stop a timer which triggers a function ~3 times a second. My initialization of the timer is
Code:
...
- 01-10-2010 #1Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
Creating and destroying timers
I am making trying to set up code that can start and stop a timer which triggers a function ~3 times a second. My initialization of the timer is
and to stop the timer I am usingCode:timer_t timerid; void scan_init (void) { scan_data[0] = scan_data[1] = scan_data[2] = 0; struct sigevent sev; struct itimerspec its; /* Install our SIGUSR2 signal handler */ struct sigaction sa; sa.sa_sigaction = scan_handler; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_SIGINFO; /* we want a siginfo_t */ if (sigaction (SIGUSR2, &sa, 0)) { printf("sigaction error\n"); exit(1); } /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGUSR2; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { printf("timer_create error\n"); exit(1); } /* Start the timer */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 350000000; // ~3 samples per second its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("timer_settime error\n"); exit(1); } }
For some reason the code works flawlessly the first time the timer run/stop/run but when it tries to stop it a second time I get no errors but the timer continues to run. When it is run again it seems like two timers are running and each time after that it looks like more and more are running.Code:void scan_stop (void) { if(timer_delete(timerid)) { printf("timer_delete error\n"); exit(1); } }
How can I fully stop a timer (if timer_delete doesn't do that) or is there a better way to pause a timer?
Thanks,
JR
- 01-10-2010 #2Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Have you tried disarming the timer before you delete it? IE:
Code:void scan_stop (void) { struct itimerspec its; memset((void*)&its, 0, sizeof(its)); if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("error disarming timer\n"); exit(1); } if(timer_delete(timerid)) { printf("timer_delete error\n"); exit(1); } }Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 01-10-2010 #3Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
I just tried it out, same result.
Could it be an issue with the timerid? I had it print the timer ID and it was the same before and after the timer was created. Is that normal? Even the second timer had the same ID as the first.
Am I supposed to supply an ID or is it given by timer_create()?
EDIT: I had the idea of just disarming the timer and my code looks like this.
However now it says "timer_settime error" when it tries to re-activate the timer the first time.Code:void scan_start (void) { struct itimerspec its; printf("scan create!\n"); /* Start the timer */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 350000000; // ~3 samples per second its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("timer_settime error\n"); exit(1); } } void scan_stop (void) { printf("scan destroyed!\n"); struct itimerspec its; memset((void*)&its, 0, sizeof(its)); if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("error disarming timer\n"); exit(1); } }
- 01-11-2010 #4Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
OK, it looks like scan_stop() and scan_start() work if called right after each other. However, between scan_stop() and scan_start() I need to start a separate timer that is done so like this.
For some reason after that code is run scan_start() fails.Code:void ann_collision (int impact) { struct sigevent sev; struct itimerspec its; /* Install our SIGALRM signal handler */ struct sigaction sa; sa.sa_sigaction = ann_undo_handler; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_SIGINFO; /* we want a siginfo_t */ if (sigaction (SIGALRM, &sa, 0)) { printf("sigaction error"); exit(1); } /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { printf("timer_create error"); exit(1); } /* Start the timer */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 350000000; // ~3 samples per second its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("timer_settime error"); exit(1); } } void ann_undo_handler ( int cause, siginfo_t *HowCome, void *ucontext ) { struct timeval time; static int step = 0; double us = move_log[step].time.tv_sec * 1000000 + move_log[step].time.tv_usec; us -= move_log[step + 1].time.tv_sec * 1000000 + move_log[step + 1].time.tv_usec; int sec = (int) us / 1000000; int usec = us - (sec * 1000000); struct itimerspec its; its.it_value.tv_sec = sec; its.it_value.tv_nsec = usec * 1000; its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; printf("Next interval: %d %d\n", sec, usec); if (timer_settime(timerid, 0, &its, NULL) == -1) { printf("timer_settime error"); exit(1); } Set_Motor1(-move_log[step].motor1); Set_Motor2(-move_log[step].motor2); gettimeofday(&time, NULL); printf("Current time: %ld %ld\n", (long int)time.tv_sec, (long int)time.tv_usec); step++; if (step > UNDO_LEN - 2) { step = 0; timer_delete(timerid); Set_Motor1(0); Set_Motor2(0); scan_start(); accel_init(); } }
Keep in mind that that code is in a separate file so this timerid should be in a different scope.
EDIT: I should probably also say I am trying to run three different timers using the signals SIGUSR1, SIGUSR2, and SIGALRM. The two timers using SIGUSR1 and SIGUSR2 are stopped while the one using SIGALRM is running, so it could be possible to use only two timers.
- 01-11-2010 #5Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
I haven't run into this problem, but you might want to zero out the timer id between creations. However, why do that? Why not just create it, and rather than destroying it and recreating it, simply disarm it.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 01-11-2010 #6Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
I tried doing that (post #3 edit).
When I tried to arm the timer after disarming it timer_settime() returned -1. I can arm it if I don't make another timer after disarming the first one (post #4)
- 01-11-2010 #7Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
I just though of something, it isn't necessary to stop the timer at all, but just switch the sigaction(). Is it possible to remove a sigaction?
- 01-12-2010 #8Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
You could just change the handler to SIG_IGN (the ignore signal handler). See the sigaction() man page.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 01-12-2010 #9Just Joined!
- Join Date
- Oct 2009
- Posts
- 14
Thanks Rubberman! You've been a huge help. I have it working now, I simply switched the signal handler for one of the timers and set the other to ignore.
Thanks again,
JR
- 01-12-2010 #10


Reply With Quote
