rtai - earliest deadline first
Post on 07-May-2015
317 Views
Preview:
DESCRIPTION
TRANSCRIPT
RTAI &
Earliest Deadline First Real-Time Operative Systems M
Stefano Bragaglia
stefano.bragaglia@unibo.it
Overview
Introduction � RTAI: Real-Time Application Interface
� 1996: feasibility study to abandon DOS in favour of the Linux kernel
� 1999: first working release on Linux kernel 2.2
� 2001: further extended to run several kernels together
Overview RTHAL: Real-Time Hardware Abstraction Layer
� Introduces a new layer between the hardware and the Linux kernel
� Involves minimal changes with respect to the standard kernel
� The first releases required to replace about 70 lines of code
User Space
Hardware
Real-Time Processes
Standard Processes
Linux Kernel
Real-Time Kernel
System Calls
Overview RTHAL: Real-Time Hardware Abstraction Layer
� Critical data and t-functions held in a single place
� Interrupts, system calls, timers are easier to capture
� Native operations are replaced by operations on dynamic RTHAL pointers
� When RTAI is on, they lead to the real-time kernel structures, otherwise to the original ones
User Space
Hardware
Real-Time Processes
Standard Processes
Linux Kernel
Real-Time Kernel
System Calls
Linux can not enable/disable interruptions anymore!
Overview RTHAL: Real-Time Hardware Abstraction Layer
� RTHAL does not provide real-time services, it only intercept system calls
� Calls are redirected towards structures referenced by RTHAL
� Hardware only accessed by real-time functions, hence Linux run as a low priority process
User Space
Hardware
Real-Time Processes
Standard Processes
Linux Kernel
Real-Time Kernel
System Calls
RTAI is a kernel module which does not require to be loaded at boot: can be enabled at will!
Overview ADEOS: Adaptive Domain Environment for Operating Systems
� RTHAL further improved into ADEOS
� Hierarchy of operative systems divided in layers
� A flexible environment to share hardware among several (instances of) operative systems
� A micro-kernel handles the communication between the different domains
� Chains of responsibility
User Space
Hardware
Real-Time Processes
Standard Processes
Linux Kernel
Real-Time Kernel
System Calls
RTAI is a kernel module which does not require to be loaded at boot: can be enabled at will!
Architecture ADEOS: Adaptive Domain Environment for Operating
Systems
Hardware
Real-Time Processes
I/O
RTHAL / ADEOS
Real-Time Kernel
Scheduler
User Space
Standard Processes
Linux Kernel
User Space
Standard Processes
Linux Kernel
User Space
Linux Kernel
Interrupts
SW Interrupts HW Interrupts SW Interrupts I/O
RTAI Inter-Process Communication
� Real-time FIFOs � Basic mechanism to asynchronously exchange data between RT and user space
processes
� Shared Memory � Shares memory areas between RT and user space processes
� Messages � Allows to send messages both asynchronously and synchronously (RPC) among RT
processes
� Mailboxes � Send/receive messages of any size (ordered by priority, arrival time, etc.) between RT
and user space processes
� Semaphores � A process synchronisation method when accessing shared resources which avoids
unsupervised priority inversions
RTAI Inter-Process Communication
� Real-time extensions of the POSIX standard poorly supported � Only pthread, mutex and pqueue partially supported
� LXRT (LinuX Real-Time) � Native RTAI processes run in kernel mode
(RTAI API only available in kernel modules) � LXRT allows to use of RTAI API in user space
(the APIs in kernel mode and user space are the same, where possible)
� A more gradual transition from Linux processes to RT ones � Hardware is more protected
(memory can be freely accessed in kernel space) � More convenient, but less efficient
An example of RTAI kernel module
#include <rtai.h> #include <rtai_sched.h> ... RT_TASK task; ... void task_routine() { while(1) { /* Codice real-‐time */ rt_task_wait_period(); } } ... int init_module(void) { ... rt_task_init(&task, task_routine, 0, stack_size, priority, 0, 0); timer_period = start_rt_timer(nano2count(1e9)); task_period = 2*timer_period; rt_task_make_periodic(&task, now, task_period); } ... void cleanup_module(void) { rt_task_delete(&task); stop_rt_timer(); }
Dec
lara
tive
par
t R
eal-ti
me
par
t M
odule
se
tup
An example of RTAI LXRT process
#include <rtai_lxrt.h> ... int main(void) { RT_TASK *task; ... sched_setscheduler(0, SCHED_FIFO, &priorita); mlockall(MCL_CURRENT | MCL_FUTURE); task = rt_task_init(nam2num("Name"), priority, stack_size, 0); timer_period = start_rt_timer(nano2count(1e9)); task_period = 2*timer_period; ... rt_make_hard_real_time(); rt_task_make_periodic(task, now, task_period); while(1) { /* Real-‐time code */ rt_task_wait_period(); } rt_make_soft_real_time(); rt_task_delete(task); return 0; }
Dec
l.
par
t R
eal-ti
me
par
t P
roce
ss
term
inat
ion
Pro
cess
in
itia
lisat
ion
RT Scheduling: EDF
RTAI Scheduling � RTAI supports various scheduling policies
� Priority-driven (native; process priorities are assigned manually): � FIFO: First-In-First-Out
� RR: Round Robin
� More advanced solutions: � RM: Rate Monotonic
� EDF: Earliest Deadline First
Priority-driven Scheduling Policies
FIFO – specific priorities Proc3: started Proc3: iteration 1 Proc3: iteration 2 Proc3: terminated Proc1: started Proc1: iteration 1 Proc1: iteration 2 Proc1: iteration 3 Proc1: iteration 4 Proc1: terminated Proc2: started Proc2: iteration 1 Proc2: iteration 2 Proc2: iteration 3 Proc2: terminated
FIFO – same priority Proc1: started Proc1: iteration 1 Proc1: iteration 2 Proc1: iteration 3 Proc1: iteration 4 Proc1: terminated Proc2: started Proc2: iteration 1 Proc2: iteration 2 Proc2: iteration 3 Proc2: terminated Proc3: started Proc3: iteration 1 Proc3: iteration 2 Proc3: terminated
RR – same priority Proc1: started Proc2: started Proc3: started Proc1: iteration 1 Proc2: iteration 1 Proc3: iteration 1 Proc1: iteration 2 Proc2: iteration 2 Proc3: iteration 2 Proc1: iteration 3 Proc2: iteration 3 Proc1: iteration 4 Proc1: terminated Proc2: terminated Proc3: terminated
Other Scheduling Policies RM – Rate Monotonic
� Can be easily implemented from FIFO scheduling
� Process priority is inferred from the frequency of its activation
� RTAI functions: � rt_task_make_periodic(…)
finds priority of available processes from their period
� void rt_spv_RMS(<cpu>) sets priority of processes on given CPU by their frequency
EDF – Earliest Deadline First
� Can be similarly implemented from FIFO scheduling
� Priority is given to the process that is ready and has to complete first
� RTAI functions: � void rt_task_set_resume_
end_times(<resume>,<end>) sets the absolute resume and deadline of the process; rescheduled on resume; periodicity with neg values
Other Scheduling Policies RM – rate monotonic scheduling Proc HF: started Proc HF: terminated Proc LF: started Proc LF: terminated Proc HF: started Proc HF: terminated Proc HF: started Proc HF: terminated Proc LF: started Proc HF: started <preemption!> Proc HF: terminated Proc LF: terminated Proc HF: started Proc HF: terminated Proc LF: started Proc LF: terminated
EDF – earliest deadline first scheduling Proc 1: started Proc 1: terminated Proc 2: started <preemption!> Proc 1: started <desp. prior.> Proc 1: terminated Proc 1: started Proc 1: terminated Proc 2: terminated Proc 1: started Proc 1: terminated Proc 2: started Proc 1: started Proc 1: terminated Proc 1: started Proc 1: terminated Proc 2: terminated
EDF – Earliest Deadline First � Optimal scheduling algorithm on preemptive
uniprocessors
� 100% utilisation bound with processes whose deadline is equal to their period � EDF guarantees that all the processes meet their
deadlines if CPU utilisation is not more than 100%
� No fault signal (ASAP execution policy) � Missed deadlines are handled by the user
EDF – Earliest Deadline First � Create the RT processes with priorities (discarded later)
� rt_task_init(&task1, task_execution, "1", 10000, LOW_PR, 0, 0); � rt_task_init(&task2, task_execution, "2", 10000, HIGH_PR, 0,
0);
� Make the RT processes periodic (period useless) � rt_task_make_periodic(&task1, now + ..., PERIOD_1); � rt_task_make_periodic(&task2, now + ..., PERIOD_2);
� Set activation and deadline per process � rt_task_set_resume_end_times(now + ..., -‐REL_DEADL_1); � rt_task_set_resume_end_times(now + ..., -‐REL_DEADL_2);
� Reset activation and deadline on completion � rt_task_set_resume_end_times(-‐PERIOD_n,-‐REL_DEADL_n);
EDF – Earliest Deadline First (LXRT) � Create a child process
� fork();
� Create a real-time “agent” for each process � rt_task_init(nam2num(“Task1”), LOW_PR, 0, 0); � rt_task_init(nam2num(“Task2”), HIGH_PR, 0, 0);
� Start real-time mode � rt_make_hard_real_time();
� Make the processes periodic � rt_task_make_periodic(task1, now + ..., PERIOD_1); � rt_task_make_periodic(task2, now + ..., PERIOD_2);
� Set activation and deadline per process � rt_task_set_resume_end_times(now + ..., -‐REL_DEADL_1); � rt_task_set_resume_end_times(now + ..., -‐REL_DEADL_2);
� Reset activation and deadline on completion � rt_task_set_resume_end_times(-‐PERIOD_n,-‐REL_DEADL_n);
Installing and Using RTAI
Installing RTAI 1. Install Linux (any common distro will do)
� Ubuntu, Fedora, Mandrake, Slackware, Gentoo…
2. Download the source code of a vanilla kernel � http://www.kernel.org
3. Download a compatible RTAI version � http://www.rtai.org (match the kernel version!)
4. Patch the kernel source code � cd sources && patch –p1 < ../rtai/…/file.patch
Installing RTAI 5. Configure the kernel (default .config as reference)
� cp /boot/config-‐current_version .config
� make menuconfig
6. Set the code maturity level � Code maturity level -‐-‐> Promptfordevelopmentand/or incomplete drivers -‐-‐> YES
� Loadable module support -‐-‐> Enable loadable module support -‐-‐> YES
� Module versioning support -‐-‐> NO
� Processor type and features -‐-‐> Preemptible kernel -‐-‐> NO
� Processor type and features -‐-‐> Use register arguments -‐-‐> NO
� Processor type and features -‐-‐> Interrupt pipeline (IPIPE) -‐-‐> YES
� File systems -‐-‐> Pseudo filesystems -‐-‐> /proc file system support -‐-‐> YES
Installing RTAI 7. Compile and install the kernel
� make � make modules_install � mkinitrd /boot/initrd-‐versione_kernel.img vesione_kernel � cparch/i386/boot/bzImage/boot/vmlinuz-‐versione_kernel � cp System.map /boot/System.map-‐versione_kernel � ln –s /boot/System.map-‐versione_kernel /boot/System.map
8. Add entry to the bootloader config file � vi /boot/grub/menu.lst
9. Reboot into the new kernel
Installing RTAI 10. Configure and install RTAI
� cd /rtai/ � make menuconfig
� Machine --> Number of CPUs = 1 � General à Installation directory = /path/to/
patched_kernel/
11. Reboot
12. Test � cd /rtai/testsuite/user/latency � ./run
Using RTAI � Write your own module
� See example
� Compile it � Makefiles are a convenient solution
� Verify that only 1 CPU is enabled � sudo nano /etc/default/grub � GRUB_CMDLINE_LINUX=“maxcpus=1”
� Put it into execution…
Using RTAI � Put it into execution
� Load a RTAI module to kernel: sudo insmod /usr/realtime/modules/<module>.ko
� Unload a RTAI module from kernel: sudo rmmod <module>
� “Debug” it � See the output of the real-time subsystem:
dmesg � It prints errors messages as well as the outcome of calls to
printntk(…) and rt_printk(…) � If other modules are required (rtai_hal.ko, rtai_shm.ko,
rtai_sched.ko, etc.), you have to load them first!
top related