Recently I was trying to control standard servo motor with PWMs. The
system is 600MHz BeagleBoard xM (ARM) running Linux kernel version
2.6.35.9 with Xenomai version 2.5.6.
Pulses needs to be generated with 20milliseconds interval (50Hz).
Pulse width defines servo position and is typically in the range of
0.8milliseconds to 2.0milliseconds. To generate PWMs I am using GPIO
pin connected to the servo through TI's TXS0108E voltage-level
translator to translate +1.8V GPIO to required +5V. To trigger GPIO
state I am using direct memory writes (to mmapped area).
The generation loop is running in the Xenomai thread with priority 99
and looks like this:
for(; {
//set_data_out has offset 0x94
gpio[OFFSET(0x6094)]=0x40000000;
rt_task_sleep(up_period);
//clear_data_out has offset 0x90
gpio[OFFSET(0x6090)]=0x40000000;
rt_task_wait_period(NULL); }
So now the question/problem I have. If the system load is low, then
everything is fine. However, if the system load goes beyound ~60%,
servos starts shaking which is a sign of not precise PWM timing. I
have written the blog post with more details and relevant videos: http://veter-project.blogspot.com/2011/09/real-time-enough-about-pwms-and-shaky.html
. Just scroll down to the section named "Solution 2 - predictable
timing with Xenomai" since the rest is probably obvious for the folks
hanging around here .
Running the Xenomai's latency application in parallel with our test
program reveals the latency of around 40 microseconds. Based on what I
read in Internet, 40 microseconds is considered "normal/OK" latency
for Linux/Xenomai running on ARM at 600MHz. Taking in account typical
pulse width of about 1 millisecond, 40 microseconds is about 4%. Could
it be that this 4% is in fact what causes servos to shake? If yes,
does it mean that even with Xenomai it is not possible to control
servos reliably even under moderate system load on the mentioned
hardware?
I am kind of hope that there are some tweeks could be done to make the
timing more precise and would really appreciate any hints.
Running the Xenomai's latency application in parallel with our test
program reveals the latency of around 40 microseconds. Based on what I
read in Internet, 40 microseconds is considered "normal/OK" latency
for Linux/Xenomai running on ARM at 600MHz. Taking in account typical
pulse width of about 1 millisecond, 40 microseconds is about 4%. Could
it be that this 4% is in fact what causes servos to shake? If yes,
does it mean that even with Xenomai it is not possible to control
servos reliably even under moderate system load on the mentioned
hardware?
I am kind of hope that there are some tweeks could be done to make the
timing more precise and would really appreciate any hints.
You have a real time task to perform. There are only two reliable
ways:
1) Connect up some dedicated PWM hardware, controlled by the BB.
The hardware keeps on generating the pulses. The BB only needs
to send any changes to the hardware.
You have a real time task to perform. There are only two reliable
ways:
1) Connect up some dedicated PWM hardware, controlled by the BB.
The hardware keeps on generating the pulses. The BB only needs
to send any changes to the hardware.
Well, this is what we are already doing with two hardware PWM
generators available on the BB. The idea is to use the power of the BB
to do more real-time tasks without going the dedicated hardware way.
PWMs with GPIO is just a kind of concept proove.
2) Use a real time OS.
My hope was that Linux with Xenomai can perform good enough for tasks
such standard PWM generation. And if I take in account all the other
required software components we are using and which are available on
Linux (things like WLan drivers, Gstreamer, Video4Linux, Ice, etc.) I
can hardly imagine which real-time OS can offer the same. Do you have
concrete suggestions here?
My hope was that Linux with Xenomai can perform good enough for tasks
such standard PWM generation. And if I take in account all the other
required software components we are using and which are available on
Linux (things like WLan drivers, Gstreamer, Video4Linux, Ice, etc.) I
can hardly imagine which real-time OS can offer the same. Do you have
concrete suggestions here?
Sorry, no. I have been involved with use of VxWorks on another platform
years ago, but lack of drivers was an issue that stopped us from using
it on other projects; you can write them or have them written for you,
but you need substantial sales to justify it.
20 years ago, we were using the Motorola MC68332, which has lots of very
powerful channels of dedicated Time Processing Unit. We used it for some
digital servos. It was a dream - a hugely satisfying project. But we
used no OS at all. You clearly have very different requirements.
Sorry, no. I have been involved with use of VxWorks on another platform
years ago, but lack of drivers was an issue that stopped us from using
it on other projects; you can write them or have them written for you,
but you need substantial sales to justify it.
20 years ago, we were using the Motorola MC68332, which has lots of very
powerful channels of dedicated Time Processing Unit. We used it for some
digital servos. It was a dream - a hugely satisfying project. But we
used no OS at all. You clearly have very different requirements.
Yes, merging real-time capabilities of VxWorks with the great amount
of the good free software and drivers available for Linux would be of
great help! This is what we are essentially trying to achieve with
our experiments with Xenomai. I've send similar email to the Xenomai
mail list and already got some hints what could be done to reduce the
jitter causing servo shaking. We will definitely continue to play with
it. The hope is not lost yet .
run a mini RTOS besides linux. Take e.g. one timer and route it to the FIQ. Then write a small FIQ handler that controls the GPIOs you need
for your PWM. This FIQ will interrupt even the linux kernel and
therefore should have a very constant rate and no latency at all.
Communicate between your FIQ handler and Linux by using a small amount
of shared memory, just for Linux to write the current PWM value(s) and
the FIQ handler to read them.
According to my understanding, Xenomai *is* a kind of mini RTOS. There
are even "skins" which emulate API of VxWorks and a couple of other
popular RTOSes. Xenomai acts as a supervisor running Linux kernel as
one of it's tasks and it can be preempted if necessary (if there is
higher priority process ready to run). That is why I was expecting
more precise timing.
it appears that there is some hardware support for PWM pulse
generation in the Beagleboard hardware. Perhaps consider using that.
There are probably more hardware details in the processor data sheet.
If the hardware generates the pulse width, the only latency issue
would be when software changes the pulse width; there should be no
jitter at all when the servo is at a fixed position. In some PWM
hardware (don't know about OMAP), even the changing of pulse width can
be double-buffered, with the new value clocked in by the expiration of
a hardware timer with no OS involvement.
By the way, thanks for bringing Xenomai to the attention of the list.
Trolls aside, it looks like very interesting work with the potential
to give the best of both worlds: the rich app and infrastructure
environment of Linux along with improved real-time performance.
Running the Xenomai's latency application in parallel with our test
program reveals the latency of around 40 microseconds. Based on what I
read in Internet, 40 microseconds is considered "normal/OK" latency
for Linux/Xenomai running on ARM at 600MHz. Taking in account typical
pulse width of about 1 millisecond, 40 microseconds is about 4%. Could
it be that this 4% is in fact what causes servos to shake? If yes,
does it mean that even with Xenomai it is not possible to control
servos reliably even under moderate system load on the mentioned
hardware?
Playing around with cyclictest should give you a good idea of what you
are going to expect.
I am kind of hope that there are some tweeks could be done to make the
timing more precise and would really appreciate any hints.
At the moment I don't have any hints, except that real-time is not
about speed, but about determinism.
Can you please post the results of running what I suggested above and
also with which parameters you ran the applications.
it appears that there is some hardware support for PWM pulse
generation in the Beagleboard hardware. Perhaps consider using that.
We are already using two of the three available hardware PWM generators.
Our current experiments with PWM generation using GPIO is just to test
what we can reach with Xenomai. My hope is that if I learn how to
generate precise PWMs, then I can reuse the same technique for other
real-time tasks. So it is not our ultimate goal to generate PWM.
Instead to learn what is doable with Xenomai.
By the way, thanks for bringing Xenomai to the attention of the list.
Trolls aside, it looks like very interesting work with the potential
to give the best of both worlds: the rich app and infrastructure
environment of Linux along with improved real-time performance.
I am absolutely agree with you. Specially in the hobby domain (like
for example hobby robotics) I see big potential for Xenomai on
BeagleBoard.
Based on the responses I've got in the Xenomai mail list, it seams to
be unavoidable for me to write RTDM driver for better timing. This is
what everybody was suggesting. So I just start learning and reading
how to do it. After I will get the first running version, I will
definitely use your suggestions to test the application under
different conditions.
Is it possible to compile your program with the standard c library?
I am not sure what exactly did you mean here but if the question is whether it is possible to write GPIO triggering application running in user space and without Xenomai, then the answer is yes. In fact, our very first attempts to generate PWMs to control the servo was made from user space using /dev/mem (memmap) to get direct access to GPIO registers.