accurate time resolution in ucLinux - Embedded

This is a discussion on accurate time resolution in ucLinux - Embedded ; I am developing on Moxa ucLinux box (200+mhz arm9), and I need to execute either a process or pthread exactly once every 50ms +- 1ms. I can poll the RTC and get usec resolution times, but I see that when ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: accurate time resolution in ucLinux

  1. accurate time resolution in ucLinux

    I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    execute either a process or pthread exactly once every 50ms +- 1ms.

    I can poll the RTC and get usec resolution times, but I see that when
    your timeslice is over, the scheduler does not get back to you until
    10ms later, so polling alone won't guarantee accuracy. This happens for
    blocking functions including usleep(). usleep(100) gives up a 10ms
    slice. I need a low-latency pre-emptive mechanism. Is there one?

    I was thinking of an interrupt routine, but there appear to be no hw
    timers I can access directly.


  2. Re: accurate time resolution in ucLinux

    tns1 wrote:
    > I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    > execute either a process or pthread exactly once every 50ms +- 1ms.
    >
    > I can poll the RTC and get usec resolution times, but I see that when
    > your timeslice is over, the scheduler does not get back to you until
    > 10ms later, so polling alone won't guarantee accuracy. This happens for
    > blocking functions including usleep(). usleep(100) gives up a 10ms
    > slice. I need a low-latency pre-emptive mechanism. Is there one?
    >
    > I was thinking of an interrupt routine, but there appear to be no hw
    > timers I can access directly.


    I'm not sure if it is available also in ucLinux. Maybe you could try it.

    Use a recent kernel with HRT (High Resolution Timer) support, add the RT
    Preempt patch to this kernel and you will get what you want with the simple
    POSIX function clock_nanosleep() for your purpose. With this kernel feature
    you don't need a interrupt routine any more, everything can happen in
    userspace (including hard realtime behaviour)

    Here an example (works reliably only on HRT + RT Preempt kernels!):

    /**
    * compile with:
    * gcc -lrt -o periodic periodic.c
    **/

    #include
    #include

    #define NSEC_PER_SEC 1000000000L

    static inline void timespec_add_ns(struct timespec *a, unsigned int ns)
    {
    ns += a->tv_nsec;
    while(ns >= NSEC_PER_SEC) {
    ns -= NSEC_PER_SEC;
    a->tv_sec++;
    }
    a->tv_nsec = ns;
    }

    static inline int timespec_compare(const struct timespec *lhs, const struct
    timespec *rhs)
    {
    if (lhs->tv_sec < rhs->tv_sec)
    return -1;
    if (lhs->tv_sec > rhs->tv_sec)
    return 1;
    return lhs->tv_nsec - rhs->tv_nsec;
    }

    int main()
    {
    struct timespec time, now;
    unsigned int interval = 100000000;

    clock_gettime(CLOCK_MONOTONIC, &time);
    while (1)
    {
    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &time, 0);

    /**
    * Do the periodic work here.
    **/
    printf("Hello World\n");

    timespec_add_ns(&time, interval);

    /**
    * Drop cycles if we are too slow.
    * This is a failsave that might not be necessary or desired.
    **/
    clock_gettime(CLOCK_MONOTONIC, &now);
    if (timespec_compare(&time, &now) < 0)
    {
    time = now;
    timespec_add_ns(&time, interval);
    printf("Too Slow.\n");
    }
    }
    return 0;
    }

    Hope it helps
    JB

  3. Re: accurate time resolution in ucLinux

    tns1 wrote:
    > I need to
    > execute either a process or pthread exactly once every 50ms +- 1ms.
    >


    This is not possible. Linux is not a hard real time OS so there is not
    guarantee that you get a scheduling delay _much_ larger than 50 ms now
    and then which will result in no execution in one of your 50 ms
    intervals. There are several means to add hard realtime features t6o
    Linux (e.g. RTAI).

    -Michael


  4. Re: accurate time resolution in ucLinux

    tns1 wrote:
    > I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    > execute either a process or pthread exactly once every 50ms +- 1ms.
    >
    > I can poll the RTC and get usec resolution times, but I see that when
    > your timeslice is over, the scheduler does not get back to you until
    > 10ms later, so polling alone won't guarantee accuracy. This happens for
    > blocking functions including usleep(). usleep(100) gives up a 10ms
    > slice. I need a low-latency pre-emptive mechanism. Is there one?
    >
    > I was thinking of an interrupt routine, but there appear to be no hw
    > timers I can access directly.
    >

    If it helps, I can simplify the chunk of code I need to be hard-realtime
    to just a few writes to HW, something that could easily be done in an isr.

  5. Re: accurate time resolution in ucLinux


    Juergen Beisert wrote:
    > tns1 wrote:
    >> I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    >> execute either a process or pthread exactly once every 50ms +- 1ms.
    >>
    >> I can poll the RTC and get usec resolution times, but I see that when
    >> your timeslice is over, the scheduler does not get back to you until
    >> 10ms later, so polling alone won't guarantee accuracy. This happens for
    >> blocking functions including usleep(). usleep(100) gives up a 10ms
    >> slice. I need a low-latency pre-emptive mechanism. Is there one?
    >>
    >> I was thinking of an interrupt routine, but there appear to be no hw
    >> timers I can access directly.

    >
    > I'm not sure if it is available also in ucLinux. Maybe you could try it.
    >
    > Use a recent kernel with HRT (High Resolution Timer) support, add the RT
    > Preempt patch to this kernel and you will get what you want with the simple
    > POSIX function clock_nanosleep() for your purpose. With this kernel feature
    > you don't need a interrupt routine any more, everything can happen in
    > userspace (including hard realtime behaviour)
    >
    > Here an example (works reliably only on HRT + RT Preempt kernels!):



    This sounds great.

    After more reading I see that vanilla Linux could not meet my hard
    real-time requirement even if my app were only a single process, and
    probably even if put my crucial code in an isr. I am surprised that
    these features were not built into the kernel long ago. After all I am
    only trying to do what is easy for much slower 8-bit uCs (no OS).

    I have been trying to see if the ucLinux kernel ported to this board
    already has the HRT support and/or if it is suitable for this patch. I
    don't have the uCLinux kernel source right now, but it is based on
    2.6.19. The wiki on rt suggests I may need a newer version and that
    uClib used by uCLinux has some problems with rt. There is a full Linux
    kernel available for this board, but I believe it is kernel 2.6.9 which
    may be too old.


  6. Re: accurate time resolution in ucLinux

    tns1 wrote:

    >
    > Juergen Beisert wrote:
    >> tns1 wrote:
    >>> I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    >>> execute either a process or pthread exactly once every 50ms +- 1ms.
    >>>
    >>> I can poll the RTC and get usec resolution times, but I see that when
    >>> your timeslice is over, the scheduler does not get back to you until
    >>> 10ms later, so polling alone won't guarantee accuracy. This happens for
    >>> blocking functions including usleep(). usleep(100) gives up a 10ms
    >>> slice. I need a low-latency pre-emptive mechanism. Is there one?
    >>>
    >>> I was thinking of an interrupt routine, but there appear to be no hw
    >>> timers I can access directly.

    >>
    >> I'm not sure if it is available also in ucLinux. Maybe you could try it.
    >>
    >> Use a recent kernel with HRT (High Resolution Timer) support, add the RT
    >> Preempt patch to this kernel and you will get what you want with the
    >> simple POSIX function clock_nanosleep() for your purpose. With this
    >> kernel feature you don't need a interrupt routine any more, everything
    >> can happen in userspace (including hard realtime behaviour)
    >>
    >> Here an example (works reliably only on HRT + RT Preempt kernels!):

    >
    >
    > This sounds great.
    >
    > After more reading I see that vanilla Linux could not meet my hard
    > real-time requirement even if my app were only a single process, and
    > probably even if put my crucial code in an isr. I am surprised that
    > these features were not built into the kernel long ago. After all I am
    > only trying to do what is easy for much slower 8-bit uCs (no OS).
    >
    > I have been trying to see if the ucLinux kernel ported to this board
    > already has the HRT support and/or if it is suitable for this patch. I
    > don't have the uCLinux kernel source right now, but it is based on
    > 2.6.19. The wiki on rt suggests I may need a newer version and that
    > uClib used by uCLinux has some problems with rt. There is a full Linux
    > kernel available for this board, but I believe it is kernel 2.6.9 which
    > may be too old.


    2.6.9 *is* ways to old...

    JB

  7. Re: accurate time resolution in ucLinux

    Juergen Beisert wrote:
    There is a full Linux
    >> kernel available for this board, but I believe it is kernel 2.6.9 which
    >> may be too old.

    >
    > 2.6.9 *is* ways to old...
    >
    > JB


    What do you think is the oldest kernel that can still be used?

  8. Re: accurate time resolution in ucLinux

    tns1 wrote:
    > Juergen Beisert wrote:
    > There is a full Linux
    >>> kernel available for this board, but I believe it is kernel 2.6.9 which
    >>> may be too old.

    >>
    >> 2.6.9 *is* ways to old...

    >
    > What do you think is the oldest kernel that can still be used?


    For HRT I believe you need at least 2.6.18 (or was it 2.6.20?). For RT
    preempt you always should start with the most recent one. Our first ARM
    XSCALE board support package with (a working) HRT support was 2.6.21 (but
    without RT preempt). An ARM i.MX1 one was 2.6.20 (with HRT and RT preempt).
    And a PowerPC one was 2.6.20 (which included RT preempt).

    Is there mainline support for your platform?

    JB

  9. Re: accurate time resolution in ucLinux

    Juergen Beisert wrote:
    > tns1 wrote:
    >> Juergen Beisert wrote:
    >> There is a full Linux
    >>>> kernel available for this board, but I believe it is kernel 2.6.9 which
    >>>> may be too old.
    >>> 2.6.9 *is* ways to old...

    >> What do you think is the oldest kernel that can still be used?

    >
    > For HRT I believe you need at least 2.6.18 (or was it 2.6.20?). For RT
    > preempt you always should start with the most recent one. Our first ARM
    > XSCALE board support package with (a working) HRT support was 2.6.21 (but
    > without RT preempt). An ARM i.MX1 one was 2.6.20 (with HRT and RT preempt).
    > And a PowerPC one was 2.6.20 (which included RT preempt).
    >
    > Is there mainline support for your platform?
    >
    > JB


    Not sure what 'mainline support' means. The specs are here:
    http://www.moxa.com/product/UC-7110-LX.htm
    I currently have the uClinux version, but a standard Linux is available
    using the kernel versions I mentioned. The kernel/fs source is available
    on request. I don't think it would be that easy to move to a new kernel
    and get all the custom pieces working in just a day or two (at least
    for me). I've rebuilt a kernel before, but this seems like it could turn
    into a porting effort. The processor is a custom die built for the
    vendor and they already have many drivers/kernel modules the app depends
    on. If all that had to be rebuilt and debugged it would just take too
    long. I need a pretty quick solution.

    This RT preempt seems too good for any embedded Linux vendor to pass up.
    I need to ask Moxa about adding this.


  10. Re: accurate time resolution in ucLinux

    tns1 wrote:
    > tns1 wrote:
    >> I am developing on Moxa ucLinux box (200+mhz arm9), and I need to
    >> execute either a process or pthread exactly once every 50ms +- 1ms.
    >>
    >> I can poll the RTC and get usec resolution times, but I see that when
    >> your timeslice is over, the scheduler does not get back to you until
    >> 10ms later, so polling alone won't guarantee accuracy. This happens
    >> for blocking functions including usleep(). usleep(100) gives up a 10ms
    >> slice. I need a low-latency pre-emptive mechanism. Is there one?
    >>
    >> I was thinking of an interrupt routine, but there appear to be no hw
    >> timers I can access directly.
    >>

    > If it helps, I can simplify the chunk of code I need to be hard-realtime
    > to just a few writes to HW, something that could easily be done in an isr.

    I now see that simply adding an isr does not guarantee real-time since
    isrs on linux are all gated and not real-time isrs.

    A second revelation is that the few writes I want to do in real-time are
    writes to a serial port which are writes to a kernel driver buffer and
    not to HW. Even with the RT preempt for the app code, the actual latency
    will depend on when the driver code is run. I would probably need to
    re-write the driver too.

+ Reply to Thread