Hi Drew,
I hope you're well!
I recently experimented briefly with both, here' s the steps I used to install Xenomai (Rob Nelson helped me find the pre-built kernel, the link to them is below).
Not all Xenomai APIs are enabled in the kernel. Anyway, I did get reduced jitter when using one of the API sets called Alchemy, which I guess is probably the easiest to code with. In a nutshell you can use the API to create a task thread, and do your low-latency stuff there.
For my experiment, I used this content in my makefile:
XENO_CONFIG := /usr/xenomai/bin/xeno-config
CFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --cflags)
LDFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --ldflags)
CC := gcc
EXECUTABLE := atest
all: $(EXECUTABLE)
%: %.c
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
clean:
rm -f $(EXECUTABLE)
and, code needs to look like this:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <alchemy/task.h>
RT_TASK hello_task;
// function to be executed by task
// this is your stuff for which you want low jitter
void helloWorld(void *arg)
{
RT_TASK_INFO curtaskinfo;
printf("Hello World!\n");
// inquire current task
rt_task_inquire(NULL,&curtaskinfo);
// print task name
while(1)
{
// do your stuff here in a forever loop if you like
// use this sleep command if you need to use any sleep. This sleep has low jitter:
rt_task_sleep(50000);
}
}
int main(int argc, char* argv[])
{
char str[10];
printf("start task\n");
sprintf(str,"hello");
/* Create task
* Arguments: &task,
* name,
* stack size (0=default),
* priority,
* mode (FPU, start suspended, ...)
*/
rt_task_create(&hello_task, str, 0, 99, 0);
/* Start task
* Arguments: &task,
* task function,
* function argument
*/
rt_task_start(&hello_task, &helloWorld, 0);
while(1)
{
sleep(10);
}
}
To test latency I ran this:
cyclictest -n -p 90 -i 1000
and the result was:
T: 0 ( 2914) P:90 I:1000 C: 31719 Min: 6 Act: 19 Avg: 18 Max: 51
which was about ten times lower for the Max value, compared to PREEMPT RT.
And it was far lower than x86 Linux running a standard kernel with Ubuntu. The x86 Linux was a virtual machine on ESXi on an Intel NUC.
It was all over the place with that - especially if I tried opening another terminal to do something. With Xenomai, it was stable.
In summary, provided one is willing to code for Xenomai, then the jitter difference is large - still no-where as good as PRU or a microcontroller of course, but fantastic for Linux.
Also, it seems that the pre-built Machinekit images use PREMPT RT, not Xenomai : ( I've no idea if Machinekit is coded to support Xenomai, I've not really investigated too far currently.
Installing pre-built Xenomi kernel:
https://github.com/beagleboard/linux/releases
cd /opt/scripts/tools/
git pull
As root user:
./update_kernel.sh --ti-xenomai-channel --lts-4_14
as non-root user:
cd development
mkdir xenomi
cd xenomi
wget https://xenomai.org/downloads/xenomai/stable/latest/xenomai-3.0.9.tar.bz2
bunzip2 xenomai-3.0.9.tar.bz2
tar xvf xenomai-3.0.9.tar
cd xenomai-3.0.9
./configure --enable-smp CFLAGS="-march=armv7-a -mfpu=vfp3" LDFLAGS="-march=armv7-a -mfpu=vfp3"
make
As root user:
make install
Testing it:
/usr/xenomai/bin/xeno-test
Development/xtest
make -f Mafefile-a
as root user:
export LD_LIBRARY_PATH=/usr/lib:/usr/xenomai/lib
./atest