Sunteți pe pagina 1din 7

0

Exercice RTAI
2014

Exercice 1
Tches Priodiques
Le but de ce premier exercice est de crer deux tches priodiques
en utilisant la librairie RTAI.

Cration d'une tche priodique


La cration et l'excution d'une tche se fait en plusieurs tapes :
initialisation du timer,
cration de la tche,
lancement de la tche,
initialisation de la priodicit de la tche.

Cration d'une tche priodique

Initialisation du Timer
Toutes les fonctions relatives aux temps de RTAI utilisent le Timer,
c'est pourquoi il est indispensable de l'initialiser et de le lancer au
dbut de chaque programme mme si nous n'utilisons pas
directement les fonctions associes au Timer. L'initialisation est
ralise de la manire suivante:
rt_timer_start(TM_ONESHOT)
De manire gnrale nous utiliserons une initialisation non
priodique du timer, car elle permet d'utiliser les nanosecondes
comme unit de temps dans certains paramtres de fonctions la
place du nombre de ticks du processeur.
3

Cration d'une tche priodique

Cration d'une Tche


La cration d'une tche de priorit 50 se fait de la manire suivante :
RT_TASK task;
rt_task_create(&task, "TASK", 0, 50, 0)

Lancement d'une tche


Le lancement de la tche prcdemment cre se fait de la manire
suivante:
rt_task_start(&task, &task_code, NULL)
Le second paramtre est un pointeur de fonction pointant sur le
corps de la tche. Il est important de noter que la fonction
"task_code" est excute une seule fois, c'est pourquoi nous
devrons crer la priodicit de la tche au sein de cette fonction.
4

Cration d'une tche priodique

Priodicit de la Tche
Nous devons en premier lieu indiquer que la Tche est priodique:
rt_task_set_periodic(NULL, TM_NOW, (RTIME)10000000);
La valeur "TM_NOW" pour le second paramtre indique la date de
rveil de la tche. Le dernier paramtre spcifie la priode en
nanosecondes. Dans cet exemple la priode est de 10 ms.
Nous devons maintenant faire en sorte que notre tche ait un
comportement priodique:
for (i = 0; i < nb_iter; i++) {
// coeur de la tche
rt_task_wait_period(); // attente de la periode suivante
}
La tche s'excute donc "nb_iter" fois.
5

Cration d'une tche priodique


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <rtai/task.h>
#include <rtai/timer.h>
RT_TASK task;
int nb_iter = 10;
static void task_code(void *cookie);
int main () {
rt_timer_start(TM_ONESHOT);
if (rt_task_create(&task, "TASK", 0, 30, 0)) {
perror("creation task");
exit(1);
}
if (rt_task_start(&task, &task_code, NULL)) {
perror("start");
exit(1);
}
pause();
return 0;
}

"

"

"

<

>

"

Exemple

Vous devez raliser un programme comportant trois tches


priodiques dont les caractristiques sont les suivantes :

R reprsente la date de rveil,


T la priode,
P la priorit,
C le temps d'excution,
Itrations le nombre de fois ou l'instance de la tche est excute.
7

Exemple
Dvelopper 2 tches qui assurent lordre dexcution suivant, vous
utiliserez les smaphores. Faites varier les priorits relatives des 2
tches, lordre dexcution ne doit pas tre modifi.

Solution
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <rtai/task.h>
#include <rtai/timer.h>
RT_TASK task1, task2;
SEM *sem1, *sem2, *sem3, *sem4;
int nb_iter = 10;
static void task_code(void *cookie);
int main () {
rt_timer_start(TM_ONESHOT);
if (rt_task_create(&task1, "TASK1", 0, 30, 0)) {
perror("creation task"); exit(1);}
if (rt_task_create(&task2, "TASK2", 0, 30, 0)) {
perror("creation task"); exit(1);}
if (rt_task_start(&task1, &task_code1, NULL)) {
perror("start"); exit(1);}
if (rt_task_start(&task2, &task_code2, NULL)) {
perror("start"); exit(1);}
pause();
return 0;
rt_typed_sem_init (sem1, 1, 0);
rt_typed_sem_init (sem2, 0, 0);
rt_typed_sem_init (sem3, 0, 0);
rt_typed_sem_init (sem4, 0, 0);

void task_code1(void *cookie) {


int i;
if (rt_task_set_periodic(NULL, TM_NOW,
(RTIME)10000000)) {
perror("set_periodic");
exit(1);}
for (i = 0; i < nb_iter; i++) {
rt_sem_wait(sem1);
printf( T1");
rt_sem_signal(sem2);
rt_sem_wait(sem3);
printf( T2 aprs T1");
Rt_sem_signal(sem4)
rt_task_wait_period();}}
void task_code2(void *cookie) {
int i;
if (rt_task_set_periodic(NULL, TM_NOW,
(RTIME)10000000)) {
perror("set_periodic");
exit(1);}
for (i = 0; i < nb_iter; i++) {
rt_sem_wait(sem2);
printf( T2 dmarre aprs T1");
rt_sem_signal(sem3);
rt_sem_wait(sem4);
printf( T2 finit T1");
Rt_sem_signal(sem1)
rt_task_wait_period();}}

Exemple
Soit une tche logicielle de type chien de garde qui vrifie quun
compteur est rgulirement incrment et qui a le comportement
suivant en cas derreur:
Si le compteur na pas t incrment au bout de 1,5 seconde,
mission dun message derreur (fonction de chien de garde)
Si son excution ne sest pas termine en 1 seconde, mission dun
message derreur (respect dchance)
Ecrire les taches compteur et chien de garde.

Cration d'une tche priodique


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <rtai/task.h>
#include <rtai/timer.h>
RT_TASK cpt, dog;
SEM sem1;
RTIME t1, t2, t3, t4;
Int c = 0;
int nb_iter = 10;
static void task_code(void *cookie);
int main () {
rt_timer_start(TM_ONESHOT);
if (rt_task_create(& cpt, "TASK", 0, 30, 0)) {
perror("creation task"); exit(1);}
if (rt_task_create(& dog, "TASK", 0, 30, 0)) {
perror("creation task"); exit(1);}
if (rt_task_start(& cpt, &task_code1, NULL)) {
perror("start");exit(1);}
if (rt_task_start(& dog, &task_code2, NULL)) {
perror("start");exit(1);}
rt_typed_sem_init (sem1, 0, 0);
pause();
return 0;
}

void task_code1(void *cookie) {


int i;
if (rt_task_set_periodic(NULL, TM_NOW,
(RTIME)1500000000)) {
perror("set_periodic");exit(1);}
for (i = 0; i < nb_iter; i++) {
rt_sem_signal(sem1);
c = c+1;
rt_sem_wait(sem1);
t2 = rt_get_time();
rt_task_wait_period();}}
void task_code1(void *cookie) {
int i;
for (i = 0; i < nb_iter; i++) {
rt_sem_wait(sem1);
t1 = rt_get_time();
If (t1 t2 > (RTIME)1500000000)
{perror("start");exit(1);}
rt_sem_signal(sem1);
t3 = rt_get_time();
If (t3 t1 > (RTIME)1000000000)
{perror("start");exit(1);}
}}

Exercice (pris du Commissariat Energie Atomique CEA, France)


Soit un Systme Embarqu contrlant la temprature de la cuve de lenceinte de confinement
dun Racteur Eau Pressurise REP. On se limite au cas de 6 tches priodiques supportant
le contrle de la temprature (en ralit nous avons 78 tches de contrle). Le CEA utilise le PC
embarqu ARCOMGX533 qui se base sur RTAI3.4. On sintresse au contrle de 2 points A et
B (chacun est contrl par un capteur et un stabilisateur) :
T1 : une tche de lecture de temprature du capteur A. Elle est de priode 10ms (WCET = 1ms)
crivant la Temp sur un buffer Buf1. Cette tche ncrit rien si le buffer est plein,
T2 : une tche de lecture de temprature du capteur B. Elle est de priode 20ms (WCET = 1ms)
crivant la Temp sur le mme buffer Buf1. Cette tche ncrit rien si le buffer est plein. La
tche T2 est moins prioritaire que la tche T1,
T3 : une tche de stabilisation lisant les 5 dernires valeurs de temprature avant dcrire la
nouvelle Temp sur un buffer Buf2, elle est priodique de priode 20ms (WCET = 1ms),
T4 : une tche lisant la nouvelle valeur de temprature de Buf2 chaque 40ms avant de
lappliquer sur le stabilisateur A (WCET = 1ms),
T5 : une tche lisant la nouvelle valeur de temprature de Buf2 chaque 40ms avant de
lappliquer sur le stabilisateur B, T5 est moins prioritaire que T4.
Le systme doit envoyer un SIGNAL URGENT dALARME:
Si on ne fait pas une lecture du capteur A au bout de 20ms ou du capteur B au bout de 40ms,
Si on ne fait pas une stabilisation avec T4 ou T5 au bout de 40ms,
Dvelopper en RTAI le programme du Systme.
1

Solution Partielle de T1,T2


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <rtai/task.h>
#include <rtai/timer.h>
RT_TASK T1, T2, T3, T4, T5;
RTIME t1,t2,t3,t4;
SEM *sem1, *sem2, *sem3, *sem4;
MBX *BUFF1, *BUFF2 ;
int main () {
rt_timer_start(TM_ONESHOT);
// Creation Blocks of T1, T2, T3, T4, T5
// Start Time de T3 est 50ms
rt_typed_sem_init (sem1, 0, 0);
// entre T1 et T2
rt_typed_sem_init (sem2, 1, 0);
//entre T1,T2 et T3
rt_typed_sem_init (sem3, 1, 0);
//entre T4,T5 et T3
rt_typed_sem_init (sem3, 1, 0);
//entre T4,T5
rt_MBX_init(BUFF1, 1000) ; // 1000 cases
rt_MBX_init(BUFF2,1000) ;//1000 cases
pause(); return 0; }

void task_code1(void *cookie) {


int I, val;
if (rt_task_set_periodic(NULL, TM_NOW,
(RTIME)10000000)) {
perror("set_periodic"); exit(1);}
for (i = 0; i < nb_iter; i++) {
t2 = rt_get_time();
If (t2 t1 > (RTIME)2000000000) {perror("start");exit(1);}
sensorA_get(&val)
rt_sem_wait(sem2);
if(!empty(BUFF1)) rt_mbx_send(BUFF1,val) ;
rt_sem_signal(sem2);
rt_sem_signal(sem1);
t1 = rt_get_time();
rt_task_wait_period();}}
void task_code2(void *cookie) {
int i, val; int j = 0;
if (rt_task_set_periodic(NULL, TM_NOW,
(RTIME)20000000)) { perror("set_periodic"); exit(1);}
for (i = 0; i < nb_iter; i++) { t4 = rt_get_time();
If (t4 t3 > (RTIME)4000000000) {perror("start");exit(1);}
sensorB_get(&val); if(j==0) {rt_sem_wait(sem1); j=1;}
rt_sem_wait(sem2);
if(!empty(BUFF1)) rt_mbx_send(BUFF1,val) ;
rt_sem_signal(sem2);
t3 = rt_get_time(); rt_task_wait_period();
rt_sem_wait(sem1);}}
1

S-ar putea să vă placă și