Let userspace app sleep for 1 ms using nanosleep? - Linux

This is a discussion on Let userspace app sleep for 1 ms using nanosleep? - Linux ; Hi there, I try to generate a square signal on a fox board (axis) to its gpio A with a duty cycle of 1ms. The generated signal is watched by an oscillator. My code is: #include #include #include #include #include ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Let userspace app sleep for 1 ms using nanosleep?

  1. Let userspace app sleep for 1 ms using nanosleep?

    Hi there,

    I try to generate a square signal on a fox board (axis) to its gpio A
    with a duty cycle of 1ms. The generated signal is watched by an
    oscillator.

    My code is:

    #include
    #include
    #include
    #include
    #include
    #include
    #define _POSIX_C_SOURCE 199309
    #include
    #include
    #include

    int main(int argc, char **argv) {
    struct timespec ts={
    ..tv_sec=0,
    ..tv_nsec=1000000
    };
    int return_value=0;

    // set PA0 as output
    gpiosetdir(PORTA, DIROUT, PA0);

    while(1) {
    gpiosetbits(PORTA, PA0);
    return_value=nanosleep(&ts, NULL);

    gpioclearbits(PORTA, PA0);
    return_value=nanosleep(&ts, NULL);
    }
    return(0);
    }

    But whatever I will use as .tv_nsec (if smaller than 20000000), the
    duty cycle is 20 ms! I also tried usleep - the same.
    My kernel is:
    2.6.15 #1 PREEMPT Thu Oct 30 10:41:51 CET 2008 cris unknown
    with Preempt on!

    Best regards
    Johann

  2. Re: Let userspace app sleep for 1 ms using nanosleep?

    horvat.johann@gmx.net writes:

    > Hi there,
    >
    > I try to generate a square signal on a fox board (axis) to its gpio A
    > with a duty cycle of 1ms. The generated signal is watched by an
    > oscillator.
    >
    > My code is:
    >
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #define _POSIX_C_SOURCE 199309
    > #include
    > #include
    > #include
    >
    > int main(int argc, char **argv) {
    > struct timespec ts={
    > .tv_sec=0,
    > .tv_nsec=1000000
    > };
    > int return_value=0;
    >
    > // set PA0 as output
    > gpiosetdir(PORTA, DIROUT, PA0);
    >
    > while(1) {
    > gpiosetbits(PORTA, PA0);
    > return_value=nanosleep(&ts, NULL);
    >
    > gpioclearbits(PORTA, PA0);
    > return_value=nanosleep(&ts, NULL);
    > }
    > return(0);
    > }
    >
    > But whatever I will use as .tv_nsec (if smaller than 20000000), the
    > duty cycle is 20 ms! I also tried usleep - the same.
    > My kernel is:
    > 2.6.15 #1 PREEMPT Thu Oct 30 10:41:51 CET 2008 cris unknown
    > with Preempt on!


    I think you posted this before, and got some ideas. But I think there's
    a much greater problem. When some other process decides to run, your
    process will get scheduled out, possibly for many tens of milliseconds,
    and your square wave will stop oscillating until your process is
    scheduled again.

    Fundamentally, you don't want a multitasking operating system for
    something like this. Dedicated hardware would probably be the ideal
    choice. However, if you must use Linux, you should look into real-time
    scheduling. Start with the man page for sched_getscheduler. It looks
    like there are also some kernel config options that you will need to
    turn on.

  3. Re: Let userspace app sleep for 1 ms using nanosleep?

    horvat.johann@gmx.net wrote:

    > Hi there,
    >
    > I try to generate a square signal on a fox board (axis) to its gpio A
    > with a duty cycle of 1ms. The generated signal is watched by an
    > oscillator.
    >
    > My code is:
    >
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #define _POSIX_C_SOURCE 199309
    > #include
    > #include
    > #include
    >
    > int main(int argc, char **argv) {
    > struct timespec ts={
    > .tv_sec=0,
    > .tv_nsec=1000000
    > };
    > int return_value=0;
    >
    > // set PA0 as output
    > gpiosetdir(PORTA, DIROUT, PA0);
    >
    > while(1) {
    > gpiosetbits(PORTA, PA0);
    > return_value=nanosleep(&ts, NULL);
    >
    > gpioclearbits(PORTA, PA0);
    > return_value=nanosleep(&ts, NULL);
    > }
    > return(0);
    > }
    >
    > But whatever I will use as .tv_nsec (if smaller than 20000000), the
    > duty cycle is 20 ms! I also tried usleep - the same.


    Cannot work. This old kernel misses the high resolution timer (=HRT)
    support.

    > My kernel is:
    > 2.6.15 #1 PREEMPT Thu Oct 30 10:41:51 CET 2008 cris unknown
    > with Preempt on!


    Try with a more recent kernel (2.6.26.6), add the RT-Preempt patch on top of
    it (http://rt.et.redhat.com/download/pat....26.6-rt11.bz2), lock your
    application's memory (man mlock/mlockall), give your application realtime
    priority (man pthread_attr_setschedpolicy) and (may be) it will work as
    expected.
    It depends on the architecture your application is running on. On my PowerPC
    the HRT/RT-Preempt kernel is able to hit this 1ms period with about ~80us
    accuracy, independent from any other system activity.

    jbe


+ Reply to Thread