Relazione finale
di
Sistemi Real-Time
La Loggia Salvatore
Collotta Mario
Cos’è un sistema Real-time?
x(t)
Sistema
Real-time
Ambiente
y(t+Δ)
E’ un sistema in cui la correttezza dipende non solo dai risultati che si
ottengono in uscita, ma anche dal tempo entro cui tali risultati sono
ottenuti.
Cos’è un sistema Real-time?
x(t)
Sistema
Real-time
Ambiente
y(t+Δ)
TEMPO: la validità dei risultati prodotti da un processo di elaborazione non dipende soltanto dalla
correttezza delle singole operazioni, ma anche dal tempo entro cui tali risultati sono ottenuti.
REALE: la risposta del sistema agli eventi esterni deve avvenire durante l’evolversi degli eventi stessi,
e quindi il tempo interno di sistema deve essere misurato secondo un riferimento temporale
uguale a quello dell’ambiente in cui il sistema opera.
I sistemi real-time vengono solitamente distinti in
due tipi:
HARD: un processo real-time è di tipo hard se la violazione
della propria deadline comporta un effetto catastrofico sul
sistema.
SOFT: un processo real-time è di tipo soft se la
violazionedella
propria deadline non compromette il corretto funzionamento
del sistema. In tal caso il processo non è caratterizzato da una
scadenza rigida, e può essere completato anche oltre il tempo
specificato dalla sua deadline.
Real-time ≠ velocità
Un sistema real-time non è un sistema veloce!!!
τ1
τ2
Raddoppiando la velocità, si ha una deadline miss:
Deadline miss
Analisi di fly.c
Elaborazione : “TZE-TZE”
La
storia
della
mosca
attaccata
dall’insetticida più potente al mondo.
Utilizzeremo per testare il comportamento dei task fly:
S.Ha.R.K.
• E’ un kernel real - time (open source)
creato dalla Scuola Superiore S.Anna.
Analizziamo il codice:
#define YMENU 10
/* spazio menu schermata shark */
#define XMIN
50 /*posizioni limite
#define XMAX
600
lungo le ascisse
#define YMIN
100
e le ordinate*/
#define YMAX
450
#define VEL
5
/* velocità lineare (= 5)
*/
#define ANG
30
/* angolo massimo sterzata (30) */
#define D
5
/* raggio mosca
*/
#define ESC
27
/* codice ASCII del tasto ESC */
#define MAX_P
30 /* max numero di mosche
*/
#define FLYGROUP 1
double tick = 1.0;
/* tick = 1 ms
*/
int fly_period = 40000; /* task periodico */
int fly_wcet = 1000;
/* task tempo di esecuzione nel caso peggiore */
PID pid;
sem_t mutex;
void draw_fly(int x, int y, int c)
{
sem_wait(&mutex);
grx_disc(x, y, D, c); /*disegna un cerchio*/
sem_post(&mutex);
}
void sangue(int x, int y)
{
sem_wait(&mutex);
grx_disc(x,y,D,RED); /*coordinate,diametro e colore*/
sem_post(&mutex);
}
TASK fly(void *arg) /*crea il task*/ {
int x, y;
int ox, oy;
int dx, dy, da;
/*da= direzione obliqua*/
int teta, col;
int outx, outy;
double r;
/* angolo */
int i = (int)arg;
x = ox = (XMIN+XMAX)/2;
y = oy = (YMIN+YMAX)/2;
teta = 0;
col = 2 + i;
/* colore fly */
while (1) {
da = rand()%(2*ANG) - ANG;
/* da = [-ANG,ANG] */
teta += da;
/*sterzata casuale rand()*/
if (teta > 360) teta -= 360;
/*per ottenere valori compresi tra 0 e 360*/
if (teta < 0) teta += 360;
/*per ottenere valori compresi ra 0 e 360*/
r = (double) teta * PI / 180.;
/*si ottiene il valore dell'angolo*/
dx = (float)(VEL * cos(r));
/*distanza percorsa lungo x*/
dy = (float)(VEL * sin(r));
/*distanza percorsa lungo y*/
x += dx;
/*aggiornamento*/
y += dy;
/*aggiornamento*/
outx = (x >= XMAX) || (x <= XMIN);
/*valori oltre i quali si esce dal rett.*/
outy = (y >= YMAX) || (y <= YMIN);
/*valori oltre i quali si esce dal rett.*/
if (outx || outy) {
sangue (ox,oy);
/*ox,oy coordinate del punto di impatto con il rettangolo*/
myexit=1;
return 0;
}
draw_fly(ox, oy, 0);
draw_fly(x, y, col);
ox = x; oy = y;
grx_line ((XMIN+XMAX)/2,YMIN+30,(XMIN+XMAX)/2,YMIN+300,RED);
grx_line ((XMIN+XMAX)/2+70,YMIN+100,(XMIN+XMAX)/2-70,YMIN+100,RED);
task_endcycle();
}
}
/* funzione chiamata nel momento in cui il sistema esce */
void byebye(void *arg)
{
grx_close();
cprintf("Bye Bye!\n");
}
/****************************** MAIN ******************************/
int main(int argc, char **argv)
{
HARD_TASK_MODEL m;
char c;
/**** carattere da tastiera ****/
int i = 0;
/**** numero di task creati ****/
TIME seme;
/* usata per inizializzare il “seme”, var temporale */
/**** Setta la funzione di chiusura (BYE-BYE) ****/
sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);
/**** inizializzazione grafica ****/
if (grx_init() < 1) {
sys_abort(1);
}
if (grx_open(640, 480, 8) < 0) {
cprintf("GRX Err\n");
sys_abort(1);
}
/**** scenario ****/
grx_rect(XMIN-D-1, YMIN-D-1, XMAX+D+1, YMAX+D+1, 14);
grx_text("Simulation of Random Flies", XMIN, YMENU+10, 13, 0);
grx_text("SPACE crea una mosca TZE-TZE", XMIN, YMENU+20, 12, 0);
grx_text("ESC exit to DOS"
, XMIN, YMENU+30, 12, 0);
/**** Il programma attende uno “spazio” per creare una mosca ****/
c = keyb_getch(BLOCK);
/**** casuale ****/
seme = sys_gettime(NULL);
srand(seme);
do {
if ((c == ' ') && (i < MAX_P)) {
hard_task_default_model(m);
hard_task_def_ctrl_jet (m);
hard_task_def_arg
(m, (void *)i);
hard_task_default_model(m)
hard_task_def_wcet
(m, fly_wcet);
hard_task_def_ctrl_jet(m)
hard_task_def_mit
fly_period);
Valori di(m,default
per il modello Model (periodic
Se chiamata il Kernel può chiedere
hard_task_def_group (m, FLYGROUP);
task, altri= 0).
informazioni per il task.
hard_task_def_usemath (m);
pid = task_create("fly", fly, &m, NULL);
if (pid ==hard_task_def_arg(m,a)
NIL) {
grx_close();
Setta un void * argomento passato al task. Il
perror(“Non è possibile creare la mosca");
valore di default è NULL.
sys_abort(1);
}
task_activate(pid);
hard_task_def_wcet(m,w)i++;
Setta il Worst Case Execution
} Time a w.
c = keyb_getch(BLOCK);
hard_task_def_mit(m,p)
Setta il Minimo tempo di interarrivo (MIT) del
hard_task_def_group(m,g)
} while (c != ESC);
modello
p. =1
Setta il gruppo dei task g. Nel nostro
caso
( perché hard). sys_end();
hard_task_def_usemath(m)
return 0;
Dichiara che il task usa un puntatore aritmetico
}
a float.
/*--------------------------------------------------------------*/
ANALISI
DEL FILE: initfile.c
File di inizializzazione del sistema
Sono 2 funzioni che servono ad inizializzare il sistema.
Queste funzioni registrano i seguenti livelli:
livello EDF (Earliest Deadline First)
livellp RR (Round Robin)
livello CBS (Costant Bandwidth Server)
livello Dummy
Possono accettare questi modelli di task:
HARD_TASK_MODEL
SOFT_TASK_MODEL
NRT_TASK_MODEL
IL TICK è settato a 0
Inizio del codice:
initfile.c
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/cbs.h"
#include "modules/rr.h"
#include "modules/dummy.h"
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
Port: task per scambiare messaggi
#include "drivers/keyb.h"
/*+ sysyem tick in us +*/
#define TICK 0
/*+ RR tick in us +*/
#define RRTICK 10000
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info
*)arg;
KEYB_PARMS kparms = BASE_KEYB;
Alla
fine
di
ogni
modulo
di
schedulazione, viene creato e attivato
un task. Il corpo di questo task è
generalmente chiamato __init__(), e
provvede all’inizializzazione dei più
comuni device usati, come ad es. la
tastiera.
HARTPORT_init();
keyb_def_ctrlC(kparms, NULL);
keyb_def_map(kparms,itaMap);
KEYB_init(&kparms);
__call_main__(mb);
return (void *)0;
}
Quando un sistema parte, una delle
cose che bisogna fare prima di entrare
nel modello multitask è inizializzare le
risorse e le tecniche di schedulazione
che verranno usate dalle applicazioni.
Per fare ciò il kernel chiama la
funzione __kernel_register_levels__.
La funzione ritorna un valore di tick (in
microsecondi) che è il tempo che sarà
usato per programmare l’interrupt
periodico del PC. Tipi di valori di ritorno
vanno da 250 a 2000 ms.
TIME __kernel_register_levels__(void
*arg)
{
struct multiboot_info *mb = (struct
multiboot_info *)arg;
EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL,
0);
RR_register_level(RRTICK,
RR_MAIN_YES, mb);
dummy_register_level();
SEM_register_module();
CABS_register_module();
return TICK;
}
FINE
ENNA – 18 giugno 2003
Scarica

Elaborato 1