• Aucun résultat trouvé

Spécification et vérification des ordonnanceurs Temps Réel en B

N/A
N/A
Protected

Academic year: 2021

Partager "Spécification et vérification des ordonnanceurs Temps Réel en B"

Copied!
192
0
0

Texte intégral

(1)

Spe i ation et Veri ation des

Ordonnan eurs Temps Reel en B

TH  ESE

Presentee en vuede l'obtentiondu titrede

Do teur de l'Universite Paul Sabatier (Dis ipline: Informatique)

par

Odile NASR

Soutenue publiquement le 16 Novembre 2007 devant le jury ompose de:

Rapporteurs : YamineAit-Ameur Professeur LISI/ENSMA

Regine Laleau Professeur UniversiteParis12 Examinateurs : Pierre Bieber Ingenieur de re her he ONERA - Toulouse

Jean-PaulBodeveix Professeur UPS- Dire teur de these Mamoun Filali Cher heurCNRS UPS- Co-dire teurde these

(2)
(3)

Mes travaux de recherche ont été menés à l’Institut de Recherche et Informatique de Toulouse (IRIT) de l’université Paul Sabatier au sein de l’équipe Assistance à la Certification d’Applications DIstribuées et Embarquées (ACADIE).

J’aimerais tout d’abord remercier Mr. Louis Féraud, directeur de l’école doctorale et Mme Martine Labruyère pour l’aide apportée dans les démarches administratives.

J’adresse toute ma gratitude à Mme Régine Laleau, Professeur à l’université Paris 12, et à Mr. Yamine Ait-Ameur, Professeur à LISI/ENSMA, pour avoir immédiatement accepté la charge de rapporteurs. Merci pour le temps passé à lire et à évaluer mon travail au travers de ce manuscrit, ainsi que pour toutes les remarques et commentaires constructifs qui ont pu en découler.

J’aimerais remercier également Mr. Frank Singhoff, Maître de conférence à l’université de Bretagne Occidentale et Mr. Pierre Bieber, Ingénieur de recherche à l’ONERA/CERT de Toulouse, de m’avoir fait l’honneur de participer à mon jury de thèse.

Je tiens à remercier tout particulièrement mon directeur de recherche Jean-Paul Bodeveix et le respon-sable de l’équipe Mamoun Filali, pour leur dévouement et leur aide constante au cours de toutes ces années, grâce auxquels il m’a été possible de mener cette thèse à bien.

Merci à toute ma famille, mes parents, mes frères pour leur soutien malgré les kilomètres, sans oublier toutes les personnes qui m’ont soutenue durant cette thèse.

Enfin, un grand merci à toi Miloud, qui partage ma vie, pour toute ton affection, ta tendresse, mais aussi ta compréhension et ton soutien de tous les instants. Je t’embrasse.

(4)
(5)
(6)
(7)

Table des matières

Table des figures IX

Liste des tableaux XI

Introduction 1

1 Les méthodes déductives . . . 2

2 Les méthodes basées sur les modèles . . . 2

2.1 La simulation . . . 2

2.2 La méthode de test . . . 2

2.3 Le model-checking . . . 3

3 Plan de la thèse . . . 3

Chapitre 1 Les langages de description d’architecture 5 1.1 Les langages de description d’architecture: Concepts et caractéristiques . . . 5

1.1.1 Caractéristiques des composants et des connecteurs . . . 6

1.1.2 Caractéristiques des configurations . . . 6

1.2 Le langage Wright . . . 8 1.2.1 Principales notations . . . 8 1.2.2 Exemple . . . 9 1.2.3 Analyse . . . 10 1.3 Le langage ACME . . . 11 1.3.1 Structure . . . 11 1.3.2 Propriétés . . . 12 1.3.3 Styles . . . 12

1.3.4 Expression des contraintes d’architecture . . . 14

1.3.5 Analyse . . . 14

1.4 Le langage Rapide . . . 15

1.4.1 Evénements . . . 16

(8)

1.4.3 Expression des propriétés dynamiques . . . 18 1.4.4 Analyse . . . 18 1.5 Le langage AADL . . . 19 1.5.1 Composants . . . 19 1.5.2 Connexions . . . 20 1.5.3 Propriétés . . . 21 1.5.4 Modes . . . 21 1.5.5 Sémantique temporelle . . . 21 1.5.6 Exemple . . . 22 1.5.7 Analyse . . . 23 1.6 Le langage COTRE . . . 24 1.6.1 Structure . . . 25

1.6.2 Propriétés dans COTRE . . . 26

1.6.3 Sémantique et vérification . . . 27

1.6.4 Outillage de vérification . . . 27

1.6.5 Exemple . . . 28

1.6.6 Analyse . . . 28

1.7 Conclusion . . . 29

Chapitre 2 Vérification de modèles 31 2.1 Développement certifié en B . . . 32

2.1.1 Substitutions généralisées de B . . . 32

2.1.2 Sémantique et calcul des substitutions . . . 35

2.1.3 Machines Abstraites . . . 36

2.1.4 Raffinement . . . 38

2.1.5 Exemple . . . 42

2.1.6 Relations entre machines abstraites . . . 43

2.2 Automates temporisés avec invariants . . . 44

2.2.1 Contraintes d’horloges . . . 44

2.2.2 Syntaxe des automates temporisés . . . 45

2.2.3 Sémantique des automates temporisés . . . 45

2.2.4 Exemple . . . 46

2.3 Automates hybrides . . . 46

2.3.1 Syntaxe des automates hybrides linéaires . . . 47

2.3.2 Exemple . . . 47

2.4 Logiques temporelles et temporisées . . . 48

(9)

2.5 Conclusion . . . 51

Chapitre 3 Ordonnancement temps réel et outils de vérification 53 3.1 Tâches . . . 53

3.2 Ordonnancement temps réel . . . 54

3.2.1 Ordonnancement hors ligne et en ligne . . . 54

3.2.2 Ordonnancement périodique . . . 54

3.2.3 Ordonnancement conjoint . . . 57

3.2.4 Ordonnancement des tâches dépendantes . . . 58

3.3 Les outils de vérification . . . 60

3.3.1 L’outil Uppaal . . . 60

3.3.2 L’outil HyTech . . . 63

3.3.3 L’outil TIMES . . . 66

3.3.4 L’outil Cheddar . . . 68

3.4 Approches de vérification d’ordonnanceurs temps réel . . . 73

3.5 Automates temporisés étendus et ordonnancement . . . 75

3.6 Conclusion . . . 75

Chapitre 4 Modélisation et validation des systèmes ordonnancés 77 4.1 Expression des politiques d’ordonnancement en Cotre . . . 77

4.1.1 Ordonnancement non préemptif . . . 79

4.1.2 Ordonnancement préemptif . . . 80

4.2 B et le temps réel . . . 83

4.2.1 B et les chronomètres . . . 83

4.2.2 B et les horloges (automates temporisés) . . . 83

4.2.3 Relation entre chronomètres et horloges . . . 84

4.2.4 Notions et mécanismes de base pour la modélisation de l’ordonnancement . . . . 84

4.3 Modélisation des politiques d’ordonnancement en B . . . 86

4.3.1 Architecture de la modélisation . . . 86

4.3.2 Validation et vérification des POs . . . 109

4.4 Conclusion . . . 115

Chapitre 5 Génération du code Uppaal d’un ordonnanceur 117 5.1 Les langages B0 et B0_Uppaal . . . 117

5.1.1 Le langage B0 classique . . . 117

5.1.2 Le langage B0_Uppaal . . . 124

(10)

5.2.1 Extension de Uppaal . . . 125

5.2.2 Principe de la transformation . . . 126

5.2.3 Exemples . . . 127

5.3 Application à l’ordonnanceur . . . 129

5.3.1 Utilisation de la notion des fonctions Uppaal . . . 130

5.3.2 Spécification du système fermé . . . 132

5.4 Conclusion . . . 133

Conclusion et perspectives 139 Appendix A Caractéristiques de quelques ADLs 141 Appendix B Machines B 143 B.1 Machine timed_nonpreemptive . . . 143 B.2 Machine fcfspolicy . . . 144 B.3 Machine priority_graph . . . 145 B.4 Machine timed_priority_graph . . . 146 B.5 Machine preemptive_priority . . . 147 B.6 Machine preemptive_timed_priority . . . 148 B.7 Machine preemptiveuppaal . . . 149

Appendix C Preuves interactives dans l’Atelier B 151 C.1 Le prouveur interactif de l’atelier B . . . 151

C.2 Commandes du prouveur interactif . . . 151

C.2.1 Commandes de preuve . . . 152

C.2.2 Commandes de position . . . 153

C.2.3 Commandes d’information . . . 153

Appendix D Obligations de preuves 155 D.1 Machine preemptive_timed_priority . . . 155

D.2 Machine preemptiveuppaal . . . 155

Appendix E Machine BASIC_ARRAY_VAR 165

Appendix F Code Uppaal du système ordonnancé 167

(11)

Table des figures

1 Etapes de vérification d’un système . . . 3

1.1 Vitesse d’évolution des variables . . . 22

1.2 Annotation d’un état . . . 22

1.3 Annotation d’une transition . . . 22

1.4 Transformations Cotre . . . 25

2.1 Etapes de développement en B. . . 32

2.2 Structure d’une machine abstraite. . . 38

2.3 Expression générale d’une machine abstraite. . . 39

2.4 Structure de base d’un raffinement en B. . . 40

2.5 Machine et raffinement. . . 41

2.6 Exemple de modélisation en B. . . 43

2.7 Automate temporisé de la barrière . . . 46

2.8 Automate hybride d’un thermostat . . . 47

3.1 Séquence RM pour le système S1 . . . 55

3.2 Ordonnancement par DM du système S2 . . . 56

3.3 Ordonnancement par EDF du système S3 . . . 56

3.4 Ordonnancement par LL du système S4 . . . 57

3.5 Serveur à scrutation . . . 58

3.6 Inversion de priorités . . . 59

3.7 Exemple d’urgence . . . 62

3.8 Exemple simple en Uppaal . . . 62

3.9 Automate du train avec délai d’entrée paramétré et Automate de la barrière . . . 64

3.10 Editeur TIMES . . . 69

3.11 Simulateur TIMES . . . 70

3.12 Analyse TIMES . . . 71

3.13 Analyse Cheddar . . . 72

3.14 Graphe de dépendance Cheddar . . . 73

4.1 Retardement de la borne de calcul . . . 80

4.2 Comportement d’un processus . . . 85

4.3 Prise en compte de la préemption . . . 85

4.4 Ready . . . 86

4.5 Hiérarchie des machines . . . 87

4.6 Machine scheduler en B . . . 89

(12)

4.8 Machine untimed_nonpreemptive en B . . . 90 4.9 De untimed_nonpreemptive à timed_nonpreemptive . . . . 91 4.10 De timed_nonpreemptive à fcfspolicy . . . . 93 4.11 Machine edfpolicy en B . . . 100 4.12 Machine istacks en B . . . 101 4.13 De scheduler à preemptive_priority . . . 102 4.14 De preemptive_priority à preemptive_timed_priority . . . 104 4.15 De preemptive_timed_priority à preemptive_uppaal . . . 106

5.1 Vérification sous Uppaal . . . 117

5.2 Structure d’une implantation de la méthode B . . . 119

5.3 istacks en B . . . 120

5.4 Machine istacks_fun en B . . . 122

5.5 Machine istacks_seq en B . . . 123

5.6 Machine istacks_implementation en B0 . . . 124

5.7 Transformation du IF en automate Uppaal . . . 128

5.8 Transformation du SELECT en automate Uppaal . . . 128

5.9 Tansformation des séquences et conditions en automate Uppaal . . . 129

5.10 Transformation du SELECT imbriqué en automate Uppaal . . . 129

5.11 Automates des clients . . . 132

5.12 Automate de choice . . . 133

5.13 Automate de l’ordonnanceur . . . 135

5.14 Simulation . . . 136

5.15 Vérification de la propriété “E<> deadlock” . . . 137

(13)

Liste des tableaux

1.1 Caractéristiques des composants et des connecteurs . . . 7

1.2 Fonctions simples pour l’expression des contraintes . . . 14

2.1 Liste des substitutions primitives. . . 34

2.2 Règles de calcul des substitutions. . . 36

2.3 Obligations de preuves d’une machine B. . . 39

3.1 Outils de vérification . . . 74

4.1 Calcul des priorités . . . 83

5.1 Transformation B/Uppaal des substitutions . . . 127

5.2 Code Uppaal d’un raffinement de la machine edfpolicy . . . 131

5.3 Code Uppaal de la machine istacks_seq . . . 132

A.1 Modélisation des composants . . . 141

A.2 Modélisation des connecteurs . . . 142

(14)
(15)

Introduction

Le temps joue un rôle de plus en plus important dans la définition des services et des applications. Ceci se vérifie, non seulement dans le domaine de l’informatique industrielle, mais aussi dans le domaine des télécommunications qui est aujourd’hui florissant. Les débits élevés des liens de communications imposent des contraintes sur les temps de traitement. Les services proposés impliquent souvent l’accès à plusieurs flux d’informations hétérogènes qu’il faut synchroniser et ordonnancer.

De façon informelle, on définit les systèmes temps réel comme des systèmes dont le comportement dépend, non seulement de l’exactitude des traitements effectués, mais également du temps où les résultats de ces traitements sont produits. En d’autres termes, un retard (le fait de dépasser une échéance) est considéré comme une erreur qui peut d’ailleurs entraîner de graves conséquences.

En plus, ces systèmes peuvent être considérés comme des systèmes interagissant avec leur envi-ronnement et contraints par le temps. De tels systèmes deviennent de plus en plus complexes. Cette complexité est dûe en particulier à leurs aspects distribués (fonctionnement en parallèle sur différentes machines), d’où la nécessité d’utiliser des techniques d’ordonnancement fiables. Le disfonctionnement ou le bug de ce type de systèmes peut, ainsi causer des catastrophes économiques et humaines. L’absence d’anomalie à l’issue de la phase de test ne permet alors pas de conclure à l’absence de bugs. Un exemple malheureux de système médical est la machine de radiation Therac25 [LT93], développée par la com-pagnie AECL. Cette machine utilisée entre 1985 et 1987 pour le traitement du cancer, permet de détruire les tumeurs en émettant des radiations sur celles-ci sans affecter l’organe touché par la tumeur. Cepen-dant, une anomalie dans son fonctionnement a entraîné la mort de 6 patients. En effet, une erreur dans la programmation du logiciel conduisait dans certaines situations à utiliser erronément la machine dans le mode Rayon-X au lieu du faisceau d’électrons, ce qui envoyait 125 fois plus de radiations que dans la dose prescrite par le médecin. On peut citer également d’autres exemples, comme le crash d’avions qui se renouvelle jusqu’à nos jours et le bug du système d’Ariane5 en juin 1996. Cette fusée a explosé 37 secondes seulement après son décollage à cause d’une simple erreur introduite après conversion de 64 bits flottants en 16 bits entiers [Gle].

Pour régler ce type de problèmes, il est nécessaire de mettre en oeuvre des techniques destinées à fiabiliser le processus de développement des applications temps réel ou non, tant du point de vue de leur conception que de leur vérification. Ceci va nous permettre de spécifier avec précision des systèmes, et par la suite de vérifier les propriétés exigées sur leur comportement.

Les techniques de spécification et de vérification formelles permettent une approche fiabilisée des systèmes, et elles constituent un domaine de recherche important et très actif. La spécification formelle a pour but à partir d’une modélisation informelle des besoins et du système à développer, d’exprimer le sys-tème en tenant compte d’un ensemble de contraintes, de spécifier les propriétés exigées par l’utilisateur et par la suite, de vérifier que la spécification du système satisfait bien ces propriétés.

Le choix de la méthode formelle la plus appropriée dépendra des particularités du système à réaliser et de la nature des propriétés à vérifier sur celui-ci. Nous distinguons deux classes de méthodes de preuve: les méthodes déductives et les méthodes basées sur les modèles.

(16)

1

Les méthodes déductives

Ces méthodes consistent à interpréter le problème de vérification comme un théorème de la forme: Système ) Propriété. Pour s’appliquer, cette méthode requiert donc que le système ainsi que la propriété puissent être modélisés dans une théorie mathématique. Ceci est exploité par exemple, par les méthodes B et Z utilisant la théorie des ensembles et la logique du premier ordre [Toy98, ISO02, Ate, B-T, CLE02].

A partir d’axiomes (propriétés de base supposées vérifiées) et de règles d’inférence (règles permettant de déduire de nouveaux théorèmes), un outil, le prouveur de théorèmes ou l’assistant de preuves, génère les étapes intermédiaires d’une preuve formelle ou la réfute. Le prouveur de théorèmes ne peut évidem-ment pas vérifier automatiqueévidem-ment toutes les propriétés valides et des interactions avec l’utilisateur sont possibles à toute étape de la preuve.

L’avantage de cette méthode est le niveau de détails de description du système qui peut même être le code final. Son inconvénient majeur est que l’utilisateur interagissant avec le prouveur doit être capable d’aider le prouveur à toute étape intermédiaire, c’est à dire connaître la preuve ou au moins être capable de guider le prouveur.

2

Les méthodes basées sur les modèles

Ces techniques sont basées sur des modèles décrivant les comportements des systèmes, et sur des algo-rithmes qui explorent les états des modèles. Ces techniques sont: la simulation, le test et la vérification de modèle (model-checking).

2.1 La simulation

Cette méthode est l’une des méthodes les plus utilisées dans la vérification des systèmes. Elle consiste à utiliser un outil, "un simulateur", qui permet de déterminer comment un système donné réagit à un certain scénario (stimulus). Les scénarios utilisés sont soit établis par l’usager, soit générés par le simulateur. L’inconvénient de la simulation réside dans son inefficacité de détecter toutes les erreurs subtiles puisqu’il est impossible de générer tous les scénarios possibles. Par exemple, pour un téléphone mobile avec 5 choix par étape, le nombre de scénarios possibles avec 20 étapes seulement atteindrait la valeur 5

20 . Il serait alors difficile de quantifier le nombre d’erreurs oubliées dans le système à cause du nombre réduit de scénarios explorés.

2.2 La méthode de test

Elle est différente des autres méthodes qui nécessitent la modélisation du système à vérifier. En effet, cette méthode est toujours applicable sur le produit, même quand il est difficile voire impossible d’obtenir le modèle du système, par exemple, si un logiciel est protégé et que son code source n’est pas disponible. A l’aide des algorithmes de génération de test, les produits réalisés sont testés afin de vérifier si le résultat de l’exécution des tests appartient bien à l’ensemble des réponses attendues selon la spécification du système implanté. Cette technique de test n’est pas systématique, cependant elle a été utilisée avec succès pour plusieurs logiciels, par exemple pour les systèmes embarqués qui contrôlent les échanges d’informations entre l’ensemble des gros terminaux de télévision et les magnétoscopes [Kat02]. En général, cette méthode n’est pas suffisante pour vérifier le logiciel correctement car des erreurs peuvent rester cachées.

(17)

2.3 Le model-checking

Le model-checking effectue la vérification d’un modèle d’un système par rapport aux propriétés exp-rimant le comportement de ce système. Il repose en général sur l’idée de l’énumération de tous les états possibles auxquels peut mener le programme, ce qui permet de s’assurer qu’aucun cas n’est en contradiction avec les comportements que l’on souhaite. Cette vérification est entièrement automatisée et n’exige aucune interaction avec l’utilisateur. Le résultat de cette analyse est soit la confirmation que chaque propriété est satisfaite par le modèle, soit qu’elle ne l’est pas. Si la propriété n’est pas satisfaite, le model-checker renvoie un contre exemple montrant pourquoi elle n’est pas satisfaite.

La vérification du modèle est également appelée analyse d’atteignabilité. Elle consiste à générer tous les états du système atteignables depuis l’état initial et à vérifier en même temps que la propriété énoncée est toujours satisfaite.

L’espace des états est défini à l’aide de toutes les variables qui participent au contrôle du comporte-ment du modèle. Si cet espace est fini, il est alors possible d’énumérer tous les états et de vérifier si des formules logiques sont valides pour tous ces états [Hol91].

On peut cependant se heurter au problème d’explosion combinatoire limitant l’utilisation du model checking, lorsque l’ensemble des états accessibles du système devient trop grand. Cette technique peut aussi s’appliquer lorsque l’espace d’état est infini. Elle devient alors une procédure de semi-décision dont la terminaison n’est plus garantie. Les systèmes infinis peuvent aussi être traités en mettant en oeuvre des techniques d’abstraction permettant de se ramener à des espaces finis. Tel est par exemple le cas des automates temporisés pouvant être abstraits en automates de régions. La figure 1 représente les étapes de vérification d’un système par un model-checker.

Propriété Spécification Propriété Spécifiée Model-checker Mémoire pleine Système Modélisation Système Modélisé Violation + Contre exemple Satisfaite

Figure 1: Etapes de vérification d’un système

3

Plan de la thèse

Dans cette thèse, nous proposons une démarche de spécification et de validation des ordonnanceurs temps réel. Le modèle à analyser et les politiques d’ordonnancement sont exprimés à l’aide d’un langage de description d’architecture permettant l’expression formelle du comportement d’un système, ainsi que les contraintes à respecter. La vérification du système ordonnancé repose sur la traduction du modèle en

(18)

automates temporisés. Notre modélisation des ordonnanceurs préemptifs devant être traduite en Uppaal, ne doit gérer le temps qu’à travers des horloges. Nous cherchons ensuite à valider notre modélisation en utilisant la méthode B. Pour cela, nous avons débuté par une spécification abstraite des ordonnanceurs, et nous l’avons raffiné par étapes successives afin de prendre en compte les caractéristiques des auto-mates temporisés. Nous avons ensuite vérifié la hiérarchie de raffinements en prouvant les différentes obligations de preuve générées. Notre travail a donné lieu à des publications dans des conférences et workshops nationaux et internationaux [NRBF04, RBFN05b, RBFN05a, NBFR06b, NBFR06a] et à un rapport technique [ABB+

02]. La suite de ce document comprend cinq chapitres:

 Dans le premier chapitre, nous introduisons les langages de description d’architecture avec leurs différents concepts et caractéristiques, tels que les composants, les connecteurs et les configura-tions. Nous détaillons les langages Wright, ACME, Rapide, AADL et Cotre et nous les illustrons par un exemple client/serveur.

 Le deuxième chapitre présente les différents formalismes utilisés pour la vérification des modèles, comme la méthode B, les automates temporisés avec invariants, les automates hybrides, et les logiques temporelles et temporisées. Nous introduisons d’abord les concepts et les notions de base de la méthode B, tels que les substitutions généralisées, les machines abstraites, le raffinement ainsi que les règles à respecter pour la vérification d’une machine B et d’un raffinement. Nous présentons ensuite la syntaxe et la sémantique des automates temporisés avec invariants, puis ceux des automates hybrides. Enfin, nous abordons les logiques temporelle CTL et temporisée TCTL permettant de décrire les propriétés d’un système.

 Dans le troisième chapitre, nous présentons l’ordonnancement temps réel et les outils de vérifica-tion. Nous commençons par introduire la notion de tâches et les différents types d’ordonnancement, comme l’ordonnancement en ligne et hors ligne, périodique et conjoint, . . . . Nous distinguons dif-férents algorithmes d’ordonnancement, puis nous présentons l’ordonnancement de tâches dépen-dantes. Ces dernières peuvent être liées soit par des contraintes de précédence, soit par des ressources partagées. Nous abordons enfin les outils de model-checking comme Uppaal et HyTech, ainsi que les outils de vérification d’ordonnançabilité comme Times et Cheddar. Enfin, nous pro-posons une synthèse des approches de vérification d’ordonnanceurs temps réel utilisant des auto-mates temporisés.

 Le quatrième chapitre présente une première partie de notre contribution. Elle consiste à exprimer différentes politiques d’ordonnancement préemptives ou non dans le langage Cotre. Pour mod-éliser la préemption, nous proposons une démarche reposant sur le retardement de la borne de calcul. Cette démarche ne doit gérer le temps qu’au travers des horloges exploitées dans les auto-mates temporisés. Cette spécification est ensuite validée en utilisant la méthode B. Le modèle B est obtenu par des raffinements successifs introduisant l’ordonnancement, l’ordonnancement préemp-tif, la gestion du temps à l’aide des chronomètres puis par des horloges. Enfin, notre modélisation est vérifiée en prouvant les obligations de preuve générées par l’outil Atelier B.

 Dans le cinquième chapitre, nous proposons une traduction Uppaal de la modélisation B des or-donnanceurs. Pour cela, nous définissons un langage B0_Uppaal qui est une variante du langage B0 de B, et des règles à respecter lors de la transformation. Cette traduction est ensuite vérifiée par des propriétés d’ordonnançabilité exprimées en logique CTL.

(19)

Les langages de description d’architecture

L’architecture logicielle d’un système définit son organisation comme étant une collection de composants interagissant entre eux [GMW00]. Une bonne architecture permet à un ingénieur de bien raisonner sur les propriétés d’un système. Parmi ces propriétés, on peut citer la compatibilité entre les composants, la conformité aux standards, la performance, etc.

Le modèle architectural a toujours joué un rôle important dans la détermination du succès des sys-tèmes complexes. Le choix d’une bonne architecture peut aboutir à un produit qui satisfait les besoins demandés et qui peut évoluer vis-à-vis de nouveaux besoins.

Cette description architecturale présente plusieurs inconvénients :

 Impossibilité de tester la complétude qui permet de justifier que toutes les informations nécessaires pour l’analyse sont présentes dans le modèle, et la consistance qui permet de vérifier qu’il n’existe pas de contradiction entre les différentes parties du système.

 Non évolution des contraintes avec le système.

Pour remédier à ces problèmes, les premiers travaux ont été menés dès le début des années 90. Des chercheurs ont proposé des notations formelles, connues sous le nom de langages de description d’architecture ou ADL (Architecture Description Language [SG96, DFMV04]), pour la représentation et l’analyse des modèles architecturaux et non des instructions. Le but d’un ADL est de fournir une structure de haut niveau de l’application entière plutôt que les détails d’implantation dans un code source spécifique [Ves93]. Un ADL peut alors être considéré comme une notation pour la conception architec-turale des applications.

Plusieurs ADLs ont été proposés comme par exemple ACME [GMW97, GMW00], Wright [All97, AG97], Rapide [LKV+

95, LV95], AADL [SA04], ... Dans ce chapitre, nous ne nous intéressons pas à les présenter tous, mais nous nous contenterons d’introduire quelques uns.

On notera que les concepts de base introduits par les ADLs ont été repris pour la plupart, par les notations apparues ces dernières années, comme par exemple le diagramme de composants introduit récemment dans UML 2.0 [OMG03a, OMG03b].

1.1

Les langages de description d’architecture: Concepts et

caractéris-tiques

Les ADLs fournissent un support pour la définition et la conception des structures de haut niveau. Ils permettent la réutilisation d’architectures afin de faciliter les analyses des systèmes et de réduire le

(20)

coût de développement. Mais chaque ADL fournit sa propre architecture, les uns privilégiant les élé-ments de l’architecture et leur assemblage structurel, les autres s’orientant plutôt vers la configuration de l’architecture et la dynamique du système. Suite à ce manque de concensus sur la nature et la défini-tion d’un ADL, Medvidovic et Taylor ont proposé une classificadéfini-tion et une comparaison entre différents ADLs [MT00]. Ils en définissent trois constituants: composants, connecteurs et configuration.

 Le composant est une unité de calcul ou de stockage de données ou un périphérique. Il peut être matériel ou logiciel, une simple procédure ou une application entière.

 Le connecteur spécifie les interactions entre les composants. Tout comme les composants, la com-plexité d’un connecteur peut aller du simple appel de fonction à un protocole de communication complexe.

 La configuration de l’architecture définit la topologie de l’application; c’est un graphe de com-posants et de connecteurs qui permet de valider l’assemblage entre les différentes parties et le comportement global de l’application.

Un autre concept est également abordé dans [MT00], les outils associés aux différents ADLs. Ils fournissent une aide à la conception, des vues multiples de l’application ainsi que des fonctions d’analyse et de raffinement.

1.1.1 Caractéristiques des composants et des connecteurs

Les composants et les connecteurs présentent plusieurs caractéristiques communes: l’interface, les types, la sémantique, les contraintes, l’évolution et les propriétés non fonctionnelles. Le tableau 1.1 définit leurs caractéristiques et leurs significations pour les composants et les connecteurs.

1.1.2 Caractéristiques des configurations

Les topologies, ou configurations architecturales, traduisent la structure d’une application sous forme d’un graphe de composants et de connecteurs. Elles permettent de valider la connexion des composants et des connecteurs ainsi que le comportement de l’architecture, tout en évaluant les performances, les niveaux de sécurité et les possibilités de deadlock.

Un ADL doit fournir plusieurs possibilités de configurations, classées en trois catégories:

 Qualités de la description: compréhension, composition, raffinement et traçabilité, hétérogénéité.  Qualités du système décrit: hétérogénéité, mise à l’échelle, évolution, dynamisme.

 Propriétés du système décrit: dynamisme, contraintes et propriétés non fonctionnelles.

Spécifications compréhensibles Un ADL doit fournir une syntaxe simple et intuitive du modèle topolo-gique. Dans ce cas, la structure de l’application peut se comprendre à partir de sa configuration, sans rentrer dans les détails des composants et connecteurs.

Composition C’est la possibilité de décrire les architectures à différents niveaux de détail; on parle alors de composition hiérarchique. Un composant primitif est considéré comme une unité non décompos-able. Un composant composite est formé d’autres composants (composites ou primitifs). La composition hiérarchique est utilisée dans les raffinements successifs.

(21)

Composant Connecteur Interface:

Ensemble de points d’interaction Spécifie les services et les propriétés Points d’interaction entre le avec le monde extérieur. fournis par le composant ainsi que connecteur, les composants et

ceux requis par celui-ci. d’autres connecteurs.

Mécanisme de connexion des différents composants, qui définit le rôle des participants à l’interaction.

Types:

Abstraction des fonctionnalités Abstraction des fonctionnalités Abstraction des mécanismes dans le but de les réutiliser. fournies par le composant. de communication, de

Un type peut être instancié coordination et de médiation. plusieurs fois dans l’architecture,

comme il peut être paramétré pour faciliter sa réutilisation. Sémantique:

Modèle de haut niveau permettant Abstraction des fonctionnalités Abstraction des protocoles l’abstraction du comportement. du composant. L’interface du associés à l’interaction. Il permet de faire des analyses, composant permet aussi de

de vérifier des contraintes raisonner de façon limitée architecturales et d’effectuer des sur la sémantique.

mappings entre les différents niveaux d’abstraction. Contraintes:

Propriétés ou assertions sur Renforcer les limites d’usage Limiter l’utilisation des une partie ou la totalité du système; et établir des dépendances entre protocoles d’interaction et leur violation entraine une les différentes parties internes établir les dépendances entre incohérence du système. du composant. les différents connecteurs. Evolution:

Un ADL doit permettre l’évolution Modification des propriétés du Modification des propriétés des éléments de l’architecture. composant: évolution de du connecteur: interface, Elle est faite grâce aux techniques l’interface, du comportement sémantique et contraintes. de sous-typage ou de raffinement. et de l’implantation. Permet aussi de faire

évoluer les protocoles. Les propriétés non fonctionnelles des composants et des connecteurs sont liées à la sécurité, la sûreté, la performance et la portabilité. Elles ne diffèrent pas entre les composants et les connecteurs.

Tableau 1.1: Caractéristiques des composants et des connecteurs

Raffinement et traçabilité Les ADLs doivent fournir un raffinement et une description de plus en plus détaillée. La traçabilité permet de garder trace des changements successifs entre les différents niveaux d’abstraction.

Hétérogénéité C’est une caractéristique importante pour le développement de systèmes complexes et la réutilisation de l’existant. Un ADL doit permettre de spécifier une architecture dont les composants

(22)

et les connecteurs font appel à des langages de programmation, de modélisation ou à des systèmes d’exploitation différents.

Mise à l’échelle Les ADLs doivent permettre la réalisation de spécifications complexes et dont la taille peut s’accroitre avec le temps.

Evolution La configuration doit pouvoir évoluer pour prendre en compte de nouvelles fonctionnalités. Cela se traduit par l’ajout, le retrait ou le remplacement des composants ou des connecteurs.

Dynamisme Il consiste à faire des modifications de l’architecture en cours d’exécution. Le dynamisme est une propriété importante dans les systèmes critiques comme le contrôle du trafic aérien par exemple.

Contraintes Elles décrivent les dépendances dans la configuration, et s’ajoutent à celles des com-posants et connecteurs.

Propriétés non fonctionnelles Certaines de ces propriétés sont spécifiées pour le système tout entier. Elles sont nécessaires pour sélectionner les composants et les connecteurs appropriés, faire des analyses, renforcer les contraintes et aider dans la gestion du projet.

Dans ce qui suit, nous présentons quelques langages de description d’architecture comme Wright, ACME, Rapide, AADL et COTRE. Afin d’illustrer ces différents langages, nous allons considérer l’exem-ple d’un siml’exem-ple système client/serveur. On suppose que le client envoie une requête au serveur. Ce dernier lui répond en renvoyant les données transmises mais pas de façon instantanée. Donc le serveur prend du temps pour transmettre sa réponse.

1.2

Le langage Wright

Wright [All97, AG97] est un langage de description d’architecture développé à l’université de Carnegie Mellon. Il fournit les bases formelles pour spécifier le comportement des composants et des connecteurs au moyen d’une algèbre de processus, CSP (Communicating Sequential Processes) [Hoa85, Ros98]. Il repose sur les trois concepts fondamentaux des ADLs (composant, connecteur et configuration).

 La description d’un composant peut être divisée en deux parties: l’interface et le calcul. L’interface, basée sur les événements, est décrite par un ensemble de ports. Ces derniers définissent un point d’interaction entre le composant et son environnement. Une interface contient également des événements émis ou reçus sans distinction entre les interfaces fournies et requises. La partie calcul décrit le comportement réel du composant. Elle décrit la réaction du composant aux événements reçus des ports.

 Le connecteur est défini par un ensemble de rôles et une glue. Les rôles décrivent le comporte-ment local et les obligations des différentes parties participant à une interaction. La glue montre comment coordonner les rôles des différents composants.

 La configuration représente des instances de composants liées par des connecteurs. Elle com-prend également des connexions entre ports appelées attachements définissant la topologie de la configuration. Ils montrent les composants qui participent à chaque interaction.

(23)

1.2.1 Principales notations

CSP fournit un grand nombre d’opérateurs permettant de décrire les entités communicantes. Wright en a emprunté quelques-uns:

 Processus et événements: Un processus décrit une entité produisant des événements. Un événe-ment peut être primitif comme il peut être associé à des données. Les représentations syntaxiques e?x et e!x expriment respectivement des données en entrée et en sortie. Le processus STOP ne produit aucun événement. L’événementp

représente un succès. L’ensemble des événements d’un processus P est appelé alphabet de P ou P.

 Préfixe: Un processus prenant part à l’événement e puis se comportant comme le processus P est noté e!P.

 Alternative ou choix externe: Un processus qui peut se comporter comme P ou Q, où le choix est déterminé par l’environnement, est noté P8Q.

 Décision ou choix interne: Un processus qui peut se comporter comme P ou Q, où le choix est effectué de façon non déterministe par le processus lui-même, est noté PuQ.

 Processus paramétré: On a restreint la syntaxe de CSP afin d’introduire un nombre fini de noms. Les processus paramétrés ne sont pas autorisés.

 Composition parallèle: La composition des processus est effectuée grâce à l’opérateur k. Les processus parallèles peuvent s’engager d’une manière synchrone dans des événements appartenant à l’intersection de leurs alphabets. Si un événement est commun aux alphabets des processus P1 et P2, alors P1 peut s’engager dans l’événement si P2 le peut aussi.

En complément de la notation standard de CSP, Wright introduit trois nouvelles notations. Le sym-bolexreprésente une terminaison correcte du processus, ce qui veut dire que le processus s’est engagé dans un événement succès p

et s’est arrêté. Formellement, x = p

! STOP . On a autorisé les expressions du type : let Q = expression in R ainsi que les étiquettes. L’écriture l.e signifie que l est l’étiquette de l’événement e et l:P signifie que tous les événements de P sont étiquetés par l. Le symbole représente tous les événements sans étiquettes.

1.2.2 Exemple

Le système client/serveur peut être modélisé en Wright comme suit où seuls les protocoles du connecteur sont décrits et la communication entre le client et le serveur se fait de manière asynchrone. Cet asyn-chronisme est introduit par la glue.

System ClientServer Component Server =

port provide [provide protocol] spec [Server specification] Component Client =

port request [request protocol] spec [Client specification] Connector C-S-connector =

role Client = (request!x ! result?x ! Client) u x

role Server = (invoke!x ! return?x ! Server) 8 x

glue = (Client.request!x ! Server.invoke!x !

Server.return?x ! Client.result?x ! glue) 8 x

(24)

s: Server c: Client cs: C-S-connector Attachments s.provide as cs.server; c.request as cs.client end ClientServer

La description du connecteur montre le comportement de chaque élément de ce connecteur:

 Le rôle du client décrit le comportement de l’utilisateur du service. Ce client est également un processus, soit il invoque le service et reçoit une réponse, soit il termine. Ici, ce choix est déterminé par le processus lui-même.

 Le serveur est défini comme un processus qui peut, soit accepter une invocation et retourner un ré-sultat à plusieurs reprises, soit accepter un événement de succès et terminer. Ce choix est déterminé par l’environnement. Le serveur termine lorsque le client termine.

 La glue coordonne les comportements des rôles en séquençant les événements qui interagissent. Elle permet au rôle du client de décider s’il invoque un service ou s’il termine. Puis, elle séquence les autres événements et leurs données.

Pour illustrer le dynamisme introduit par ce langage, on suppose que le système comporte un client Client et deux serveurs Server1 et Server2. Dans ce cas, la glue peut être de la forme:

glue = (Client.request!x ! Server1.invoke!x !

Server1.return?x ! Client.result?x !

Client.request!x ! Server2.invoke!x !

Server2.return?x ! Client.result?x ! glue) 8 x 1.2.3 Analyse

Wright assure la vérification de la compatibilité entre les différents ports et rôles. Cette caractéristique permet de détecter les anomalies comportementales des entités comme les interblocages par exemple. Il permet de décrire, grâce à CSP, de nouveaux types de connecteurs effectuant des interactions complexes entre les composants. Mais cette tâche peut s’avérer très difficile pour les personnes qui ne maîtrisent pas CSP.

Ce langage possède l’avantage de faciliter la compréhension des structures architecturales. Il fournit des composants et des connecteurs composites. Grâce à sa caractéristique de mise à l’échelle, Wright a été utilisé pour modéliser et analyser l’infrastructure d’exécution pour un environnement de simulation du département de la défense américaine, dont la spécification originale s’étendait sur une centaine de pages. Il cible ses analyses sur des informations locales à un seul connecteur par exemple, ce qui le rend plus adapté à l’expansion d’une architecture que d’autres ADLs.

Wright supporte les notions de styles et d’instances d’architectures sous forme textuelle. Il a adopté une approche pour les changements dynamiques d’une architecture: on distingue les événements de communication et de contrôle. Ces derniers sont utilisés pour spécifier les conditions sous lesquelles les changements dynamiques sont permis. Ce langage permet également la spécification d’invariants structurels selon différents styles architecturaux.

Les connecteurs et les composants ne sont pas des entités exécutables et jusqu’à aujourd’hui, il n’existe pas d’outils d’exécution spécifiques associés à ce langage. Ceci entraîne que les connecteurs sont réalisés par les outils existants avec de simples moyens d’interaction. Ainsi l’interaction, qui est une entité de première classe, devient éparpillée dans les différents composants. A noter également que Wright ne traite pas les aspects temporisés.

(25)

1.3

Le langage ACME

Le langage ACME [GMW97, GMW00] a été créé dans le but de combiner l’utilisation des outils associés à des formalismes différents. C’est un langage générique pour la description d’architectures. Il permet de faciliter l’échange de descriptions architecturales entre les différents ADLs et outils. Il supporte la description composant-connecteur ainsi que les familles d’architecture.

ACME assure plusieurs fonctionnalités:

 Il fournit sept entités différentes permettant de spécifier la structure d’une architecture: composant, connecteur, système, ports, rôles, représentations et carte de représentation (rep-map).

 Il fournit un mécanisme d’annotations permettant d’intégrer des informations spécifiques apportées par d’autres ADLs.

 Il permet de créer et de réutiliser des modèles comme le style d’une architecture.

 Il favorise l’intégration d’outils afin de faciliter la spécification formelle de la sémantique d’une architecture.

1.3.1 Structure

Un composant ACME est considéré comme l’unité de traitement ou de gestion de données d’une appli-cation. Il est spécifié par une interface composée de ports. Un port définit un point d’interaction entre le composant et son environnement. Ce port permet de définir également une interface plus complexe comme un ensemble d’appels à distance invoqués selon un certain ordre.

Le connecteur représente l’interaction entre les composants. Il s’agit d’un médiateur de commu-nication qui coordonne les connexions. Il est spécifié par une interface composée de rôles. Chaque rôle définit un participant à une interaction. Les connecteurs binaires possèdent deux rôles, appelant et appelé dans un connecteur RPC, lecture et écriture dans un canal, émetteur et récepteur dans un con-necteur d’échange de messages. D’autres types de concon-necteurs peuvent avoir plus que deux rôles; par exemple, le connecteur de diffusion d’évènements (event broadcast connector) possède un rôle émetteur d’évènements et un nombre arbitraire de rôles récepteurs d’évènements.

Le système représente l’assemblage entre les composants et les connecteurs. Il est défini par un graphe où les noeuds et les arcs représentent respectivement les composants et les connecteurs.

Pour faciliter la description hiérarchique des architectures, ACME permet une description de bas niveau des composants et des connecteurs. Un composant ou un connecteur peut être décrit d’une façon générale puis détaillée, il peut donc être raffiné. Chaque nouvelle description est appelée représentation. Quand un composant ou un connecteur possède une représentation architecturale, il faut indiquer la correspondance entre la représentation et l’élément; cette correspondance est définie par la map (carte) de représentation. Ainsi, on peut établir une correspondance entre les ports de l’interface d’un composant et ceux des interfaces de ses sous-composants.

L’exemple suivant décrit l’architecture client/serveur en ACME:

System ClientServer = {

Component Client = {Port request; } Component Server = {Port provide; }

Connector C-S-connector = {Roles { client, server; } } Attachments { Client.request to C-S-connector.client;

Server.provide to C-S-connector.server; } }

(26)

1.3.2 Propriétés

Les sept concepts déjà cités permettent la définition de la structure d’une architecture, mais sont insuff-isants pour spécifier des informations précises sur le comportement du système lors de l’exécution par exemple.

ACME intègre ces caractéristiques via la notion de propriété. Ainsi, chacune des entités citées au-paravant possède une liste de propriétés identifiées par un nom, un type optionnel et une valeur. Ces propriétés permettent de donner les détails nécessaires pour l’analyse, la manipulation et la traduction.

Le type optionnel d’une propriété peut être:

 un type simple comme un entier, un booléen ou une chaîne de caractères.  un type indiquant une propriété d’un autre sous-langage ADL.

 un type indiquant un lien externe (external) avec une implantation comme un programme par exemple.

Dans l’exemple client/serveur, on peut spécifier la fréquence des requêtes émises par le client, le lien vers le code source, le protocole d’interaction entre le client et le serveur, . . . . Ces informations sont exploitées par des outils d’analyse permettant par exemple, de vérifier que le serveur supporte la charge.

System ClientServer = { Component Client = {

Port request;

Properties { requestRate : float = 17.0; /* fréquence des requêtes sourceCode : externalFile = "CODE-LIB/client.c";

/* langage externe pour le comportement, /* ici le langage C } }

Component Server = { Port provide;

Properties { idempotent : boolean = true;

maxConcurrentClients : integer = 1; multithreaded : boolean = false;

sourceCode : externalFile = "CODE-LIB/server.c"; } } Connector C-S-connector = {

Role client; Role server;

Properties { synchronous : Boolean = true; maxRoles : integer = 2;

protocol : WrightSpec = " ... "; } } Attachments { Client.request to C-S-connector.client;

Server.provide to C-S-connector.server; } }

1.3.3 Styles

ACME fournit des gabarits de conception (templates) équivalents à la notion de styles présents dans la plupart des ADLs. Les styles représentent les familles de systèmes reliés. Ils définissent les types des éléments formant le modèle et les règles qui leur sont imposées. Les gabarits ACME sont paramétrables et réutilisables pour spécifier des patrons de conception.

Le style d’architecture client/serveur peut être décrit comme suit:

Style client-server = {

Component Template Client(C-S-call-ports : Ports) = { Ports C-S-call-ports;

(27)

Properties { requestRate : float = 17.0;

sourceCode : externalFile = "CODE-LIB/client.c"; } } Component Template Server(C-S-receive-ports : Ports) = {

Ports C-S-receive-ports;

Properties { idempotent : boolean = true;

maxConcurrentClients : integer = 1; multithreaded : boolean = false;

sourceCode : externalFile = "CODE-LIB/server.c"; } } Template C-S-connector(client_port, server_port : Port) defining

(conn : Connector) = /* un connecteur est spécifié avec deux /* ports en entrée. La clause ‘‘defining’’ /* signifie qu’un identifiant unique ‘‘conn’’ /* doit être généré lorsque ce modèle est utilisé { conn = Connector {

Roles {client, server}

Properties { synchronous : boolean = true; max-roles : integer = 2; protocol : Wright = " ... " }} Attachments { conn.client to client_port;

conn.server to server_port; }} }

System cs : client-server = {

/* description de la configuration d’un système /* typé par le style client/serveur. Assemblage /* statique des composants au moyen des connecteurs. c1 = Client(request); c2 = Client(request); c3 = Client(request); s1 = Server(provide); s2 = Server(provide); C-S-connector(c1.request, s1.provide); C-S-connector(c2.request, s1.provide); C-S-connector(c3.request, s2.provide); }

Ici, client-server peut être considéré comme un patron (un type générique) où il faut instancier les différents paramètres. Le système cs est défini comme une instance du patron client-server.

Le langage ACME ne se focalise pas sur la sémantique, il a été conçu pour spécifier une architecture syntaxiquement. Néanmoins, il propose un cadre (Open Semantic Framework) permettant de décrire formellement une contrainte sur l’architecture d’un système. Ce cadre fournit un moyen de projeter les aspects structurels du langage (composant, connecteur) sur un formalisme logique basé sur des relations et des contraintes. Une spécification est alors exprimée par un prédicat appelé une prescription.

La prescription du système client/serveur peut être définie comme suit:

exists Client, Server, C_S_Connector | component(Client) ^ component(Server) ^ connector(C_S_Connector) ^ attached(Client.request, C_S_Connector.client_port) ^ attached(Server.provide, C_S_Connector.server_port) ^ Client != Server ^ Server != C_S_Connector ^ Client != C_S_Connector ^

(for all y : component(y) ) y = Client | y = Server) ^

(for all y : connector(y) ) y = C_S_Connector) ^

(for all p,q : attached(p,p) ) (p = Client.request ^ q = C_S_Connector.client_port)

(28)

1.3.4 Expression des contraintes d’architecture

ACME utilise un langage de contraintes basé sur les prédicats de la logique du premier ordre et ajoute des fonctions spéciales sur les aspects spécifiques de l’architecture du système. Par exemple, il existe des prédicats permettant de déterminer si deux composants sont interconnectés et si un composant possède des propriétés particulières. D’autres fonctions servent à retourner l’ensemble des composants d’un système, l’ensemble des ports d’un composant, l’ensemble des représentations d’un connecteur, . . . . Le tableau 1.2 liste quelques fonctions simples permettant d’exprimer les contraintes en ACME.

Fonctions Résultat

Connected(comp1, comp2) Vrai si le composant comp1 est connecté au composant comp2 par au moins un connecteur.

Reachable(comp1, comp2) Vrai si le composant comp2 est dans une clôture transitive de Connected(comp1,*).

HasProperty(elt, propName) Vrai si l’élément elt possède une propriété appelée propName. HasType(elt, typeName) Vrai si l’élément elt est de type typeName.

SystemName.Connectors L’ensemble des connecteurs du système SystemName. ConnectorName.Roles L’ensemble des rôles du connecteur ConnectorName.

Tableau 1.2: Fonctions simples pour l’expression des contraintes

Les contraintes peuvent être associées à tout élément d’une description ACME. Si une contrainte est attachée à un système, alors elle porte sur tout élément de ce système qu’il soit un composant, un connecteur, . . . . Une contrainte attachée à un composant porte sur ce composant (désigné par self ), ses ports, ses propriétés et ses représentations. Considérons quelques contraintes qui peuvent être associées à un système:

 Connected(client, server) est vrai si les composants client et server sont connectés directement par un connecteur.

 Forall conn : connector in systemInstance.Connectors @ size(conn.roles)= 2 est vrai dans un système où tous les connecteurs sont binaires.

 Forall conn : connector in systemInstance.Connectors @ Forall r : role in conn.Roles @

Exists comp : component in systemInstance.Components @

Exists p : port in comp.Ports @ attached(p, r) and (p.protocol = r.protocol)

est vrai si tous les connecteurs du système sont attachés à un port, et le couple attached(port, role) partage le même protocole. Les protocoles du port et du rôle sont considérés comme des propriétés de ces deux éléments.

Les contraintes peuvent définir également la plage de valeurs de certaines propriétés ou la relation entre différentes propriétés comme par exemple self.throughputRate >= 3095 ou comp.totalLatency = (comp.readLatency + comp.processingLatency + comp.writeLatency).

1.3.5 Analyse

Le langage ACME peut être considéré comme un langage pivot à d’autres ADLs. Il ne propose pas de nouveaux formalismes ou concepts, mais fournit un moyen simple et efficace pour unifier les concepts

(29)

proposés par les ADLs existants. Il offre une base standard pour de nouveaux ADLs et intègre des notions existantes plus spécifiques à un domaine ou à la spécification du comportement d’un composant. Il ne peut pas supporter l’extension d’une architecture sans redéfinir ce qui est déjà existant. ACME est considéré comme le seul ADL capable de spécifier explicitement des familles architecturales comme étant des constructions du langage et supporter leur évolution. Les types de composants et de connecteurs déclarés dans une famille fournissent un vocabulaire pour tous les systèmes déclarés comme membres de la famille.

Mais, ACME ne fournit aucun moyen de spécifier facilement et clairement la dynamique d’un sys-tème. Ce dernier est représenté par un ensemble d’instances de composants liées par des connecteurs. Cette description de l’assemblage reste statique et on ne fournit aucun moyen pour modéliser les change-ments au cours de l’exécution.

Cependant, ce langage permet de réutiliser des éléments définis antérieurement comme par exemple les modèles de conception ou les styles d’architecture.

1.4

Le langage Rapide

Rapide est un langage de description d’architecture développé par l’université de Stanford. Il se base sur la simulation, pour vérifier la validité d’une architecture logicielle. Une architecture Rapide est construite par un ensemble de modules ou composants communiquant par échange de messages ou d’événements. Le langage Rapide est basé sur la notion d’événements, de composant et d’architecture.

Un événement est un objet généré par l’appel d’une action. C’est en fait une information transmise qui peut être une demande de service ou la valeur d’un attribut. Il permet de définir des expressions appelées patrons d’événements. Leur but est de spécifier les contraintes d’un composant en précisant les événements à l’origine des interactions entre les différents composants. Ces expressions utilisent des opérateurs pour définir les dépendances au sein d’un patron: L’opérateur de dépendance causal!, l’opérateur d’indépendancek, l’opérateur de différenceet l’opérateur de simultanéitéand.

Un composant ou module est déclaré à l’aide d’interfaces. Ces dernières renseignent sur le com-portement et sur les services requis ou fournis par les différents composants. Trois types de service sont définis:

 Les services Provides sont fournis par le composant et appelés par d’autres d’une manière syn-chrone.

 Les services Requires sont exigés par le composant et appelés de manière synchone.

 Les Actions sont des communications asynchrones entre les composants. Elles sont divisées en actions in et out modélisant respectivement les événements acceptés et envoyés.

L’interface peut contenir une clause behavior décrivant le comportement observable du composant, comme par exemple l’ordonnancement des événements ou des appels aux services.

Rapide permet également de spécifier les contraintes par la clause constraint. Elles définissent des patrons d’événements qui doivent se produire ou non durant l’exécution. Elles permettent de spécifier des restrictions sur le comportement, comme par exemple fixer un ordre précis pour les événements d’une application.

L’architecture contient les instances des composants et leurs règles de connexions. Une règle est di-visée en deux patrons: un patron à vérifier et un patron à déclencher si le premier est vérifié. L’architecture peut aussi contenir des contraintes sur les connexions. Ces contraintes permettent de restreindre le com-portement de l’architecture en définissant des patrons d’événements qu’on doit appliquer pour certaines connexions. Il existe trois types d’opérateurs de connexion:

(30)

 L’opérateur To met en relation deux composants, un émetteur et un récepteur. Il ne peut y avoir qu’un événement possible vers un composant. Si la partie gauche est vérifiée, la partie droite permet le déclenchement de l’événement vers un seul composant. Il permet de spécifier un appel de type RPC.

 L’opérateur k>, appelé opérateur de diffusion permet de connecter deux patrons quelconques. Quand la partie gauche est vérifiée, tous les événements de la partie droite sont alors déclenchés et envoyés vers les destinataires.

 L’opérateur ), appelé opérateur pipe-line ajoute la notion d’ordre d’évaluation à l’opérateur précédent.

Rapide est capable de modéliser des systèmes dynamiques dont le nombre de composants peut varier lors de l’exécution. Pour transcrire la dynamique, ce langage introduit deux types de variables partic-ulières: les placeholder et les iterator. Les variables placeholder dont le nom commence par ?, désignent un objet qui est susceptible d’être présent. Les variables iterator dont le nom débute par !, désignent l’ensemble des instances d’un certain type. Ainsi, on définit un objet ou un ensemble (pas forcément borné) d’objets devant être présents dans l’application. Il n’est pas obligatoirement nécessaire de définir exactement les instances de composants présents. Cela peut se faire dynamiquement à l’exécution. Les règles de création définissent quand, pendant l’exécution, les composants d’un type doivent être créés ou détruits.

1.4.1 Evénements

Un calcul ou une exécution dans Rapide représente un ensemble d’événements reliés par des ordres partiels. Un événement est un objet généré par l’appel d’une action. Chaque appel d’une action génère un événement distinct des précédents. Un événement peut être défini comme un triplet comportant le nom de l’action qui l’a généré, des paramètres et une information sur l’événement à l’origine de l’action. L’ensemble des événements produits pendant l’exécution avec leurs relations causales et temporelles est appelé poset (partially ordered set).

Relations entre les événements Rapide fournit deux types de relations entre les événements:

 les dépendances appelées relations causales, elles indiquent quel événement lance l’autre,  le temps qui représente l’instant d’occurrence de l’événement tout en respectant des horloges. Ces relations définissent des ordres partiels entre les différents événements.

Génération d’événements dépendants Les dépendances entre les événements sont définies par trois types de caractéristiques [Luc96]:

 Règles et processus réactifs: Les règles réactives représentent les règles de transition dans les comportements de l’interface, les règles de connexion dans l’architecture et les règles de mappings. Les processus réactifs sont les when dans les modules.

 Code séquentiel : Les événements générés par des exécutions séquentielles possèdent une dépen-dance linéaire représentée par leur ordre de génération.

 Objets ref : Un type d’objet ref définit la dépendance entre les événements générés par les proces-sus qui partagent l’objet.

(31)

Génération d’événements temporisés Un type ou un module peut être temporisé par une horloge; les événements reçoivent des valeurs de début et de fin pour chaque horloge associée. Si une action A peut durer d unités de temps tout en respectant l’horloge C, alors pour un événement E associé à l’exécution de A, on a: C :Start(E)+d = C :Finish(E). Si aucune durée n’est définie, les événements peuvent alors être générés infiniment rapidement.

Observation d’événements Les événements générés par un module sont visibles à et peuvent être observés par, d’autres modules. Ils sont disponibles pour observation quand d’autres modules appellent les fonctions de l’interface provides et les actions in. L’observation peut se faire selon l’ordre causal des événements, c’est à dire qu’un événement ne peut être observé qu’après les événements dont il dépend. Ce mécanisme est appelé observation ordonnée.

1.4.2 Exemple

L’exemple client/serveur peut alors être modélisé en Rapide comme suit:

type Client is interface

action out request(x: Data) action in C-S-client(x: Data); end Client;

type Server is interface

action in provide(x: Data); action out C-S-server(x: Data); behavior

(?x in Data) C-S-server(?x) ) provide(?x);

end Server;

architecture ClientServer is

?c: Client; /* Une instance de Client

!s: Server; /* Toutes les instances de Server ?x: Data; /*Un bloc de paramètres de type Data connect

?c.request(?x) ) !s.provide(?x); /* règle d’interconnexion. Si un

/* événement request est transmis, /* alors tous les serveurs de /* l’application le recevront end architecture ClientServer;

Ici, ?c est une variable placeholder qui fait référence à une instance de type Client. !s est une variable iterator qui désigne toutes les instances de Server présentes dans l’application. Ces variables définissent respectivement un objet devant être présent dans l’architecture et un ensemble d’objets d’un certain type. Il n’est pas nécessaire de définir les instances de composants présents, car cela peut se faire dynamiquement au fur et à mesure de l’exécution.

La partie connexion contient les règles de connexion et les règles de création. Les règles de création définissent les conditions sur les événements qui guident la création de nouveaux composants. Dans l’exemple, la règle de création spécifie l’existence d’un client ?c qui envoie une requête avec une donnée de type Data. La partie droite de la règle est exécutée, elle spécifie que tous les serveurs !s du système reçoivent la même donnée ?x. Ces règles peuvent être conditionnées par une clause where.

(32)

1.4.3 Expression des propriétés dynamiques

Un calcul ou une exécution consiste en un ensemble d’événements S, un ordre partiel de dépendance d et un ordre partiel de temps

C pour les horloges C. L’expressionA

C

Best définie parC :Finish(A)C :Start(B).

Les posets générés par Rapide satisfont les deux invariants de consistence suivants:

 Invariant de consistence entre les dépendances et le temps: Pour tous les événements A, B et pour chaque horloge C, on aA 

d

B ! A  C

B. Ceci signifie qu’en respectant chaque horloge, un événement dans le passé ne doit pas dépendre d’un événement dans le futur. Cet invariant peut être représenté en Rapide par la contrainte:

never

(?A in event(), ?B in event(), ?C in Clock)

?A -> ?B where not ?C.Finish(?A)  ?C.Start(?B);

 Invariant de consistence entre les ordres temporels: Pour tous les événements A, B et les horloges C, C’, on aA<

C

B !notB < C

0 A, avec<l’opérateur “après”. Ceci signifie qu’un événement qui précède un autre en respectant une horloge, ne doit pas suivre ce dernier en respectant l’autre horloge. Cet invariant peut être représenté en Rapide par la contrainte suivante, oùreprésente l’opérateur “distinct”:

never

(?A in event(), ?B in event(), ?C1 in Clock, ?C2 in Clock) ?A ~ ?B where (?C1.Finish(?A) < ?C1.Start(?B) and

not ?C2.Finish(?B) < ?C2.Start(?A));

Pour plus de détails sur les syntaxes Rapide, le lecteur est invité à consulter l’article [LV95].

1.4.4 Analyse

Rapide est un langage dont l’outillage fournit des capacités intéressantes pour la modélisation et l’analyse. Grâce à la simulation, il permet de vérifier la validité d’une architecture logicielle en confrontant l’ensem-ble des propriétés obtenues, formant un poset, aux propriétés souhaitées. Il supporte des communications synchrones, asynchrones ainsi que des opérateurs pour regrouper les destinataires. Ce langage offre une forte expression de la dynamique d’un système avec la possibilité de créer, de supprimer ou de raffiner une instance d’un composant.

Il supporte le raffinement et la traçabilité d’une manière étendue. Il permet l’expression des rela-tions de raffinement sur les architectures selon différents niveaux d’abstraction et génère des simularela-tions comparatives d’architectures. Bien que Rapide fut d’abord considéré comme un ADL dont les carac-téristiques gênent la mise à l’échelle, il a été utilisé pour spécifier les systèmes émanant du monde réel. Il supporte des manipulations dynamiques contraintes sur les architectures, où tous les changements au cours de l’exécution doivent être connus à priori. Il supporte également les configurations condition-nelles. Rapide fournit un langage temporisé de posets pour contraindre les configurations. Il permet aussi la configuration directe des propriétés non fonctionnelles d’une architecture, tout en modélisant les informations temporelles dans son langage de contraintes.

Mais, il ne permet pas de décrire explicitement un connecteur et de le typer. Ceci empêche la réutil-isation des connecteurs comme dans d’autres ADLs. Les interactions sont décrites par la description de l’architecture.

(33)

1.5

Le langage AADL

AADL (Architecture Analysis & Design Language) [SA04] signifiait initialement Avionics Architecture Description Language. Il est issu des travaux réalisés sur MetaH [Ves98] qui est un langage de descrip-tion d’architectures des systèmes avioniques, développé dans le cadre militaire. Pratiquement, AADL couvre tous les systèmes embarqués temps réel, et pas seulement les systèmes avioniques.

Il fournit des concepts de modélisation formelle permettant de décrire et d’analyser les architectures des systèmes en distinguant les composants et leurs interactions. Ce langage inclut des abstractions de composants logiciels, matériels et systèmes permettant de :

 spécifier et analyser les systèmes temps réel embarqués, les systèmes complexes.  faire le mapping entre les éléments logiciels et matériels.

Le langage AADL est dédié surtout à l’analyse des systèmes basés sur les modèles et à la spécification des systèmes embarqués temps réel complexes. La description d’une architecture en AADL consiste à décrire ses composants et leur composition sous forme d’une arborescence.

AADL ne vise que la description des aspects architecturaux de l’application. Le comportement des entités n’y est pas spécifié directement. Les spécifications sont structurées sous forme de paquetages (packages) définissant un espace de nommage pour les entités qui y sont définies. Ils rassemblent un ensemble de composants, leur implémentation, leurs canaux de communication, ainsi que les librairies annexes qui leur sont associées. Ces dernières représentent un moyen de spécialisation et d’adaptation du langage aux besoins des différentes applications. Elles permettent d’introduire des constructions d’autres langages dans les spécifications AADL.

1.5.1 Composants

Un composant AADL comprend deux parties: le type et l’implémentation. Le type correspond à l’interface fonctionnelle du composant, visible des autres composants. Une description du type revient à spécifier le composant et exprimer à quoi il ressemble vu de l’extérieur. L’interface d’un composant est décrite sous forme de features (points d’interaction de contrôle et de données), de flow specifications (description du comportement observable du composant) et de properties (différents attributs du com-posant). Elle doit être respectée par toutes les implémentations. Dans la pratique, les descriptions du type et de l’implémentation pourront être faites par des personnes différentes, chacune ayant en charge une étape dans le raffinement de la description de l’architecture du plus haut niveau jusqu’aux moindres détails.

L’implémentation représente la structure interne d’un composant sous forme d’une configuration de sous-composants. Elle décrit la façon dont les sous-composants échangent des données et des flots de contrôle. Cette description est enrichie par un ensemble de modes de fonctionnement du composant initial. Un changement de mode de ce dernier implique l’activation/désactivation de sous-composants, le changement des valeurs de certaines propriétés, . . . Contrairement à d’autres ADLs, AADL permet à une interface fonctionnelle d’avoir des implémentations multiples.

Chaque composant appartient à une catégorie prédéfinie choisie parmi les catégories logicielle, matérielle ou composite décrites dans les paragraphes suivants.

Catégorie logicielle Elle comprend les notions de thread, groupe de threads, processus, données et sous-programme.

 Thread: Composant actif pouvant s’éxecuter d’une façon concurrente et être organisé dans des groupes.

Figure

Figure 1: Etapes de vérification d’un système
Figure 1.4: Transformations Cotre
Figure 2.1: Etapes de développement en B.
Tableau 2.1: Liste des substitutions primitives.
+7

Références

Documents relatifs

Since acetate challenge reduces final cell densities in a variety of bacteria (Lasko et al. 2000; Steiner and Sauer 2003), we first determined final optical densities

Fressengeas Band Transport Schematics Carrier Generation Charge Transport Electro-optics Harmonic illumination Two Wave Mixing.. Introducing Donors

Ces premiers calculs apportent déjà une information im- portante : les résonances dans le coefficient de transmission ne peuvent pas être associées à une seule orbitale

Rendu par la Cour européenne des droits de l’homme le 14 mars 2013, l’arrêt Eon contre France ] réaffirme la large protection dont bénéficie le discours politique et satirique

Copyright and moral rights for the publications made accessible in the public portal are retained by the authors and/or other copyright owners and it is a condition of

At each position for each amplitude of electric current (3 to 14 tested amplitudes per anatomical position; mean: 5,78), up to the maximum stimulation threshold (3mA),

The concentration of ions, electrons and charged aerosols has been obtained in the lower ionosphere of Mars (0–70 km) with a new photochemical model that takes into account the effect

ANOVA: Analysis of variance; CSU: Colorado State University; DS1- DS6: Datasets 1 –6; EIP: Extrinsic incubation period; enPLS: Ensemble PLS; iPLS: Interval PLS; IRSS: Institute