EmbeddedRelated.com
Forums

Embedded linux and achievable timer rate

Started by Bruce Varley October 20, 2012
I've been stopped dead by a limitation with the ARM-9 250 MHz SBCs, running 
Linux, that I've been relying on for my next project. The maximum rate I can 
run a repeat timer (setitimer, etc) at is 50Hz, ie. 20000 uS repeat time. If 
I set the repeat rate any faster the thing still repeats every 20mS.
Is this a standard 'feature' of Linux SBCs? Does anyone run an SBC that will 
do significantly better, without torching the Linux OS? (I'm looking for 
10mS).


Bruce Varley wrote:
> I've been stopped dead by a limitation with the ARM-9 250 MHz SBCs, running > Linux, that I've been relying on for my next project. The maximum rate I can > run a repeat timer (setitimer, etc) at is 50Hz, ie. 20000 uS repeat time. If > I set the repeat rate any faster the thing still repeats every 20mS. > Is this a standard 'feature' of Linux SBCs? Does anyone run an SBC that will > do significantly better, without torching the Linux OS? (I'm looking for > 10mS). > >
I believe the Linux kernel discipline is built around an assumption of 100Hz "preemption rate". You may need to carve out your own hardware timer and have it generate events, or hit a callback. Or there's this: http://stackoverflow.com/questions/10812858/timers-in-linux-device-drivers There's example code for a kernel space timer - but it may well be up against the same limitation. I haven't tried it... it *is* kernel space, so use your plus-4 Linux wizard's hat and all that. -- Les Cargill
On Sat, 20 Oct 2012 17:56:26 +0800, Bruce Varley wrote:

> I've been stopped dead by a limitation with the ARM-9 250 MHz SBCs, > running Linux, that I've been relying on for my next project. The > maximum rate I can run a repeat timer (setitimer, etc) at is 50Hz, ie. > 20000 uS repeat time. If I set the repeat rate any faster the thing > still repeats every 20mS. Is this a standard 'feature' of Linux SBCs? > Does anyone run an SBC that will do significantly better, without > torching the Linux OS? (I'm looking for 10mS).
There are a variety of timing sources within Linux. setitimer may be limited, but if you want to do a bit more work to roll your own using some higher resolution resource you should be able to get there. Depending on the nature of your device you may find some gaps while some interrupt or other takes all the time (yada yada about "hard real time"), but you should be able to get far better performance (<1ms) without much work so long as you don't have lots of competing demands on the processor. If "hard real time" is necessary, you need to run an OS that can deliver it - not a standard linux kernel. (Les) many linux versions these days are either tickless or have tunable tick rates, often 1ms or faster on PCs, generally settable at kernel compile time. There may be user-space tools to change that (?)
Frank Miles wrote:
> On Sat, 20 Oct 2012 17:56:26 +0800, Bruce Varley wrote: > >> I've been stopped dead by a limitation with the ARM-9 250 MHz SBCs, >> running Linux, that I've been relying on for my next project. The >> maximum rate I can run a repeat timer (setitimer, etc) at is 50Hz, ie. >> 20000 uS repeat time. If I set the repeat rate any faster the thing >> still repeats every 20mS. Is this a standard 'feature' of Linux SBCs? >> Does anyone run an SBC that will do significantly better, without >> torching the Linux OS? (I'm looking for 10mS). > > There are a variety of timing sources within Linux. setitimer may be > limited, but if you want to do a bit more work to roll your own using > some higher resolution resource you should be able to get there. > Depending on the nature of your device you may find some gaps while some > interrupt or other takes all the time (yada yada about "hard real time"), > but you should be able to get far better performance (<1ms) without much > work so long as you don't have lots of competing demands on the processor. > > If "hard real time" is necessary, you need to run an OS that can deliver > it - not a standard linux kernel. > > (Les) many linux versions these days are either tickless or have tunable > tick rates, often 1ms or faster on PCs, generally settable at kernel > compile time. There may be user-space tools to change that (?) >
Good to know - I never actually had to dive into it. -- Les Cargill
On Sat, 20 Oct 2012 13:01:19 -0500
Les Cargill <lcargill99@comcast.com> wrote:

> I believe the Linux kernel discipline is built around an assumption > of 100Hz "preemption rate".
Maybe. There&rsquo;s a build-time configuration parameter, CONFIG_HZ. In menuconfig, it can be found at Processor Type and Features / Timer Frequency. On my amd64 it has options to be set to 100, 250, 300, or 1000. See if that&rsquo;s set incorrectly for your application before going and wading into the code! Chris
The native 10ms ticking rate can be achieved with the select() system call, which can be used as a fairly portable way to sleep. For some reason, all other system calls (setitimer(), nanosleep(), etc.) seem to be unable to block for less than two clock ticks (20 milliseconds). 

When using select() in Linux, the timeout value passed to select() is rounded up to the nearest tick (10 milliseconds on desktop POSIX). The timeout cannot be too short, because the system might choose to busy-wait for very short timeouts.  Also according to the man pages, the function select() on POSIX modifies the timeout argument to reflect the amount of time not slept. Most other implementations do not do this. This quirk is handled in a portable way by 
always setting the microsecond part of the structure before each select() call:

struct timeval timeout = { 0 };
. . .
while (1) {
    // do timed processing at 10ms interval...
    timeout.tv_usec = 10000UL; /* set the desired tick interval */
    select(0, 0, 0, 0, &timeout); /* sleep for the full tick */
}

Miro Samek
state-machine.com