This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Periodic execution of code in a thread context


On 09/23/2009 08:59 AM, Steven Clugston wrote:
Hi all

I need to have a function with some control code in it to execute at regular and consistent intervals.
The way I've done this is just to create a thread and trap the execution path in an infinite loop using while(1){some code;cyg_thread_delay()} or for(;;){some code; cyg_thread_delay()}.

The trouble with this approach is that if the code doesn't take the same path every time, then the overall interval will vary and the drift will be cumulative. This hasn't mattered too much until now, but I need it to not drift for my current application. I guess it could be improved by using cyg_real_time_clock() at the start and end of the code section to find how long it took then modify the delay time to try to keep the time interval at which the code is started the same, but it seems a bit clumsy and might suffer from jitter which would still be cumulative.

The other way I've tried is to use a timer/alarm attached to the system clock, but this executes in a DSR context which causes some limitations and I would prefer to use a normal thread context.

Could I use a cyg_thread_suspend() at the end of each iteration then re-wake the thread from an alarm handler?

Is there anything which I've missed like a scheduler policy or API call which might help?

Do I need to resort to a hardware timer to achieve this goal?

One way to handle this is to use select() with a timeout which is set to a relative time value (computed by checking the current time relative to a known value). Hence your loop looks something like this:

   gettimeofday(&base_time, NULL);
   while (1) {
     ... do some work
     // Calculate when to resume
     timeradd(&base_time, &time_per_loop, &base_time);
     // And how long that is from now
     gettimeofday(&now, NULL);
     timersub(&base_time, &now, &delta);
     // Wait for that much time
     select(0,0,0,0,&delta);
   }

Of course this solution, like the others that have been posted,
is only accurate to the system timer/tick.  If you need higher
resolution than that, you'll need a separate hardware timer.

--
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]