Xenomai
Xenomai architecture
The Adeos interrupt pipeline abstraction
- From the Adeos point of view, guest OSes are prioritized domains.
- For each event (interrupts, exceptions, syscalls, etc...), the various domains may handle the event or pass it down the pipeline.
Xenomai features
- Factored real-time core with skins implementing various real-time APIs
- Seamless support for hard real-time in user space
- No second-class citizen, all ports are equivalent feature-wise
- Xenomai support is as much as possible independent from the Linux kernel version (backward and forward compatible when reasonable)
- Each Xenomai branch has a stable user/kernel ABI
- Timer system based on hardware high-resolution timers
- Per-skin time base which may be periodic
- RTDM skin allowing to write real-time drivers
Xenomai user space real-time support
- Xenomai supports real-time in user space on 5 architectures, including 32 and 64 bits variants.
- Two modes are defined for a thread
- the primary mode, where the thread is handled by the Xenomaischeduler
- the secondary mode, when it is handled by the Linux scheduler.
- Thanks to the services of the Adeos I-pipe service, Xenomai system calls are defined.
- A thread migrates from secondary mode to primary mode when such a system call is issued
- It migrates from primary mode to secondary mode when a Linux system call is issued, or to handle gracefully exceptional events such as exceptions or Linux signals.
Life of a Xenomai application
- Xenomai applications are started like normal Linux processes, they are initially handled by the Linux scheduler and have access to all Linux services
- After their initialization, they declare themselves as real-time applications, which migrates them to primary mode. In this mode:
- They are scheduled directly by the Xenomai scheduler, so they have the real-time properties offered by Xenomai
- They don't have access to any Linux service, otherwise they get migrated back to secondary mode and loose all real-time properties
- They can only use device drivers that are implemented in Xenomai, not the ones of the Linux kernel
- Need to implement device drivers in Xenomai, and to split real-time and non real-time parts of your applications.
Real Time Driver Model (RTDM)
- An approach to unify the interfaces for developing device drivers and associated applications under real-time Linux
- An API very similar to the native Linux kernel driver API
- Allows to develop in kernel space:
- Character-style device drivers
- Network-style device drivers
- See the whitepaper on http://www.xenomai.org/documentation/xenomai-2.6/pdf/RTDM-and-Applications.pdf
- Current notable RTDM based drivers:
- Serial port controllers;
- RTnet UDP/IP stack;
- RT socket CAN, drivers for CAN controllers;
- Analogy, fork of the Comedi project, drivers for acquisitioncards.
Setting up Xenomai
How to build Xenomai
- Download Xenomai sources at http://download.gna.org/xenomai/stable/
- Download one of the Linux versions supported by this release
(see ksrc/arch/
/patches/) - Since version 2.0, split kernel/user building model.
- Kernel uses a script called script/prepare-kernel.sh which integrates Xenomai kernel-space support in the Linux sources.
- Run the kernel configuration menu.
Xenomai user space support
- User space libraries are compiled using the traditional autotools
- ./configure --host=arm-linux && make && make DESTDIR=/your/rootfs/ install
- Xenomai installs pkg-config files which helps you to compile your own programs against the Xenomai libraries.
- See Xenomai's examples directory.
- Installation details may be found in the README.INSTALLguide.
Developing applications on Xenomai
The POSIX skin
- The POSIX skin allows to recompile without changes a traditional POSIX application so that instead of using Linux real-time services, it uses Xenomai services
- http://www.xenomai.org/index.php/Porting_POSIX_applications_to_Xenomai
- Clocks and timers, condition variables, message queues, mutexes, semaphores, shared memory, signals, thread management
- Good for existing code or programmers familiar with the POSIX API
- Of course, if the application uses any Linux service that isn't available in Xenomai, it will switch back to secondary mode
- To link an application against the POSIX skin
CFL="pkg-config --cflags libxenomai_posix"
LDF="pkg-config --libs libxenomai_posix"
ARCH-gcc $CFL -o rttest rttest.c $LDF
Communication with a normal task
- If a Xenomai real-time application using the POSIX skin wishes to communicate with a separate non-real-time application, it must use the rtipc mechanism
- In the Xenomai application, create an IPCPROTO_XDDP socket
socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP); setsockopt(s, SOL_RTIPC, XDDP_SETLOCALPOOL,&poolsz, sizeof(poolsz)); memset(&saddr, 0, sizeof(saddr)); saddr.sipc_family = AF_RTIPC; saddr.sipc_port = PORTX; ret . = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
- And then the normal socket API sendto() / recvfrom()
- In the Linux application
- Open /dev/rtpPORTX, where PORTX is the XDDP port
- Use read() and write()
The native API
- A Xenomai specific API for developing real-time tasks
- http://xenomai.org/documentation/branches/v2.4.x/pdf/Native-API-Tour-rev-C.pdf
- Usable both in user space and kernel space. Development of tasks in user space is the preferred way.
- More coherent and more flexible API than the POSIX API. Easier to learn and understand. Certainly the way to go for new applications.
- Applications should include
, where service can be alarm, buffer, cond, event, heap, intr, misc, mutex, pipe, queue, sem, task, timer To compile applications:
CFL=`pkg-config --cflags libxenomai_native` LDF=`pkg-config --libs libxenomai_native` ARCH-gcc $CFL -o rttest rttest.c $LDF
Task management services
- rt_task_create(), rt_task_start(), rt_task_suspend(), rt_task_resume(), rt_task_delete(), rt_task_join(), etc.
- Counting semaphore services
- rt_sem_create(), rt_sem_delete(), rt_sem_p(), rt_sem_v(), etc.
- Message queue services
- rt_queue_create(), rt_queue_delete(), rt_queue_alloc(), rt_queue_free(), rt_queue_send(), rt_queue_receive(), etc.
Mutex services
- rt_mutex_create(), rt_mutex_delete(), rt_mutex_acquire(), rt_mutex_release(), etc.
Alarm services
- rt_alarm_create(), rt_alarm_delete(), rt_alarm_start(), rt_alarm_stop(), rt_alarm_wait(), etc.
- Memory heap services
- Allows to share memory between processes and/or to pre-allocate a pool of memory
- rt_heap_create(), rt_heap_delete(), rt_heap_alloc(), rt_heap_bind()
- Condition variable services
- rt_cond_create(), rt_cond_delete(), rt_cond_signal(), rt_cond_broadcast(), rt_cond_wait(), etc.
Xenomai and normal task communication
- Using rt_pipes
- In the native Xenomai application, use the Pipe API
- rt_pipe_create(), rt_pipe_delete(), rt_pipe_receive(), rt_pipe_send(), rt_pipe_alloc(), rt_pipe_free()
- In the normal Linux application
- Open the corresponding /dev/rtpX file, the minor is specified at rt_pipe_create() time
- Then, just read() and write() to the opened file
Xenomai worst-case latencies results
- ARM OMAP5432 1.1 GHz: 24 us
- ARM OMAP4430 1 GHz: 23 us
- ARM OMAP3530 720 MHz: 44 us
- ARM SAMA5D3 528 MHz: 51 us
- ARM AT91RM9200 180 MHz: 181 us
- x86 Atom 1.6 GHz: 35 us
- Geode LX800 processor at 500 MHz: 55 us
See results at http://xenomai.org/~gch/core-3.14-latencies/