• Aucun résultat trouvé

[PDF] Tutoriel Ada 95 pour le temps réel et les systèmes distribués | Cours informatique

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Tutoriel Ada 95 pour le temps réel et les systèmes distribués | Cours informatique"

Copied!
83
0
0

Texte intégral

(1)
(2)

Histoire du langage

• Ada remontent au début des années 1980.

• Son développement a commencé au début des

années 1980 pour donner

Ada 83

.

• Ada 83 a été ensuite repris et amélioré au milieu

des années 1990 pour donner

Ada 95

, le

premier langage objet normalisé de manière

internationale.

(3)

• Ada 95 est souvent utilisé pour

l'apprentissage de l'informatique, car il est

clair et structuré,

• Une autre raison pour adopter Ada 95 est

qu'il est gratuit.

• On appelle aussi Ada 95

le langage vert :

– Lors de

l’appel d’offre

du

DoD

(Departement

of Defense), les différentes propositions

étaient désignées par des

couleurs

, et

l’équipe qui l’a conçu était

l’équipe verte

.

(4)

• Il a été créé par l'équipe de Jean

Ichbiah et résulte d'un cahier des

charges extrêmement précis fourni par

le

Département

de

la

Défense

américaine.

• Son nom a été choisi en l'honneur

d'Ada Lovelace

, une femme qui est

supposée être la première à avoir écrit

un programme informatique.

(5)

• Ada Lovelace,

officieusement Augusta Ada King,

comtesse Lovelace, née le

10 décembre 1815 et morte

le 27 novembre 1852 à Londres, est principalement connue pour avoir traduit et annoté une description de la machine analytique de Charles Babbage, un ancêtre de l'ordinateur. • Dans ses notes, on trouve le

premier algorithme publié Woolley 1, destiné à être exécuté par une machine, ce qui fait considérer Ada Lovelace comme une programmeuse, voire « le premier programmeur du monde »

(6)

Programmez avec AdaGide et Gnat

• Nous utiliserons les logiciels suivants :

• comme éditeur de texte, ADAGide ;

• comme compilateur, Gnat.

• ADAGide

nous servira donc de support afin

d'y écrire notre code ADA.

(7)
(8)

Créer un fichier et l'enregistrer avec

ADAGide

• Pour créer un nouveau fichier avec ADAGide

– Il suffit tout simplement d'aller dans le menu File

et de cliquer sur New (raccourci : Ctrl + n).

• Pour sauvegarder un fichier, allez dans le

menu File et cliquez sur Save as.... Là,

choisissez le nom de votre fichier et cliquez

sur Enregistrer

(9)

Compilation

• En informatique, la compilation est le travail réalisé

par un compilateur qui consiste à transformer un

code source lisible par un humain en un fichier

binaire exécutable par une machine.

Le code source

• Le code source est le code que vous taperez dans

votre éditeur de texte (ADAGide ou autre). Il est

donc compréhensible par un humain. Bien

entendu, afin d'en faire un exécutable (un fichier de

type *.exe), il faudra

le compiler

.

(10)

Compilez un programme écrit avec ADAGide !

• Imaginez maintenant que vous ayez tapé un

programme ADA et qu'il soit entièrement correct

(qu'il ne comporte aucun problème).

• Pour le compiler suivez les instructions ci-dessous:

– appuyez sur F2 : ceci compilera le programme ; – appuyez sur F3 : ceci terminera la compilation.

• Vous disposez maintenant d'un fichier exécutable,

et afin de voir son rendu (c'est-à-dire comment il va

apparaître à l'écran), il vous suffit d'effectuer

(11)

La structure d'un programme ADA

• Un programme ADA se compose de quatre parties principales:

1. La clause de contexte contient tous les outils

nécessaires au programmeur. On les appelle

"paquetages". Voici comment "appeler" un paquetage :

with Ada.Text_IO; use Ada.Text_IO;

Ce paquetage est nécessaire pour afficher des caractères à l'écran ou encore pour récupérer du texte entré par l'utilisateur.

» Pour appeler un paquetage. Tout d'abord, nous avons le mot réservé with. Ensuite, vient le nom du langage : ADA. Suivie du nom du paquetage (ici Text_IO, qui signifie Text Output

Input ou "texte en entrée et sortie").

» La partie après le ";" et commençant par le mot réservé use signifie que nous allons utiliser ce paquetage. En français, nous pourrions traduire la ligne de commande comme suit :

(12)

• Il reste un type différent des deux présentés

ci-Paquetage permettant de faire intervenir des nombres entiers relatifs :

(13)

2. L'

en-tête du programme

, où est spécifié le

nom du programme. Voici l'en-tête de notre

programme :

procedure Exemple1 is

3. La

partie déclarative

, comprise entre

l'en-tête

et le mot réservé

begin

. C'est cette

partie qui contient les déclarations

(constantes, lettres, etc.).

4. la

partie instructions

, comprise entre les

mots

begin et end et qui contient les

instructions du programme, c'est-à-dire

les actions à entreprendre.

(14)

Les commentaires

--

Cette ligne de code est un commentaire

with Ada.Text_IO; use Ada.Text_IO;

--

Cette ligne est elle aussi un commentaire,

mais pas celle située au-dessus

(15)

PROGRAMME AFFICHANT

BONJOUR A L’ECRAN

-- EKARI

--FERVRIER 2013

-- Description : programme affichant le mot

"bonjour" dans une console

with Ada.Text_IO; use Ada.Text_IO;

procedure afficheBonjour is

begin

(16)

Exercice

Écrire un programme affichant ceci :

Coucou

tout le

monde

! ! !

(17)

Solution

With ada.text_io ;

use ada.text_io ;

procedure

Hello2

is

begin

Put("

Coucou

") ; New_line ;

Put("

tout le

") ; New_line ;

Put("

monde

") ; New_line ;

Put("

! ! !

")

;

(18)

Deuxième solution

With ada.text_io ;

use ada.text_io ;

procedure

Hello3

is

begin

Put_line("

Coucou

") ;

Put_line("

tout le

") ;

Put_line("

monde

") ;

(19)

Variables I : Typage et affectation

Une déclaration se fait toujours de la façon suivante :

NOM_DE_LA_VARIABLE : TYPE ;

Il est possible de déclarer plusieurs variables d'un coup de la manière suivante :

NOM_DE_LA_VARIABLE1 , NOM_DE_LA_VARIABLE2 : TYPE ;

Il est aussi possible, aussitôt la variable déclarée, de lui

affecter une valeur à l'aide du symbole ":=". On écrira alors :

(20)

Exemple

Procedure VotreAge is

NOM_DE_LA_VARIABLE1 : TYPE1 := VALEUR ;

--zone réservée aux déclarations

NOM_DE_LA_VARIABLE2 : TYPE2 ;

begin

Put("Quel age avez-vous ?") ;

(21)

Déclaration d’une variable

Exemple:

Age: Integer; --Age est de type Integer

On remarque aisément qu'il y a d'un côté le nom de cette variable, et après les ":" son type.

Syntaxe:

NOM de la variable :TYPE

Affectation:

Age: Integer:=18; --Age, de type Integer, possède la valeur 18

(22)
(23)

Comment récupérer une saisie ?

L'instruction Get

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure DemandeAge is

Age:Integer; --Age est donc un nombre begin

Put("Entrez votre age : "); --On demande l'âge de l'utilisateur Get(Age); --On récupère ce qu'il a entré à l'aide de son clavier New_Line;

Put(Age); --On affiche l'âge entré end DemandeAge;

(24)

Que fais ce programme et quel

est le rôle de skip_line?

with Ada.Text_IO, Ada.Float_Text_IO ; use Ada.Text_IO, Ada.Float_Text_IO ;

Procedure TaillePoids is

Taille, Poids : float ;

Begin

Put("Quelle est votre taille ?") ; Get(Taille) ; Skip_line ;

Put("Vous mesurez ") ; Put(Taille) ;

(25)

Déclaration d’une constante

with Ada.Text_IO, Ada.Float_Text_IO ; use Ada.Text_IO, Ada.Float_Text_IO ;

Procedure TaillePoids is

Taille, Poids : float ;

Begin

MaVariable : Constant Integer := 15 ;

(26)

Comment obtenir le plus petit et le plus grand Integer ? Comment savoir quel est le 93ème character ? Grâce aux attributs, bien sûr. Ce sont des sortes

d'instructions qui s'appliquent aux types.

WITH Ada.Text_Io ;USE Ada.Text_Io ;

WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;

with ada.Characters; use ada.Characters;

PROCEDURE attri IS

N,M,p : Integer; c : character;

BEGIN

N := integer'first ; --N sera le premier des integer M := integer'last ; --M sera le dernier des integer

C := character'val(93) ; -- C sera la 93ème valeur des character

(27)
(28)
(29)
(30)
(31)

Exercice :

Rédiger un programme appelé Multiple qui demande à l'utilisateur de saisir un nombre entier et lui retourne son double, son triple et son quintuple. J'ajoute une difficulté ! Vous n'aurez le droit qu'à deux multiplications pas une de plus !

(32)

Solution :

WITH Ada.Text_IO, Ada.Integer_Text_IO ; USE Ada.Text_IO, Ada.Integer_Text_IO ; PROCEDURE Multiple IS N : Integer ; Double, Triple : Integer ;

BEGIN

Put("Saisissez un nombre entier : ") ; Get(N) ; Skip_Line ;

Double := 2*N ; Triple := 3*N ;

Put("Le double de ") ; Put(N) ; Put(" est ") ; Put(Double) ; New_Line ; Put("Le triple de ") ; Put(N) ; Put(" est ") ; Put(Triple) ; New_Line ;

(33)

Exercice :

Rédiger un programme appelé Euclide qui

demande deux nombres entiers à l'utilisateur puis

renvoie le quotient et le reste de leur

division euclidienne (c'est à dire la division entière

telle que vous l'avez apprise en primaire).

(34)

Solution :

WITH Ada.Text_IO, Ada.Integer_Text_IO ; USE Ada.Text_IO, Ada.Integer_Text_IO ;

PROCEDURE Euclide IS N,M : Integer ; BEGIN Put("Saisissez le dividende : ") ; Get(N) ; Skip_Line ; Put("Saisissez le diviseur : ") ; Get(M) ; Skip_Line ;

(35)

Les conditions :

Procedure Questionnaire is

Reponse : Character := 'n' ; --on définit Reponse et on lui

--attribue par défaut la valeur n (pour non)

begin

Put("Avez-vous plusieurs ordinateurs ? (o/n) ") ; Get(Reponse) ; Skip_line ;

--On saisit la réponse et on vide la mémoire tampon if Reponse = 'o' --SI Reponse est égal à o

then Put("Vous avez bien de la chance.");

--ALORS on affiche la phrase.

(36)

Conditions multiples avec CASE :

case Reponse is

--on indique que l'on va regarder les différents cas --possibles pour Reponse

when 'o' => Put("Vous avez bien de la chance.") ; -- si oui

when 'n' => Put("Ah ... dommage. ") ; -- si non

when 'p' => Put("Reponses normandes non valides") ;

when 'f' => Put("J'aurais pas du prendre Allemand ...") ;

when others => Put("C'est pas une reponse.") ;

(37)
(38)

Les opérateurs de comparaison

Exemple :

Procedure Questionnaire2 is

Reponse : integer := 0 ; --on définit la réponse et on l'initialise à 0 begin

Put("Combien d'ordinateurs avez-vous?") ; Get(Reponse) ; Skip_line ;

if Reponse >= 2

then Put("Genial!") ;

else Put("C'est toujours ca") ; end if ;

(39)

Les boucles en ADA

case Nb is

when 0 => Null ; --ne rien faire when 1 => Put("#") ;

when 2 => Put("##") ; when 3 => Put("###") ; when 4 => Put("####") ; when 5 => Put("#####") ;

when others => Put("######") ; end case ;

Compteur : integer := 0;

loop

if Compteur = 6 then exit ; else Put('#') ;

Compteur := Compteur +1 ; end if ;

(40)

Les boucles en ADA

loop

exit when Compteur = Nb ;

--comme tout à l'heure, on sort si on a affiché assez de dièses Put('#') ;

--on peut tranquillement afficher un dièse, car si le nombre était atteint, la boucle serait déjà cassée

Compteur := Compteur +1 ; --et on n'oublie pas d'incrémenter

(41)

La boucle while en ADA

while

Compteur /= Nb

loop

Compteur := Compteur +1 ;

Put('#') ;

end loop ;

---

while

Nb /= 0

loop

Nb := Nb - 1 ;

Put('#') ;

end loop

;

(42)

La boucle FOR en ADA

FOR

i

IN

1

..

Nb

loop

put("#") ;

end loop ;

---

Et si on voulais faire le décompte "en sens inverse" ? En décrémentant plutôt qu'en incrémentant ?

(43)

La boucle FOR en ADA

FOR

i

IN

1

..

Nb

loop

put("#") ;

end loop ;

---

Et si on voulais faire le décompte "en sens inverse" ? En décrémentant plutôt qu'en incrémentant ?

FOR

i

IN reverse

1

..

nb

loop

(44)

La boucle GOTO en ADA

<<debut>>

if Compteur <= Nb

then Put('#') ;

Compteur := Compteur + 1 ;

goto

debut

;

end if ;

---

(45)

Solution avec une seule boucle :

with ada.Text_IO, ada.Integer_Text_IO ; use ada.Text_IO, ada.Integer_Text_IO ;

procedure Carre is

Nb : integer ; Begin

Put("Quel est le cote de votre carre ? ") ; Get(Nb) ; Skip_line ;

for i in 1..Nb**2 loop --Nb**2 est la notation du carré, Put('#') ; --on affiche le dièse

if i mod Nb = 0 --Si i est multiple de Nb then New_line ; --On retourne à la ligne end if ;

end loop ;

(46)

Solution avec deux boucle :

with ada.Text_IO, ada.Integer_Text_IO ; use ada.Text_IO, ada.Integer_Text_IO ;

procedure Carre is

Nb : integer ; Begin

Put("Quel est le cote de votre carre ? ") ; Get(Nb) ; Skip_line ;

for i in 1..Nb loop --Boucle chargée d'afficher toutes les lignes for j in 1..Nb loop --Boucle chargée d'afficher une ligne Put('#') ;

(47)
(48)

Les procédures

Procédure sans paramètre:

Procedure Nom_De_Votre_Procedure is

--Partie pour déclarer les variables

begin

--Partie exécutée par le programme

(49)

Procédure avec un paramètre (ou argument):

with Ada.Text_IO, Ada.Integer_Text_IO ; use Ada.Text_IO, Ada.Integer_Text_IO ; procedure Figure is

Procedure Affich_Ligne(nb : natural) is begin for j in 1..nb loop put('#') ; end loop ; new_line ; end Affich_Ligne ; --- nb_lignes, nb_colonnes : natural;

begin

Put("Combien de lignes voulez-vous dessiner ? ") ; get(nb_lignes ) ; skip_line ;

Put("Combien de colonnes voulez-vous dessiner ? ") ; get(nb_colonnes ) ; skip_line ;

(50)

Procédure avec deux arguments :

Procedure Affich_Rect(nb_lignes : natural ; nb_colonnes : natural) is

begin

for i in 1..nb_lignes loop

Affich_Ligne(nb_colonnes);

end loop ;

(51)

Les fonctions:

C'est la même chose que les procédures. La différence, c'est que les fonctions renvoient

un résultat.

Exemple

function A_Rect(larg : natural, long : natural) return natural is A : natural ;

begin

A:= larg * long ; return A ;

end A_Rect ; ---

Par return, il faut comprendre "résultat". Dans la première ligne,

« return natural is » indique que le résultat de la fonction sera de type

natural. En revanche, le "return A" de la 5ème ligne a deux actions : •Il stoppe le déroulement de la fonction (un peu comme exit pour une

(52)

Utilisation de la fonction :

Exemple :

...

if choix=1

then Put("Combien de colonnes voulez-vous dessiner ? ") ; get(nb_colonnes ) ; skip_line ;

Affich_Rect(nb_lignes, nb_colonnes) ;

Aire := A_Rect(nb_lignes, nb_colonnes) ;

Put("L'aire du rectangle est de ") ; Put(Aire) ; put_line(" dieses.") ; else Affich_Tri(nb_lignes) ;

end if ; ...

(53)

Mode : In, Out, In Out

procedure Affich_Rect(nb_lignes : in natural, nb_colonnes : in natural) is

Les instructions in indiquent que nos paramètres sont uniquement des paramètres d'entrée. Les emplacements-mémoire qui contiennent leur valeur

peuvent être lus mais il vous est interdit d'y écrire : ils ne sont accessibles qu'en lecture. Donc impossible d'écrire "nb_lignes := 5" au cours de cette procédure.

procedure Affich_Rect(nb_lignes : out natural, nb_colonnes : out natural) is

vos paramètres deviendront des paramètres de sortie. Il sera possible d'écrire dans les emplacements-mémoire réservés à nb_lignes et nb_colonnes. Sauf qu'il vous sera impossible de lire la valeur initiale, donc impossible d'effectuer des

tests par exemple. Vos paramètres ne sont accessibles qu'en écriture.

(54)

Les tableaux

Type

T_Tableau

is

array(0..5) of integer

;

Scores : T_Tableau ;

Ou encore

TailleMax :

constant natural

:= 5 ;

Type

T_Tableau

is array(0..TailleMax) of integer ;

(55)

Affectation globale

Maintenant que nous avons déclaré un tableau d'entiers (Scores de type T_Tableau), encore faut-il lui affecter des valeurs. Cela peut se faire de deux façons distinctes. Première façon, la plus directe possible :

Scores := (15,45,27,8,19,27) ; Ou bien Scores := (1|3 => 17, others => 0) ; C’est équivalent à : Scores := (17,0,17,0,0,0) ; Ou encore : Scores := (17,0,17,4..6 => 0) ;

(56)

Affectation valeur par valeur

C'est pourquoi on utilise souvent la seconde méthode :

Scores(1) := 15 ; Scores(2) := 45 ; Scores(3) := 27 ; Scores(4) := 8 ; Scores(5) := 19 ; Scores(6) := 27 ;

En utilisant des boucles :

(57)

Attributs pour les tableaux

for i in T'range loop

T(i) := 0 ;

end loop ;

---

(58)

Tableaux multidimensionels

Tableaux bidimensionnels

La déclaration se fait très facilement de la manière suivante :

Le premier intervalle correspond au nombre de lignes, le second au nombre de colonnes.

(59)

Exercice

Énoncé

Créer un programme TriTableau qui crée un tableau unidimensionnel avec des valeurs entières aléatoires, l'affiche, trie ses valeurs par ordre croissant et enfin affiche le tableau une fois trié.

(60)
(61)
(62)
(63)
(64)
(65)
(66)
(67)
(68)

EXERCICE

FAITES VARIER LE DELAY DANS LA TACHE UN_TYPE QUE REMARQUEZ VOUS

(69)

EXERCICE

Écrire un programme qui contient deux tâches. La première tâche calcule et affiche les éléments de la suite

La tâche doit attendre une seconde entre le calcul/affichage de deux éléments successifs.

La deuxième tâche calcule et affiche les éléments de la suite

La tâche doit attendre deux secondes entre le calcul/affichage de deux éléments successifs.

1 2 0 1   U avec U Un n 0 2 0 1   U avec U Un n

(70)

Exercice : Décollage d’une Fusée

Prenons comme exemple un domaine très friand de programmation temps réel : l'aérospatiale ! Vous devez rédiger un programme d'aide au pilotage pour la fameuse fusée Z123. Votre programme doit vérifier régulièrement l'altitude et la vitesse et afficher les valeurs lues.

(71)
(72)

POUR FINIR IL FAUT TEMPORISER LES TACHES :

Notre programme prend fin, le décollage de la fusée de Zozor a bien eu lieu mais on n'a le temps de rien voir. Quand le programme prend fin, on voit seulement que l'altitude est de 10 000 mètres et la vitesse de 1000 km/H

(73)

POUR FINIR IL FAUT TEMPORISER LES TACHES :

Et pour éviter que le décollage ne soit terminé avant que le moindre affichage n'ait eu lieu, nous allons également temporiser le décollage en attendant un centième de seconde avant l'incrémentation :

(74)

POUR FINIR IL FAUT TEMPORISER LES TACHES : Temporiser jusqu'à ...

Une autre possibilité est d'utiliser la combinaison de deux instructions : delay until ### ; où ### est de type Time. Cela signifie "attendre jusqu'à une date précise". Vous aurez alors besoin soit du package Ada.calendar soit de Ada.Real_Time. Tous deux définissent un type Time et une fonction clock vous permettant

(75)
(76)
(77)

Exemple de synchronisation par Rendez-vous Round-Robin ou "l'effet tourniquet"

(78)

Exemple de synchronisation par Rendez-vous

Round-Robin ou "l'effet tourniquet"

(79)

Exercice

Écrire un programme qui crée deux tâches qui doivent se synchroniser par rendez-vous en vue de convertir des caractères. La tâche cliente produit un caractère et demande à la tâche serveur de convertir son caractère en majuscule.

Une fois le caractère converti, il est retourné à la tâche cliente qui l’affiche. Le point de RDV est représenté à l’aide de la procédure service().

La tâche serveur doit définir un point d’entrée avec le nom de cette procédure.

(80)
(81)
(82)

Priorités, Complément sur le tourniquet

• La

priorité d'une tâche peut être fixée de manière statique grâce à une directive de compilateur : Les

fameux pragma. Nous ferons appel ici le pragma priority.

Celui-ci permet de fixer la priorité d'une tâche de manière statique : nous définirons la priorité lors des spécifications de la tâche une fois pour toute. Le langage Ada accepte des niveaux de priorités allant de 0 à 30, 30 étant le niveau de priorité maximal. Nous allons également faire appel à un nouveau package : System. Attention ! Pas Ada.system, mais System tout court ! Ce

(83)

Priorités, Complément sur le tourniquet

Autre exemple :

task Tspeed i s

pragma P r i o r i t y ( 1 0 ) ;

Déclaration d’un type tâche :

task type T i s

Références

Documents relatifs

Résumé — Dans cette étude, des couplages de techniques de corrélation d’images avec des calculs par éléments finis ont permis d’étudier la plasticité se produisant en pointe

Depuis la fin décembre 2017, la République islamique d’Iran était entrée dans une phase nou- velle de son histoire, marquée par une succession de mouvements sociaux qui allaient

La diversité des personnalités transhumanistes présentées dans cette étude constitue une limite. En effet, le choix de ces personnalités est limité premièrement par la restriction

Yuan- Yuan, « Simulation of transition from townsend mode to glow discharge mode in a helium dielectric barrier discharge at atmospheric pressure », Chi- nese Physics B , vol.

In this experience, RU, with a BSc programme in Biomedical engineering, wanted to learn more on integrated curricula including design projects, different learning styles, and

In this paper, we analyzed the runtime resulting from the authentication of a joining node by a distributed AAA framework within a mobile ad-hoc network. The built model

Le troisième exemple de ce groupe est représenté par un couple qui constitue une sous- catégorie, mais à la différence des deux premiers cas où la situation socio-économique a été

Parmi les 42 articles, 11 articles rapportent des résultats relatifs à trois des quatre composantes de la théorie de Meleis (2010), 20 articles concernent deux des