Set GPIO in a precisely time using usleep()

Hi,

I am trying to control a servo with my BeagleBoneBlack using Angstrom. I must have a high-level on a GPIO for 1 millisecond. I use the following simple code:

while(1){
servo.setValue(BlackLib::low);

usleep(19000);

servo.setValue(BlackLib::high);

usleep(1000);

}

The GPIO is high for about 1.5 Milliseconds. The usleep()-function is not linear, so it did not work with any other value e.g. usleep(500). Sometimes I decrease the value by one (1 microsecond) but the time decrease by 100 microseconds.
Has anybody an idea what could be wrong?

The GPIO is high for about 1.5 Milliseconds. The usleep()-function is not linear, so it did not work with any other value e.g. usleep(500). Sometimes I decrease the value by one (1 microsecond) but the time decrease by 100 microseconds.
Has anybody an idea what could be wrong?

First of all, usleep() is not your problem. The problem most likely is related to kernel latency. You could improve this by using a PREEMPT RT kernel, but that will only at best give you 95% determinism.

Second, since you have not made your code public, we can not tell if servo.setValue() is well written or not. In the context of determinism. I will say however if you’re not using mmap() with /dev/mem/ on the GPIO registers directly. Your code will be “slow”, and not very deterministic.

Lastly, if you need absolute determinism, you had better start using the PRUs . . .

I will say that it is very likely that if you switch to a PREEMPT RT kernel, that determinism down to 1ms should be easily achievable. So long as you do not have too much in the way of background processes running at the same time.

It looks like you're trying to generate the servo PWM output in
software. This seems like a wrong way; you should use PWM hardware
units instead. There will always be some jitter from software context
switches, other OS activity and/or memory/cache/TLB latencies, and the
servo will be jerky.

Set up the PWM or PRU to generate your output. This way, software will
only be activated when you need to change the output values.

Thanks all for the response.
It is right, I try to generate a PWM, because all hardware PWMs are occupied.

I will check the PREEMPT RT kernel.