Syst `emes temps r ´eel et Syst `emes embarqu ´es
Linux temps r ´eel et embarqu ´e
Lo¨ıc Cuvillon
Ecole Nationale Sup ´erieure de Physique de Strasbourg
29 novembre 2015
Plan
1 Linux Operating System Linux Kernel
Linux Driver Model
2 Compilation of userland applications and library Compilation and libraries
3 Le temps r ´eel
Ordonnancement pr ´eemptif
4 Programmation Muli-t ˆaches (Posix/Xenomai) Les threads
IPC : mutex, semaphore, pipes, signaux Le temps
5 Linux Xenomai
Linux n’est pas temps r ´eel Architecture de Xenomai
Bibliographie
Le noyau Linux
Understanding the Linux kernel, 3 `eme Edition, D.P. Bovet et M. Cesati, O’Reilly.
Linux Kernel Development, 2 `eme Edition, Robert Love, Novell Press.
Linux Device Drivers, Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman,O’Reilly
Le temps r ´eel :
Real-time concepts for embedded systems, Q. Li, CMP Books.
Xenomai documentation Documents de cours et Annales :
http ://eavr.u-strasbg.fr/wiki/index.php/ENSPS 3A et master ISTI
Plan
1 Linux Operating System Linux Kernel
Linux Driver Model
2 Compilation of userland applications and library Compilation and libraries
3 Le temps r ´eel
Ordonnancement pr ´eemptif
4 Programmation Muli-t ˆaches (Posix/Xenomai) Les threads
IPC : mutex, semaphore, pipes, signaux Le temps
5 Linux Xenomai
Linux n’est pas temps r ´eel Architecture de Xenomai
Operating System
Operating system
a collection of software that provide services and abstraction of the hardware to multiple user programs enable multi-tasking, multi-user share CPU, memory,... for processes
enable inter-processes communication
Hardware Operating System
User Application
Operating System Features
2. Memory
− memory allocation
− virtual memory Management
Drivers 1. Process
Management
− process creation/
CPU time−sharing
− scheduling/
destruction
Device System 3. File and
− open / close
− read / write
Keyboard Mouse Screen
Hard−drive CPU
6. System Call Handling
GCC Internet Browser
Shell
libc
system calls
management
− Timers / Alarms
− System Time 5. Time
Hardware abstraction
OS/kernel Space
Hardware User Space OS
Communication 4. Inter−Process
− Message queues / Shared memory
Networking
− Socket/
− Synchronization
Process scheduling
scheduler(odonnanceur) select the process to run at one time CPU time-sharing for multi-tasking
3 states for a process : ready, running, blocked
vlc gedit
−read()
−sleep()
−sem_wait()
− ...
ssh gcc bash xterm
CPU timeline CPU
Ready Tasks Pool Blocked Tasks Pool
Running Task
blocking function return of the
Scheduler :
periodically select the task to run
If call to a blocking function:
Scheduling
Ordonnancement disponible sous Linux
SCHED OTHER : ordonnanceur ´equitable (default)
augmentation de la priorit ´e des t ˆaches qui ont eu peu de temps CPU niveau de”nice”pour favoriser des t ˆaches
SCHED FIFO : ordonnanceur TR `a priorit ´e fixe (need to be root user) t ˆaches utilisant cet ordonnanceur sont prioritaires sur les t ˆaches SCHED OTHER
si priorit ´e identique la premi `ere dans la file est enti `erement ex ´ecut ´ee SCHED RR : ´equivalent `a SCHED FIFO
mais une t ˆache interrompue est remise en bout de sa file de priorit ´e
Linux Process/Task scheduling
Running Task
CPU The Rule: Task with highest level run first.
99 98 ... 2 1
T3
T4 T5
RT Tasks (SCHED_FIFO/RR) (SCHED_OTHER)
Priority level T1
0 T7
T6 T9
T8 T2
scheduler
Ready RT Tasks Pool
Inside Priority level 0 only, tasks have a nice level.
POSIX system calls
ONLY way to ask the OS a service :
open filesys_open, write on screensys_write, memory allocation..
each OS syscall has its corresponding function in the libc : open(),write()
call notification to the OS through interruption (INT 0X80)
R7 Name Linux Source R0 R1 R2
1 sys exit kernel/exit.c int
2 sys fork kernel/process.c struct pt regs
4 sys write fs/read write.c unsigned int const char * size t
5 sys open fs/open.c const char * int int
11 sys execve kernel/process.c struct pt regs
15 sys chmod fs/open.c const char * mode t
23 sys setuid kernel/sys.c uid t ...
37 sys kill kernel/signal.c int int
39 sys mkdir fs/namei.c const char * int
78 sys gettimeofday kernel/time.c struct timeval * struct timezone * ...
System call
The “Hello World !”
.data
HelloWorldString:
.ascii "Hello World\n"
.text
.globl _start _start:
# Load all the arguments for write () mov r7, #4
mov r0, #1
ldr r1,=HelloWorldString mov r2, #12
swi #0
# Need to exit the program mov r7, #1
mov r0, #0 swi #0
System call
The “Hello World !”
as hello.S -o hello.o ls hello.o -o hello strace ./hello:
straceenable to track system call and signals of the process
System Call
R7 5 R0 @filename R1 1 IR SWI 0x00 int fd=
open(filename, O_RDONLY);
1
libc
fopen(filename, FILE *F=
"w"
return fd User Space
SWI 0x00
−call syscall function
−retrieve syscall number
−rise CPU privilege
sys_open
−retrieve parameters
−check parameters
−retrieve process userID
−browse file system
−return file descriptor *fd* number via R0
−check file permission
−lower CPU privilege OS (Kernel) Space
user process
Linux Kernel
Linux Kernel
the Kernel :
software providing all OS functionality kernel monolithic, 1 binary file
but parts of kernel can be unload/load : the modules
written in C, open-source
version 0.01 in 1991 by Linus Torvald
Process scheduling Process communication
Memory management File Systems Network stack
Syscalls Drivers Module 1
Module 2
Module 3
Linux Kernel
Kernel compilation
$> cp linux−3.8/arch/x86/boot.bzimage /boot 5. Kernel installation on PC plateform
make install
$> update−grub (update bootloader (amorçage)) or linux−3.8.tar.gz
1. Download Kernel source from kernel.org in /usr/src
2. Kernel configuration in linux−3.8/ folder
$> make menuconfig
3. Compilation of kernel and modules
$> make
4. Module installation
$> make modules_install
Menu to select kernel core features, optionnal features as static code or module
Create compress kernel image (bzimage) and module objects *.ko
Create /lib/modules/3.8.0 and copy *.ko in it
Kernel compilation
Kernel configuration
save and load in the.configfile
features can be set has [] not include , [*] include in kernel image or [M] compiled as a module
correct configuration not easy
(base .config files available at www.kernel-seeds.org)
Modules
kernel object (*.ko) can be load/unload on demand used for drivers, file system support, optional features avoid to compile again the kernel if one driver missing useful for development-debug
Module Manipulation
vga_fb
Linux Kernel 1. list of loaded modules
2. load/unload modules
> rmmod vga_fb
soundcoresoundcore vga_fb
bluetooth
> lsmod
> insmod /lib/.../bluetooth.ko
Exercise : unload and load the Ethernet card driver
Kernel Module Programming
in Kernel Programming
in kernel programming→C language
only kernel API (printk, kalloc)→no libc (user-space) : no printf, fopen dynamic linking with Kernel procedure at insertion of module
User Space User Space
libc User API library function call
system call
Kernel function call Kernel Task
time libc
Kernel API Kernel Space
time Kernel Space
User task
Kernel Module Programming
API function : printk()
print message in kernel ring buffer (in RAM since kernel can not fopen) availability of printk() in kernel can be checked in/proc/kallsyms otherwise error message :Undefined symbolat loading
printk("hello!");
[43.0] ACPI: error [52.6] usb−2: new dev [54.3] hello!
root@pc: dmesg
To visualize ring buffer in terminal:
RAM memory
[43.0] ACPI: error [52.6] usb−2: new dev [54.3] hello!
3.
printk("hello!");
1.
1.> insmod ./hello.ko 2. Dynamic Linking
at insertion 3. Execution printk
drivers ...
register_c kalloc:
printk:
2.
Linux Kernel kernel procedure:
...IPC Scheduler
Lo¨ıc Cuvillon (ENSPS) Syst `emes temps r ´eel et Syst `emes embarqu ´es Ann ´ee scolaire 2013-2014 19 / 125
Module programming
nomain()function
one called at insertion :init_module()ormodule_init(*func) one called at removal :cleanup_module()ormodule_exit(*func) other functions have to be called through the 2 previous ones
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
int init_module (void)
{ printk("Hello world!\n"); return 0;
}
void cleanup_module(void) { printk("Bye! \n");}
Module compilation
Module Compilation
Kernel source tree is needed (kernel headers and .config)
forhello.cmodule, this makefile is used and then commandmake:
obj-M := hello.o all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Exercise : compilation and test of the previoushello.cmodule
Device drivers
Device files
each device accessed by a special file called ’device file’ in/dev
→ open,read,writesyscalls can be used to access devices
device file associated with a driver
read Mouse device
open(/dev/input/mice) and read it
orcat /dev/input/mice
Hw Devices
User Application
system call
/dev/cdrom
Kernel Space
Virtual file system
User Space
/dev/mice /dev/sda
driver A driver B driver C
Device drivers
Inside the driver
write one function for each file operation :
fops={
.open=device_open, .write=device_write, .read=device_read };
int device_open() {...}
copy_from_user(): to copy in the kernel data from a user sidewrite()
copy_to_user(): to copy kernel data to the user side
read (fd, )
write(fd, ) close(fd)
fd=open("
.open function
.write function
.read function
.release function
Hardware device User Application
/dev/newdriver
driver functions Virtual file system
Kernel
Device Files
Create a device file
mknod name device_type major minor Exemple : mknod /dev/newdriver c 60 0
the major number is the unique ID of the associated kernel driver.
(numbers list in kernel /Documentation/devices.txt)
crw− r−− −−− 1 root root 13, 63 janv 23 19:42 /dev/input/mice group’s member rights
owner rights (r=read,w=write,x=execute)
> ls −l /dev/input/mice
Device type:
c, for character device (data transmitted one byte at a time)
b, for block device (hard disks, data transmitted one block of data at a time) users group
owner other users rights
Minor number: to identify devices using same drivers Major number: ID of associated driver
Char Device driver
Exemple : char device driver with .openoperation
#include <linux/kernel.h><linux/module.h><linux/fs.h><asm/uaccess.h><asm/io.h>
static int device_open(struct inode *, struct file *);
static int Major=60;
static struct file_operations fops = { .open = device_open
};
static int device_open(struct inode *inode, struct file *file) {
printk("open\n");
return 0;
}
int init_module(void) { int Res;
Res = register_chrdev(Major, "newdriver", &fops); /*enregistre le pilote*/
return 0; }
void cleanup_module(void)
{ unregister_chrdev(Major, "newdriver"); }
Char device driver
Char device driver
register_chrdev(Major, "newdriver", &fops): to register a major number for the driver and its file operation.
driver linked to device files with the same major number
Exercise :
create a special device file with a major number 60.
give all users rights to read/write on the device file : chmod o+rxdevice name
load previous driver
test opening with a small C program or with the shell command : echo -n 1 >device name
Char device driver
addition of .write operation to the previous driver
char my_data[1];
ssize_t device_write(struct file *filep,const char *buff,size_t count, loff_t *offp );
static struct file_operations fops = { .write = device_write,
.open = device_open };
ssize_t device_write(struct file *filep,const char *buff,size_t count, loff_t *offp ) {
/*function to copy user space buffer to kernel space*/
if ( copy_from_user(my_data,buff,1) != 0 ) { printk( "Userspace -> kernel copy failed!\n" );
return 0; }
printk("int: %i",my_data[0]);
return 1;
}
Plan
1 Linux Operating System Linux Kernel
Linux Driver Model
2 Compilation of userland applications and library Compilation and libraries
3 Le temps r ´eel
Ordonnancement pr ´eemptif
4 Programmation Muli-t ˆaches (Posix/Xenomai) Les threads
IPC : mutex, semaphore, pipes, signaux Le temps
5 Linux Xenomai
Linux n’est pas temps r ´eel Architecture de Xenomai
Compilation of userland applications in C
main:
ldr r1, a bl printf add r0,#1
EF 00 03 1C 10 32 C4 00
libc.a libm.a 03 92
1C BF libjpeg.a
EF 00 03 1C 10 32 C4 00 84 68
objet
executable (ELF) gcc −lm −ljpg
ld −lm −ljpg cpp file.c −o file.i
gcc −E file.c −o file.i
file.s file.o
#include < >
int main() {
int a;
/*comment*/
int main() int scanf(, ,) int printf(, ,)
{ int a;
file.i file.c
gcc −S gcc −c
assembly
1-The preprocessor (cpp)
gcc -E file.c -o file.ioucpp file.c -o file.i to include files, remove comments, expend #define
Compilation of userland applications in C
EF 00 03 1C 10 32 C4 00
libc.a libm.a 03 92
1C BF libjpeg.a
EF 00 03 1C 10 32 C4 00 84 68
objet
executable (ELF) gcc −lm −ljpg
ld −lm −ljpg file.o gcc −c
file.c int a;
/*comment*/
{ int main()
#include < >
gcc −E
file.i file.s
int printf(, ,) int scanf(, ,) int main() {
int a;
main:
ldr r1, a bl printf add r0,#1 gcc −S file.i −o file.s
assembly
2-The compilator (gcc or cc)
gcc -S file.i -o file.s
to translate C langage in assembly langage
Compilation of userland applications in C
libc.a libm.a 03 92
1C BF libjpeg.a
EF 00 03 1C 10 32 C4 00 84 68
executable (ELF) gcc −lm −ljpg
ld −lm −ljpg file.c
int a;
/*comment*/
{ int main()
#include < >
gcc −E
file.s main:
ldr r1, a bl printf add r0,#1 int printf(, ,)
int scanf(, ,) int main() int a;
{
file.i
EF 00 03 1C 10 32 C4 00
file.o gcc −S
gcc −c file.s −o file.o as file.s −o file.o
assembly objet
3-The assembler (as)
gcc -c file.s -o file.oouas file.s -o file.o to translate assembly in binary machine langage
Compilation of userland applications in C
gcc −lm −ljpg file.c
int a;
/*comment*/
{ int main()
#include < >
gcc −E
int printf(, ,) int scanf(, ,) int main() int a;
{
file.i
EF 00 03 1C 10 32 C4 00
file.o gcc −S
objet
ld −lm −ljpg main:
ldr r1, a bl printf add r0,#1
file.s assembly
as
84 68 EF 00 03 1C 10 32 C4 00
03 92 1C BF
libc.a libm.a
libjpeg.a
executable (ELF)
4-The linker options (ld)
-l[libname]with library name without the ’lib’ prefix of the filename.
Exemple :-lmfor math librarylibm.so.
-L[path]to give library location. Ex :-L.for current directory.
le format ELF
ELF (Executable and Linking Format)
conteneur des fichiers objets, ex ´ecutables et biblioth `eques.
utilis ´e par Linux, Wii, PS3,...
la table des sections :
donne la position dans le fichier ELF des diverses sections (.text (code), .data, .symbols, ...)
la table de programme :
indique o `u charger en m ´emoire les sections avant ex ´ecution
ELF Header
Section Header Table (other
sections) .rodata
.text
.data Programm Header
Table
le format ELF et relocation
utilitaires du format elf
objdump [-option] [file]
-f : affiche l’ent ˆete ELF du fichier -h : affiche la table des sections -t : affiche la table des symboles -r : affiche la table de relogement -d : d ´esassemble le code de la section .text -D : d ´esassemble toute les sections nm [file]
liste les symboles du fichier et leur ´etat (Undefined,Text(fonction d ´efinie), Data d ´efinie)
les diff ´erents fichiers objets
Fichier objet relogeable : .o
1 table de symboles : noms des fonctions et variables globales Si le symbole est d ´efini, l’offset `a partir du d ´ebut de la section o `u se trouve sa d ´efinition (code pour une fonction, valeur pour une variable).
1 table de relogement : offsets o `u apparaissent chaque symbole non d ´efini dans le fichier.
un fichier adapt ´e au relogement:
les 2 tables permettent facilement de remplacer les symboles non d ´efinie par leur d ´efinition quand celle-ci est connue.
Fichier objet relogeable .o
analyse du fichier objet :objdump -t -r -D hello.o
0000000a 0000001a
10=0x0a
OFFSET TYPE VALUE R_386_PC32
R_386_32 a
printf Disassembly of section .text:
extern int a;
00 00 00 00 <main>:
1: ....
e: ....
9: a1 00 00 00 00 mov ?, %eax 0: 55 push %epb
Offset
Undefined 00000000 *UND* 00000000
00000000 *UND* 00000000 a printf 00000000 g .text 00000020 main
section name
void main()
{ printf("Hello world %i!",a); }
hello.c hello.o
SYMBOL TABLE:
RELOCATION RECORDS FOR [.text]:
19: e8 fc ff ff ff call 1a <main+0x1a>
Fichier objet relogeable .o
analyse du fichier objet :objdump -t -r -D def.o
Disassembly of section .data:
0:aa 00 00 00
00000000 g .data 00000000 a SYMBOL TABLE:
RELOCATION RECORDS: empty
def.c def.o
int a=0xaa;
Edition de lien et affectation d’adresse m ´emoire
gcc hello.o def.o -o hello: fusion sections et affectation d’adresses m ´emoires effectives aux symboles
20 a0 04 08
8048425: a1 mov ,%eax0x804a020 hello.o
def.o
hello Disassembly of section .text:
8048322: ...
804841c <main>:
804841d: ...
804842a: ...
8048320 <start_>:
804841c: 55 push %ebp 8048320: 31 ed xor %ebp,%ebp
80482f0 b6 fe ff ff
(@ via un offset) 804843a: ...
Disassembly of section .data:
SYMBOL TABLE : 804a020: aa 00 00 00 <a>
(optional, can be removed with cmd strip)
8048435: e8 call <printf@plt>
ELF HEADER:
NO RELOCATION RECORDS
start address 0x08048320
Les biblioth `eques
biblioth `eque statique .a
code de la librairie copi ´e dans l’ex ´ecutable
ex ´ecutable sans d ´ependance lourde empreinte disque et m ´emoire
biblioth `eque dynamique .so
´edition de liens `a l’ex ´ecution pas de duplication de code empreinte m ´emoire l ´eg `ere d ´ependance : biblioth `eque install ´ee ?
Hello world ! avec la lib C
gcc–static
hello.c -o hello ls -l hello: 564 Ko
gcc hello.c -o hello ls -l hello: 7 Ko ldd ./hello: (liste d ´ependances) libc.so.6 ld-linux.so.2
Les biblioth `eques dynamiques et statiques
biblioth `eques statiques .a biblioth `eques dynamiques .so
add.o
linker linker
Executables printf.o fopen.o
...
libc.a
x x x add: x x main: x printf: x
main: x x x printf: x
source.o source2.o
printf.o fopen.o
...
add.o
printf.o fopen.o
...
libc.so
linker linker
main: x main: x
add: x x x
x printf:−
printf:−
libc.so (en mémoire)
dynamic linker (ld−linux.so)
loader (execv) loader (execv)
dynamic linker partially linked executables
full executable in memory
source.o source2.o
Static library creation (.a)
EF 00 03 1C C4 00 10 32
EE A0 03 1C EF 00 23 D2 84 68
file2.o
ar −q libmylib.a file1.o file2.o
libmylib.a file1.o
EE A0 03 1C 84 68
Static library .a
libprefix must be added to the library filename.
Example : formyliblibrary,libmylib.a
Compilation
use of link options :-land-L
Example :gcc [sources.c,.o] -lmylib -L. -o [exe]
Dynamic library creation (.so)
EF 00 03 1C C4 00 10 32 EF 00
03 1C C4 00 10 32
file2.o file1.o
EE A0 03 1C EF 00 23 D2 84 68 file2.c
file1.c
gcc −shared file1.o file2.o −o libmylib.so gcc −fPIC −c file2.c −o file2.o gcc −fPIC −c file1.c −o file1.o
libmylib.so EE A0 03 1C 84 68 EE A0
03 1C 84 68
2 steps creation
1 create position independant objects(-fPIC) : gcc -fPIC -c [.c] -o [.o]
2 create the mylib library :gcc -shared -o libmalib.so [.o]
Shared dynamic library installation
/etc/ld.so.conf(/etc/ld.so.conf.d/) has to be updated with the directory containing the library
Or
the library file has to be moved in one directory listed by /etc/ld.so.conf
runldconfigto update the library location database by scanning directories listed in/etc/ld.so.conf
Linking with shared library
Example :gcc prog.c -lmylib -o prog
at running time, theldconfigdatabase is used by the linker to find the library and load it.
Cr ´eation d’une librairie dynamique
Utilitaires
ldd: liste les librairies dynamique n ´ecessaires `a un ex ´ecutable nm: liste les symboles d ´efinis dans le biblioth `eque
ldconfig: met `a jour la liste des librairies connues en parcourant les r ´epertoires d ´efinis dans/etc/ld.so.conf
ldconfig -p, affiche la liste des biblioth `eques connues.
Exercice1
1 Cr ´eer les fichiershello.cetdef.cpr ´ec ´edemment introduit.
2 Faire dedef.cune biblioth `eque statique. Compilerhello.cen la liant avec votre biblioth ´eque statique.
3 Faire de m ˆeme mais avec une biblioth `eque dynamique.
On utilisera la commandesudo -spour passer utilisateur root et installer la biblioth `eque dans un r ´epertoire ad ´equat.
(Attention `a ne pas ecraser une biblioth `eque existante.)
Plan
1 Linux Operating System Linux Kernel
Linux Driver Model
2 Compilation of userland applications and library Compilation and libraries
3 Le temps r ´eel
Ordonnancement pr ´eemptif
4 Programmation Muli-t ˆaches (Posix/Xenomai) Les threads
IPC : mutex, semaphore, pipes, signaux Le temps
5 Linux Xenomai
Linux n’est pas temps r ´eel Architecture de Xenomai
Syst `eme temps r ´eel
Syst `eme temps r ´eel
D ´ef :syst `eme (mat ´eriel et logiciel) qui satisfait aux contraintes fonctionnelles et temporelles qui lui sont impos ´ees.
Temps de r ´eponse d’un syst `eme :
temps entre l’apparition d’un vecteur d’entr ´ee et l’apparition du vecteur de sortie associ ´e.
Système
S1
S0
E0
E1 E2
Syst `eme temps r ´eel mou (soft real-time)
la majorit ´e des syst `emes informatiques sont temps r ´eel ”mou” : un lecteur mp3
lecteur vid ´eo (variation possible du framerate : fps)
Syst `emes Temps r ´eel mou
D ´ef :syst `eme devant satisfaire des ´ech ´eances temporelles mais avec un degr ´e de flexibilit ´e, tol ´erance sur l’ ´ech ´eance.
une ´ech ´eance non satisfaite : pas de destruction du syst `eme
a une p ´enalit ´e relative au retard sur l’ ´ech ´eance
Syst `eme temps r ´eel dur (hard real-time)
Syst `eme temps r ´eel dur
D ´ef :syst `eme devant respecter des ´ech ´eances avec une tol ´erance nulle.
utilit ´e nulle des r ´esultats obtenus apr `es ´ech ´eance.
p ´enalit ´e ´elev ´ee : panne compl `ete du syst `eme + danger pour l’int ´egrit ´e physique du syst `eme ou des ˆetres humains.
la crit `ere entre un syst `eme temps r ´eel dur et mou est la p ´enalit ´e en cas de non-respect de l’ ´ech ´eance.
Syst `eme temps r ´eel dur (hard real-time)
Majoritairement des t ˆaches p ´eriodiques
T ˆache de r ´egulation et d’asservissement d’un syst `eme physique.
Tout retard d ´establise l’asservissement.
(Exemple : r ´egulation de l’altitude en mer des misiles rasants Exocet) T ˆache de supervision
Applications du temps r ´eel dur
a ´eronautique/spatial, automobile (ABS, Airbag. . . ) syst `emes militaires, m ´edicaux (IRM)
process industriel (centrales nucl ´eaires, robotique ( ´evitons les but ´ees !),. . . )
Probl `ematique du temps r ´eel
Simple : si 1 t ˆache p ´eriodique
Pas de syst `eme d’exploitation
1µ-contr ˆoleur avec 1 tache (code) ex ´ecut ´e `a chaque interruption d’une
horloge
temps r ´eel si : Temps ex ´ecution<P ´eriode de la tache
Example : ABS, 1978
Probl `ematique du temps r ´eel
Complexe : multitude de t ˆaches de p ´eriodes diff ´erentes
t ˆaches de supervision, d’archivage, de l’interface graphique, d’asservissement...
→ Probl `eme de concurrence pour l’acc `es au CPU, la m ´emoire...
→ Politique d’ordonnancement n ´ecessaire pour assurer les ´ech ´eances des t ˆaches
OS temps r ´eel
Caract ´eristiques
une politique d’ordonnancement ”temps r ´eel”
R ´esoudre la concurrence des t ˆaches pour le CPU
un temps de r ´eponse (latence) assez court pour l’application vis ´ee
Usage
n’assure pas le respect des contraintes temps r ´eel d’un programme quelconque !
(exemple : inversion de priorit ´e avec pathfinder (NASA)) mais donne les primitives pour y parvenir
si conception et timings valid ´es par experience ou simulation.
Ordonnancement
Ordonnancement
appel `a l’ordonnanceur (scheduler)
→choix du process `a ex ´ecuter parmi les processus pr ˆets
En exécution
Bloqué Prêt
Ordonnanceur Appel à une
fonction bloquante
Retour de la fonction bloquante
Ordonnancement pr ´eemptif
Objectif de l’ordonnanceur temps r ´eel
faisabilit ´e : assurer l’ordonnancement des t ˆaches et leurs ´ech ´eances impl ´ementable
le plus utilis ´e : ordonnanceur pr ´eemptif `a priorit ´e fixe
Ordonnanceur pr ´eemptif `a priorit ´e fixe
pr ´eemption : capacit ´e `a interrompre une t ˆache au profit d’une autre priorit ´e fixe : chaque t ˆache a une priorit ´e d’ex ´ecution invariante r `egle : ex ´ecution de la t ˆache de plus haute priorit ´e non-bloqu ´ee`a chaque appel `a l’ordonnanceur
Ordonnancement pr ´eemptif `a priorit ´e fixe
Ordonnancement RM (rate-monotonic)
´etudi ´e dans les ann ´ees 70 (Liu&Leyland) et ´etendu par la suite g ´en ´eralisation des ordonnanceurs pr ´eemptifs `a priorit ´e fixe hypoth `eses :
t ˆaches p ´eriodiques et ind ´ependantesuniquement priorit ´e P de la t ˆache inverse `a sa p ´eriode T
Ai+Ti Ai
Ci
t tache i
Caract ´erisation d’une t ˆache
Ai : date d’activation de la t ˆache i (pr ˆete)
Ti : p ´eriode d’activation de la t ˆache i
Ci : dur ´ee de la t ˆache i Pi : priorit ´e de la t ˆache i
Ordonnancement RM
Condition suffisante d’ordonnancement
N t ˆaches p ´eriodiques et ind ´ependantes sont ordonnanc¸ables si :
U= XN
i=1
Ci
Ti < N(2N1 −1)
| {z }
cst. de liu & Leyland
(1) avec
avec Pi = 1
Ti (2)
N Cst. de l&l
1 1
2 0.82
3 0.78
.. ..
∞ 0.69
U : taux de charge du CPU si{cst de l&l}<U<1 :
on ne peut conclure avec ce test
Ordonnancement RM
Exemple 1
ordonnanceur ex ´ecut ´e toutes les unit ´es de temps occupation du CPU 81.5% (2550+3095)
→condition suffisante d’ordonnanc¸abilit ´e v ´erifi ´ee
i Ci Ti Pi
1 25 50 0.02
2 30 95 0.01
échéance
2ème 3ème échéance
A1 1ère échéance
A1 A1 A1
A2 A2
0 50 100 150
t
échéance
1ère fin 2ème échéance
fin fin fin
fin Tâche 2
Tâche 1
Ordonnancement RM
Exemple 2
ordonnanceur ex ´ecut ´e toutes les unit ´es de temps occupation du CPU →condition suffisante poursuite de l’analyse
i Ci Ti Pi
1 25 50
2 30 75
A1 A2
0 50 100 150
t Tâche 2
Tâche 1
Ordonnancement RM
Temps d’ex ´ecution dans le pire cas de la t ˆache i : W
isoithp(i), l’ensemble des t ˆaches de priorit ´e sup ´erieur `a la tache i soit⌈⌉, l’op ´erateur plafond (entier sup ´erieur)
Wi =Ci+ XN
j∈hp(i)
⌈Wi Tj
⌉Cj (3)
M ´ethode de calcul de W
iit ´erative `a partir dek =0 et avecWi0=Ci arr ˆet si∃k′tel queWik′ >Ti ouWik′ =Wik′+1
Wik+1=Ci + XN
j∈hp(i)
⌈Wik
Tj ⌉Cj (4)
Ordonnancement RM
Retour sur l’exercice 2 :
T ˆache 1 : (pas de t ˆache plus prioritaire) W10 = C1=25 W11 = C1=W10 T ˆache 2 : 1 t ˆache prioritaire,hp(j) ={1}
W20 = C2=30 W21 = C2+⌈W20
T1
⌉C1
= 30+⌈30
50⌉C1=30+1∗25=55 W22 =
=
Ordonnancement RM
Conclusion
en pr ´esence d’un ordonnancement pr ´eemptif et de t ˆaches p ´eriodiques ind ´ependantes :
RM permet d’utiliser des priorit ´es fixes pour les t ˆaches RM donne un crit `ere suffisant d’ordonnanc¸abilit ´e
Remarques
un grand nombre de t ˆaches=69% du CPU utilisable (Cst. de l&l) 31% restant (instants creux) utilisable pour les t ˆaches sporadiques, asynchrones
le RME (RM Etendu) peut prendre en compte des t ˆaches d ´ependantes des ordonnancements pr ´eemptifs `a priorit ´es variablesexistent : EDF
crit `ere n ´ecessaire et suffisant U<100%
mais bien + complexe `a impl ´ementer (priorit ´es `a recalculer dynamiquement)
Le mod `ele pr ´eemptif
Piles multiples d’éxecution Changement
de contexte
Mutex (race condition)
Inter−blocage
Inversion de priorité Préemption
mais des inconv ´enients par rapport `a un syst `eme non pr ´eemptif
changement de contexte : sauver l’ ´etat d’un processus pr ´eempt ´e (pile, registres CPU)
n ´ecessit ´e de prot ´eger une ressource par un mutex implique : blocage possible du syst `eme
inversion de priorit ´e
Plan
1 Linux Operating System Linux Kernel
Linux Driver Model
2 Compilation of userland applications and library Compilation and libraries
3 Le temps r ´eel
Ordonnancement pr ´eemptif
4 Programmation Muli-t ˆaches (Posix/Xenomai) Les threads
IPC : mutex, semaphore, pipes, signaux Le temps
5 Linux Xenomai
Linux n’est pas temps r ´eel Architecture de Xenomai
Thread : 1 processus l ´eger
Un processus :
plusieurs fils d’ex ´ecution
pour chaque fil (thread): 1 ´etat des registres 1 compteur ordinal ex ´ecution en parral `ele
l ´eg `eret ´e
m ˆeme espace d’adressage variables globales (data) partag ´ees entre threads
global var 2 global var1
{ var1, var2 thread1( )
...
}
{ var1, var2 thread2( )
...
}
Prog. counter CPU Registers
{ thread1( ) thread2( ) ...
} main( )
Prog. counter CPU Registers
Prog. counter CPU Registers
thread1
main main thread2 thread2
Processus
thread1 CPU timeline time
Thread : Cr ´eation et destruction
Cr ´eation d’une thread
la fonctionmain()est la thread initiale
une thread peut cr ´eer une nouvelle thread avec
pthread_create()/rt_task_create()andrt_task_create()
Fin d’une thread
si fin d’execution de son code
si appel `a la fonctionpthread_exit()/rt_task_delete()
si une thread la stoppe avecpthread_cancel()/rt_task_delete() si le processus se termine : lemain()retourne.
Thread : Destruction
Attente de la fin d’une thread
pthread_join()/rt_task_join():
thread appelante bloque tant que la thread indiqu ´ee n’est pas finie
´eviter que le main ne se termine et d ´etruise les threads.
thread 1
thread 2 Main
thread pthread_create() pthread_join()
pthread_exit()
Thread : Example cr ´eation de 2 t ˆaches parall `eles
/* Function as body of the thread */
void* dad_is_having_a_beer( void *ptr ) {
printf("Is my beer in the fridge?");
return NULL; } ...
int main( void ) {
pthread_t thread1, thread2; //thread descriptor pthread_create( &thread1, NULL, dad_is_having_a_beer,
(void*) NULL );
pthread_create( &thread2, NULL, son_is_having_a_coke, (void*) NULL );
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
return 0; }
Thread : Propri ´et ´e
Attributs de cr ´eation
la politique d’ordonnancement, la taille de la pile,...
API native : en param `etre dert_task_create()
API POSIX : attributs dans une structure de typepthread_attr_t
Politique d’ordonnancement temsp r ´eel
SCHED FIFO et SCHED RR pour du pr ´emeptif `a priorit ´e fixe (0 (priorit ´e basse)-99(priorit ´e haute))
seul l’utilisateur root peut choisir un ordonnancement TR (prioritaire sur t ˆaches classiques SCHED OTHER)
pthread_setschedparam()etpthread_getschedparam()
Thread : Example ordonnancement
void* dad_is_having_a_beer( void *ptr ) {
int my_policy =SCHED_FIFO;
struct sched_param my_param;
my_param.sched_priority = 90;
if ( pthread_setschedparam( pthread_self( ), my_policy, &my_param ) ) printf( "Unable to change scheduling parameters.\n" );
if ( !pthread_getschedparam ( pthread_self( ),
&my_policy, &my_param ) ) printf ("Thread_HP : running in mode %d %d \n",
my_policy ,my_param.sched_priority );
...
}
Situation de comp ´etition (race condition)
D ´efinition
manipulation conjointe d’une m ˆeme ressource ou variable par 2 t ˆaches sans synchronisation de l’acc `es
Cons ´equence : r ´esultat non d ´eterministe, fonction de l’ordonnancement des processus.
Example : race.c (partage d’une variable refrigerator)
Mutex
Illustration avec une variable partag ´ee entre 2 processus l ´egers (threads)
if (frigo==EMPTY) frigo=BEER;
else
frigo=EMPTY;
if (frigo == BEER)
printf("who stole my beer!");
{
} Dad:
preemption
preemption preemption
EMPTY COKE BEER EMPTY 0.
1.
2.
3.
frigo:
Etat variable
if (frigo==EMPTY) frigo=COKE;
else
frigo=EMPTY;
if (frigo == COKE)
printf("who stole my coke!");
Son:
{
} 0.
2.
3.
1.
> who stole my coke!
Mutex
Illustration avec une variable partag ´ee entre 2 processus l ´egers (threads)
if (frigo==EMPTY) frigo=BEER;
else
frigo=EMPTY;
if (frigo == BEER)
printf("who stole my beer!");
{
} Dad:
EMPTY 0.
1.
2.
3.
frigo:
Etat variable
if (frigo==EMPTY) frigo=COKE;
else
frigo=EMPTY;
if (frigo == COKE)
printf("who stole my coke!");
Son:
{
}
1.
0.
2.
preemption
BEER EMPTY COKE 4.
4.
3.
EMPTY
> (no message display)
l’objet Mutex (Mutual Exception)
D ´efinition
2 ´etats : ouvert/libre (1), ou ferm ´e (0)
une t ˆache peut acqu ´erir le mutex si il est libre : 1→0
si le mutex n’est pas libre, la t ˆachebloquetant qu’il n’est pas lib ´er ´e la t ˆache ayant acquis le mutex, doit le lib ´erer ensuite : 0→1
Fonction Xenomai Fonction Posix Op ´eration
rt mutex create() pthread mutex init() cr ´eer un mutex (toujours h ´eritage de priorit ´e) pthread mutexattr init() d ´efinir propri ´et ´es du mutex
rt mutex delete() pthread mutex destroy() d ´etruire un mutex rt mutex aquire() pthread mutex lock() acqu ´erir un mutex rt mutex release() pthread mutex unlock() lib ´erer un mutex
Mutex
Usage
protection par une section critique : encadr ´ee par une acquisition et lib ´eration d’un mutex
pour un m ˆeme mutex, seul 1 processus `a la fois peut ˆetre dans une section critique
partagée Ressource
Mutex Tâche
Tâche
Tache() { ...
pthread\_mutex\_lock();
//lecture/ecriture sur la ressource : la section critique pthread\_mutex\_unlock();
}
Mutex
un mutex pour pr ´evenir l’acc `es simultan ´e au frigo (race_mutex.c)
if (frigo==EMPTY) frigo=BEER;
else
frigo=EMPTY;
if (frigo == BEER)
printf("who stole my beer!");
}
pthread_mutex_unlock(&mx);
pthread_mutex_lock(&mx);
{ Dad:
{ Son:
if (frigo==EMPTY) frigo=COKE;
else
frigo=EMPTY;
if (frigo == COKE)
printf("who stole my coke!");
pthread_mutex_unlock(&mx);
pthread_mutex_lock(&mx);
} preemption
preemption (Son bloque,
Mutex deja acquis)
preemption (Mutex libre)
Mutex
Probl `emes courants avec les mutexes (et s ´emaphores)
famine : priv ´ee de la ressource monopolis ´ee par les t ˆaches prioritaires interblocage : t ˆaches ayant chacune une ressource voulue par une autre inversion de priorit ´e : ex ´ecution de t ˆaches non prioritaires car la t ˆache prioritaire attend une ressource
Solutions possibles
interblocage :
d ´etection du blocage par le RTOS
proc ´edure de d ´eblocage (lib ´eration forc ´ee d’une ressource) inversion de priorit ´e : algorithme d’h ´eritage de priorit ´e
Mutex
Interblocage (Deadlock)
la ressource est prot ´eg ´ee par un mutex (exclusion mutuelle)
une chaˆıne de 2 t ˆaches ou plus, o `u chaque t ˆache poss `ede une ressource voulue par une autre
A
Tâche Tâche
B A1
A2 mutex_unlock
A et B (prévu)
0 50 100
mutex_lock B
mutex_lock A
t
possédé
par veut veut
possédé par mutex_lock
t mutex_lock
B A
Inter−blocage
Mutex
Inversion de priorit ´e
D ´ef :situation o `u des t ˆaches de basse priorit ´e s’ex ´ecutent avant une t ˆache de haute priorit ´e d ˆu `a un blocage sur une ressource
situation aggrav ´ee par les t ˆaches de priorit ´e interm ´ediaire
A2
A1
t Priorité
0 50 100
t 150
mutex_lock
t mutex_lock
3
mutex_unlock
mutex_lock
section critique de (comportement normal)
∆t
∆t≤ T1
Mutex
Inversion de priorit ´e
D ´ef :situation o `u des t ˆaches de basse priorit ´e s’ex ´ecutent avant une t ˆache de haute priorit ´e d ˆu `a un blocage sur une ressource
situation aggrav ´ee par les t ˆaches de priorit ´e interm ´ediaire
A2
A1
t Priorité
0 50 100
t 150
mutex_lock
t
t mutex_lock
A4
A3
mutex_unlock mutex_lock
Inversion de priorité
∆t +C3+C4
Mutex
H ´eritage de priorit ´e
algorithme pour r ´esoudre le probl `eme d’inversion de priorit ´e le plus fr ´equemment impl ´ement ´e dans les RTOS
(rarement impl ´ement ´e dans les GPOS (linux))
Principe :
lib ´erer au plus t ˆot la ressource qui bloque la t ˆache prioritaire
→ si une t ˆacheAbloque sur une ressource d ´etenue par une t ˆacheBde priorit ´e inf ´erieure :
1 la priorit ´e de la t ˆacheBest ´elev ´ee `a celle deA
2 d `es que la ressource est lib ´er ´ee,Bretrouve sa priorit ´e initiale
Mutex
H ´eritage de priorit ´e
algorithme pour r ´esoudre le probl `eme d’inversion de priorit ´e le plus fr ´equemment impl ´ement ´e dans les RTOS
(rarement impl ´ement ´e dans les GPOS (linux))
A2
A1
t
3
t Priorité
0 50 100
t 150
mutex_lock
t mutex_lock
A4
A
mutex_unlock
mutex_lock
héritage:
initial)
∆t
(P1=P1
P1=P2
Mars Pathinder : un cas c ´el `ebre d’inversion de priorit ´e
Mars Pathinder
sonde avec rover (sojourner) pour exploration de la surface de Mars
“faster, better and cheaper” concept (<150 million $)
le bug: r ´e-initialisation de la sonde annulant les commandes en cours cause : inversion de priorit ´e retardant assez l’ex ´ecution d’une t ˆache pour d ´eclencher le watchdog de r ´einitilisation de la sonde
Cas d’ ´etude : Robot `a cable et tracking visuel
End−effector IR cameras
Driving cable actuator Robot
INCA
But: Commander les courants moteurs pour asservir la position de l’effecteur via la mesure de sa position par vision.
Windows PC
End−effector pose
RT Linux Xenomai PC (via Ethernet) VRPN server
Tracker software
VRPN RT client RT robot controller (1 kHz)
(200 Hz) Bonita M3 cameras
PCIcards
Encoders values currents Motors
Cas d’ ´etude : Robot `a cable et tracking visuel
Robot INCA
rt_mutex_acquire(&mutex_b);
position_b=position;
rt_mutex_release(&mutex_b);
} while (1) {
position=recvfrom(sockUDP, );
tant qu’aucun paquet UDP n’est présent*/
/*recvfrom est un appel bloquant
rt_mutex_acquire(&mutex_b);
bonita=position_b;
rt_mutex_release(&mutex_b);
compute_cmd(commande,bonita,encoders);
send_currents(commande);
...
rt_mutex_create(&mutex_b);
int position_b;
rt_task_spawn(&task_loop, , loop, );
rt_task_spawn(&task_bonita, , bonita_loop, );
Encoders values End−effector pose
bonita_loop();
Motors currents rt_task_set_periodic(NULL, TM_NOW, (via Ethernet)
main():
while(1) {
rt_task_wait_period(NULL);
..
}
1000000);
1kHz loop():