Find the answer to your Linux question:
Results 1 to 7 of 7
Is there a way to make a function run every x microseconds. I need it to run 100-10 times a second. Right now I am accomplishing this by using threads ...
  1. #1
    Just Joined!
    Join Date
    Oct 2009
    Posts
    14

    C call a function every x microseconds.

    Is there a way to make a function run every x microseconds. I need it to run 100-10 times a second. Right now I am accomplishing this by using threads and usleep(). The problem with that is that the function can take a while to finish which makes the time longer than the time it sleeps.

    It seems like I read something where you can use timers (timer.h?), but I can't find that now.

    Preferably it would run the function as a new thread.

    Thanks,
    Justin

  2. #2
    Linux Guru Rubberman's Avatar
    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
    Read the man pages for setitimer()/getitimer().
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Oct 2009
    Posts
    14

    Sleep fails

    I got it working now, as far as I can tell. However, I ran into a new problem with this.

    I don't know that much about linux programming, but from what I've read it looks like sleep() can use SIGALRM and is conflicting with the timer interrupt.

    In my code I have sleep(30); which exits once the timer interrupt is run once, not after 30 seconds.

    Is there a way to sleep without the conflict of SIGALRM or avoid it some other way?

    Thanks,
    Justin

  4. #4
    Linux Guru Rubberman's Avatar
    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 can set up your timers to use something other than SIGALRM, such as SIGUSR1, etc. Use different handlers for the different signals. That way, you know which event occurred, your timer vs. sleep().
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Oct 2009
    Posts
    14
    How would I do that? Looking up setitimer shows
    ITIMER_REAL
    decrements in real time, and delivers SIGALRM upon expiration.
    That makes it look like it can only return SIGALRM when set to ITIMER_REAL, but I've never dealt with timers before.

    Thanks

  6. #6
    Linux Guru Rubberman's Avatar
    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 need to use the posix interval timers. See the man page for timer_create. The sigevent structure you pass will have the signal information you need to configure, including functions to start when the timer triggers. The old itimer stuff doesn't have nearly enough flexibility for what you want.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  7. #7
    Just Joined!
    Join Date
    Oct 2009
    Posts
    14
    Thanks! I set up the timer using SIGUSR1 (I think) but it is still exiting sleep after one call to the handler.
    Code:
    timer_t timerid;
        struct sigevent sev;
        struct itimerspec its;
    
        /* Install our SIGUSR1 signal handler */
        struct sigaction sa;
    
        sa.sa_sigaction = LogAccel;
        sigemptyset( &sa.sa_mask );
        sa.sa_flags = SA_SIGINFO; /* we want a siginfo_t */
        if (sigaction (SIGUSR1, &sa, 0)) {
        	printf("sigaction error");
            exit(1);
        }
    	printf("SIG done...\n");
    
        /* Create the timer */
    
    	sev.sigev_notify = SIGEV_SIGNAL;
    	sev.sigev_signo = SIGUSR1;
    	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 = 1;
    	its.it_value.tv_nsec = 0;
    	its.it_interval.tv_sec = 1;
    	its.it_interval.tv_nsec = 0;
    
    	if (timer_settime(timerid, 0, &its, NULL) == -1)
    	{
    		printf("timer_settime error");
    		exit(1);
    	}
    
    
    	printf("Going to Sleep!\n");
    
    	sleep(30);
    
    	printf("Awake\n");
    I am getting something like
    Code:
    SIG done...
    Going to Sleep!
    307 308 394
    Awake
    where it should print the three numbers (readings from an accelerometer) once per second.

    Now thinking about it could using I2C cause problems? This code is running on a Gumstix.
    EDIT: Just tested and it's not the I2C bus, if the function just uses printf() it still exits.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...