Vous êtes sur la page 1sur 144

Université de Dschang

Faculté des Sciences


Master Pro

Cours : Systèmes Embarqués Temps réel

Volume : 45h (3 crédits)

Enseignant : Elie FUTE T., PhD

Pré requis (codes) : Système d’exploitation, pseudocode.

Objectifs du cours : L’objectif de ce cours est d’initier l’étudiant aux concepts et


notions sur les systèmes embarqués. Il devra être en mesure de maîtriser la
programmation des processus et les outils (environnements, langages de
programmation, …) et mécanismes appropriés.

DESCRIPTIF DU COURS

Chapitre 1 : Généralités sur les systèmes embarqués

Chapitre 2 : Développement des Systèmes embarqués temps réel

Chapitre 3 : Spécification fonctionnelle

Chapitre 4 : Conception à l’aide d’AADL

Chapitre 5 : Architecture matérielle, Système d’exploitation et Programmation des


systèmes multitâches

Références bibliographiques (Auteurs, titre, n° édition, année, éditeur)


1. Pierre Ficheux, Linux embarqué, Ed. Eyrolles, 2005.
2. Ch. Bonnet, I. Demeure. Introduction aux systèmes temps réel. Edition HERMES
3. J. Ganssle. The Art of Designing embedded Systems. Editions Butterworth-
Heinemann.
4. Addison-Wesley. Introduction to the SAE Architecture Analysis & Design
Language. 2012.
5. Cottet Francis, Grolleau Emmanuel, Gérard Sébastien, Hugues Jérôme,
Ouhamou Yassine and Tucci Sarah. Systèmes temps réel embarqués:
spécification, conception, implémentation et validation temporelle. 2014.
Page 1 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Chapitre 1 : Généralités sur les systèmes embarqués
1. Introduction aux systèmes embarqués
Ce chapitre est une introduction aux systèmes enfouis et embarqués, c'est-à-dire aux
ordinateurs invisibles qui sont intégrés dans un grand nombre d'objets utilisés pour
communiquer (téléphones portables, PDA, télévision numérique, etc.), dans les
systèmes de transports (automobile, train, avion), dans les infrastructures grandes ou
petites (contrôle des centrales nucléaires, automatismes industriels, etc.). Il présente
les spécificités de ces systèmes en termes de coût, de taille, de contraintes
énergétiques, de performances, avec notamment les contraintes de fonctionnement
temps réel qui existent pour un certain nombre de ces systèmes.

Les systèmes embarqués et/ou intégrés rappellent par certains côtés les ordinateurs
d'antan, par les ressources limitées dont ils disposent. Ceci conduit à des besoins de
compacité de code et à une exploitation optimisée du matériel qui n'est plus de mise
dans les systèmes informatiques actuels où l'abondance de ressources de calcul et de
mémorisation est la règle. Que l'on ne s'y trompe pas cependant : comparaison n'est
pas raison, et les systèmes informatiques embarqués d'aujourd'hui sont souvent bien
plus performants que leurs prédécesseurs non embarqués, mais ils sont aussi
extrêmement contraints, et les quelques kilo-octets, microsecondes ou milliwatts qui
sont épargnés par un système d'exploitation ad hoc seront toujours utiles à
l'application, pour permettre de faire fonctionner mieux, de manière plus sûre et plus
longtemps un appareillage. Globalement, le but d'un système d'exploitation consiste à
abstraire et partager les ressources matérielles pour simplifier l'écriture des
applications. Les systèmes d'exploitation des ordinateurs modernes visent à optimiser
les temps de réponses moyens pour l'utilisateur face à un clavier et une souris, quitte
à requérir de nombreuses ressources à un instant donné pour garantir cet objectif.
Dans le monde de l'embarqué, un tel objectif n'a souvent pas de sens, car il n'y a pas
d'utilisateur à proprement parler et la notion assez subjective et mal formalisée de
temps de réponse acceptable est clairement inadaptée. Les systèmes d'exploitation
pour les systèmes embarqués ont en général besoin de contraintes clairement
précisées pour réaliser les services qu'ils sont sensés fournir. Ces critères peuvent être
liés à la performance temporelle, par exemple sur la latence minimale et maximale du
traitement des interruptions, en espace mémoire maximal requis, en capacité de
contrôle du matériel en vue par exemple de la basse consommation, etc. Les systèmes
pour lesquels la réalisation d'une action doit être faite dans un laps de temps prédéfini,
potentiellement de manière répétée, sont dits temps réel. Ils ont une importance
particulière dans le monde de l'embarqué, car le contrôle du déclenchement d'un air
Page 2 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
bag ou le décodage d'une vidéo n'ont d'intérêt que si l'action est réalisée dans le temps
imparti.

Par ailleurs, les méthodes de construction des systèmes d'exploitation ont évolué au
cours du temps et permettent aujourd'hui de n'inclure que les parties qui sont utiles à
la fois à l'application, si celle-ci est connue d'avance, ce qui est le cas bien souvent, et
au matériel. Elles permettent ainsi de construire un système « sur mesure » qui
maximise l'efficacité de l'appareil. L'intégration posant des questions cruciales de
rendement et de flexibilité, les systèmes intégrés actuellement en cours de conception
tendent à inclure plusieurs (voire de nombreux) processeurs. La gestion de ces
nombreux processeurs, qui peuvent être de type identiques ou différents, par exemple
un processeur à usage général et un processeur de traitement de signal, a clairement
un impact sur les systèmes d'exploitation destinés à être embarqués.

La plupart des applications intégrées actuelles font appel à des algorithmes qui sont
très gourmands en termes de ressources mémoire et de capacité de calcul. Ainsi, les
systèmes électroniques embarqués, du moins ceux qui visent les appareillages grand
public, doivent non seulement être d'un coût très faible mais ils doivent de plus fournir
une performance très élevée. Ce faible coût implique une faible consommation, car
cela seul permet l'utilisation de boîtiers plastique à faible coût (par opposition aux
boîtiers en céramique) et l'absence de radiateur et de ventilateur. La solution utilisée
dans le passé pour satisfaire ces contraintes a été de développer du matériel ad hoc :
il est généralement admis que le nombre de MIPS (millions d'instructions par seconde)
par watt (unité de mesure de la performance vis-à-vis de la consommation) est de deux
à trois ordres de grandeur plus élevé dans le matériel spécialisé que dans le logiciel.
Cependant, les applications récentes sont peu pérennes à cause de l'évolution
continue et en profondeur des différents standards sur lesquels elles se basent. Ainsi,
les solutions purement matérielles ne sont plus acceptables car elles ne permettent
pas une flexibilité suffisante pour s'adapter au besoin, et les solutions au moins
partiellement programmables sont maintenant la règle. En conséquence, il est à
présent reconnu que des systèmes d'exploitation dédiés sont nécessaires.

1.1 Définitions et caractéristiques des systèmes embarqués


Un Système Embarqué (SE) peut être défini comme le système (ensemble physique,
électronique et informatique) autonome, embarqué dans le produit (souris, clavier,
montre, voiture, fusée spatiale, carte bancaire, etc la liste est très longue), dédié à une
tâche bien précise. A l'image des produits, la conception d’un système embarqué peut
offrir de multiples facettes. Il peut être communicant (téléphone mobile, Ebooks,
Page 3 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
montre connectée, IOT, etc) en utilisant divers protocoles de communication sans fil
ou filaire (WIFI, Bluetooth, 2/3/4G, LORA, Ethernet, USB, etc), autonome sur réserve
par stockage d'énergie électrique (tablette, souris, voiture, etc), portable dans la main
(carte bancaire, clé de voiture, etc), faiblement encombrant (lecteur MP3, carte
monétique, etc) comme très encombrant (fusée spatiale, avion, voiture, etc).

Il suffit de regarder autour de soi au quotidien pour voir et avoir d’autres SE sous ses
yeux. Vous êtes réveillé le matin par votre radio-réveil ; c'est un système
embarqué...Vous programmez votre machine à café pour avoir un bon petit serré ;
c'est un système embarqué...Vous allumez la télévision et utilisez votre télécommande
; ce sont des systèmes embarqués...Vous prenez votre voiture et la voix suave du
calculateur vous dit que vous n'avez pas mis votre ceinture (pas bien) ; c'est un système
embarqué...Vous appelez votre patron avec votre téléphone portable pour signaler
que vous serez en retard (pas bien) ; c'est un système embarqué ! On peut continuer à
énumérer tous les systèmes embarqués croisés sans le savoir au cours d'une journée.
Bref, les systèmes embarqués nous entourent et nous sommes littéralement envahis
par eux, fidèles au poste et prêts à nous rendre service. On en croise des dizaines par
jour sans le savoir avant de retrouver son seul et unique PC.
Ils sont donc partout, discrets, efficaces et dédiés à ce à quoi ils sont destinés.
Omniprésents, ils le sont déjà et le seront de plus en plus. On parle en fait
d'informatique (et d'électronique) diffuse ou ubiquitous computing/ubiquitous
hardware dans la langue de Shakespeare... Ils sont bourrés d'électronique plus ou
moins complexe et d'informatique plus ou moins évoluée.
Un SE ne possède généralement pas des entrées/sorties standards et classiques
comme un clavier ou un écran d'ordinateur. Le système matériel et l’application sont
intimement liés, le logiciel embarqué étant enfoui, noyé dans le matériel. Le matériel
et le logiciel ne sont pas aussi facilement discernables comme dans un environnement
de travail classique de type ordinateur PC.

Page 4 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Un SE peut encore être défini comme un système informatisé spécialisé qui constitue
une partie intégrante d’un système plus large ou une machine. Typiquement, c’est un
système sur un seul processeur et dont les programmes sont stockés en ROM. A priori,
tous les systèmes qui ont des interfaces digitales (i.e. montre, caméra, voiture…)
peuvent être considérés comme des SE.
Certains SE ont un système d’exploitation et d’autres non car toute leur logique peut
être implantée en un seul programme.
Un système embarqué peut également être vu comme une combinaison de logiciel et
matériel, avec des capacités fixes ou programmables, qui est spécialement conçu pour
un type d’application particulier. Les distributeurs automatiques de boissons, les
automobiles, les équipements médicaux, les caméras, les avions, les jouets, les
téléphones portables et les PDA sont des exemples de systèmes qui abritent des SE.
Les SE programmables sont dotés d’interfaces de programmation et leur
programmation est une activité spécialisée.
Un système embarqué est une composante primordiale d’un système (i.e. un avion,
une voiture…) dont l’objectif est de commander, contrôler et superviser ce système.

Les propriétés communes aux systèmes embarqués sont :


- Encombrement mémoire (mémoire limitée, pas de disque en général)
- Consommation d’énergie (batterie : point faible des SE)
- Poids et volume
- Autonomie
- Mobilité
- Communication (attention : la communication affecte la batterie)
- Contraintes de temps réel
- Contraintes de sécurité
- Coût de produits en relation avec le secteur cible

Les principales caractéristiques d'un système embarqué sont les suivantes :


 C'est un système principalement numérique.
 Il met en œuvre généralement un processeur.
 Il exécute une application logicielle dédiée pour réaliser une fonctionnalité
précise et n'exécute donc pas une application scientifique ou grand public
traditionnelle.
 Il n'a pas réellement de clavier standard (Bouton Poussoir, clavier matriciel...).
L’affichage est limité (écran LCD…) ou n’existe pas du tout.
 Ce n’est pas un PC en général mais des architectures similaires (x86) basse
consommation sont de plus en plus utilisées pour certaines applications
embarquées.

De ce constat, on peut voir :

Page 5 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 Qu'un PC standard peut exécuter tout type d'applications car il est généraliste
alors qu'un système embarqué n'exécute qu'une application dédiée.
 Que l’interface IHM peut être aussi simple qu’une led qui clignote ou aussi
complexe qu’un cockpit d'avion de ligne.
 Que des circuits numériques ou des circuits analogiques sont utilisés en plus
pour augmenter les performances du système embarqué ou sa fiabilité.

1.1.1 Historique

L'omniprésence des systèmes embarqués dans notre vie est liée à la révolution
numérique opérée dans les années 1970 avec l'avènement des processeurs. Les
processeurs, de plus en plus rapides, puissants et bon marché ont permis cette
révolution et aussi le boom du marché de l'embarqué. Ceci se confirme au travers de
la loi empirique de Gordon Moore, cofondateur d'Intel, qui stipule que pour une
surface de silicium donnée, on double le nombre de transistors intégrés tous les 18
mois ! La figure ci-dessous montre cette évolution inexorable.

En 1999, il a été vendu pour le marché de l'embarqué :


• 1,3 milliard de processeurs 4 bits.
• 1,4 milliard de processeurs 8 bits.
Page 6 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
• 375 millions de processeurs 16 bits.
• 127 millions de processeurs 32 bits.
• 3,2 millions de processeurs 64 bits.
A côté de cela, à cette époque, il a été vendu seulement 108 millions de processeurs
(famille x86) pour le marché du PC grand public !
Pour 2004, il a été vendu environ 260 millions de processeurs pour le marché du PC
grand public à comparer aux 14 milliards de processeurs tout type confondu
(microprocesseur, microcontrôleur, DSP) pour le marché de l'embarqué. Le marché des
processeurs pour l'embarqué selon Electronics.ca Research Network devrait croître de
6 % en 2005 pour un chiffre d'affaire mondial de 18 milliards USD ! Les chiffres parlent
d'eux-mêmes. Le marché du processeur pour les PC grand public n'est que la partie
émergée de l'iceberg et n'est rien par rapport au marché de l'embarqué qui est la partie
immergée de l'iceberg...
On peut aussi tirer le constat actuel suivant :
 Moins de 2 % des processeurs vendus sont pour le marché du PC contre 98 %
pour l'embarqué. On utilise massivement pour le PC grand public le système
d'exploitation commercial bien connu.
 Pour les 98 % autres processeurs vendus, on utilisera généralement un autre
système d’exploitation. On trouvera ici dans 60 % des cas un système
d'exploitation commercial spécialisé pour l'embarqué (VxWorks, QNX...). Pour
le reste, il s'agit d'un système d'exploitation home made mais de plus en plus
optent pour des systèmes d'exploitation libres comme Linux pour l'embarqué.
 Moins de 10 % des processeurs vendus sont des processeurs 32 bits pour près
de 31 % du chiffre d'affaire sur les processeurs. Cette part du chiffre d'affaire
est estimée à près de 48 % pour 2008 : cela montre la migration rapide vers ces
processeurs 32 bits dans l'embarqué, condition nécessaire pour pouvoir mettre
en œuvre Linux.
 Si l'on regarde le prix moyen d'un processeur tout type confondu, on arrive à 6
USD par unité à comparer au prix moyen de 300 USD par unité pour un
processeur pour PC. Le marché du processeur pour PC (458 millions de PC
vendus en 2020) est très faible en volume mais extrêmement lucratif ! Ces
quelques chiffres permettent bien de prendre conscience de l'importance du
marché de l'embarqué et de mettre fin à l'idée qu'en dehors du marché du PC,
point de salut.

Les grands secteurs de l'embarqué concernent les domaines suivants :

 Jeux et calcul général : application similaire à une application de bureau mais


empaquetée dans un système embarqué : jeux vidéo, set top box...
 Contrôle de systèmes : automobile, process chimique, process nucléaire,
système de navigation...

Page 7 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 Traitement du signal : radar, sonar, compression vidéo...
 Communication et réseaux : transmission d’information et commutation,
téléphonie, Internet...

Système embarqué typique

On retrouve en entrée des capteurs généralement analogiques couplés à des


convertisseurs A/N. On retrouve en sortie des actionneurs généralement analogiques
couplés à des convertisseurs N/A. Au milieu, on trouve le calculateur mettant en œuvre
un processeur embarqué et ses périphériques d'E/S. Il est à noter qu'il est complété
généralement d'un circuit FPGA jouant le rôle de coprocesseur afin de proposer des
accélérations matérielles au processeur.

Page 8 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
On retrouve en fait un beau système d'asservissement entre les entrées et les sorties !
Il est à noter que l'expression la plus simple de cette figure est de considérer comme
capteurs, des interrupteurs et comme actionneurs, des Leds et l'on retrouve toutes les
manipulations de TP que vous avez pu rencontrer à l'école ou à l'université en
électronique numérique et en informatique industrielle...
Sur le schéma théorique ci- dessus se greffe un paramètre important : le rôle de
l'environnement extérieur. Contrairement au PC ronronnant bien au chaud dans un
bureau, un système embarqué doit faire face à des environnements plus hostiles. Il
doit faire face à un ensemble de paramètres agressifs :
 Variations de la température.
 Vibrations, chocs.
 Variations des alimentations.
 Interférences RF.
 Corrosion.
 Eau, feu, radiations.

L'environnement dans lequel opère le système embarqué n'est pas contrôlé ou


contrôlable. Cela suppose donc de prendre en compte ce paramètre lors de sa
conception. On doit par exemple prendre en compte les évolutions des
caractéristiques électriques des composants en fonction de la température, des
radiations...Pense-t-on à tout cela lorsque l'on conçoit une carte mère de PC ?

Enfin pour terminer cette partie, les systèmes embarqués sont aujourd'hui fortement
communicants. Cela est possible grâce aux puissances de calcul offertes par les
processeurs pour l'embarqué (32 bits en particulier) et grâce aussi à l'explosion de
l'usage la connectivité Internet ou connectivité IP. La connectivité IP permet
fondamentalement de contrôler à distance un système embarqué par Internet. Ce
n'est en fait que l'aboutissement du contrôle à distance d'un système électronique par
des liaisons de tout type : liaisons RS.232, RS.485, bus de terrain...
Cela permet l'emplio des technologies modernes du web pour ce contrôle à distance
par l'utilisateur : il suffit d'embarquer un serveur web dans son équipement
électronique pour pouvoir le contrôler ensuite à distance, de n'importe où, à l'aide d'un
simple navigateur. Il n'y a plus d'IHM spécifique à concevoir pour cela, ce rôle étant
rempli par le navigateur web.
Cela est une réalité : les chauffagistes proposent maintenant des chaudières pouvant
être pilotées par le web !
Il faut aussi noter la montée en puissance des communications sans fil dans l'embarqué
au détriment des communications filaires pour limiter le câblage et faciliter la mise en
place du système embarqué. Le Wifi et toutes les normes de réseaux sans fil IEEE
802.15 comme Zigbee ont le vent en poupe dans l'embarqué et surtout en domotique
(réseaux de capteurs sans fil par exemple).

Page 9 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Mais ne nous méprenons pas sur ces facilités et commodités, cela a bien sûr un revers
: la sécurité du système embarqué puisque connecté à Internet.
La sécurité des systèmes embarqués est donc cruciale aujourd'hui et doit être prise en
compte dès leur conception sous peine de voir apparaître une armée de hackers
prompts à venir planter votre belle chaudière high tech !

1.3 L'art de bien concevoir un système embarqué


C'est bien là le point le plus excitant et qui est l'essence même de ce Hors-Série. Du
point de vue technique, la conception d'un système embarqué demande à son
concepteur d'être pluridisciplinaire : électronique, informatique, réseaux, sécurité
n'ont pas de secrets pour lui. Mais le concepteur se doit aussi d'être un bon
gestionnaire car concevoir un système embarqué revient finalement à un exercice
d'optimisation : minimiser les coûts de production pour des fonctionnalités optimales.

Le système embarqué se doit d'être :


 Robuste.
 Simple. La simplicité est gage de robustesse.
 Fiable.
 Fonctionnel. Le système doit toujours fonctionner correctement.
 Sûr surtout si la sécurité des personnes est en jeu.
 Tolérant aux fautes.

D'autres contraintes sont aussi à prendre en compte :


 L’encombrement.
 Le poids.
 Le packaging : difficulté de faire cohabiter dans un faible volume, électronique
analogique, électronique numérique et RF sans interférences.
 L’environnement extérieur.
 La consommation électrique. Le système embarqué nomade doit être faible
consommation car il est alimenté par des batteries. Une consommation
excessive augmente le prix de revient du système embarqué car il faut alors des
batteries de plus forte capacité.
 Le coût. Beaucoup de systèmes embarqués sont fabriqués en grande série et
doivent avoir des prix de revient extrêmement faibles.

Page 10 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 Le temps de développement. Dans un marché concurrentiel et de niches, il
convient d'avoir un système opérationnel le plus rapidement possible pour être
le premier sur le marché.

Devant toutes ces contraintes, le concepteur adopte des règles de bon sens :
 Faire simple.
 Utiliser ce que l'on a déjà fait ou fait par d'autres. On appellera cela
pudiquement du design reuse.
 Ne pas se jeter sur les technologies dernier cri. Quelle est leur pérennité dans le
temps ?
 Ne pas se jeter sur le dernier composant sorti surtout s'il est grand public. Quelle
est sa pérennité dans le temps surtout s'il l'on travaille pour la défense où l'on
demande une maintenance sur 30 ans !
 Utiliser des technologies éprouvées qui ont fait leur preuve. Ces technologies
peuvent d'ailleurs avoir plusieurs générations de retard par rapport à leurs
homologues grand public.
Pour le grand public, le concepteur de systèmes embarqués peut sembler faire de
l'inertie face aux nouvelles technologies mais il faut le comprendre : c'est pour le bien
du système qu'il conçoit surtout si la sécurité des personnes est en jeu…

1.4 Systèmes embarqués : gérer la criticité


Le développement des systèmes embarqués, dont les domaines d'applications,
d'abord limités à l'aérospatiale et à l'aviation, se sont étendus à des domaines grand
public (téléphonie, jeux vidéo), implique la prise en compte de contraintes diverses et
hétérogènes.

Un système critique est un système dont une panne peut avoir des conséquences
dramatiques, tels des morts ou des blessés graves, des dommages matériels
importants, ou des conséquences graves pour l'environnement. Par opposé, un
système non critique va correspondre aux applications dédiées aux loisirs (les jeux
vidéo par exemple). Ainsi, sont par exemple critiques les logiciels intervenant dans :

 les systèmes de transport : pilotage des avions, des trains, logiciels embarqués
automobiles ;
 la production d'énergie : contrôle des centrales nucléaires ;

Page 11 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 la santé : chaînes de production de médicaments, appareil médicaux (à
rayonnement ou contrôle de dosages) ;
 le système financier : paiement électronique ;
 les applications militaires.

En fait, de par la diffusion inexorable et généralisée des technologies logicielles et donc


de l'impact plus massif d'un défaut quelconque, la notion de criticité tend à se diffuser
même s'il s'agit plus souvent d'un risque de désorganisation sur le plan économique,
social ou financier.

1.4.1 Bien évaluer le niveau de criticité


Il existe différents niveaux de criticité d'un système, suivant l'impact possible des
dysfonctionnements. On apprécie ainsi différemment, par exemple, un
dysfonctionnement provoquant des pertes coûteuses, mais sans mort d'homme (cas
des missions spatiales non habitées) et un dysfonctionnement provoquant des morts
dans le grand public (cas des vols commerciaux). De même, on apprécie différemment
des dysfonctionnements faisant courir un danger de mort ou de blessure à des
humains, ou des dysfonctionnements augmentant la charge de travail et les risques
d'erreur de pilotage des opérateurs humains.

Prenons l'exemple de l'aviation. En aviation, la norme DO-178B sépare les logiciels


avioniques en 5 catégories :

 niveau A : un dysfonctionnement du logiciel provoquerait ou contribuerait à une


condition de perte catastrophique de l'appareil ;
 niveau B : un dysfonctionnement du logiciel provoquerait ou contribuerait à une
condition dangereuse ou un dysfonctionnement sévère et majeur de l'appareil
;
 niveau C : un dysfonctionnement du logiciel provoquerait ou contribuerait à un
dysfonctionnement majeur de l'appareil ;
 niveau D : un dysfonctionnement du logiciel provoquerait ou contribuerait à un
dysfonctionnement mineur de l'appareil ;
 niveau E : aucun impact sur le fonctionnement de l'appareil ou la charge de
travail du pilote.

La criticité du système définit un niveau d'exigence par rapport à la tolérance aux


pannes. Elle aura des conséquences sur l'évaluation des niveaux d'assurance pour la
sécurité.

Page 12 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Un autre aspect de la criticité s’applique aux logiciels : un logiciel critique est un logiciel
dont le mauvais fonctionnement aurait un impact important sur la sécurité ou la vie
des personnes, des entreprises ou des biens. L'ingénierie logicielle pour les systèmes
critiques est particulièrement difficile, dès lors que les systèmes sont complexes, mais
l'industrie aéronautique, ou plus généralement l'industrie du transport de passagers, a
réussi à définir des méthodes pour réaliser des logiciels critiques. Des méthodes
formelles peuvent servir à améliorer la qualité du logiciel des systèmes critiques. Le
coût de réalisation d'un logiciel de « système critique » est beaucoup plus élevé que
celui d'un logiciel ordinaire.

1.4.2 Des contraintes particulières de développement


Les précautions à prendre dans le développement d'un logiciel critique sont
généralement fixées par une norme, et dépendent du domaine d'application et surtout
de la criticité du logiciel. Généralement, on trouve des impératifs :

 de documentation : tous les composants doivent être documentés, notamment


dans l'interface qu'ils présentent aux autres composants ;
 de traçabilité : le système doit répondre à chaque spécification, soit dans sa
mise en œuvre, soit dans des spécifications intermédiaires (auquel il faudra
aussi répondre) ; on doit donc avoir une chaîne complète de traçabilité entre les
spécifications fonctionnelles et la mise en œuvre du système ;
 de limitation des pratiques dangereuses : certaines techniques de
programmations, sources possibles de problèmes, sont interdites, ou du moins
leur usage doit être justifié par des raisons impératives (ex: allocation
dynamique de mémoire, procédures récursives) ;
 de test : on devra essayer le logiciel dans un grand nombre de configurations,
qui couvrent tous les points et un maximum des chemins de fonctionnement du
programme ;
 d'utilisation d'outils de développement et de vérification eux-mêmes sûrs.

Les systèmes les plus critiques sont généralement soumis à des autorités de
certification, qui vérifient que les impératifs prévus par la norme ont été remplis.
L'usage de méthodes formelles pourra, à l'avenir, être encouragé, voire imposé.

1.5 Nécessité d’une méthodologie de conception


Pour concevoir un système, l’ingénieur dispose de techniques et de moyens variés.
Quelle que soit la nature ou la complexité de ces systèmes, il se doit de respecter un
certain nombre d’exigences:

Page 13 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
- satisfaire les besoins du client : en d’autres termes, le système final doit être
conforme aux exigences de fonctionnement établies dans le cahier des charges,
- respecter les délais et les coûts,
- satisfaire des critères de qualité, en particulier en termes de sûreté de
fonctionnement.

Le respect de ces contraintes face à la complexité des systèmes mécatroniques passe


nécessairement par la définition de « règles » permettant de passer rigoureusement
de l’expression d’un besoin à la réalisation du produit. L’ensemble des règles et des
méthodes appliquées constitue la méthodologie.
Des études montrent que les principaux défauts de conception résultent:
- de besoins mal spécifiés,
- d’une déformation des besoins dans le temps,
- d’une modification sauvage, parfois faite avec de bonnes intentions,
- de la perte de savoir-faire,
- du pari technologique (qui consiste à penser que si quelque chose marche pour
3m/s, elle devrait marcher pour 10m/s…),
- d’une mauvaise définition d’interfaces,
- de la pression de la concurrence,
- d’une modification fonctionnelle.

L’objectif d’une méthodologie consiste précisément à améliorer les méthodes de


conception pour éviter que des défauts n’apparaissent, dans le meilleur des cas, avant
la phase de production.

1.5.1 Etat des lieux : l’Approche Système


Avant l’ère mécatronique (terme désignant la coopération intime de la mécanique, de
l’hydraulique, de l’électronique et du logiciel dans un système. Ce concept est
applicable à des fonctions aussi diverses que les commandes de portes, de l’éclairage
ou encore aux fonctions dynamiques du véhicule), un organe automobile était conçu
de façon à remplir une fonction locale bien définie. Chaque fonction pouvait être
étudiée et développée indépendamment des autres et l’implication de la sûreté de
fonctionnement se résumait à la réutilisation de modèles génériques issus du retour
d’expérience. Cependant, cette approche ne permet pas de considérer les risques
inhérents à un nouveau système exploitant des technologies différentes et de
complexité accrue. En effet, le choix d’une architecture fonctionnelle, matérielle, des
lois de pilotage, ne doit plus se limiter à la tenue de performances locales mais doit
être lié à des objectifs globaux de l’automobile. Cette approche est motivée par les
interactions des différents sous-systèmes et par l’existence de coopérations
constructeur/équipementiers. Les performances de sûreté de fonctionnement doivent
être formulées au niveau le plus haut, c’est-à-dire au niveau du système complet, puis
Page 14 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
être déclinées à des niveaux inférieurs (sous-systèmes, organes, composants) suivant
la structure arborescente du véhicule. Il n’est pas nécessaire de descendre tout en bas
de l’arborescence, si les exigences sont justifiées à des niveaux intermédiaires ou si les
analyses de sûreté de fonctionnement sont traitées par les fournisseurs. Par
conséquent, la démarche de sûreté de fonctionnement au niveau global se résume en
trois points :
1. l’Analyse des Risques visant à identifier les événements redoutés critiques pour la
sécurité et la disponibilité,
2. l’allocation d’objectifs de sûreté,
3. l’étude de la sûreté par les méthodes et outils adaptés.
Cette Approche Système retenue par de grosses firmes permet d’assurer une
cohérence globale de l’ensemble des études de sûreté de fonctionnement à chaque
niveau intermédiaire tout en respectant l’objectif global à tenir au niveau véhicule et
en prenant en compte les contraintes organisationnelles liées à la sous-traitance.
Soulignons également l’importance de disposer de méthodes et outils de sûreté de
fonctionnement. Pendant longtemps, les constructeurs automobiles étaient assimilés
à des intégrateurs de systèmes en raison de la forte sous-traitance des équipements à
des fournisseurs, les analyses de sûreté étant alors confiées à ces derniers. Cependant,
pour certains systèmes spécifiques aux constructeurs, les analyses doivent être
menées au sein de l’équipe projet.

1.5.2 Méthodologie de conception intégrant la sûreté de fonctionnement


Le cycle de vie généralement utilisé pour décrire le développement des systèmes
embarqués est le « cycle en V ». Celui-ci présente un découpage du processus de
développement en deux branches. La branche descendante du « V » décrit les phases
de conception en allant du général, l’expression des besoins, au particulier selon une
démarche de raffinements successifs. La branche ascendante détaille les phases
d’intégration et de validation correspondant à chaque phase de conception.
Le principal objectif de ce type de démarche en V est de retarder le choix de la
technologie de réalisation. Cela permet de se concentrer sur la spécification et la
conception, en faisant abstraction de la solution technologique dans les premières
phases du développement. Cette démarche est issue de la méthodologie MCSE
(Méthodologie de Conception des Systèmes Electroniques).
Ainsi, les phases de spécification et de conception conduisent à définir des niveaux de
description de plus en plus détaillés. Les phases d’intégration, de test et de vérification
permettent d’évaluer la conformité de la réalisation pour chaque niveau de la
conception en commençant par les parties les plus élémentaires puis en remontant
jusqu’au système complet.
Le cycle en V le plus général correspond au système véhicule. Celui se décompose alors
en plusieurs niveaux hiérarchiques par raffinements successifs du niveau véhicule

Page 15 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
complet jusqu’à la définition des sous-systèmes organes. Cette structure hiérarchique
suggère un certain nombre de remarques :
- toute réalisation est un constituant développé comme un tout mais intégrable
dans un ensemble plus complexe,
- pour chaque constituant (système, sous-système, organe, composant,…) on
retrouve les phases de spécification, de conception, de réalisation,
d’assemblage et de test. Ces terminologies ne sont pas liées au niveau de
description.
- un système complet (par exemple au niveau véhicule) ne devient opérationnel
que lorsque tous ses constituants sont réalisés et testés.

Le modèle en V de la figure ci-dessous est une autre façon de présenter une démarche
qui reste linéaire, mais qui fait mieux apparaître les produits intermédiaires à des
niveaux d’abstraction et de formalité différents et les procédures d’acceptation
(validation et vérification) de ces produits intermédiaires. Le V est parcouru de gauche

à droite en suivant la forme de la lettre : les activités de construction précèdent les


activités de validation et vérification. Mais l’acceptation est préparée dès la
construction (flèches de gauche à droite). Cela permet de mieux approfondir la
construction et de mieux planifier la ‘remontée’.

Page 16 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chapitre 2 : Développement des Systèmes embarqués temps réel

1.1 Introduction

1.1.1 Définitions

La plupart des systèmes embarqués temps réel sont avant tout des systèmes de
contrôle-commande. Un système de contrôle-commande est un système informatique
de contrôle de procédé. Le terme procédé est un terme générique désignant un
système physique contrôlé.
Afin de contrôler le procédé, le système informatique est en relation avec
l’environnement physique externe par l’intermédiaire de capteurs et/ou
d’actionneurs. Les grandeurs physiques acquises grâce aux capteurs permettent au
système de contrôle-commande de s’informer de l’état du procédé ou de son
environnement. Le système de contrôle-commande, à partir de consignes décrivant
l’état voulu du procédé, calcule des commandes qui sont alors appliquées sur le
procédé par l’intermédiaire d’actionneurs. Donnons ainsi une définition générale d’un
système de contrôle-commande comme illustré à la figure ci-dessous :

Représentation schématique d’un système de contrôle commande.

Un système de contrôle-commande reçoit des informations sur l’état du procédé


externe, traite ces données et, en fonction du résultat, évalue une décision qui agit sur
cet environnement extérieur afin d’assurer un état voulu.

Exemple 1 : la figure ci-dessous représente un exemple de système de contrôle-


commande pour un drone. Un drone est un aéronef autonome, ou semi-autonome.
L’un des buts principaux du système de contrôle-commande est de contrôler l’attitude
(tangage, roulis) et la vitesse du drone : cela s’appelle la commande de vol. Le système
Page 17 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
de contrôle-commande est exécuté par un calculateur qu’on appelle microcontrôleur.
Les capteurs utilisés sont une centrale inertielle, permettant de connaître les angles de
tangage et roulis du drone, et un récepteur GPS (Global Positionning System)
permettant notamment de connaître la position absolue (latitude, longitude), la
vitesse par rapport au repère sol et la vitesse ascensionnelle. Un modem sans fil
permet au drone de recevoir des consignes de la part d’un opérateur (par exemple un
angle de roulis, une vitesse et une vitesse ascensionnelle), et de lui envoyer des
informations sur le vol. À la fois capteur (lit des informations en provenance de
l’opérateur) et actionneur (permet l’affichage ou l’enregistrement d’informations pour
l’opérateur), ce modem est qualifié d’organe de dialogue. Enfin, trois actionneurs
permettent de commander respectivement la puissance du moteur et la position des
deux ailevons. Le différentiel des ailevons (l’un plus haut, l’autre plus bas), permet de
donner une vitesse angulaire sur l’axe de roulis de l’aéronef, alors que leur position
parallèle par rapport à l’angle d’équilibre permet d’appliquer une vitesse angulaire sur
l’axe de tangage. La vitesse ascensionnelle dépend de la puissance du moteur et des
angles de tangage et roulis.

Système de contrôle-commande embarqué sur un mini-drone

Un système embarqué est un système informatique dont les moyens de calcul sont
embarqués sur le procédé contrôlé. Le fait d’embarquer les moyens de calcul implique,
en plus des contraintes d’encombrement (taille, poids, forme), des contraintes de
consommation d’énergie puisque l’alimentation électrique des éléments de calcul est
soit embarquée (batteries, carburant, etc.), soit ambiante (panneaux solaires, etc.). À
technologie équivalente, l’énergie consommée par un calculateur est fonction du carré
de la vitesse de celui-ci ; en d’autres termes, plus le calculateur est performant, plus
l’énergie consommée est importante, avec une relation quadratique. Un système
embarqué se caractérise donc souvent par des ressources de calcul dimensionnées (ou
à dimensionner) au plus juste en fonction des besoins en calcul.

Page 18 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Un système temps réel est un système informatique soumis à des contraintes de
temps. Une définition du temps réel peut être : un système est dit temps réel si
l’exactitude des applications ne dépend pas seulement du résultat mais aussi du temps
auquel ce résultat est produit.
Une autre définition du temps réel peut être : un système est dit temps réel s’il doit
s’exécuter suffisamment vite par rapport à la dynamique du procédé contrôlé. La
notion relative de vitesse s’exprime par des contraintes temporelles.

La notion « suffisamment vite » est relative à la dynamique du procédé contrôlé. Par


exemple, le drone de la ci-dessus, est considéré comme un système temps réel. De par
sa forme d’aile delta, il est très instable en roulis ; par conséquent, il est important que
la commande de vol se rafraîchisse fréquemment, par exemple toutes les 20
millisecondes. Si le drone avait une forme de planeur, plus stable, une fréquence de
rafraîchissement plus faible (de l’ordre de 10 Hz, soit 100 millisecondes) pourrait peut-
être suffire à assurer une commande de vol acceptable.

Un système critique est un système informatique pour lequel une défaillance, totale
ou partielle, du système, peut entraîner des conséquences graves, par exemple
économiques, humaines, écologiques, etc. La défaillance d’un drone d’observation
entraîne des conséquences économiques (perte de l’engin) mais surtout peut entraîner
des conséquences humaines en cas de collision, moteur allumé, avec une personne.
Un drone est donc considéré comme un système critique lorsqu’il évolue dans une
zone habitée. Un système est temps réel critique si une défaillance temporelle (le
système ne réagit pas suffisamment vite par rapport à la dynamique du procédé) peut
aussi entraîner des conséquences graves. Le drone peut être considéré comme temps
réel critique, puisque le fait de ne pas être capable d’appliquer les commandes de vol
à temps peut aboutir à une perte de contrôle. La plupart des systèmes de transport
sont des systèmes embarqués de contrôle-commande, temps réel critique.

Une grande difficulté inhérente à la validation des systèmes de contrôle-commande


provient du fait que les comportements ne sont pas reproductibles :
 Indépendance du résultat produit par rapport à la vitesse d’exécution. Le
résultat d’un calcul effectué à partir de données d’entrée similaires est
indépendant de la vitesse du calculateur. En revanche, l’état stable d’un
procédé dépend de la dynamique du procédé par rapport à la vitesse
d’exécution du système de contrôle-commande.
 Comportement reproductible. Un calcul effectué à partir de données d’entrée
identiques donne toujours le même résultat. En revanche, dans le cas de
données d’entrée (grandeurs physiques) obtenues par des capteurs, le système
de contrôle-commande travaille sur un domaine de données réelles
approximées qui sont très rarement identiques.

Page 19 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Cette définition des systèmes de contrôle-commande ayant été faite, nous pouvons
replacer ces systèmes par rapport aux autres systèmes informatiques en faisant trois
catégories (voir figure ci-dessous) :

Comparaison des systèmes de contrôle-commande par rapport aux autres


applications informatiques

 Les systèmes transformationnels qui utilisent des données fournies à


l’initialisation par l’utilisateur. Ces données, leurs traitements et l’obtention du
résultat n’ont aucune contrainte de temps.
 Les systèmes interactifs dans le sens où les données sont produites par
interaction avec l’environnement sous différentes formes (clavier, fichier,
réseaux, souris, etc.). Mais le temps n’intervient pas en tant que tel si ce n’est
avec un aspect confort de travail ou qualité de service.
 Les systèmes de contrôle-commande ou réactifs qui sont en relation avec
l’environnement physique réel pour les données capteur/actionneur ; l’aspect
« temps » a une place importante sous la forme d’un temps de réaction, d’une
échéance à respecter, etc.

Nous terminons cette section par des définitions qualifiant des systèmes temps réel
ayant des spécifications particulières. Ces contraintes temporelles peuvent être de
plusieurs types :
 Contraintes temporelles relatives ou lâches (temps réel mou : soft real-time) :
les fautes temporelles sont tolérables (Ex. : jeux vidéo, applications
multimédias, téléphonie mobile...).

Page 20 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 Contraintes temporelles strictes ou dures (temps réel dur : hard real-time) : les
fautes temporelles ne sont pas tolérables (Ex. : fonctions critiques avionique,
véhicules spatiaux, automobile, transport ferroviaire...).
 Contraintes temporelles fermes (temps réel ferme : firm real-time) : les fautes
temporelles sont autorisées dans une certaine limite, par exemple une erreur
toutes les trois exécutions au plus.
 Systèmes multi-critiques : les sous-systèmes composant le système sont
caractérisés par des degrés de criticité. Par exemple en avionique civile, la DO-
178C caractérise les sous-systèmes par un niveau de criticité appelé DAL (Design
Assurance Level), allant de niveau A (Ex. : commande de vol), catastrophique en
cas de défaillance, à niveau E (Ex. : divertissement en vol), sans effet sur la
sécurité.

1.1.2 Principales caractéristiques des systèmes temps réel

Considérons un exemple représentatif d’une application temps réel de contrôle-


commande représenté sur la figure ci-dessous. Le contrôle-commande de cette
application est fait par l’intermédiaire d’un ensemble de capteurs et d’actionneurs
(pédale d’accélérateur, température air, pression air, température eau, rotation
vilebrequin, capteurs de pollution, injection essence, allumage, admission air, etc.) et
d’une connexion au réseau interne à l’automobile. L’analyse de cet exemple
d’application permet de mettre en exergue les principales caractéristiques des
systèmes de contrôle-commande :
 Grande diversité des dispositifs d’entrées/sorties : les données à acquérir qui
sont fournies par les capteurs et les données à fournir aux actionneurs sont de
types très variés (continu, discret, tout ou rien ou analogique). Il est aussi
nécessaire de piloter un bus de terrain pour les communications.
 Prise en compte des comportements concurrents : l’ensemble de ces données
physiques qui arrivent de l’extérieur et le réseau qui permet de recevoir des
messages ne sont pas synchronisés au niveau de leurs évolutions, par
conséquent, le système informatique doit être capable d’accepter ces variations
simultanées des paramètres.
 Respect des contraintes temporelles : la caractéristique précédente impose de
la part du système informatique d’avoir une réactivité suffisante pour prendre
en compte tous ces comportements concurrents et en réponse à ceux-ci, de
faire une commande en respectant un délai compatible avec la dynamique du
système.
 Sûreté de fonctionnement : les systèmes de type contrôle-commande mettent
souvent en jeu des applications qui demandent un niveau important de sécurité
pour raisons de coût ou de vies humaines. Pour répondre à cette demande, il
est nécessaire de mettre en œuvre toutes les réponses de la sûreté de
fonctionnement (développements sûrs, tests, méthodes formelles, prévisibilité,
Page 21 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
déterminisme, continuité de service, tolérance aux fautes, redondance,
ségrégation des moyens de calcul et de communication, etc.).

Exemple d’une application de contrôle-commande d’un moteur à combustion

1.1.3 Caractéristiques temporelles des systèmes temps réel


Les contraintes temporelles qui sont classiquement présentées sont des contraintes de
bout en bout, appelées aussi contraintes de latence. Ces contraintes représentent le
délai maximal entre lecture de l’état du système (lecture des capteurs) et commande
de celui-ci (commande des actionneurs). Par exemple, la commande de vol du drone
présenté dans l’Exemple précédant, puisqu’elle doit s’exécuter à 50 Hz, c’est-à-dire
avec une période de 20 millisecondes, se verra vraisemblablement munie de
contraintes temporelles de bout en bout sur la commande de vol, par exemple de 20
millisecondes, afin d’obliger le système à s’exécuter une fois par période.

Le respect du protocole de communication avec les capteurs, actionneurs, ou bus de


communication est une autre source, très importante, de contraintes temporelles.
Ainsi, à chaque fois qu’une trame est disponible sur un réseau, le système doit la lire
et soit la traiter, soit la stocker pour traitement ultérieur, sous peine de la voir être
remplacée (ou « écrasée ») par la trame suivante.
Il est nécessaire de préciser et de formaliser les caractéristiques temporelles d’un
système. Cette caractérisation peut prendre de nombreuses formulations. Ainsi, nous
pouvons définir de manière non exhaustive :
 Durée d’exécution d’une activité : l’activité d’une application, qui peut être
l’enchaînement de plusieurs activités élémentaires (acquisition, traitement,
Page 22 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
commande, affichage...), possède une durée d’exécution qui peut être mesurée
de diverses manières. Cette durée n’est pas constante à chaque occurrence de
cette activité puisque les programmes et les enchaînements de programmes ne
sont pas toujours identiques (branchement conditionnel, itération,
synchronisation...).
 Cadence de répétition ou périodicité d’une activité : l’acquisition d’une donnée
ou la commande d’un actionneur peuvent nécessiter une régularité liée par
exemple à la fréquence d’échantillonnage.
 Date au plus tôt ou date de réveil : dans certains cas, un traitement doit être
déclenché à une date précise relative par rapport au début de l’exécution de
l’application ou absolue (plus rarement). Cette date de réveil n’implique pas
obligatoirement l’exécution ; il peut y avoir un délai dû à l’indisponibilité du
processeur.
 Date de démarrage : cet instant correspond à l’exécution effective de l’activité.
 Date de fin : instant correspondant à la fin de l’exécution de l’activité.
 Date au plus tard ou échéance : le traitement ou la commande d’un actionneur
doit être terminé à un instant fixé par rapport au début de l’exécution de
l’application. Dans le cas d’applications à contraintes temporelles strictes, cette
échéance doit être respectée de façon impérative, sinon il y a faute temporelle
et l’application est déclarée non valide.
 Temps de réponse : cette caractéristique peut s’appliquer à une activité de
régulation ou à un ensemble d’activités de régulation ; elle est directement liée
à la dynamique du système. Ce paramètre correspond à la différence entre la
date de réveil et la date de fin de l’activité.
 Gigue temporelle : ce paramètre caractérise la répétabilité d’une activité au fur
et mesure de ses occurrences. En effet, entre deux exécutions successives d’une
même activité, ses caractéristiques temporelles peuvent changer : date
d’activation, durée d’exécution, temps de réponse, etc.

1.1.4 Quelques exemples d’applications

Nous pouvons citer quelques exemples d’applications temps réel de contrôle-


commande :
 Système de transport : que cela soit pour le transport terrestre (véhicule de
tourisme, utilitaire, poids lourd, etc.), ferroviaire, aérien, ou spatial, les
systèmes de transport sont caractérisés par une forte criticité et une forte
complexité due à l’expansion du nombre de fonctions et la nécessité de
tolérance aux fautes. Ils sont typiquement décomposés en sous-systèmes
interconnectés par un ensemble de bus de terrains.
 Drone volant, roulant, navigant, ou sous-marin : ce type d’applications est de
plus en plus répandu, et de plus en plus d’autonomie est donnée aux drones.
Qu’ils soient d’observation ou tactiques, ce type d’application trouve une large
Page 23 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
place aussi bien dans les applications militaires que civiles (exploration de zone
radioactive après un accident, planétaire, sous-marine, cinéma et télévision,
etc.).
 Robot de production : un robot, réalisant une activité spécifique (peinture,
assemblage, tri) sur une chaîne de production, doit effectuer son travail en des
temps fixés par la cadence de fabrication. S’il agit trop tôt ou trop tard, l’objet
manufacturier traité sera détruit ou endommagé conduisant à des
conséquences financières ou humaines graves (oubli d’un ou plusieurs rivets sur
un avion).
 Téléphone mobile : le système de contrôle-commande doit remplir plusieurs
fonctions dont certaines ont des contraintes temporelles fortes pour avoir une
bonne qualité de service (QoS : quality of service). Ainsi, la première fonction
est de transmettre et de recevoir les signaux de la parole (577 μs de parole
émises toutes les 4,6 ms et 577 μs de parole reçues toutes les 4,6 ms à des
instants différents). En parallèle, il est nécessaire de localiser en permanence le
relais le plus proche et donc de synchroniser les envois par rapport à cette
distance (plus tôt si la distance augmente et plus tard si la distance diminue).
Des messages de comptes rendus de la communication sont aussi émis avec une
périodicité de plusieurs secondes. Les contraintes temporelles imposées au
système doivent être imperceptibles à l’utilisateur.
 Système de vidéoconférence : ce système doit permettre l’émission et la
réception d’images numérisées à une cadence de 20 à 25 images par seconde
pour avoir une bonne qualité de service. Afin de minimiser le débit du réseau,
une compression des images est effectuée. D’autre part la parole doit aussi être
transmise. Bien que correspondant à un débit d’information moindre, la
régularité de la transmission, qualifiée par une gigue temporelle, est nécessaire
pour une reproduction correcte. De plus ce signal doit être synchronisé avec le
flux d’images. Ces traitements (numérisations images et parole, transmission,
réception, synchronisation...) sont réalisés en cascade, mais avec une cohérence
précise.
 Pilotage d’un procédé de fabrication (fonderie, laminoir, four verrier...) : par
exemple la fabrication d’une bobine d’aluminium (laminage à froid) exige un
contrôle en temps réel de la qualité (épaisseur et planéité). Cette vérification en
production de la planéité nécessite une analyse fréquentielle (FFT) qui induit un
coût important de traitement. Le système doit donc réaliser l’acquisition d’un
grand nombre de mesures (246 Ko/s) et traiter ces données (moyenne, FFT…) à
la période de 4 ms. Ensuite, il affiche un compte-rendu sur l’écran de l’opérateur
toutes les 200 ms et enfin imprime ces résultats détaillés toutes les 2 s. Un
fonctionnement non correct de ce système de contrôle de la qualité peut avoir
des conséquences financières importantes : production non conforme à la
spécification demandée.

Page 24 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
1.2 Architecture des applications temps réel

1.2.1 Architecture logicielle des applications temps réel

1.2.1.1 Architecture multitâche


Le comportement concurrent des événements et grandeurs physiques externes amène
à décrire l’environnement comme un système fortement parallèle. Cela conduit
naturellement à adapter les méthodes de conception et de réalisation du système de
contrôle-commande d’un tel environnement à ce parallélisme. Aussi, l’architecture la
mieux adaptée pour répondre à ce comportement parallèle du procédé externe est
une architecture multitâche. Ainsi au parallélisme de l’environnement, la réponse est
le parallélisme de conception. Nous pouvons définir la tâche ou activité ou processus
comme « une entité d’exécution et de structuration de l’application ». Cette
architecture logicielle multitâche facilite la conception et la mise en œuvre et surtout
augmente l’évolutivité de l’application réalisée.
D’une manière très générique, la figure ci-dessous donne l’architecture logicielle d’une
application de contrôle-commande multitâche. Nous pouvons ainsi découper cet
ensemble de tâches ou activités selon les groupes suivants :
 Tâches d’entrées/sorties : ces tâches permettent d’accéder aux données
externes par l’intermédiaire de cartes d’entrées/sorties et ensuite de capteurs
et d’actionneurs directement liés au procédé géré. Ces tâches peuvent être
activées de façon régulière ou par interruption.
 Tâches de traitement : ces tâches constituent le cœur de l’application. Elles
intègrent des traitements de signaux (analyse spectrale, corrélation, traitement
d’images, etc.) ou des lois de commande (régulation tout ou rien, régulation du
premier ordre, régulation PID, etc.). Dans le cadre de ce cours, nous
considérerons ces tâches comme des boîtes noires, c’est-à-dire que le
traitement effectué par ces tâches relève des domaines comme le traitement
du signal, le traitement d’images ou l’automatique, disciplines qui débordent
largement le contexte de ce cours.
 Tâches de gestion de l’interface utilisateur : ces tâches permettent de présenter
l’état du procédé ou de sa gestion à l’utilisateur. En réponse, l’opérateur peut
modifier les consignes données ou changer les commandes. Ces tâches peuvent
être très complexes et coûteuses en temps de calcul si l’interface gérée est de
taille importante (tableau de bord) ou de type graphique (représentation 3D).

Page 25 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Architecture logicielle d’une application de contrôle-commande multitâche

 Tâches de communications : ces tâches sont destinées à gérer les messages


envoyés ou reçus à travers un ou plusieurs réseaux ou bus de terrain. Si ce type
de tâches existe, l’application est dite distribuée ou répartie.
 Tâches de sauvegarde : ces tâches permettent de stocker l’état du système à
des instants fixés. Cette sauvegarde peut être utilisée a posteriori pour analyser
le fonctionnement de l’application ou lors d’une reprise d’exécution à une étape
précédente.

Après l’analyse et la conception de l’application, nous obtenons un ensemble de tâches


ou activités qui coopèrent afin de réaliser le contrôle-commande du procédé géré. Ces
tâches appartiennent aux différents groupes listés précédemment : tâches
d’entrées/sortie, tâches de traitement, tâches de gestion de l’interface utilisateur,
tâches de communications et tâches de sauvegarde. Ce découpage purement
fonctionnel peut être modifié dans certains cas en utilisant une conception tournée
vers les entités ou « objets » à contrôler.

Les tâches obtenues, qui constituent l’application de contrôle-commande, ne sont pas


des entités d’exécution indépendantes. En effet certaines tâches sont connectées vers
l’extérieur pour les entrées/sorties. De plus elles peuvent être liées par des relations
de type (voir figure ci-dessous) :
 Synchronisation : cela se traduit par une relation de précédence d’exécution
entre les tâches ;
Page 26 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
 Communications : à la notion de précédence, traduite par la synchronisation,
s’ajoute le transfert de données entre les tâches ;
 Partage de ressources : les tâches utilisent des éléments mis en commun au
niveau du système comme des zones mémoire, des cartes d’entrées/sorties,
cartes réseau, etc. Certaines de ces ressources, comme par exemple les zones
mémoire, ne sont pas ou ne doivent pas être accessibles, pour avoir un
fonctionnement correct, par plus d’une tâche à la fois, elles sont dites
ressources critiques.

Représentation schématique de l’architecture multitâche d’une application de


contrôle-commande

1.2.1.2 Modèles d’exécution et ordonnancement


Cette architecture logicielle peut être vue comme un ensemble de tâches
synchronisées, communicantes et partageant des ressources critiques. Le rôle
essentiel du système informatique est donc de gérer l’enchaînement et la concurrence
des tâches en optimisant l’occupation du processeur, cette fonction est appelée
l’ordonnancement. L’ordonnancement est un point crucial des systèmes temps réel ;
en effet l’ordonnancement va déterminer le comportement temporel et être le garant
du respect des contraintes de temps imposées à l’exécution de l’application.
Nous pouvons distinguer deux modèles d’exécution des systèmes temps réel :
l’exécution dite synchrone et l’exécution asynchrone. Nous allons présenter ces deux
modèles d’exécution à l’aide d’un modèle d’application très simple. Cette application,
constituée d’un ensemble de tâches pour gérer le procédé, intègre en particulier les
deux tâches suivantes :
 Tâche de lecture des données entrées par l’opérateur à l’aide d’un clavier,
appelée « Lecture_consigne ». L’intervention humaine fait que cette tâche peut
être longue.
 Tâche d’alarme qui se déclenche sur un événement d’alerte correspondant au
dépassement d’un paramètre critique, appelée « Alarme ». Celle-ci doit
s’exécuter au plus vite pour éviter l’endommagement du procédé.

Page 27 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Pour mettre en avant les différences entre les deux modèles d’exécution nous allons
étudier la situation dans laquelle la tâche « Lecture_consigne » s’exécute et la tâche «
Alarme » demande son exécution alors que la tâche « Lecture_consigne » n’est pas
terminée.
Dans le modèle d’exécution synchrone, la perception de l’occurrence de tout
événement par le système est différée du temps d’exécution de la tâche en cours. Dans
l’exemple proposé, nous pouvons constater que la prise en compte d’un signal d’alerte
n’est effective que lors de la fin de la tâche « Lecture_consigne » (voir figure ci-
dessous). D’un point de vue du procédé, la réaction est perçue comme différée, alors
que du point de vue du système informatique, elle est perçue comme immédiate.
L’occurrence des événements externes a donc été artificiellement synchronisée avec
le système informatique, d’où le nom d’exécution synchrone.

Modèle d’exécution synchrone d’une application de contrôle-commande

Ce retard peut affecter la prise en compte de n’importe quel événement, quelle qu’en
soit la gravité pour l’application. Il faut donc vérifier que l’architecture opérationnelle
choisie permettra de prendre en compte les contraintes temporelles : hypothèse de la
fenêtre de visibilité des événements ou d’instantanéité des actions. La capacité du
système à appréhender un événement externe est caractérisée par la durée de la tâche
la plus longue puisque les tâches sont non interruptibles ou non préemtibles.
Dans le cas du modèle synchrone d’exécution, nous avons un système
d’ordonnancement complètement prévisible et, en conséquence, il est possible en
faisant une analyse exhaustive de l’exécution de produire une séquence d’exécution
qui est jouée de façon répétitive. Cette étude de la séquence est appelée analyse de
l’ordonnancement hors-ligne. L’ordonnancement peut se réduire à un séquencement.
Nous avons alors un environnement informatique très simple de l’application
développée puisqu’il se réduit à une liste de tâches à exécuter. L’environnement
informatique pour piloter cette liste de tâches se réduit à un système très simple : un
séquenceur.

Page 28 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Dans le modèle d’exécution asynchrone, l’occurrence de tout événement est
immédiatement prise en compte par le système pour tenir compte de l’urgence ou de
l’importance. Dans l’exemple proposé, nous pouvons constater que la prise en compte
d’un signal d’alerte est immédiate sans attendre la fin de la tâche « Lecture_consigne
» (voir figure ci-dessous). La prise en compte de l’événement « alerte » est identique
pour le procédé et le système informatique. L’occurrence des événements externes
n’est pas synchronisée avec le système informatique, d’où le nom d’exécution
asynchrone.

Modèle d’exécution asynchrone d’une application de contrôle-commande

Dans ce contexte, nous avons des tâches qui sont interruptibles ou préemtibles. En
conséquence, l’ordonnancement n’est pas totalement prévisible et l’analyse de
l’exécution des tâches doit se faire en ligne par simulation ou par test. Cela nécessite
l’utilisation d’un gestionnaire centralisé des événements et de la décision d’exécution:
exécutif ou noyau temps réel.
Pour terminer cette section nous allons rappeler trois définitions importantes que nous
avons utilisées et fixer le contexte de ce cours. Nous avons ainsi défini :
 Tâche non préemptible ou préemptible :
-Une tâche non préemptible ne peut être interrompue qu’à des endroits
spécifiques et à la demande de la tâche elle-même : fin_de_tâche,
attente_signal… Dans ce cas, la programmation est plus simple et aucun
mécanisme de partage de ressources critiques n’est à prévoir. En revanche,
des temps de réponse longs peuvent se produire.
-Une tâche préemptible peut être interrompue à n’importe quel instant et
le processeur être affecté à une autre tâche. Dans ce cas, les temps de
réponse à un événement externe peuvent être très courts ; mais nous avons
alors une programmation plus complexe avec un besoin de mécanisme de
partage de ressources critiques.
 Analyse de l’ordonnancement hors-ligne ou en ligne :

Page 29 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
-Une analyse de l’ordonnancement hors-ligne correspond à la construction
d’une séquence d’exécution complète sur la base des paramètres temporels
des tâches en utilisant une modélisation (réseaux de Petri...) ou une
simulation (animation ou énumération du modèle). L’ordonnanceur
nécessaire est simple puisque la séquence d’exécution est prédéfinie, il se
réduit à un séquenceur. En revanche, l’application ainsi figée est peu flexible.
-Une analyse de l’ordonnancement en ligne correspond à un choix
dynamique de la prochaine tâche à exécuter en fonction des paramètres de
la tâche. Si le système a des contraintes temporelles, on doit utiliser
préalablement à la mise en exploitation du système des tests permettant de
vérifier qu’en toutes circonstances les contraintes temporelles seront
respectées. On appelle ces tests des tests d’ordonnançabilité.
 Exécution synchrone ou asynchrone :
-Une exécution est dite synchrone si les tâches sont non préemtibles et
s’exécutent les unes après les autres dans un ordre qui peut être défini par
une analyse hors-ligne de l’ordonnancement.
-Une exécution est dite asynchrone si les tâches sont préemtibles et
s’exécutent selon l’ordonnancement. Une analyse de la séquence doit se
faire obligatoirement en ligne.
Dans la suite de ce cours, nous nous intéressons plus particulièrement aux systèmes
asynchrones composés de tâches préemptibles avec un ordonnancement en ligne.
Ainsi l’architecture logicielle de l’application est composée de plusieurs tâches
réalisées par le concepteur et d’un environnement spécifique, le noyau temps réel, que
nous allons décrire. Le point central de cet environnement est l’ordonnanceur qui
permet d’affecter à tout instant le processeur à une tâche afin de respecter l’ensemble
des contraintes temporelles attachées à la gestion du procédé.

1.2.1.3 Exécutif ou noyau temps réel


Cet environnement particulier d’exécution, exécutif ou noyau temps réel, peut être
assimilé à un système d’exploitation de petite taille dédié aux applications de contrôle-
commande. La caractéristique fondamentale est son déterminisme d’exécution avec
des paramètres temporels fixés (temps de prise en compte d’une interruption,
changement de contexte entre deux tâches, etc.). Nous pouvons comparer les
différences au niveau des objectifs fixés pour le noyau d’exécution d’un système
informatique classique et d’un système informatique de contrôle-commande.
Un système classique n’a pas été conçu pour permettre de respecter des contraintes
temporelles, mais il suit les règles suivantes :
 Politiques d’ordonnancement des activités basées sur le partage équitable du
processeur : affectation identique du temps processeur à tous les processus en
cours ;
 Gestion non optimisée des interruptions ;

Page 30 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 Mécanismes de gestion mémoire (cache...) et de micro-exécution engendrant
des fluctuations temporelles (difficulté pour déterminer précisément les durées
des tâches) ;
 Gestion des temporisateurs ou de l’horloge pas assez fine (plusieurs ms) ;
 Concurrence de l’application temps réel avec le système d’exploitation toujours
actif ;
 Gestion globale basée sur l’optimisation d’utilisation des ressources et du temps
de réponse moyen des différents processus en cours.
Un système informatique de contrôle-commande s’attache aux caractéristiques
suivantes :
 Efficacité de l’algorithme d’ordonnancement avec une complexité limitée ;
 Respect des contraintes de temps (échéances...). Ces contraintes temporelles
se traduisent plus en termes de choix d’une activité à exécuter à un instant
donné plutôt que de rapidité d’exécution de toutes les activités ;
 Prédictibilité (répétitivité des exécutions dans des contextes identiques) ;
 Capacité à supporter les surcharges ;
 Possibilité de certification pour les applications de certains domaines comme
l’avionique, l’automobile…
 Une application temps réel étant par définition un système multitâche, le rôle
essentiel du noyau temps réel est donc de gérer l’enchaînement et la
concurrence des tâches en optimisant l’occupation de l’unité centrale du
système informatique. Les principales fonctions d’un noyau temps réel peuvent
être scindées en trois groupes :
1. gestion des entrées/sorties (gestion des interruptions, gestion des
interfaces d’entrées/sorties, gestion des réseaux de communications...) ;
2. ordonnancement des tâches (orchestration du fonctionnement normal,
surveillance, changements de mode, traitement des surcharges...) ;
3. relations entre les tâches (synchronisation, communication, accès à une
ressource critique en exclusion mutuelle, gestion du temps...).

Il est important de noter que les tâches sont les unités actives du système ; le
noyau temps réel n’est actif que lors de son appel. Une tâche activée peut
appeler le noyau temps réel par une requête. Les différentes requêtes sont
servies par des modules du noyau temps réel appelées primitives. Ensuite le
noyau temps réel réactive une tâche de l’application selon l’algorithme
d’ordonnancement utilisé (voir figure ci-dessous).

Page 31 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Interaction entre les tâches et le noyau temps réel

Ainsi le noyau temps réel centralise toutes les demandes d’activation des tâches et
gère des tables lui permettant de comparer les priorités (ou les urgences) et l’état de
ces diverses tâches, ainsi que l’état d’occupation des ressources. La décision
d’activation d’une tâche étant prise, le noyau temps réel lance les modules de
programmes correspondant à cette tâche et lui alloue les ressources disponibles. La
tâche activée occupe un processeur jusqu’à la fin de son exécution sous le respect des
conditions suivantes :
 Elle ne réalise pas d’opérations d’entrées-sorties ;
 Les ressources utilisées sont disponibles ;
 Aucun événement extérieur ne revendique le déroulement d’une tâche plus
prioritaire.

Nous pouvons donc décrire schématiquement le contexte complet d’exécution


d’une application temps réel avec les deux parties : tâches et noyau temps réel
(voir figure ci-dessous).

Page 32 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Architecture de l’application : tâches et noyau temps réel

En conclusion, l’ordonnancement dans le cas des systèmes temps réel à


contraintes temporelles strictes a pour objectif principal de répondre aux deux
cas suivants :
 Fautes temporelles : cela correspond à un non-respect d’une contrainte
temporelle associée à une tâche comme le dépassement de la date limite
d’exécution ou échéance. Cela induit la notion d’urgence d’une tâche.
 Surcharge : lors de l’occurrence d’une ou plusieurs fautes temporelles,
l’ordonnanceur peut réagir en supprimant une ou plusieurs tâches de
l’application, ce qui amène à la notion d’importance, c’est-à-dire le choix d’une
tâche à exécuter par rapport aux spécifications fonctionnelles de l’application.

1.2.1.4 Implémentation des applications de contrôle-commande


Comme nous le verrons au cours de ce cours, les langages de développement des
applications de contrôle-commande sont très divers. Cependant, par rapport à
l’environnement d’exécution que nous venons de décrire (noyau temps réel avec les
trois fonctions décrites : 1-gestion des interruptions, 2-ordonnancement, 3-relations
entre les tâches), il possible de décliner les langages en trois groupes (voir figure ci-
dessous) :

Page 33 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Langages utilisés pour développer les applications avec un noyau temps réel (1:
gestion des interruptions, 2 : ordonnancement, 3 : relations entre les tâches)

 Langages standards (langage C...) : le noyau temps réel qui supporte ce type de
langage doit être complet puisque le langage n’intègre aucune spécificité multi-
tâche.
 Langages multitâches (langage C, Ada, Java...) : ces langages permettent de
décrire l’application en termes de tâches ; ainsi le noyau peut être plus réduit
et ne comporter que les deux premières fonctions.
 Langages réactifs (langages Lustre, Esterel, Signal...) : ces langages donnent non
seulement la possibilité de décrire les fonctionnalités du programme, mais
aussi l’enchaînement des différentes parties. Le noyau est donc limité à une
couche proche du matériel lié notamment à la gestion des interruptions. En
revanche, étant donnée la possibilité très limitée d’expression de l’aspect
fonctionnel, ils sont souvent associés à un langage standard pour pallier ce
manque.

Page 34 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chapitre 3 : Spécification fonctionnelle

1. Introduction générale aux méthodes d’analyse fonctionnelle

Au fil des années, il nous est apparu comme une évidence que le moyen le plus naturel
de concevoir un système pour un ingénieur est une approche descendante, partant de
fonctions de haut niveau, qui seront décomposées de façon arborescente jusqu’à des
fonctions élémentaires. Différents formalismes sont utilisés, comme SART
(Structured Analysis for Real-time), ou SysML (Systems Modeling Language) : ceux-ci
permettaient déjà d’opérer une analyse fonctionnelle descendante. Le point commun
de ces trois formalismes (SART, SysML, Capella) est que l’on utilise des diagrammes
flots de données pour la décomposition fonctionnelle. En effet, si l’on pouvait faire
l’hypothèse que tout traitement s’exécute en continu et de façon instantanée,
hypothèse qui est généralement faite pendant la phase de décomposition
fonctionnelle, alors tout système embarqué pourrait être totalement conçu à base de
flots de données.
L’exécution de celui-ci contrôlerait le système tel que le concepteur le souhaitait. La
manière dont les systèmes sont conçus a aussi évolué au cours de ces dernières
décennies. De façon à diminuer les coûts, on a pu voir des sociétés se spécialiser dans
différentes phases, et il est de plus en plus fréquent qu’un système soit spécifié par un
donneur d’ordres, décomposé en sous-systèmes, eux-mêmes spécifiés de façon
détaillée par un équipementier, qui sera à son tour donneur d’ordre pour externaliser
le développement de certaines fonctions élémentaires, développement ayant lieu
souvent en off-shore de façon à en diminuer les coûts. Ce sont donc souvent des
équipes pluriculturelles, ne communiquant pas directement, qui sont amenées à
joindre leurs efforts pour développer un système de grande envergure.
Il est donc primordial qu’une spécification soit bien comprise, et que toute fonction
non triviale puisse être exprimée de façon non ambigüe. L’expression formelle du
comportement attendu dans la conception de systèmes est un très bon moyen de lever
toute ambiguïté. Elle a bien entendu un coût en temps non négligeable, puisqu’il est
plus rapide de spécifier une fonction, en exprimant le comportement attendu en
langage naturel, plutôt que d’exprimer son comportement par un modèle formel.
Cependant, le modèle formel pourra être utilisé lors de la phase de validation formelle,
si elle existe pour le système, mais aussi simplement comme outil de test des fonctions
développées, voire même pour générer automatiquement le code de celles-ci.
L’expression formelle des comportements a pris plusieurs formes dans
les méthodes de spécification et conception durant les dernières décennies : de
l’utilisation de réseaux de Pétri, aux Grafcets, en passant par l’utilisation de différents
formalismes de machines à états. L’un de ces formalismes nous semble
particulièrement intéressant pour sa relative simplicité d’utilisation : le statechart, issu
des travaux de David Harel, et normalisé par l’OMG comme machine à états d’UML. Le
Page 35 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
choix de ce formalisme n’est pas un hasard : en effet, il intègre en particulier le concept
de régions orthogonales, permettant d’exprimer de façon parallèle le comportement
d’un système. Il est ainsi possible de spécifier formellement le comportement d’un
système de façon ascendante : le concepteur peut ajouter des détails au fur et à
mesure qu’il avance dans l’expression du comportement. Marier ce formalisme
ascendant à une méthode de spécification fonctionnelle descendante ouvre de
nombreuses possibilités, puisque la méthode de spécification mêlant flots de données
et automates de Harel peut être, au besoin, ascendante ou descendante.
L’approche « flots de données » pourrait donner directement l’implémentation d’un
système, si l’on pouvait considérer que toutes les fonctions s’exécutent
instantanément et en continu. Cependant, cette hypothèse est généralement éloignée
de la réalité sur un système embarqué. En effet, plus les ressources de calcul sont
importantes, plus l’énergie consommée par celles-ci est importante. Dans la
conception de systèmes embarqués, la dernière phase précédant l’implémentation est
donc la phase de co-conception logiciel/matériel, pendant laquelle le concepteur est
amené à choisir un rythme discret d’exécution de ses fonctions, et qui l’amène à casser
la confortable sémantique flots de données utilisée jusqu’alors, dans le but de
minimiser les ressources de calcul, et donc d’énergie, à embarquer sur le système.
Lorsqu’on parle de co-conception logiciel/matériel, on pense aussi à la conception de
matériel. Or, il existe aujourd’hui de très nombreuses cartes électroniques sur étagère.
Il nous semble donc que la diversité et le coût réduit de ces plateformes sur lesquelles
les systèmes embarqués sont déployés rend relativement rare le besoin de développer
sa propre architecture matérielle. Par conséquent, le parti pris du cours est de montrer
comment déployer le système logiciel sur des ressources matérielles existantes. Les
métriques non fonctionnelles, en particulier la réactivité du système de contrôle par
rapport au procédé contrôlé, sont très fortement impactées par le rythme choisi pour
l’exécution des fonctions. Cependant, le problème général du choix du rythme
d’exécution des fonctions pour respecter des contraintes temporelles de bout en bout
est en général un problème complexe. D’autant qu’à ce niveau de la phase de
conception, de nombreuses informations manquent. Par exemple, on n’a
généralement qu’une idée approximative de la durée d’exécution des fonctions, même
prises individuellement, puisque celles-ci n’ont souvent pas encore été déployées sur
la plateforme cible.

2. Méthodologie de co-design et estimation des performances


Le co-design permet de concevoir en même temps à la fois le matériel et le logiciel
pour une fonctionnalité à implémenter. Cela est maintenant possible avec les niveaux
d’intégration offerts dans les circuits logiques programmables. Il permet par ailleurs de
repousser le plus loin possible dans la conception du système les choix du matériel à
faire contrairement à l’approche classique où les choix matériels sont faits en premier
lieu.

Page 36 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le problème du co-design est celui du développement d’une méthodologie de
conception et des outils supports. Il est important de noter qu’une approche système
est nécessaire pour déterminer les parties du système relevant de l’activité de co-
design. Le développement de ces parties se distingue des approches système par la
nécessité d’une interaction forte entre les développements de la partie logicielle et de
la partie matérielle.
Lorsque les parties du système relevant de l’activité de co-design ont été clairement
identifiées et spécifiées, le concepteur doit effectuer la sélection d’une architecture
matérielle et l’allocation des constituants fonctionnels sur les unités matérielles de
l’architecture choisie.
L’espace des solutions possibles apparaît très vaste. Les choix du concepteur doivent
satisfaire à un nombre important de critères (performances, flexibilité, testabilité,
reutilisabilité, sécurité, etc). Il s’agit de la problématique du partitionnement
matériel/logiciel. En limitant le nombre de critères et en figeant l’architecture cible, le
problème se réduit à un problème d’allocation qui peut se résoudre automatiquement
avec une heuristique basée sur une fonction pondérée dont les coefficients dépendent
des critères retenus. Dans le cas général (architecture cible hétérogène et nombre de
critères élevé), il faut aider le concepteur en lui offrant des moyens d’estimations
rapides des performances statiques et/ou dynamiques du partitionnement choisi.
Le niveau de description des modèles utilisés ainsi que le niveau de granularité du
partitionnement sont alors très influents sur les moyens et les résultats obtenus.
L’estimation des performances statiques telles que la surface de silicium occupée, la
puissance consommée repose sur des techniques de synthèse qui nécessitent une
description au moins du niveau algorithmique. Pour estimer les performances
dynamiques, il faut recourir à une analyse des contraintes temporelles ou à l’utilisation
d’un modèle de performance. L’analyse temporelle nécessite une description sous la
forme de diagramme de flot de données et/ou flot de contrôle et permet de calculer
une approximation des caractéristiques des processeurs. L’utilisation d’un modèle de
performance ne nécessite pas une description aussi détaillée que pour les estimateurs
cités précédemment et permet d’extraire un nombre plus important de résultats de
performances dynamiques du partitionnement choisi: temps de latence, débit sur un
bus, taux d’occupation d’une ressource, nombre moyen de messages dans un port de
communication, etc.
Ces résultats de performances s’obtiennent généralement par une approche
analytique (réseau de files d’attente, réseau de Petri stochastique) ou par simulation.
La complexité des systèmes que nous considérons sort souvent du domaine
d’application strict des modèles analytiques et la simulation reste alors la seule
alternative possible. Comme le modèle de performance représente à la fois la partie
logicielle et la partie matérielle résultant du partitionnement, il s’agit en fait d’une
technique de co-simulation.
Cette section présente la méthodologie de co-design préconisée par la méthode MCSE
caractérisée par sa méthode de partitionnement et sa technique de co-simulation.
Page 37 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Avant de décrire le principe de partitionnement qui repose sur une démarche itérative
et sur une évaluation des performances dynamiques du système, nous passons en
revue différentes méthodes de partitionnement. L’évaluation des performances
dynamiques est effectuée par une co-simulation. Nous présentons donc ensuite un
panorama des techniques de co-simulation existantes et celle retenue par l’équipe qui
est macroscopique et non interprétée. Le terme macroscopique signifie que le système
n’a pas besoin d’être entièrement détaillé. Le terme non-interprété signifie que seul le
temps des opérations et les dépendances temporelles sont pris en compte.

1.1 Présentation de la méthodologie de co-design

Les méthodologies proposées pour le co-design se distinguent essentiellement par :


- les concepts de modélisation utilisés de la spécification du système au produit
final,
- les modèles de l’architecture cible. L’architecture cible peut être une
architecture monoprocesseur constituée d’un processeur, d’un ensemble de
composants matériels spécifiques (ASIC, FPGA) et éventuellement une mémoire
commune. Il peut s’agir aussi d’une architecture distribuée composée d’un
réseau de processeurs matériels (ASIC, FPGA) et de processeurs logiciels
(microprocesseur, DSP, ASIP).
- La méthode de partitionnement (interactif, semi-automatique ou automatique).
- La méthode et technique de co-vérification.
- La technique de co-synthèse où l’on retrouve la synthèse du logiciel, du matériel
et des interfaces matériel/logiciel.

La méthodologie de co-design présentée ici est basée sur la méthodologie MCSE et est
caractérisée par une approche système, une modélisation selon 3 vues (fonctionnelle,
comportementale et architecturale), une architecture cible hétérogène et non figée,
une méthode de partitionnement interactif basée sur une évaluation des performances
dynamiques, une technique de co-simulation macroscopique et non-interprétée basée
sur un modèle d’attributs et une technique de co-synthèse incluant la génération des
interfaces matériel/logiciel qui repose sur un modèle de bus (protocole) générique et
l’utilisation d’une librairie de fonctions d’adaptation vers un bus spécifique.
L’utilisation de la méthodologie MCSE est recommandée pour faire tout d’abord
l’approche système nécessaire afin de rechercher une solution si possible globalement
optimale vis-à-vis de l’ensemble des contraintes. La solution fonctionnelle développée
servira alors comme base pour identifier les parties qui relèvent du co-design. La
description fonctionnelle de chaque partie sert ainsi de spécification. L’architecture de
la solution complète se déduit par MCSE. Les parties de l’architecture plus spécifiques
du co-design seront décidées selon les contraintes à satisfaire.

1.1.1 Rappel de la méthodologie MCSE


Page 38 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

MCSE est une solution possible comme schéma d'organisation pour tout
développement de systèmes électroniques et informatiques à caractère temps-réel.
Cette méthodologie conduit à la conception et la réalisation de composants, de cartes,
de systèmes à la fois pour les aspects matériel et logiciel, ainsi qu’au développement
de logiciels en divers langages de manière à particulariser le matériel pour que celui-ci
réponde aux fonctionnalités exigées de l'application.
Un développement, selon MCSE, est décomposé en 4 étapes :
- l'étape de Spécification qui a pour objectif d'élaborer une description externe la
plus complète possible du système à concevoir, et ceci à partir du cahier des
charges.
- l'étape de Conception fonctionnelle. Elle conduit à rechercher une solution pour
le système sous la forme d'un ensemble de fonctions et de relations entre celles-
ci. Cette solution est une vue orientée vers l'application et se doit d'être
indépendante de la technologie.
- l'étape de Définition de la réalisation. Il s'agit d'introduire la répartition
géographique et les interfaces physiques pour satisfaire les contraintes
technologiques, puis après avoir défini le partitionnement matériel/logiciel
compte-tenu des contraintes de temps et autres contraintes de réalisation, de
déterminer les spécifications des parties matérielles et logicielles.
- l'étape de Réalisation qui consiste à développer le matériel et le logiciel à partir
des spécifications de l'étape précédente.

A chaque niveau de description correspond un modèle bien formalisé qui sert


d’interface et de documentation entre les étapes successives. L’étape 3 sert à identifier
les spécifications de la réalisation. Aussi, c’est dans cette étape que se situe l’activité
de co-design.

Page 39 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Démarche de développement avec MCSE

1.1.2 Démarche pour la définition de la réalisation


L’étape de Définition de la Réalisation de MCSE est décomposée en 3 phases:
- Transformation de la solution fonctionnelle pour satisfaire les spécifications
technologiques de répartition géographique et d’interfaces. Il en résulte une
solution fonctionnelle détaillée et optimisée.
- Partitionnement au niveau système, qui vise à identifier à partir de la solution
fonctionnelle complète la partie purement logicielle, la partie purement
matérielle, la partie concernée par le co-design.
- Spécifications de réalisation pour le logiciel, le matériel et la partie co-design.
Les 3 parties sont considérées conjointement. Une vérification et une analyse
des propriétés de la solution achèvent cette phase et l’étape pour s’assurer du
respect de l’ensemble des contraintes.

La figure suivante montre l’organisation de la démarche pour cette étape. Une partie
des spécifications technologiques est considérée ici. Il s’agit des contraintes de
distance entre constituants ou/et entre entrées/sorties, des contraintes d’interfaces
physiques et d’interfaces homme/machine, des contraintes de performances, de
sûreté, de coût.
Durant l’activité de répartition géographique, un premier partitionnement est déjà
effectué. Il se base exclusivement sur les distances imposées entre certains
constituants du système. Il s’agit d’un partitionnement fonctionnel c’est-à-dire vis-à-
vis de l’objectif à satisfaire. La phase 1 amène ainsi à déformer la solution fonctionnelle
Page 40 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
de l’étape précédente au sens de son enrichissement par des détails en vue de
satisfaire des contraintes d’ordre technologique.
La phase 2 concerne cette fois le partitionnement du système complet et donc sa
solution fonctionnelle vis-à-vis de la technologie de réalisation, c’est-à-dire matériel ou
logiciel. Les contraintes influentes que sont les performances, la sûreté de
fonctionnement au sens large du terme, le coût, servent de base pour déterminer la
ou les parties qui conduisent à une réalisation purement logicielle, à une réalisation
purement matérielle, à une réalisation où une variation est possible entre le matériel
et le logiciel (partie qualifiée de co-design). Ce partitionnement est de niveau système
et se comprend bien lorsque l’on considère un système possédant le qualificatif de
complexe. La séparation radicale matériel ou logiciel est généralement assez simple
pour une grande partie du système. La partie restante (frontière à délimiter) qui se
veut plus délicate est celle relevant du co-design.

Description de la démarche pour l’étape de définition de la réalisation


La phase 3 vise à déterminer les spécifications les plus complètes possible de chacune
des parties et les interfaces entre elles. En suivant la méthodologie MCSE, la
spécification du matériel pour le système complet se fait en définissant le support
d’exécution (ou architecture matérielle) et toutes ses propriétés. La spécification du
logiciel s’obtient en définissant le schéma d’implantation du logiciel pour chaque
processeur programmable de l’architecture matérielle. Il reste alors chaque partie co-
design qui nécessite une démarche plus affinée pour aboutir à sa spécification détaillée
permettant ensuite la vérification et la réalisation. Le détail de cette démarche est
décrit dans le paragraphe suivant.

Page 41 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
L’activité de vérification et d’analyse globale vise à garantir au mieux que les
concepteurs disposent de spécifications de réalisation complètes, cohérentes et
optimales vis-à-vis des contraintes permettant d’aboutir à un système complet en
accord avec les spécifications du niveau système et donc en accord avec toutes les
exigences du client. Cette activité est basée sur l’emploi d’un modèle de description
mixte matériel-logiciel exécutable de la solution, ou tout au moins des parties critiques.
L’intérêt fondamental de cette démarche basée sur MCSE pour faciliter le travail de co-
design est de se poser réellement la question d’un partitionnement système (logiciel
ou matériel ou les deux simultanément) pour l’ensemble de l’application de manière à
correctement isoler les seules parties qui sont du ressort du co-design. D’une manière
générale, la spécification en entrée de l’activité de co-design se doit d’être le résultat
d’une démarche d’un niveau supérieur qui est le niveau système. Ceci correspond au
fait qu’une bonne résolution d’un problème passe d’abord par son “immersion” dans
un problème plus global.

1.1.3 Démarche pour le co-design


Le travail de co-design s’intègre ici comme un sous-ensemble de l’étape 3 de définition
de la réalisation de la méthodologie MCSE. Les données d’entrée en tant que
spécifications sont: la description fonctionnelle détaillée de la partie concernée par le
co-design, les spécifications non-fonctionnelles de cette partie. Il en résulte en sortie
la spécification détaillée et complète de la solution de réalisation.
La figure suivante représente les différentes phases de la démarche de co-design. On
notera bien entendu l’importance de la phase de partitionnement matériel/ logiciel et
d’allocation pour aboutir aux spécifications des 2 parties.

La démarche de co-design est décomposée en 2 phases:

Phase 1: Partitionnement et allocation, évaluation


- Décomposition de la solution fonctionnelle d’entrée en une partie logicielle et
une partie matérielle compte-tenu des performances et des contraintes de
temps à satisfaire,
- Spécification de la structure d’exécution (architecture matérielle) et allocation
des fonctions sur les composants,
- Evaluation et vérification de la solution vis-à-vis des spécifications non-
fonctionnelles imposées, ce qui implique une co-simulation.

Phase 2: Synthèse, génération, évaluation


- Conception architecturale et synthèse de la partie matérielle,
- Spécification et génération de la partie logicielle,
- Synthèse et génération des interfaces entre le matériel et le logiciel,

Page 42 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Démarche de co-design avec maîtrise des performances

Ces phases sont décrites plus en détail ci-après.

-A- Partitionnement, allocation et évaluation


La phase 1 concerne la recherche d’une architecture matérielle appropriée comme
support de la description fonctionnelle détaillée et qui va permettre d’aboutir à une
solution opérationnelle qui satisfait les contraintes de performances, les contraintes
de temps, le coût, etc. Le partitionnement de la structure fonctionnelle est la première
tâche qui permet d’identifier les fonctions qui peuvent être implantées en logiciel et
les fonctions à implanter obligatoirement en matériel.
Avec la méthodologie MCSE, nous proposons de suivre une démarche de
partitionnement interactif assuré par le concepteur car il peut aisément décider pour
chaque fonction le meilleur choix, en particulier après une modélisation et une
évaluation des performances.
La structure d’exécution peut alors être définie: les fonctions matérielles sont à
implanter sous la forme d’une architecture de composants matériels, les fonctions
logicielles sur un ou plusieurs microprocesseurs en fonction des contraintes de temps,
de coût et de répartition. Des liens nécessaires pour le couplage entre le matériel et le
logiciel doivent alors être spécifiés pour l’implantation des relations fonctionnelles.
D’une manière générale, la structure d’exécution résulte d’un travail d’abstraction fait
sur la structure fonctionnelle détaillée.

Page 43 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le résultat de ce travail doit être vérifié. Il s’agit de s’assurer que le partitionnement et
l’allocation choisis ainsi que les caractéristiques de l’architecture matérielle
permettent de satisfaire toutes les exigences attendues et écrites dans le document de
spécification sous le vocable spécifications non-fonctionnelles. Pour ce faire, le résultat
est transcrit sous la forme du modèle de performances de MCSE. Il s’agit d’un modèle
non-interprété qui, par simulation, permet de déduire les propriétés de performance.
Une modélisation de l’environnement est faite pour simuler les conditions d’utilisation
(workload).
D’autres moyens de vérification et d’analyse peuvent être ajoutés pour augmenter la
confiance dans la solution retenue.

-B- Génération, synthèse, évaluation


La phase 2 concerne la génération de l’ensemble de la solution, ce qui comprend: la
description de l’architecture matérielle en y incluant la description de tous les
composants spécifiques et/ou programmables (ASICs), les programmes pour tous les
microprocesseurs.
Pour la description du matériel, il faut distinguer 2 parties et donc 2 niveaux de détail.
Le premier niveau concerne le schéma d’interconnexion des composants retenus pour
la solution: microprocesseur(s), mémoires, etc. La description d’un tel schéma est
conventionnelle et s’obtient par l’emploi d’outils de saisie de schémas. Ce schéma
permet ensuite la réalisation directe par assemblage ou la réalisation de carte(s)
imprimée(s) comme support(s) des composants ou même la réalisation d’un "System
on a chip". Le deuxième niveau concerne la description de chaque ASIC. Cette
description est à faire de préférence en langage de haut-niveau tel que VHDL de
manière à pouvoir utiliser un synthétiseur architectural ou de haut niveau.
Pour la partie logicielle, très souvent, une organisation multi-tâches doit être retenue
par suite de l’existence de plusieurs fonctions asynchrones à implanter sur un même
microprocesseur. Une méthode efficace consiste à définir un schéma d’implantation
logicielle (voir MCSE) sans utiliser d’exécutif temps-réel. Une autre méthode consiste
à utiliser un exécutif temps-réel. Dans ce cas, chaque fonction est implantée comme
une tâche et les relations entre fonctions utilisent les mécanismes de sémaphore, de
boite à lettre, de partage de ressources. Une solution intermédiaire existe en utilisant
judicieusement les qualités de ces 2 méthodes.
Des interfaces correctes entre le matériel et le logiciel doivent aussi être générées pour
une implantation appropriée et efficace des relations fonctionnelles. Ces interfaces
sont produites par synthèse à partir des caractéristiques du couplage matériel entre le
microprocesseur et son environnement. Des modèles génériques de bus sont ici
exploitables ( bus PCI,....).
L’ensemble de la solution - matériel, logiciel, interfaces - sert ensuite pour une
vérification détaillée de toutes ses propriétés: propriétés fonctionnelles et non-
fonctionnelles. Une technique de co-simulation est alors appropriée pour ce type de
vérification. Un modèle de l’environnement est à nouveau nécessaire. Il résulte du
Page 44 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
travail déjà effectué pour l’ensemble du système au niveau fonctionnel. Il s’agit donc
d’exploiter le modèle fonctionnel complet et optimisé pour lequel la partie co-design
du système qui vient d’être conçue est remplacée par le résultat de cette phase 2.
Le résultat issu de cette étape de co-design peut ensuite être prototypé, vérifié et
validé puis intégré dans la solution d’ensemble du système complet.

1.1.4 Bilan
La présentation faite dans ce paragraphe montre clairement que la démarche de co-
design n’est pas une activité isolée de la conception de l’ensemble du système. Faisant
partie intégrante de l’étape de définition de la réalisation, le travail de co-design est
appliqué sur une ou des parties qui ont été pleinement identifiées comme justifiant
d’une telle approche. En amont, en plus d’un partitionnement géographique réalisé
durant la conception préliminaire, un travail de partitionnement au niveau système
conduit à décider d’une première grande répartition matérielle ou logiciel si possible
optimale globalement. Il en résulte une identification de zones intermédiaires qui
nécessitent un travail plus approfondi qui est alors typiquement du ressort du co-
design. Pour ces parties, un optimum local est alors recherché. Une telle approche
système en 2 temps évite les écueils du “défaut de myopie” qui amènerait à trouver
un optimum local pour une spécification donnée sans s’être assuré que la spécification
résulte elle aussi d’un optimum pour le niveau système.
Bien entendu, lorsqu’un problème posé est seulement du ressort du co-design, seule
la démarche décrite par la figure 2.3 est suffisante à condition de disposer des
spécifications correctes et complètes de l’objet à concevoir. Pour décider de la bonne
démarche à suivre, une question importante à se poser est de savoir si le problème est
ou non “immergé” dans un problème plus vaste. On constate aujourd’hui que la
plupart des problèmes sont présentés isolés alors qu’en réalité ils ne le sont pas. MCSE
impose une démarche plus globale ne serait-ce qu’en imposant d’abord une analyse et
une modélisation de l’environnement de l’objet à concevoir, modélisation bien utile
en final pour la vérification et la qualification du système placé dans son
environnement.

1.2 Méthodes de partitionnement


Le problème du partitionnement matériel/logiciel est au coeur de l’activité de co-
design. Le choix de l’architecture matérielle est un élément de décision essentiel et la
démarche diffère selon que l’architecture se trouve imposée ou choisie d’emblée ou
que l’architecture et les composants de celle-ci sont à déterminer. La première
situation est la plus commune et la plus simple. L’architecture matérielle est
généralement une architecture générique constituée d’un microprocesseur, d’un
ensemble de circuits matériels programmables ou d’ASICs et d’une mémoire
commune. Le problème du partitionnement se réduit alors à un problème de
partitionnement binaire matériel/logiciel pour l’allocation des éléments fonctionnels
sur les constituants de l’architecture et peut se résoudre de manière automatique.
Page 45 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Nous nous intéressons à la deuxième situation plus complexe et plus proche de la
réalité industrielle. Dans ce cas, face à la nature hétérogène de l’architecture cible et à
la diversité des contraintes imposées, une démarche itérative et guidée par le
concepteur s’impose. Il s’agit alors d’offrir au concepteur des moyens rapides
d’estimation des propriétés de l’implantation résultant du choix de l’architecture, du
partitionnement et de l’allocation pour vérifier si celles-ci répond aux contraintes
imposées. Pour les parties du système relevant du co-design, les contraintes imposées
sont surtout des contraintes de performances. En effet, les contraintes telles que la
flexibilité, la testabilité, l’utilisation de composants du commerce ou de technologies
maîtrisées par l’entreprise, la sûreté de fonctionnement et les coûts interviennent
principalement au niveau du partitionnement système qui a pour but le découpage du
système en un ensemble de partitions où chaque partition devra s’exécuter soit en
logiciel soit en matériel. Les contraintes de performances sont de nature statique ou
dynamique. L’estimation des performances statiques telles que la surface de silicium
occupée, la puissance consommée repose sur des techniques de synthèse. La plupart
des travaux de la communauté du co-design sur l’estimation des performances
dynamiques d’un partitionnement, sont basés sur une analyse des contraintes
temporelles et un calcul de la charge du processeur par des techniques proches de
celles utilisées en ordonnancement de tâches pour des systèmes temps-réels. Nous
proposons une autre alternative qui consiste à utiliser un modèle de performance. La
simulation de ce modèle de performance permet d’extraire un ensemble d’estimations
de performances plus riches que les approches analytiques: débit sur un bus, taux
d’occupation d’une ressource, temps de latence d’un message, détection du non-
respect d’une contrainte temporelle, etc.

1.2.1 Le partitionnement matériel/logiciel


Le partitionnement matériel/logiciel assure la transformation des spécifications de la
partie du système relevant de l’activité co-design en une architecture composée d’une
partie matérielle et d’une partie logicielle. Les spécifications considérées sont en
réalité une description fonctionnelle détaillée résultant d’une approche système. Cette
transformation s’effectue habituellement en deux phases: la sélection d’une
architecture matérielle et l’allocation des éléments (fonctions et éléments de relations)
du modèle fonctionnel sur les éléments de cette architecture. Plusieurs critères
peuvent intervenir sur le double choix (architecture et allocation) d’un
partitionnement tels que par exemple :
- les performances statiques (consommation, surface de silicium, coûts, taille du
code, taille de la mémoire, etc) et dynamiques (contraintes de temps, débit,
temps de latence, taux d’occupation, etc). Elles influent surtout sur l’allocation
des fonctions.
- la sécurité: La prise en compte de la sûreté de fonctionnement peut induire des
contraintes au partitionnement matériel/logiciel (redondance de composants
matériels et de tâches logicielles par exemple),
Page 46 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
- la flexibilité: l’implantation logicielle d’une fonction offre des possibilités
d’évolution plus importantes qu’une implantation matérielle,
- la réutilisation: La réutilisation de composants est un facteur important de
productivité, mais introduit des contraintes au niveau du partitionnement,
- la testabilité: l’extraction d’informations en temps-réel nécessite l’ajout de
composants matériels supplémentaires (Bist, Boundary Scan) ou l’ajout
d’instructions de capture.

Actuellement, il n’existe pas de méthodes formelles réellement opérationnelles qui


permettent à partir des contraintes à satisfaire et des spécifications du système de
générer directement une répartition matériel/logiciel. La difficulté du problème est
liée à la diversité des contraintes à satisfaire et des possibilités de sélection
d’architecture puis d’allocation.
Le partitionnement s’effectue par des approches successives soit de manière
automatique par le biais d’algorithmes de recherche soit de manière interactive avec
l’aide du concepteur.
La plupart des techniques de partitionnement automatique repose sur une
architecture cible imposée et monoprocesseur, une heuristique et l’utilisation d’une
fonction de coût dont les coefficients de pondération dépendent de critères tels que
ceux cités précédemment. Le partitionnement interactif cible généralement vers une
architecture hétérogène à définir et s’appuie sur des estimateurs de performances
statiques et/ou une estimation des performances dynamiques du système pour guider
le concepteur dans le choix d’une répartition.

Les techniques de partitionnement décrites dans la littérature peuvent être classées


par:
- leur degré d’automatisation allant d’une démarche manuelle à une démarche
entièrement automatique,
- Les critères influençant le choix d’un partitionnement (contraintes statiques ou
dynamiques, sûreté de fonctionnement, flexibilité, testabilité, coûts),
- le choix de l’architecture cible figée ou libre,
- le degré d’abstraction du modèle représentant les éléments de la spécification
du système à partitionner et de l’architecture matérielle allant d’une
modélisation macroscopique à une modélisation architecturale détaillée.

Pour les spécifications d’entrée d’un partitionnement, trois niveaux de granularité du


partitionnement sont habituellement utilisés: le niveau tâche, le niveau procédure et
le niveau instruction. Pour le niveau tâche (coarse-grain partitioning), l’unité
d’allocation est la fonction qui est considérée indivisible et dont le comportement n’est
pas obligatoirement séquentiel.

Page 47 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Pour le niveau procédure, une fonction est décomposée en un ensemble de séquences
d’instructions appelées procédures et qui peuvent être allouées sur des processeurs
différents.
Pour le niveau instruction (fine-grain partitioning), l’unité d’allocation est la plus petite
possible puisqu’il s’agit d’une instruction. L’utilisation d’un niveau de granularité fine
concerne plutôt des systèmes de faible complexité ou une conception architecturale
avancée qui se situe relativement tard dans le cycle de développement.

1.2.2 Le partitionnement automatique


Le problème du partitionnement est souvent présenté comme un problème NP
complexe dépendant d’un grand nombre de paramètres. Pour résoudre ce problème,
la plupart des méthodes automatiques réduit le nombre des paramètres (prise en
compte d’un nombre limité de critères) et utilise une heuristique basée sur une
fonction de coût pondérée par les critères retenus.

Actuellement de nombreuses heuristiques de partitionnement ont été développées.


On peut citer en autres (liste non exhaustive):
- l’algorithme gourmand (Greedy algorithm) utilisé dans VULCAN pour lequel
toutes les fonctions sont initialement implantées en matériel et sont migrées
vers le processeur logiciel en vérifiant les contraintes temporelles. La fonction
de coût utilisée est pondérée par la surface du matériel, la taille du programme
de code (mémoire) et le taux d’occupation du processeur.
- l’approche de COSYMA est opposée à celle utilisée dans VULCAN. Les fonctions
sont au départ toutes implantées en logiciel puis migrées vers le matériel
jusqu’au respect des contraintes de performances.
- Les algorithmes utilisés dans Co-Saw et dans SpecSyn sont basés sur la
construction progressive de groupes de fonctions (clustering based algorithm)
pouvant partager la même ressource matérielle ou logicielle.

Les algorithmes cités précédemment dépendent fortement (coefficient de


pondération de la fonction de coût) des caractéristiques de l’architecture cible choisie.
Souvent l’architecture cible est composée d’un seul processeur logiciel couplé à un ou
plusieurs ASICs et éventuellement une mémoire commune. Peu de techniques de
partitionnement ciblent vers une architecture hétérogène composée d’un ensemble
de processeurs logiciels (microprocesseur, DSP, ASIP) et matériels (ASIC). Certains
auteurs proposent cependant une heuristique basée sur la construction progressive de
groupes de process (clustering based algorithm) dont la fonction de coût dépend de la
communication inter-processeurs, des temps de commutation de contexte (approche
préemptive et non synchrone) et du taux d’utilisation des ressources. Les résultats
obtenus sont très dépendants des coefficients de la fonction de coût: "the cost function
plays an important role in our partitioning approach".

Page 48 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
L’architecture générique mono-processeur et constituée d’un ensemble de FPGA
correspond peu à la réalité industrielle. Les composants programmables ont des
performances plus faibles (surface de silicium occupée, fréquence maximale de
fonctionnement) et un coût plus élevé (production en grande série) que les circuits non
programmables. De plus, même les "System on a chip" ne sont pas mono-processeur
car ils disposent de plus en plus souvent d’un
coeur de DSP et d’un coeur de microcontroleur (MCU). Ces techniques de
partitionnement automatique ne sont donc intéressantes que pour le prototypage
rapide sur une carte constituée d’un microprocesseur, d’un ensemble de FPGA et
éventuellement une mémoire commune. Mais pour ce type d’application, la rapidité
d’obtention d’une implantation est un critère aussi important que la qualité du
partitionnement obtenu: Il s’agit avant tout de faire une vérification fonctionnelle et
non une réelle analyse des performances du futur produit industriel.
Les techniques de partitionnement automatique souffrent généralement du fait
qu’elle ne prenne pas en compte l’expérience et le bon sens des concepteurs. Dans la
réalité industrielle, le partitionnement d’un système ne pose problème que pour une
petite partie du système. Le concepteur peut facilement faire un partitionnement
grossier du système avant de se concentrer sur les parties délicates. Or les techniques
de partitionnement automatique considèrent le système dans son ensemble et
n’utilise pas le fait que le concepteur peut fournir un partitionnement initial proche de
la solution. Elles vont donc balayer un ensemble d’alternatives inutiles et dans certains
cas sont moins efficaces (temps de recherche) qu’un partitionnement interactif. Inclure
le concepteur dans la boucle de recherche de la solution optimale d’un
partitionnement, offre aussi un avantage plus subtil: cela permet d’éliminer la
suspicion des concepteurs face aux résultats obtenus par un partitionnement
automatique. En effet, la nature humaine est ainsi faite qu’elle a souvent tendance à
vouloir prouver qu’elle peut obtenir un résultat meilleur que celui obtenu par une
méthode automatique. De plus, le concepteur a aussi la maîtrise complète de la
solution retenue avec toutes ses justifications.

1.2.3 Le partitionnement interactif


Il existe dans la littérature une technique de partitionnement interactive (PARTIF)
permettant de cibler sur une architecture hétérogène. Le concepteur peut aisément
explorer plusieurs alternatives de partitionnement du système en manipulant une
hiérarchie d’automates à états finis concurrents représentée selon le formalisme
SOLAR. Un ensemble de primitives de transformations d’états (déplacement,
regroupement, décomposition,...) est disponible. Cette approche est intéressante mais
pour l’instant le concepteur dispose de peu de résultats quantitatifs en retour pour
évaluer la partie logicielle (statistiques sur les interconnexions et les variables
partagées) et la partie matérielle (statistiques sur le nombre d’états et sur le nombre
d’opérateurs de la partie opérative) obtenues de manière à les comparer aux
contraintes imposées.
Page 49 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

1.2.4 L’analyse des propriétés d’un partitionnement


Pour analyser les propriétés d’un partitionnement, la plupart des techniques de
partitionnement utilisent des estimateurs basés sur:
 une analyse des contraintes temporelles, ce qui nécessite de représenter le
comportement des fonctions à un niveau interprété et très détaillé.
Généralement, le comportement d’une fonction est représenté sous la forme
d’un flot de donnée et d’un flot de contrôle. L’analyse des graphes permet
d’extraire une approximation du temps d’exécution de chaque fonction et de
vérifier le respect des contraintes temporelles. Puis pour une implantation
logicielle de la fonction, on applique les algorithmes utilisés dans les problèmes
d’ordonnancement des systèmes temps réels pour calculer la charge du
processeur. Formulé sous sa forme la plus simple (monoprocesseur et tâches
périodiques), le problème se résout souvent par l’algorithme de base RMS "Rate
Monotonic Scheduling". Le problème se complique lorsque les tâches peuvent
être sporadiques ou lorsque le système est distribué.
 une analyse statique basée sur des résultats de techniques de synthèse qui
nécessite une description des fonctions au moins au niveau algorithmique
(synthèse haut niveau) pour extraire des caractéristiques telles que la surface
de silicium occupée, la puissance dissipée, le nombre de broches, la taille du
programme code, la taille de la mémoire nécessaire, etc.
Très peu de techniques de partitionnement sont basées sur un modèle plus abstrait et
non-interprété d’un système. Certains auteurs proposent une technique de
partitionnement basée sur un modèle "système". Les processeurs sont représentés par
des ressources caractérisées par une taille mémoire et le temps d’exécution d’une
instruction. La partie logicielle est représentée par des tâches utilisant une quantité de
mémoire et un nombre d’instructions donné.

1.2.5 La méthode de partitionnement proposée


Notre approche consiste à considérer que le partitionnement se fait à un niveau
d’abstraction le plus élevé possible afin de considérer le système dans sa globalité et
doit exploiter au mieux le bon sens et l’expérience des concepteurs. Ainsi impliqué
dans le processus de partitionnement, le concepteur continue à accumuler une
expérience et à développer ses compétences.
Pour élever le niveau d’abstraction des modèles du système, nous n’utilisons pas pour
l’instant d’estimateurs statiques puisque ceux-ci nécessitent une description détaillée
et interprétée du comportement des fonctions. L’évaluation d’un partitionnement
repose sur la simulation d’un modèle des performances du système. Contrairement
aux approches analytiques, la simulation n’est pas limitée par la complexité du système
et elle permet d’obtenir un ensemble d’estimations de performances plus important.
La méthode de partitionnement proposée repose sur la démarche itérative suivante:
Compte tenu des divers critères qui lui sont imposés, le concepteur définit une
Page 50 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
première architecture matérielle. Les critères tel que la flexibilité, la testabilité,
l’utilisation de composants du commerce (COTS) ou technologies maîtrisées par
l’entreprise, la sûreté de fonctionnement, le coût et l’expérience du concepteur
influent directement sur cette première implantation. Une fois cette architecture
matérielle définie, le concepteur alloue les fonctions à très fortes contraintes
temporelles aux processeurs matériels et le reste des fonctions aux processeurs
logiciels en limitant si possible les communications inter-processeurs. Avec MCSE,
l’alternative logiciel/matériel se détermine par le temps d’exécution approximatif de
chaque fonction et sa fréquence maximale d’activation (hypothèse de tâches
périodiques). Puis, la co-simulation reposant sur la transcription en VHDL du modèle
de performance du système donne en retour des mesures de performances tels que le
temps de réponse des fonctions, le temps de latence de messages, le débit sur un bus
ou encore le taux d’occupation d’une ressource. L’analyse de ces performances permet
de vérifier le respect ou non des contraintes de performances à satisfaire et d’identifier
les ressources critiques. Le concepteur modifie alors l’implantation des fonctions et
ressources jugées critiques et réévalue le modèle. Il peut aussi revenir sur
l’architecture matérielle en changeant sa constitution et/ou des caractéristiques de ses
composants.
Dans la plupart des cas, la mise à jour du modèle portera essentiellement sur des
attributs des modèles fonctionnel et architectural et l’allocation des fonctions. En effet,
comme nous le verrons plus tard le modèle de performance étant basé sur le concept
d’attribut, une modification de l’architecture matérielle ne nécessite pas forcément
une nouvelle saisie (graphique ou textuelle) du modèle: l’utilisation de paramètres
génériques associés aux attributs des éléments du modèle de performance permet de
parcourir un espace assez vaste des solutions possibles d’une architecture.

1.3 Techniques de co-simulation


Les problèmes de la co-simulation et du partitionnement matériel/logiciel sont souvent
liés. Par exemple, notre méthode de partitionnement repose sur une co-simulation
pour extraire les performances dynamiques du système puisque le modèle de
performance qui est simulé représente à la fois la partie matérielle et la partie logicielle
du système. De plus, une fois le partitionnement effectué, le concepteur effectue
généralement une vérification fonctionnelle du résultat obtenu. Lors de l’analyse des
résultats de cette co-simulation, la détection éventuelle d’erreurs nécessite un retour
vers les phases précédentes et notamment vers la phase de partitionnement
matériel/logiciel. La co-simulation n’est pas la seule technique disponible pour vérifier
la conception et l’implantation d’un système. D'une manière générale, l'observation
des propriétés d'un système peut résulter de 3 techniques différentes: l'évaluation
analytique (méthodes formelle), la simulation, l'observation et la mesure (monitoring)
sur un prototype ou un émulateur.
Le problème de la définition des vecteurs de test ou stimuli et de leur validité est
généralement peu abordé alors qu’il est essentiel. Il faut tenir compte de tous les cas
Page 51 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
de scénario de charge du système. Il est bon de noter que pour cet aspect de la co-
simulation, notre approche se distingue par une modélisation du système et de son
environnement avec le modèle de performance de MCSE. Cette approche évite de
passer des stimuli au simulateur et permet surtout de modéliser plus facilement les
comportements éventuellement complexes des entités de l’environnement du
système.

1.3.1 La co-simulation
Une co-simulation est une simulation simultanée de la partie logicielle et de la partie
matérielle d’un système et de leurs interactions. Elle est utilisée pour observer le
comportement du système complet qui se compose de quatre classes d’objets: les
processeurs matériels ou co-processeur dédiés, les processeurs logiciels, le logiciel
s’exécutant sur les processeurs logiciels et la logique d’interface (communication inter-
processeurs).
Un système complet peut être simulé à différents niveaux de détail. Par exemple, un
processeur logiciel peut être décrit comme un ordonnanceur de tâches et le logiciel
comme un ensemble de tâches. Mais le processeur logiciel peut aussi être représenté
par une description architecturale détaillée (pipeline, cache, registre, ALU...) et le
logiciel par une séquence d’instructions du jeu d’instructions du processeur.
Généralement, plus le développement est avancé, plus la co-simulation est détaillée.
Au cours du cycle de développement, la co-simulation repose donc sur différents
modèles et vise plusieurs objectifs: elle sert à faire une vérification fonctionnelle ou
comportementale détaillée (modèle interprété), une évaluation des performances
(modèle non interprété) ou les deux simultanément (modèle hybride).
Nous considérons qu’une méthodologie de co-design repose sur l’utilisation de
plusieurs techniques de co-simulation: une co-simulation non-interprétée pour
l’analyse des performances lors de la phase de recherche de l’architecture et du
partitionnement matériel/ logiciel, une co-simulation fonctionnelle détaillée après
synthèse (ou co-vérification) pour valider l’implantation. On parle alors de vérification
d’un prototype virtuel.
Les techniques de co-simulation se distinguent par l’utilisation d’un modèle ou langage
unique ou non et par le niveau d’abstraction du modèle de description matérielle
(VHDL comportemental, RTL, netlist) et logicielle (C, jeu d’instruction, microcode).
Pour les techniques basées sur différents modèles de représentation des parties
matérielles et logicielles, il faut faire communiquer différents simulateurs
Les techniques mono modèles se distinguent par le degré d’abstraction du modèle des
processeurs logiciels (modèle d’attributs, modèle flot de ressource, modèle ISA du jeu
d’instructions).

1.3.2 Les techniques multi-langages

Page 52 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Les techniques basées sur des modèles ou langages différents de représentation des
parties matérielles et logicielles, reposent sur la coopération de simulateurs. On parle
alors de simulation hétérogène.
La plupart des projets de co-design utilisent une simulation VHDL de la partie
matérielle et l’exécution d’une description algorithmique de haut niveau de la partie
logicielle. Le langage VHDL permet en effet d’intégrer une description écrite dans un
langage autre que VHDL grâce à l’interface Foreign Language Interface (VHDL’93). Il
s’agit souvent du langage C avec lequel a été également écrit le noyau du simulateur
VHDL auquel on accède via un ensemble de primitives spécifiques. L’interface entre
l’API du simulateur VHDL et l’environnement de programmation C (compilateur,
debuggeur, etc) utilise des mécanismes de communication inter-process (IPC d’unix.
Lorsque le simulateur VHDL reçoit une information de l’exécution de la partie C
(socket), il met à jour les signaux concernés après un délai d’attente qui correspond au
temps d’exécution de la partie C. Ainsi, l’exactitude de la simulation est préservée: "The
hardware simulator thus serves as a supervisor, ensuring that data is accessed in
correct order".
Le processeur logiciel qui est l’élément clef de la co-simulation est souvent représenté
sous la forme d’une machine virtuelle. Cette machine virtuelle peut se décrire à
différents niveaux: système d’exploitation multi-tâches, jeu d’instructions,
architecture physique.
La machine virtuelle est parfois modélisée au niveau système d’exploitation
(ordonnanceur de tâches à priorité fixe décrit en VHDL) et le logiciel est modélisé par
un ensemble de tâches écrites en C (couplage avec l’API du simulateur VHDL).
Le plus souvent la machine virtuelle est modélisée par son jeu d’instructions. Dans ce
cas, le logiciel doit être compilé pour le microprocesseur cible. Il n’est pas toujours
possible d’obtenir d’un fabricant de microprocesseurs, un modèle de simulation basé
sur le jeu d’instruction du processeur. Parfois pour protéger la propriété intellectuelle
du fabricant, le modèle de simulation du microprocesseur est uniquement un modèle
de bus (bus level model). Un modèle de bus simule les cycles requis pour une
transaction sur le bus (accès en lecture ou écriture) mais ne modélise pas les actions
d’une instruction.
Pour faire communiquer un simulateur HDL (VHDL, Verilog) et un simulateur du jeu
d’instructions d’un processeur, un simulateur de modèle de bus d’un processeur ou
l’exécution d’une description algorithmique de la partie logicielle, on peut également
utiliser un fond de panier de simulateur tel que Ptolemy ou simMatrix de Precedence
Inc.
Enfin, les vendeurs d’outils EDA fournissent aujourd’hui des solutions spécifiques au
problème de la co-simulation (Seamless CVE de Mentor, Eagle i de Viewlogic). Par
exemple, l’outil Seamless CVE de Mentor Graphics permet de synchroniser par une
modélisation particulière du bus du processeur un simulateur du jeu d’instructions du
microprocesseur (outil XRAY de Microtec) et un simulateur VHDL ou Verilog.

Page 53 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
L’utilisation d’un simulateur VHDL pour la partie matérielle et éventuellement pour la
partie logicielle augmente sensiblement les temps de simulation. Pour réduire les
temps de simulation, il faut élever le niveau d’abstraction des modèles. Ceci est
possible pour une évaluation des performances mais pas pour une vérification
fonctionnelle détaillée. Dans ce dernier cas, il faut recourir à un émulateur matériel.
L’emploi d’un émulateur matériel a cependant deux inconvénients majeurs:
 les émulateurs sont très chers,
 ils ne permettent d’émuler le système qu’à une fréquence 10 à 100 fois plus
faible que la fréquence nominale de fonctionnement. Par exemple, l’émulation
du processeur MicroSPARCII (Sun) sur le système de prototypage QuickTurn
n’a pu s’effectuer qu’à une fréquence de fonctionnement maximale de 750
Khz.
Pour la co-simulation hétérogène, l’équipe MCSE a expérimenté une technique de co-
simulation basée sur une implantation en Java des éléments de relations du modèle
MCSE (port de communication et variable partagée) pour coupler différents
simulateurs. Cette approche se caractérise par une portabilité multi plate-forme
(l’utilisation de Java permet de cibler sur tout type de plate-forme) et par la possibilité
de faire de la co-simulation distribuée en Intranet (sockets) ou en Internet (applet Java
et utilisation du protocole Remote Method Invocation).

1.3.3 Les techniques mono-langages ou mono-modèle

Les techniques mono-modèles ou mono-langage se distinguent par leur concept de


modélisation et le degré d’abstraction du modèle des processeurs qui varie en fonction
de la finalité de la co-simulation (évaluation des performances et/ou vérification
fonctionnelle).
Le processeur logiciel est encore souvent modélisé par son jeu d’instructions et son
architecture qui peut être plus ou moins détaillée (modélisation d’un cache mémoire,
pipeline d’instructions, gestion des interruptions, registres, ALU, etc.). Dans le projet
TOSCA, un processeur est modélisé pour la description VHDL d’un jeu d’instructions
virtuel et d’une architecture générique qui permettent de cibler sur différents
processeurs spécifiques. Ce type de co-simulation souffre d’un temps de simulation
important mais offre un avantage au niveau de la synthèse logicielle: la qualité du code
obtenu en appliquant les techniques de synthèse (allocation des registres,
ordonnancement,...) directement sur un modèle de jeu d’instructions est meilleur que
le résultat obtenu par compilation d’une description algorithmique de haut niveau tel
que le langage C. Dans le projet RASSP, le processeur est aussi modélisé par son jeu
d’instructions, mais le modèle est plus grossier, est non-interprété et sert uniquement
à l’analyse des performances dynamiques d’un système (outil Cosmos de Omniview
présenté plus loin).
Le processeur logiciel peut aussi être modélisé comme une ressource active
caractérisée par un ensemble d’attributs influençant son comportement temporel. Le
Page 54 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
système est alors modélisé soit par un flot de transactions (modèle de SES/workbench
soit par un modèle d’architecture dont tous les éléments sont caractérisés par des
attributs temporels tel que le modèle de performance de MCSE.

1.3.4 La technique de co-simulation utilisée

La technique de co-simulation retenue par l’équipe MCSE repose sur la transcription


du modèle de performance de la méthodologie MCSE en une description VHDL et
l’utilisation d’un simulateur VHDL du commerce.

La figure suivante illustre le principe de co-simulation retenu.

Le modèle de performance de MCSE décrit sous une forme textuelle ou résultant d’une
saisie graphique sert de point d’entrée à un générateur de code (MCSE-GEN) qui le
transforme en un code VHDL simulable. La simulation du code généré produit un fichier
de trace représentant l'évolution des fonctions et des relations inter-fonctions
(mécanismes de communication et de synchronisation). Ce fichier est alors
directement exploitable par un outil d’analyse de performances (MCSE-PERF) pour la
présentation des résultats.
Le modèle de performance capable de modéliser la partie logicielle et la partie
matérielle est un modèle :
 macroscopique: le système n’a pas besoin d’être entièrement détaillé ce qui
autorise à faire une évaluation des performances très tôt dans le cycle de
développement.
 non-interprété: seuls les temps des opérations et des dépendances temporelles
sont pris en compte ce qui permet un parcours rapide du domaine des solutions
possibles d’un partitionnement tout en évitant l’écriture des parties
algorithmiques des opérations.
 évolutif: la notion d’attributs permet d’enrichir le modèle. L’élément délicat qui
est le processeur logiciel pour la co-simulation, est représenté par sa puissance

Page 55 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
qui intervient comme un facteur multiplicatif du temps d’exécution des
opérations (attribut ‘Power), son degré de concurrence (attribut ‘Concurrency),
sa politique d’ordonnancement des tâches (attribut ‘Policy) et son temps de
commutation de tâches (attribut ‘Overhead).
Le générateur de code VHDL ne se limite pas à la génération automatique d’un code
non-interprété pour l’évaluation des performances. En effet, en remplaçant le temps
des opérations élémentaires par une description algorithmique on obtient alors un
modèle VHDL interprété qui permet de faire en plus une vérification fonctionnelle du
système. Le code algorithmique des opérations doit alors être saisi manuellement par
le concepteur. Mais comme VHDL est un langage très déclaratif, le générateur produira
entre 60-80% du code automatiquement car il se charge de traduire toute
l’organisation (ou composante structurelle) du modèle.
Une autre technique de co-simulation est également en cours de développement dans
l’équipe MCSE. Il s’agit de transcrire le modèle de performance en un code C++ et
d’obtenir les résultats par exécution du programme C++.

2. Introduction aux HDL


2.1 Historique

2.1.1 Première époque : dessin au micron


Jadis, les outils informatiques n’étant ni aussi puissants ni aussi répandus
qu’aujourd’hui, la conception de circuits intégrés était un métier manuel.
On dessinait les composants (transistors) à la main, sur un papier spécial (Mylar) avec
des crayons de couleur. C’est ce qu’on appelle le dessin au micron.

Une telle technique limitait naturellement la complexité des dispositifs conçus. La


complexité était également limitée par les performances de la technologie disponible
chez les “fondeurs” (ceux qui fabriquent véritablement le dispositif).

Tout était donc pour le mieux dans le meilleur des mondes possibles, ou presque. A
cette époque le concepteur manipulait des objets élémentaires qui étaient des
surfaces rectangulaires de couleur. Un transistor était constitué de l’assemblage d’une
dizaine de ces rectangles (25 rectangles pour l’inverseur CMOS ci-dessous).

Page 56 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

2.1.2 Deuxième époque : les langages de description


Lorsque la technologie a évolué suffisamment pour offrir des ordinateurs puissants et
des technologies permettant d’intégrer un grand nombre de transistors sur la même
puce il a fallu - et on a pu - envisager de nouvelles méthodes de travail.

Les langages de description de matériel (HDL) ont ainsi fait leur apparition. Ils avaient
pour but de modéliser, donc de simuler, mais aussi de concevoir. Des outils
informatiques (placeurs-routeurs) permettant de traduire automatiquement une
description textuelle en dessins de transistors (dessins au micron) ont fait leur
apparition.

Les principes de cette évolution-révolution sont assez simples :

 Les langages sont structurels, c’est à dire qu’ils décrivent la structure de


l’ensemble par assemblage de composants élémentaires.
 Il existe des bibliothèques de composants élémentaires. Ces bibliothèques
contiennent, pour chaque composant élémentaire, un dessin au micron, destiné
au placement-routage, et une représentation de la fonction réalisée, destinée
au simulateur.
 Les outils informatiques (simulateurs, placeurs-routeurs) utilisent la description
textuelle structurelle de l’ensemble et le contenu des bibliothèques.

Page 57 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le concepteur est donc déchargé d’une partie importante du travail. Il aborde les
problèmes à un niveau d’abstraction plus élevé. Il manipule des objets élémentaires
de l’ordre de la dizaine de transistors : les portes logiques. Un exemple de description
textuelle est présenté ci-dessous :

2.1.3 Troisième époque : les schémas


Une pseudo-révolution modifie encore le métier de concepteur de circuits intégrés :
l’apparition des interfaces graphiques et donc des éditeurs de schémas. La description
textuelle est remplacée par une description schématique.

Description schématique du même circuit

Il est important de comprendre en quoi cette modification, en apparence


fondamentale, n’est en fait que superficielle. Les anciens outils informatiques restent

Page 58 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
inchangés, à ceci près qu’on leur adjoint un traducteur automatique de description
schématique en description textuelle.
La seule réelle modification est d’ordre ergonomique : il est en général beaucoup plus
facile de lire et de comprendre un schéma qu’une description textuelle.

Les deux exemples ci-dessus montrent l’équivalence entre les deux types de
représentation. On imagine aisément comment passer de la forme schématique à la
forme textuelle. On comprend aisément aussi pourquoi les informations
supplémentaires contenues dans la première (symboles des portes, position relative
et orientation des portes, taille et couleur des objets, polices de caractère utilisées,
etc.) ne sont utiles qu’au seul concepteur humain. Les outils informatiques n’en ont
pas l’usage.

Certaines propriétés “intéressantes” des langages textuels de description de matériel


méritent d’être notées :

 Une description textuelle est plus facilement transportable d’un outil de CAO à
l’autre, d’un concepteur à l’autre, d’une entreprise à l’autre. La portabilité est
accrue.
 Il est beaucoup plus facile de modifier une description textuelle qu’un schéma.
La maintenabilité est plus grande.
 On peut aisément archiver un module sous la forme de sa description textuelle
afin de le réutiliser dans un autre projet (éventuellement après modification).
C’est plus difficile avec d’autres représentations pour lesquelles le coût de mise
à jour est plus élevé.

2.1.4 Quatrième époque : l'abstraction fonctionnelle


Les langages fonctionnels (ou comportementaux) de description de matériel, grâce aux
nouvelles possibilités de description à un niveau d’abstraction plus élevé, ont répondu
à des besoins fondamentaux des concepteurs de circuits intégrés :

 La réduction des temps de conception.


 L’accélération des simulations qui devenaient prohibitives avec l’accroissement
de complexité des dispositifs.
 La normalisation des échanges : le monde de l’électronique a souffert pendant
longtemps de la multiplicité des langages, des formats, des outils de CAO
utilisés. L’émergence des langages fonctionnels de description de matériel a été
l’occasion de remédier à ce problème. Désormais, des langages normalisés et
universellement reconnus servent aux échanges entre partenaires industriels,
entre fournisseurs et clients. Verilog, VHDL et SystemC en sont des exemples.
Page 59 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
 L’anticipation : grâce aux modèles HDL il est possible de concevoir un système
alors que ses composants ne sont pas encore disponibles.
 La fiabilité : les langages HDL sont conçus pour limiter en principe les risques
d’erreur.
 La portabilité : les langages normalisés sont très largement portables.
 La maintenabilité et la réutilisabilité : les modifications et adaptations sont
rendues plus simples donc moins risquées et moins coûteuses.

La complexité des circuits conçus augmente toujours. On conçoit aujourd’hui des


circuits composés de l’assemblage de plusieurs millions de portes. On a donc tiré
encore une fois parti de l’augmentation de puissance des ordinateurs et des progrès
réalisés en informatique pour imaginer des outils logiciels encore plus puissants : les
synthétiseurs logiques.

Il s’agit de décharger les concepteurs d’une tâche de plus, afin de leur permettre de
travailler à un niveau d’abstraction encore plus élevé, de manipuler des objets
élémentaires encore plus grands. Pour ce faire, la description structurelle ne suffit plus.
En effet, le nombre de primitives utilisables ne doit pas dépasser quelques centaines ;
au-delà, le concepteur ne peut plus mémoriser le contenu des bibliothèques et donc
ne parvient pas à en tirer le meilleur parti.

Pour aller encore plus loin, il faut permettre au concepteur de décrire le “quoi” au lieu
du “comment”. Il doit pouvoir s’affranchir de la connaissance des primitives
disponibles. Le dispositif à modéliser ou à concevoir sera désormais représenté par sa
fonction et non plus par sa structure. C’est le synthétiseur logique qui déterminera la
structure automatiquement à partir de la fonction. Bien sûr, les possibilités de
description structurelle existent toujours mais on leur associe d’autres possibilités afin
d’augmenter l’efficacité de l’ensemble.

Description fonctionnelle (comportementale) du même circuit

Page 60 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Les langages fonctionnels (on dit aussi comportementaux) de description de matériel
possèdent des avantages certains sur les langages structurels en terme de portabilité,
maintenabilité et versatilité :

 Une description textuelle fonctionnelle, donc ne faisant pas référence à une


quelconque bibliothèque de composants, est plus facilement transportable d’un
outil de CAO à l’autre, d’un concepteur à l’autre, d’une entreprise à l’autre. La
portabilité est accrue.
 Du fait de sa plus grande compacité et de sa meilleure lisibilité il est plus facile
de modifier une description textuelle de fonctions qu’un texte décrivant la
structure. La maintenabilité est plus grande.
 Les coûts de mise à jour ou d’adaptation à de nouveaux besoins sont réduits. La
réutilisabilité d’un module archivé est donc plus grande.

2.2 Usage des HDL

Il est important de comprendre la nature des différentes utilisations que l’on peut faire
des langages fonctionnels de description de matériel.

2.2.1 Simulation
En tout premier lieu vient la modélisation. Elle n’a pas pour fonction de décrire la
structure de l’objet mais son comportement. Celui qui écrit le modèle peut recourir à
la description structurelle pour se simplifier la tâche en découpant le problème en
sous-problèmes plus simples à modéliser, mais le découpage ainsi obtenu n’a aucune
raison à priori de correspondre au partitionnement qui sera effectivement utilisé lors
de la conception de l’objet. Le but de la modélisation, c’est la simulation. Ce qui compte
avant tout, c’est la fidélité - un modèle se doit d’être aussi précis que possible dans son
champ d’application - et l’efficacité - le modèle doit pouvoir être simulé le plus
rapidement possible et doit être portable, réutilisable et facile à maintenir.

Pour simuler un modèle, il faut disposer du modèle, bien sûr, mais aussi de stimuli,
c’est à dire de la description des signaux d’entrée du modèle au cours du temps. Jadis,
avec les langages structurels, il n’était pas possible de décrire les modèles et les stimuli
d’entrée à partir du même langage. Il fallait donc utiliser plusieurs langages, plusieurs
outils et c’était autant de risques d’erreurs et de coups portés à la portabilité.

Grâce aux possibilités de description fonctionnelle des nouveaux langages, on utilise


désormais le même formalisme pour ces deux opérations pourtant bien différentes. La
description de stimuli est une deuxième utilisation importante de ces langages.

Page 61 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le résultat d’une simulation n’est pas toujours évident à vérifier. La seule inspection
visuelle ne suffit pas dans les cas complexes où le nombre de données à analyser est
grand, ou encore lorsque les calculs à effectuer pour valider un résultat sont trop
complexes. Là encore, les langages fonctionnels de description de matériel permettent
de simplifier cette tâche en analysant automatiquement les résultats en cours de
simulation.

Un environnement de simulation complet comprend donc un générateur de stimuli, un


modèle de l’objet à simuler et un vérificateur automatique des résultats. Ces trois
composantes sont modélisées à l’aide du même langage. Le gain en simplicité de mise
en œuvre et en portabilité de l’ensemble est considérable.

2.2.2 Synthèse
Les langages fonctionnels de description de matériel servent aussi - et c’est sans doute
là l’une de leurs fonctions premières - à concevoir. Il ne s’agit plus de modéliser en vue
de la simulation, mais de décrire les objets qui seront véritablement fabriqués.

La totalité du langage ne peut plus être utilisée. Il est nécessaire de prendre en


considération les limites des outils logiciels qui assureront la traduction du code en
portes logiques (synthétiseurs) puis la traduction de la description structurelle en
dessin au micron (placeurs-routeurs).

Si les considérations de vitesse d’exécution en simulation existent toujours (la


description sera simulée avant d’alimenter le synthétiseur, afin de vérifier que la
fonction décrite est bien la fonction désirée) elles ne sont plus prioritaires. Ce qui
compte le plus désormais, c’est l’efficacité du code au sens du synthétiseur. En effet,
pour que ce dernier produise la description structurelle la plus économique possible
(et donc la surface de silicium la plus petite possible), il faut que le concepteur ait tenu
compte de ses limites et de ses spécificités qui ne vont souvent pas dans le sens de
l’efficacité en simulation.

Verilog, VHDL, SystemC et tous les HDL en général, permettent de modéliser un


système, c'est-à-dire d'en donner un modèle abstrait, en laissant de côté certains
détails.

2.3 Types de modèles

Suivant le type des détails précisés ou omis, on distingue plusieurs types de


modélisation, appelées aussi modèles ou vues :

Page 62 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
les vues physiques :
elles spécifient les paramètres physiques d'un système, tels que ses dimensions,
les matériaux le constituant. Dans ce type de modèles on décrit les transistors,
les masques (polysilicium, dopant N, métal, ...), leur taille, leur épaisseur, ...

Les vues structurelles :


ici on oublie les caractéristiques physiques, on ne voit un système que comme
un assemblage de composants. On s'attache donc à décrire les interconnexions
entre les différents sous-ensemble, qui peuvent eux-mêmes bien sûr être
composés de plusieurs sous-ensembles, qui peuvent eux-même etc... jusqu'au
niveau le plus petit, le transistor.

Les vues comportementales :


dans lesquelles un système est décrit en définissant comment ses sorties
réagissent en fonction des entrées et du temps. On s'intéresse ici à ce qu'un
circuit fait, et non à comment il est conçu. On utilise pour cela des descriptions
textuelles d'algorithmes, des diagrammes d'état, des fonctions de transfert, ...
C'est souvent la vue la plus abstraite.

Pour une bascule D, les différentes représentations seraient, par exemple :

modèle physique

Page 63 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Modèle structurel

2.4 Finesse des modèles

Chacun de ces modèles peut être plus ou moins raffiné, selon la finesse des détails
qu'on y présente.

1. Pour une vue physique, les différents niveaux seront :


1. cartes
2. composants électroniques
3. cellules standards
4. layout
2. Pour une vue structurelle, les différents niveaux seront :
1. processeurs, mémoires, bus, ...
2. registres, ALU, multiplexeurs, ...
3. portes logiques, bascules, ...
4. transistors
3. Pour une vue comportementale, les différents niveaux seront :
1. algorithmes, diagrammes de flot
2. transferts entre registres (RTL)
3. expressions logiques booléennes
4. fonctions de transfert des transistors

On représente souvent ces trois types de modèles et leur degrés de finesse selon un
diagramme dit "en Y" :

Page 64 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Diagramme en Y

2.4.1 Utilisation des modèles

Bien sûr, en pratiques, ces différents modèles sont souvent mélangés.


On peut décrire une partie d'un système sous forme physique (j'ai un microprocesseur,
dont le boîtier carré de 20mm de côté), une partie en comportemental (l'ALU effectue
une addition de tel et tel registre si l'instruction commence par "100", sinon elle en fait
la soustraction), une partie en structurel (le cache est une SRAM, formée de points
SRAM, eux-mêmes formés de transistors agencés de telle et telle façon), voire même
donner plusieurs modèles d'une même partie.

De plus, la frontière entre les différentes descriptions est souvent floue (sans compter
les abus de langages). Par exemple, une représentation comportementale sous forme
d'équation booléenne (S = A XOR B XOR C) suggère une implémentation directe sous
forme de portes logiques (ici deux portes XOR). Cette équation peut donc être vue

 soit comme une description comportementale (ce qui compte alors est juste la
fonction réalisée, et peu importe si on a vraiment des portes XOR ou bien plein
de AND, de OU et de NOT...)

Page 65 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 soit comme une description structurelle (on connecte ensemble deux portes
XOR).

Les abus de langage font aussi qu'on présente souvent le plus haut niveau d'abstraction
d'un système comme comportemental même s'il est structurel. Et bien souvent on
parle de RTL à la place de comportemental et vice-versa, alors que le RTL n'est qu'un
de ses niveaux de finesse...

Bref, les frontières entre niveaux sont floues, celles entre les modèles aussi.

2.4.2 Quels niveaux pour quels HDL ?

Verilog, VHDL et SystemC permettent de représenter des systèmes sous forme


structurelle ou comportementale, dans la majorité des degrés de finesse. Par contre,
ils ne savent pas décrire la partie physique.

 Verilog est particulèrement à l'aise dans les descriptions de bqs niveaux, mais
manque un peu de souplesse dans le comportemental de très haut niveau (il ne
sait par exemple pas modéliser les entités abstraites telles que des OS, des
mutex, des canaux de communications, ...).
 VHDL est semblable à Verilog, permet un tout petit peu plus de haut niveau dans
le comportemental (il dispose de la notion de pointeurs), mais est moins adapté
au bas niveau.
 SystemC est très peu adapté au bas niveau. Il a été conçu pour modéliser les
système à des niveaux intermédiaires jusqu'à très haut. Il sait modéliser des
entités propres aux OS telles que des mutex, des sémaphores, ... et dispose d'un
moyen simple de modéliser des canaux de communication abstraits (ethernet,
UMTS par exemple). Il laisse les très bas niveaux (transistors) à Verilog, VHDL et
aux langages dédiés (SPICE, ...).

De plus, les habitudes de travail font que chaque niveau n'est pas conçu par les mêmes
personnes, et chaque population a ses propres habitudes. Par exemple, la description
de plus haut niveau d'une chaîne de traitement UMTS sera faite par des gens du
traitement du signal, qui représentent généralement leurs algorithmes en C ou en
Matlab. C'est le niveau du dessous qui sera traité par les électroniciens, qui
travailleront alors en Verilog, VHDL ou SystemC.

2.5 Parallélisme et machines séquentielles

Page 66 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
L’esprit humain est familier de la programmation séquentielle. Il nous est en effet
naturel de décrire un traitement sous la forme d’un enchaînement d’opérations à
effectuer dans un ordre pré-établi.

Le matériel est, par essence, parallèle. Dans un circuit intégré, tous les composants
sont actifs simultanément.

De ces deux considérations on déduit que la forme la plus probable des langages
fonctionnels de description de matériel comportera des aspects séquentiels et des
aspects parallèles. En d’autres termes, un modèle de composant électronique sera
composé de l’assemblage de plusieurs programmes séquentiels, s’exécutant en
parallèle. Le concepteur partitionnera son problème en modules assez simples pour
être décrits sous la forme de programmes séquentiels classiques, puis il assemblera ces
modules que le simulateur exécutera en parallèle.

Le problème, car problème il y a, naît de ce que le simulateur est, en général, installé


sur une machine séquentielle, capable d’exécuter une instruction à la fois, donc un
programme à la fois. Il ne pourra donc pas paralléliser réellement les différents
programmes. Il faut donc trouver un moyen d’émuler le parallélisme sur une machine
séquentielle. Comment faire ?

2.5.1 Emulation du parallélisme


L’émulation du parallélisme repose sur une idée très simple et très efficace : pour que
chaque programme séquentiel, qu’on appellera désormais processus, s’exécute
“comme si” le parallélisme était réel, il faut que son environnement (ses variables
d’entrée) ne change pas pendant l’exécution des autres processus. Ainsi, l’ordre
d’exécution des processus n’a plus d’importance et tout se passe comme s’ils
s’exécutaient en parallèle.

Pour parvenir à ce résultat, il faut que les variables partagées entre processus
conservent leur valeur jusqu’à ce que tous les processus aient fini leur exécution. En
quelque sorte, on simule pas à pas et, à chaque pas :

1. le simulateur exécute tous les processus dans un ordre quelconque (plus


précisément, un ordre défini comme étant arbitraire)
2. toute instruction modifiant la valeur d’une variable partagée verra son
exécution différée ; on se contentera d’enregistrer la nouvelle valeur dans une
zone temporaire, la variable partagée conservant son ancienne valeur
3. lorsque tous les processus ont été exécutés, on modifie toutes les variables
partagées en allant chercher leur nouvelle valeur dans la zone temporaire
Page 67 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
4. et on recommence un nouveau pas en prenant en compte les nouveaux états
des entrées /sorties des blocs

Les variables partagées ou globales doivent donc être traitées d’une façon particulière.
On appelle ces variables des signaux, pour les distinguer des variables classiques.

2.5.2 La gestion du temps


Un simulateur / langage HDL doit avoir une notion du temps, quelle que soit son échelle
/ unité :

 les concepteurs aimeraient typiquement bien exprimer les stimuli de test ainsi
: "a vaut 0 initialement, puis 1 au bout de 10ns, puis 0 au bout de 35 ns, puis..."
 un système doit pouvoir générer des horloges de fréquences différentes, donc
avoir une notion (au moins relative) du temps physique
 il faut pouvoir éventuellement modéliser des temps de propagation

Un simulateur doit donc maintenir un compteur de temps, le temps physique courant,


et attribuer une date physique à chaque événement au sein de la simulation.

Pour pouvoir modéliser des portes idéales et des conducteurs parfaits (temps de
propagation nuls), il faut décorréler les pas de simulation du temps physique : prenons
l'exemple d'un inverseur parfait, dont le temps de propagation est nul. Si son entrée
change au temps t, sa sortie changera aussi au temps t. Pourtant les deux événements
(simultanés) n'auront pas lieu lors du même pas de simulation.

Autrement dit, un pas de simulation n'a pas de valeur temporelle physique intrinsèque.
C'est un intervalle de temps virtuel, appelé delta, dont la durée est nulle, qui ne sert
qu'à ordonner les événements "simultanés", c'est-à-dire à déterminer lequel a
provoqué lequel. Pendant un delta, le temps physique ne s'écoule pas.

Se pose alors le problème suivant : quand faire avancer le temps courant, quelle est la
relation entre ce compteur (temps physique courant) et les pas de simulation ?

2.6 La simulation

La solution à ce problème est simple et élégante, et possède pour une fois la bonne
propriété d’accélérer considérablement les simulations.

1. Chaque événement possède une date complète, comprenant une date physique
(1h, 17minutes, 43secondes, ...) et une date symbolique (... 4 deltas).
Lorsqu’une affectation de signal ne comporte pas de précision sur la date
Page 68 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
physique à laquelle l’événement doit avoir lieu, il est sous-entendu que la date
sera la date à laquelle l’affectation a été exécutée augmentée d’un delta.
Lorsque la date physique est précisée, la date de l’événement est exactement
cette date physique.
Notons que les synthétiseurs logiques n’utilisent pas le temps physique. Seul
l’ordre des opérations que subissent les données sont pertinentes pour la
synthèse. Le temps symbolique est donc le seul que les synthétiseurs
comprennent.
2. Le simulateur maintient un échéancier des requêtes pour chaque signal. Une
requête est le résultat d'une affectation; elle est composée de la valeur que doit
prendre le signal et de la date complète (date physique + date symbolique) du
futur événement. Lorsque tous les processus ont été exécutés et que toutes les
requêtes ont été enregistrées, le simulateur peut ainsi déterminer quel signal
doit changer de valeur lors du prochain pas de simulation. Il modifie donc les
signaux en question et avance le temps d’un pas (1 delta), puis il recommence
l’exécution des processus.
3. Afin de réduire les temps de simulation on optimise la stratégie du simulateur.
Les exécutions inutiles sont supprimées. Avant de commencer un nouveau pas,
le simulateur consulte l'échéancier, détermine la date du prochain événement,
ainsi que la liste des signaux devant changer de valeur à cette date, et saute
directement à cette date-là :
o soit en restant au même temps physique, mais en augmentant le delta
courant
o soit en sautant directement au temps physique correct; le delta courant
est alors remis à 0.

Cette analyse permet :

o de relancer l’exécution aux seuls instants « intéressants » ;


o de ne réveiller que les processus concernés : ainsi, si les deux entrées
d’un processus décrivant une porte ET n’ont pas changé, il est inutile de
relancer son exécution puisque la sortie conserverait la même valeur
o de pouvoir faire avancer le temps d’une valeur quelconque. Parmi tous
les événements à venir, le simulateur détermine le ou les plus proches,
les réalise effectivement et positionne la date courante en conséquence.
Il fait ainsi l’économie de pas de simulation inutiles

En fait, cette optimisation est même indispensable puisque la durée physique d’un
delta est nulle. Les durées symboliques ont pour seule fonction d’ordonner les
événements les uns par rapport aux autres. Si le simulateur ne faisait avancer le temps
que d’un delta à la fois, le temps physique n’avancerait pas.

Page 69 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

2.7 Fonctionnement interne des processus

L’aspect séquentiel est conservé à l’intérieur des processus. Ils obéissent aux règles très
classiques de la programmation séquentielle. On trouve les mêmes instructions et les
mêmes structures de contrôle qu’en langage C, en Pascal ou en Ada.
La seule exception à l’exécution séquentielle des processus concerne l’affectation des
signaux (voir ci-dessous).

De plus, chaque processus est une boucle infinie. Il doit donc comporter au moins un
point de synchronisation (appelé aussi point d'arrêt). Faute de quoi, le simulateur est
dans l’obligation de l’exécuter indéfiniment (temps physique et temps symbolique
n’évoluent pas, il s’agit d’un processus cyclique sans point d’arrêt).
Ce point d'arrêt est soit :

 implicite : le processus est déclaré avec une liste de sensibilité, généralement


une partie ou la totalité des entrées du bloc. Il ne sera exécuté que si
l'événement en cours porte sur un des signaux présent dans cette liste de
sensibilité.
 explicite : à l'aide d'une instruction de type wait(..); comportant une condition
sur un ou plusieurs des signaux du processus. Le processus ne reprend son
exécution que si cette condition est vraie.

Lorsqu'un processus a atteint un point d'arrêt, le simulateur passe au processus


suivant. S'ils ont tous été traités, le simulateur fait avancer le temps (symbolique ou
physique, selon l'échéancier).

Attention, la condition de réveil associée au point d'arrêt (implicite ou explicite) ne doit


pas être toujours vraie, sinon seul le temps symbolique évolue.
Les processus cycliques sans point d’arrêt sont un grand piège des langages
fonctionnels de description de matériel (surtout en VHDL).

On peut considérer les processus comme des threads d'un OS multitâche, sachant que
l'OS en question est non-préemptif : chaque thread doit rendre la main au scheduler.
C'est le rôle des points d'arrêt.

2.8 Variables locales et globales (signaux)

Page 70 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Les variables globales (signaux) servent à la communication entre les processus (cf. ci-
dessus). Elles modélisent les fils électriques (même si ce n'est pas la seule façon de les
modéliser).

On a déjà vu que leur affectation doit être traitée de façon spéciale (déférée à la fin
du delta courant). Lors de l'affectation des signaux, une instruction d’affectation
spéciale est créée. Lorsqu’une telle instruction est exécutée, elle ne prend pas effet
immédiatement. Elle est “enregistrée” par le simulateur, qui la traitera effectivement
lorsque tous les processus auront été exécutés.

C’est un piège classique des langages fonctionnels de description de matériel que de


croire l’affectation de signal instantanée. Le paradoxe apparent provient du fait
qu’après une telle affectation le signal n’a pas changé de valeur ...

Les variables locales aux processus sont traitées comme dans tout langage de
programmation classique. A la différence des signaux, elles sont modifiées dès
l’exécution d’une instruction d’affectation qui les concerne. Ces variables locales ne
sont, en général, pas visibles de l’extérieur du processus où elles sont déclarées. Un
autre processus ne peut ni les lire, ni les modifier. Elles ne sont pas réinitialisées d’une
exécution à l’autre du processus ; elles conservent leur valeur, comme si le processus
était en fait une boucle infinie dans un langage de programmation classique.

La différence entre variable locale et signal dépend du langage utilisé :

En VHDL :

la différence entre signal et variable locale est déterminée directement par le


type (signal ou variable).

En SystemC :

la différence entre signal et variable locale est aussi déterminée par le type
(sc_signal ou type C normal : int, bool, ...)

En Verilog :

une difficulté habituelle vient du fait que les deux ont le même type
(généralement reg). C'est la façon dont est écrite l'affectation qui détermine si
elle doit avoir lieu instantanément (la variable devrait alors être locale), ou être
déférée à la fin du delta courant (la variable est alors un signal de
communication entre processus). Nous verrons plus tard que
Page 71 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
- une affectation immédiate (dite bloquante) s'écrit ainsi : a = b;
- une affectation déférée à la fin du delta courant (dite non-bloquante) s'écrit
ainsi : a <= b;

Plutôt que de contraindre les utilisateurs à utiliser un type ou l'autre, Verilog fait
confiance à l'intelligence des concepteurs pour utiliser la bonne affectation.
Cela permet une souplesse accrue, au prix d'un risque de se tromper si on n'y a
pas pris garde.

3. Spécification SA-RT
La méthode SA-RT a été mise au point à la fin des années 80 pour exprimer les
spécifications des applications temps réel. La méthode SA-RT intègre trois aspects
fondamentaux d’une méthode de spécification :
 L’aspect fonctionnel (ou transformation de données) : représentation de la
transformation que le système opère sur les données et spécification des processus
qui transforment les données ;
 L’aspect évènementiel (piloté par les évènements) : représentation des
évènements qui conditionnent l’évolution d’un système et spécification de la
logique de contrôle qui produit des actions et des évènements en fonction
d’événement en entrée et fait changer le système d’état ;
 L’aspect informationnel (données) : spécification des données sur les flots ou dans
les stockages. Ce dernier aspect, qui est en général assez négligé dans ce type
d’application, doit faire l’objet d’une description spécifique.

3.1 Syntaxe graphique de SA-RT


 Processus fonctionnel : représente une transformation de données. Un ou
plusieurs flux de données en entrée sont traités pour donner un ou plusieurs flux
de données en sortie. Un processus est représenté par un cercle avec un étiquette
formée d’un verbe décrivant la transformation avec d’éventuels qualificatifs, et
d’un numéro pour l’indexer, comme sur la figure ci-dessous (Exemple de
processus).

 Flot de données : supporte ou transporte les valeurs d’une certaine information. Ce


concept représente le cheminement des données. Le flot de données est
représenté par un arc orienté avec une étiquette formée d’un nom (plus d’éventuel
qualificatif), comme sur la figure ci-dessous (Exemple de flot de données).

Page 72 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Le flot de données peut représenter aussi bien une donnée de type continu qu’une
donnée discrète codée par un booléen. Une donnée peut décrire une donnée
élémentaire ou bien une donnée structurée intégrant plusieurs données élémentaires.
La spécification détaillée est faite dans le dictionnaire des données.
 Stockage de données : modélise le besoin de mémorisation d’une donnée de telle
façon que sa valeur puisse être relue plusieurs fois. Il est représenté par deux traits
horizontaux encadrant l’étiquette de la donnée. Les arcs arrivants et sortants ne
sont pas étiquetés, comme sur la figure ci-dessous (Exemple de stockage de
données).

 Terminaison : représente une entité extérieure au système échangeant des


données avec le système modélisé. Ce peut être une entité logicielle (programme,
base de données, ...) ou matérielle (capteurs, actionneurs, réseau, ...). Elle est
représentée par un rectangle et nommée par une étiquette composée d’un nom
(plus d’éventuels qualificatifs).

3.1.1 Flot de contrôle


Le déclenchement de l’exécution des processus de transformation de données peut
être lié au rythme d’apparition des données mais aussi par l’occurrence d’évènements.
Le flot de contrôle est représenté par un arc orienté pointillé avec une étiquette
composée d’un nom avec d’éventuels qualificatifs. La figure (a) ci-dessous représente
le pilotage de l’exécution d’un processus par une donnée.

Les évènements sont souvent liés à l’activation ou la désactivation des processus


fonctionnels. Ces évènements spécifiques ont été formalisés et prédéfinis :
 E pour Enable (activation d’un processus périodique) ;
 D pour Disable (désactivation d’un processus périodique) ;

Page 73 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 T pour Trigger (synchrone).
On note entre parenthèse le type d’événement sur l’arc servant au flot de contrôle,
comme sur la figure ci-dessous. Les deux premiers évènements sont utilisés pour
piloter un processus fonctionnel de type boucle sans fin ou périodique, c’est-à-dire que
le processus fonctionnel débute avec l’événement E et est stoppé par l’événement D.
Entre les deux il a un comportement périodique. L’événement T est utilisé pour activer
une seule fois le processus fonctionnel.

3.2 Organisation de la méthode SA-RT


La méthode est structurée de manière hiérarchique descendante et met en avant les
aspects fonctionnels et comportementaux de l’application analysée.
La figure ci-dessous représente l’organisation générale de la méthode SA-RT avec
l’enchaînement de différentes étapes et l’ensemble des documents produits. Nous
trouvons :
 Diagramme de contexte : premier diagramme de flot de données permettant
de décrire l’environnement de l’application à développer ;
 Diagramme préliminaire : diagramme de flot de données présentant le premier
niveau de l’analyse fonctionnelle de l’application ;
 Diagramme de décomposition : diagramme de flot de données présentant les
analyses des processus fonctionnels non primitifs ;
 Spécifications des processus fonctionnels primitifs : spécification textuelle des
fonctions réalisées par les processus fonctionnels ;
 Spécifications des processus de contrôle : diagramme état/transition décrivant
le fonctionnement des processus de contrôle (ce point ne sera pas abordé ici) ;
 Dictionnaire des données : liste exhaustive des données et des évènements
utilisés dans la spécification.

Page 74 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

3.2.1. Diagramme de contexte


Le diagramme de contexte est une première étape importante qui représente
l’interaction entre le système et l’environnement. Un processus fonctionnel numéroté
0 traduit l’application à réaliser par le concepteur. Autour de ce processus fonctionnel,
un ensemble de terminaisons modélise les éléments qui fournissent ou consomment
les données ou évènements de cette application. Il n’y qu’un seul processus
fonctionnel dans un diagramme de contexte.

3.2.2 Diagramme préliminaire


Le diagramme préliminaire est la première décomposition du diagramme de contexte.
Le diagramme préliminaire représente la liste des processus fonctionnels nécessaires
à l’application avec le flot de données et de contrôle correspondant.
Le nombre de processus fonctionnels composant ce diagramme doit être limité pour
permettre une meilleure lisibilité (5 à 9 processus semblent acceptables). On ne
représente plus les terminaisons et on doit retrouver l’ensemble des données et des
évènements en entrée et en sortie du diagramme de contexte. Le passage des données
Page 75 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
entre les processus fonctionnels peut être réalisé selon les besoins avec les deux
méthodes de base : flot de données directe ou unité de stockage.

3.2.3 Diagramme de décomposition


Les diagrammes de décomposition permettent de raffiner la décomposition
fonctionnelle de chaque élément du diagramme préliminaire. Lorsqu’il n’y a plus
d’intérêt à décomposer un processus fonctionnel, celui-ci est appelé processus primitif
et doit être décrit par une spécification sous forme textuelle.
Les règles suivantes doivent être respectées :
 L’ensemble des flots de données et des évènements entrants et sortants du
processus décomposé doit se retrouver dans le diagramme de décomposition
de ce processus avec le même typage ;
 La numérotation des différents processus fonctionnels doit intégrer le numéro
du processus fonctionnel analysé N sous la forme N.x ;
 Les stockages doivent apparaître dans tous les diagrammes où les processus qui
les utilisent.

3.2.4 Spécification des processus primitifs


Tous les processus primitifs doivent être spécifiés textuellement. Cette spécification
doit comprendre le nom du processus, son mode d’activation, son mode de
désactivation (s’il existe), les données et évènements en entrée et en sortie et une
description en pseudo-code du traitement à réaliser par le processus. Le tableau ci-
dessous donne un exemple de spécification pour un processus fonctionnel devant
asservir les moteurs du bras manipulateur.
Nom : Asservir moteurs
Activation : mise en marche de l’application
Désactivation : jamais
Evènement en entrée : mise_en_marche
Donnée en entrée : consigne, positions_actuelles
Donnée en sortie : commande_moteurs
Description :
Début
Faire à chaque période
Commande_moteurs <- calcul_commande(consigne, positions_actuelles) ;
Fin Faire
Fin

3.2.5. Spécification des données


Toutes les données qui apparaissent dans les diagrammes doivent être spécifiées par
leur nom, leur rôle et leur type.

Page 76 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Nom : Consigne
Rôle : fournit la consigne d’entrée de l’asservissement du bras
Type : donnée structurée de consigne_epaule et de consigne_coude
Nom : consigne_epaule
Rôle : fournit la consigne d’entrée de l’asservissement de l’épaule
Type : entier

L’étape de conception a pour but de décrire les éléments qui seront manipulés lors de
l’implémentation pour répondre aux exigences de la spécification.

3.3 Conception
Une méthode de conception doit permettre d’exprimer les différents éléments
constituants une application. Pour un système temps réel, on doit trouver :
 Les tâches avec leur type d’activation et les paramètres ou données en entrée
et en sortie ;
 Les relations entre les tâches : synchronisation de type asynchrone ou
synchrone (rendez-vous) et les communications avec les données qui transitent
entre les tâches ;
 Le partage des ressources critiques.

3.3.1. Éléments graphiques de la conception


3.3.1.1 Modélisation des tâches
Une tâche représente l’entité de base de l’architecture. Elle peut avoir un ou plusieurs
flots de données en entrée et un ou plusieurs flots de données en sortie. Elle est
modélisée par un rectangle qui comporte une étiquette formée d’un nom avec
d’éventuels compléments d’objet.

3.3.1.2 Modélisation de synchronisations et des communications


On distingue deux types de synchronisation entre tâches :
 asynchrone : la tâche en réception est bloquée et attend la réception d’un
événement pour continuer son traitement ;
 synchrone : les deux tâches ont un rendez-vous (elles doivent être toutes les
deux au point de synchronisation en même temps).
Les synchronisations sont représentées par un arc entre deux tâches sur lequel figure
un symbole permettant de distinguer le cas asynchrone du synchrone (voir figure ci-
dessous).

Page 77 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Le moyen de réaliser cette synchronisation n’est pas du niveau de la conception mais


de la programmation.
Des tâches peuvent aussi échanger des données, on parle alors de communication. Une
communication est caractérisée par la taille de la zone d’échange des données et
éventuellement un mode de synchronisation. La communication est modélisée par des
éléments de type boîte à lettre (BAL) qui permettent de caractériser la taille de la zone
de communication et le mode de gestion des données.
Une communication est représentée par un arc orienté, étiqueté par un identifiant,
avec son mode synchronisation et sa taille (figure ci-dessous).

La figure ci-dessous présente un exemple de BAL de taille 10 avec une gestion FIFO des
données et qui est bloquante pour le récepteur.

3.3.1.3. Activation des tâches


Une tâche peut être activée soit de manière périodique soit suite à une interruption.
Ces deux cas sont représentés par une ligne brisée orientée avec une étiquette
spécifique : HTR (+ durée de la période) pour les activations périodiques et IT (+ nom
de l’interruption) pour les activations apériodiques.

3.3.1.4. Modélisation des stockages de données


Une ressource critique est représentée par un rectangle associé à des entrées
permettant de réaliser une action sur les données : LIRE, ECRIRE, etc. Elle est qualifiée
par un nom avec d’éventuels compléments d’objet.

Plusieurs tâches peuvent demander l’accès à une ressource critique qui sera gérée en
exclusion mutuelle. Sa mise en œuvre au niveau de l’implémentation n’est pas
spécifiée dans la conception.

Page 78 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
3.3.2. Mise en œuvre de la méthode de conception
Phase 1 : Création des tâches. Chaque processus fonctionnel primitif est traduit en une
tâche avec éventuellement une tâche de contrôle si le flux de contrôle est complexe.
On peut établir deux autres règles découlant de cette étape :
 Règle 1.1 : Une tâche est créée pour chaque processus fonctionnel du
diagramme SA-RT.
 Règle 1.2 : Une tâche supplémentaire est associée au processus de contrôle du
diagramme SA-RT si le processus de contrôle est complexe, c’est-à-dire qu’il
possède au moins une structure conditionnelle.

Phase 2 : Détermination de l’activation des tâches. L’activation de chaque tâche est


définie soit sur un évènement externe soit sur une synchronisation avec d’autres
tâches. Relativement à cette phase, on peut énoncer les règles suivantes :
 Règle 2.1 : Une tâche en entrée (acquisition de données) est obligatoirement
déclenchée par l’horloge temps réel (ex. tâche de scrutation d’un paramètre
physique), soit par une interruption provenant du procédé (ex. tâche d’alarme).
 Règle 2.2 : Les autres tâches sont activées sur un événement logiciel (activation
par synchronisation ou communication avec les autres tâches), soit sur un
événement interne (horloge temps réel, chien de garde, ...).
 Règle 2.3 : Les événements importants du diagramme flot de données de SA-RT
peuvent être traduits par des synchronisations qui sont utilisés pour activer des
tâches logicielles.

Phase 3 : Mise en place des transferts de données. Le transfert des données est traduit
par des communications ou par des ressources critiques. Il peut être nécessaire de
revoir le dessin de l’étape 2. Les relations de communication sont traduites par des
boîtes aux lettres ou par des modules de données. Leur établissement peut se faire en
se basant sur les deux règles suivantes :
 Règle 3.1 : les communications directes entre les processus fonctionnels (flot de
données d’un processus fonctionnel à un autre) sont traduites
préférentiellement par des boîtes aux lettres.
 Règles 3.2 : Les communications par une zone de stockage entre les processus
fonctionnels sont traduites préférentiellement par des modules de données, en
particulier si cette zone de stockage se trouve partagée par plus d’une tâche.

Phase 4 : regroupement ou rassemblement des tâches. Afin d’améliorer et de simplifier


la première conception, le diagramme multitâche est de nouveau analysé pour
regrouper certaines tâches. Ce regroupement peut être dû à :
 la cohésion temporelle : le regroupement se fait pour des tâches ayant le même
évènement d’activation ou ayant la même période.

Page 79 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 la cohésion séquentielle : le regroupement concerne des processus fonctionnels
qui doivent s’exécuter en séquence.
 la cohésion fonctionnelle : le regroupement concerne des processus
fonctionnels ayant une fonctionnalité commune.

Phase 5 : Caractérisation des objets de la conception. Chaque objet du modèle doit


être caractérisé pour en spécifier son comportement. Une tâche doit avoir :
 Une description textuelle de son rôle
 Une description algorithmique de son comportement, en portant une attention
particulière aux appels de services.
 Une priorité, éventuellement déterminée par des règles de type Rate
Monotonic.
 Un budget temporel qui représente une estimation de son temps d’exécution.
Un élément de communications doit être caractérisé par :
 Les données qu’ils transportent (taille et type).

3.3.3 Un exemple de conception pour lire, afficher et de stocker l’état d’un bouton
L’application modélisée dans la figure ci-dessous a pour but de lire, d’afficher et de
stocker l’état d’un bouton. La fonction d’affichage et de mesure ne doivent pas être
regroupée pour des raisons de modularité. Les solutions proposées sont viables, mais
présentent chacune des inconvénients et surtout ne sont pas complètes…

Page 80 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
3.3.4 Exemple de conception pour la gestion de la sécurité d’une mine
En plus de la gestion automatisée d’une mine, l’aspect sécurité est le point essentiel de la
gestion d’une zone d’extraction de minerai, située en sous-sol, avec une présence humaine.
Nous allons limiter notre étude au système de gestion de la sécurité qui concerne
principalement le contrôle des deux fluides :
– Eau : les eaux de ruissellement sont évacuées par un ensemble de conduites vers un lieu
unique, appelé puisard. Le niveau de ce puisard, qui récupère toutes les eaux, est contrôlé en
permanence avec une évacuation à l’aide de pompes afin de la maintenir entre deux valeurs
de niveaux.
– Air : la ventilation des galeries de la mine est effectuée en permanence. Lors de l’extraction,
il peut se produire un accès accidentel à une poche de gaz comme du méthane. Fortement
toxique, la meilleure protection consiste à procéder à l’évacuation de la zone ou de la mine
entière sachant que le volume de méthane n’est, a priori, pas connu. D’autre part si le niveau
de méthane est élevé, il faut éviter toutes les productions d’étincelles (moteur...).
Nous allons considérer un système simple de gestion de la sécurité de la mine vis-à-vis de ces
deux facteurs. Le pilotage de cet ensemble comprend donc les éléments suivants (figure ci-
dessous):
– un capteur analogique de niveau d’eau, appelé LS (Level Sensor), pour détecter les deux
niveaux limites de régulation, soit le niveau bas (LLS, Low Level Sensor) et le niveau haut (HLS,
High Level Sensor) ;
– une pompe à eau à débit réglable permettant l’évacuation du puisard ;
– un capteur analogique du taux de méthane contenu dans l’air, appelé MS (Methane Sensor)
;
– une interface vers l’opérateur pour affichage de l’alarme.

Page 81 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Représentation schématique de l’application de la gestion de l’aspect sécurité d’une mine


La mine doit donc fonctionner tant que la sécurité maximale peut être maintenue. Ainsi, les
indications générales ou règles de fonctionnement sont les suivantes :
– Règle 1 : La pompe doit être mise en route si le niveau d’eau dépasse le niveau maximum
(LS > HLS). La pompe s’arrête dès que le niveau descend en dessous de la valeur inférieure (LS
< LLS).
– Règle 2 : Une alarme doit être lancée vers la console de l’opérateur dès que le niveau limite
du capteur MS est franchi afin de pouvoir opérer une évacuation de la mine. Cette valeur
limite est appelée MS_L1 (Methane Sensor Level 1).
– Règle 3 : La pompe ne doit pas fonctionner quand le niveau du capteur de méthane (MS) est
supérieur à une limite fixée MS_L2 (Methane Sensor Level 2) avec la condition MS_L2 > MS_L1
afin d’éviter les risques d’explosion.
Dans cet exemple d’application simple, nous sommes donc en présence de deux lignes de
régulation : le contrôle du niveau de l’eau dans le puisard (règle 1) et le contrôle du taux de
Page 82 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
méthane dans l’air (règle 2). L’interaction entre ces deux régulations se situe au niveau de la
commande de la pompe pour l’évacuation de l’eau du puisard dont le fonctionnement est lié
non seulement au niveau d’eau, mais aussi au taux
de méthane (règle 3).

-Diagramme de contexte de l’analyse SA-RT


Le premier niveau d’analyse consiste à élaborer le diagramme de contexte de l’application. Ce
diagramme, représenté sur la figure ci-dessous, intègre les quatre bords de modèle
correspondant aux deux entrées ou capteurs (capteur de méthane, capteur de niveau d’eau)
et aux deux sorties ou actionneurs (pompe, console opérateur). Il est souvent nécessaire
d’ajouter un événement de démarrage « Mise_sous_tension » délivré par un bord de modèle
« interrupteur ». Le processus fonctionnel initial 0 « Gérer sécurité mine » constitue
l’application à réaliser. En résumé, en plus de l’événement « Mise_sous_tension », nous avons
quatre flots de données : deux entrants (MS, LS) et deux sortants (Commande_pompe,
Alarme). L’ensemble de ces flots doit se retrouver dans le diagramme préliminaire : premier
niveau d’analyse du processus fonctionnel 0.

Analyse SA-RT de l’application de la gestion de l’aspect sécurité d’une mine : Diagramme de


contexte.

-Diagramme préliminaire et diagramme état/transition


Le diagramme préliminaire, présenté sur la figure ci-dessous, donne une analyse ou
décomposition fonctionnelle du processus fonctionnel initial 0 « Gérer sécurité mine ».
Cette analyse fait apparaître quatre processus fonctionnels de base et un processus de
contrôle permettant de séquencer l’ensemble. Nous pouvons vérifier la cohérence des flots
de données ou d’événements entrants ou sortants par rapport au diagramme de contexte.

Page 83 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Les processus 1 (Acquérir capteur méthane) et 4 (Afficher alarme) concernent le contrôle du
taux de méthane dans l’air avec un processus d’acquisition et de comparaison aux niveaux de
consignes (MS_L1, MS_L2) stockés dans une mémoire de stockage «
Niveaux_consignes_méthane » et un processus de commande pour déclencher l’alarme.

Analyse SA-RT de l’application de la gestion de l’aspect sécurité d’une mine : Diagramme


préliminaire

Les processus 2 (Acquérir capteur eau) et 3 (Commander pompe) concernent la régulation du


niveau d’eau dans le puisard avec un processus d’acquisition et de comparaison aux niveaux
de consignes (LLS, HLS) stockés dans une mémoire de stockage « Niveaux_consignes_eau » et
un processus de commande de la pompe.
Contrairement à la chaîne de régulation du taux de méthane où les deux processus
fonctionnels sont indépendants en termes de données, les deux processus fonctionnels de la
chaîne de régulation du niveau d’eau sont liés par le transfert d’une donnée « Vitesse_pompe
» qui est, par exemple, proportionnelle à la hauteur du niveau d’eau.

Le processus de contrôle est lié aux différents processus fonctionnels par des événements qui
sont mis en place en même temps que la réalisation du diagramme état/transition de la figure
ci-dessous. Ce diagramme état/transition, description du fonctionnement du processus de
contrôle 5 (Contrôler mine), comprend quatre états :
– fonctionnement nominal de la mine (niveau d’eau inférieur à HLS et taux de méthane
inférieur à MS_L1) ;
– pompe en marche (niveau d’eau supérieur à LLS) ;
– état alerte (consigne MS_L1 dépassée et niveau d’eau inférieur à HLS, ou consigne MS_L2
dépassée et niveau d’eau quelconque) ;
– état alerte (consigne MS_L1 dépassée) et pompe en marche.

Nous pouvons remarquer que, dans ce diagramme état/transition complexe, nous avons
utilisé dans certains cas des combinaisons logiques de deux événements pour passer d’un état
Page 84 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
à l’autre, par exemple « MS_L2_dépassée OU Niveau_LLS » pour passer de l’état « État alerte
et pompe en marche » à l’état « État alerte ».
D’autre part, ce diagramme état/transition fait l’hypothèse pour la surveillance du taux de
méthane que les événements « MS_L1_dépassée » et « MS_L2_dépassée » se produisent
toujours dans l’ordre cité et, lors du retour à la situation normale, l’événement « Consigne
respectée » est émis.

Analyse SA-RT du système : diagramme état/transition

Page 85 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chapitre 4: Conception à l’aide d’AADL

1. Introduction

La conception et l’évolution des systèmes sont souvent ralenties par leur taille et leur
complexité. D’un côté, ces systèmes embarquent des applications logicielles utilisant
de plus en plus de nœuds de calcul devant collaborer et communiquer les uns avec les
autres. Et d’un autre côté, la capacité d’adaptation des plateformes matérielles est de
plus en plus importante notamment grâce aux cartes FPGA.
L’ingénierie basée sur les modèles consiste à fournir à l’utilisateur des interfaces de
représentation pour ce genre de systèmes. Les nombreux aspects de la plateforme
matérielle et de l’application logicielle sont abstraits sous la forme de composants. La
réutilisation et la hiérarchisation de ces composants permettent de modéliser un
système entier de façon claire et précise.
Afin d’augmenter la précision des modèles, il est possible d’associer différents types
de propriétés aux composants pouvant, ou non, être utilisés par des outils d’analyse.
Les objectifs ciblés par les méthodologies de conception basée sur les modèles sont
multiples :
 Les modèles réalisés doivent permettre d’avoir une vision globale du système
pour permettre aux différents acteurs de sa conception de s’entendre sur
l’architecture et les caractéristiques de celui-ci.
 Ces méthodologies doivent valider une cohérence du système assurant
robustesse, fiabilité et sécurité lors de son exécution.
 Les modèles mis en place doivent permettre de réaliser des analyses
préliminaires sur le système et ainsi détecter des problèmes de conception très
tôt dans un flot permettant ainsi d’économiser beaucoup de temps.
Plusieurs méthodologies ont ainsi été mises au point pour répondre à ces objectifs,
comme des extensions du langage UML très portées sur une modélisation des
systèmes à travers différents diagrammes ou le langage AADL développé à la base pour
les domaines de l’avionique et de l’automobile qui nécessitent beaucoup de
vérification et de validation.

2. Présentation du langage AADL

Nous avons retenu pour ce cours le formalisme AADL pour exprimer la co-conception
logiciel/matériel, car il permet de représenter tous les concepts qui nous semblent
importants dans cette étape. De plus, il est bien instrumenté, et de nombreux outils
ont été développés pour effectuer de l’analyse ou de la génération de code
automatique à partir de ce langage.
Le développement d’un système cyber-physique concerne de nombreux domaines : la
mécanique, la thermique, l’énergétique, l’informatique, l’automatique, la physique,
Page 86 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
voire la chimie, etc. Or aujourd’hui, ces domaines sont tellement développés qu’il est
rare de trouver un expert de plus d’un domaine à la fois. Chacun utilise ses propres
modèles, qui, par définition même du modèle, simplifient une grande partie de la
réalité pour se focaliser sur les concepts importants du domaine, en négligeant le reste.
Chaque domaine a pu se développer, et sait apporter de bonnes solutions sur son cas
particulier, sur ses propres modèles de la réalité. Le développement d’un système
cyber-physique aujourd’hui correspond donc souvent à la combinaison de plusieurs
briques, chacune traitant du système dans sa globalité, mais uniquement du point de
vue de son domaine. À partir de son propre modèle, chaque brique tente donc
d’optimiser un certain nombre de métriques, mais en prenant en considération les
autres briques de façon extrêmement simplifiée, via des contraintes de haut niveau,
(typiquement, un automaticien pourra dire à l’architecte système que le correcteur
fourni devra s’exécuter à 50 Hz). Les experts de chaque domaine ne sont souvent pas
à même de communiquer finement sur les leviers qui pourraient être employés pour
leur permettre d’améliorer leur solution (si la contrainte de 50 Hz a un
impact important sur l’architecture logicielle, est-ce que 51 Hz est acceptable ? De plus,
comment exprimer le fait que les données provenant des capteurs aient un certain
délai ? Est-ce que cela pourrait rendre le correcteur instable ?). L’ingénierie
collaborative tente de faire tomber les frontières entre les domaines, en permettant
aux modèles d’être facilement traduits d’un domaine à un autre. L’un des principaux
candidats pour faciliter la « traduction » inter-domaines est l’ingénierie dirigée par les
modèles. Dans le domaine des systèmes cyber-physiques, il nous semble que cette
technologie est prometteuse pour permettre, à terme, de concevoir un système non
pas comme un assemblage d’optimum locaux mais comme un optimum global.

Le langage AADL (Architecture Analysis & Design Language) a été développé par SAE
international et approuvé en 2004 comme le standard AS 5506. Ce langage a été conçu
dans l’optique de fournir un standard et une syntaxe précise pour des systèmes
critiques et de permettre une représentation simple et complète d’une architecture
pouvant être analysée très tôt dans le flot de conception. AADL est de plus en plus
utilisé dans des domaines porteurs et à la pointe de la technologie comme l’avionique,
l’automobile, l’aérospatial, la robotique et plus généralement dans le domaine des
systèmes temps réels.
Des composants logiciels et matériels sont déclarés et instanciés pour composer
l’architecture d’un système. Ils sont dans un premier temps modélisés comme « boites
noires » en renseignant leurs interfaces. Dans un second temps, la composition interne
et les détails de l’implémentation d’un composant sont déclarés. C’est ainsi que la
hiérarchie de l’architecture est mise en place puisqu’un composant peut être conçu à
partir de plusieurs autres composants.

Le langage AADL reste un langage de description d’architecture. Et même s’il permet


de modéliser de nombreux aspects du système grâce, notamment, à des schémas sur
Page 87 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
les échanges de données, ou encore en apportant des précisions sur les
caractéristiques temps réel des composants, le langage ne permet pas de réaliser
l’implémentation comportementale du système. Cependant, il est possible de lier les
différents composants logiciels du système à des implémentations applicatives
extérieures au modèle.
Les composants appelés « subprograms » sont associés à des fonctions provenant de
fichiers extérieurs au modèle AADL. Des appels à ces composants sont ensuite
effectués par les composants « threads » du modèle qui représentent les tâches du
système. Les fonctions ainsi associées à un modèle AADL servent uniquement à
indiquer à l’utilisateur les différents appels de fonction du système, mais ne sont pas
exécutés lors des analyses puisque le langage AADL ne permet pas de réaliser des
vérifications comportementales, mais bien des analyses architecturales.
Comme cela a été dit, l’un des buts de ce langage est de permettre à l’utilisateur de
réaliser plusieurs types d’analyses à partir d’un modèle AADL, donnant ainsi la
possibilité à celui-ci de repérer très tôt d’éventuelles erreurs structurelles. Plusieurs
outils ont été mis au point pour effectuer ces analyses comme le projet CHEDDAR qui
vérifie l’ordonnancement du système ou encore le projet REAL (Requirement
Enforcement Analysis Language) qui sert à valider l’intégrité d’un modèle AADL.
Deux mécanismes d’extension du langage AADL sont proposés. Il s’agit du mécanisme
d’extension pure et du mécanisme de définition de propriétés (de l’anglais Property
Set). Le mécanisme d’extension permet de réutiliser des composants et de compléter
leurs définitions à la manière d’une extension de classe d’un langage de
programmation orientée objet. Le mécanisme de définition de propriété permet de
définir des propriétés AADL personnalisées qui viennent se greffer à l’ensemble des
propriétés de base du langage AADL.

Les systèmes temps réel peuvent être modélisés efficacement grâce à ce langage qui
permet d’appliquer des propriétés aux différents composants d’une architecture.
Certaines de ces propriétés sont notamment utilisées pour indiquer des spécifications
temporelles comme la période d’exécution d’un thread, son pire temps d’exécution,
ces échéances, etc.
En résumé, le langage AADL permet de modéliser l’architecture d’un système de façon
simple avec un haut niveau d’abstraction. Plusieurs outils peuvent ensuite se servir de
cette modélisation dans le but d’analyser et de vérifier l’implémentation et
l’intégration, mais surtout la certification du système.
La modélisation d’un système en langage AADL peut être réalisée de façon textuelle
dans un éditeur de texte, mais également par l’intermédiaire d’une interface
graphique. De nombreux éditeurs existent, mais on retrouve très souvent l’outil OSATE
qui est greffé sur l’IDE Eclipse. OSATE intègre les différents outils d’analyse d’un
modèle AADL qui sont directement accessibles à partir de l’interface de l’outil.

Page 88 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
le langage AADL est un langage de description architecturale. Il permet de déclarer
l’architecture logicielle ainsi que les composants de la plateforme matérielle sur
laquelle va s'exécuter un système. Il est possible d'associer différentes propriétés à
chaque composant qu'il soit logiciel ou matériel. De nombreux tests peuvent ensuite
être effectués sur le modèle AADL suivant la complexité du modèle et les propriétés
qui ont été renseignées. Il est par exemple possible, en ayant au préalable défini un
flot de données dans le modèle AADL, de tester le temps maximum mis pour traverser
ce flot en entier permettant ainsi d'assurer un temps de réponse maximum du
système.

2.1.1 Composants
L'AADL est un langage déclaratif qui permet de définir des composants suivant deux
étapes : la première étape consiste à déclarer le composant comme une boite noire.
On lui associe alors des ports d'entrée et de sortie. La seconde étape permet de
déclarer une implémentation du composant en agissant sur la composition interne de
celui-ci comme les sous-composants et leurs branchements. Ces deux étapes de

déclaration des composants sont présentées à la figure ci-dessus (Exemple de


déclaration d'un processus).

Le langage propose un large éventail de composants que l'on peut dissocier en


plusieurs types :
2.1.1.1 Les composants logiciels
Ces composants permettent de définir le comportement et l’architecture de la partie
logicielle du système.
 Process
Un processus permet de définir une zone mémoire où va s’exécuter le code logiciel
associé à ses sous-composants. Il peut déclarer des threads et des groupes de threads
comme sous-composants.
Page 89 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Sur la figure ci-dessus, on peut voir la déclaration d’un processus (1) et notamment les
connexions réalisées à l’intérieur de celui-ci. Les représentations graphiques boite
noire (2) et boite blanche (3) de ce processus sont également visibles sur la figure.

 Thread et Thread group


Les threads ne sont autres que les files d’exécutions du logiciel. Ils partagent la
mémoire de leur processus père avec les autres threads de ce processus. Les groupes
de threads rassemblent plusieurs threads auxquels on peut assigner des propriétés
communes. Les threads peuvent faireappel à des bouts de fonctions appelés
subprograms.
 Subprogram
Les sous-programmes font référence à des fonctions pouvant être codées dans
plusieurs langages différents (seul le langage C va être utilisé dans la suite). Ces sous-
programmes peuvent être appelés par des threads où ils sont regroupés en séquence
d’appels. La figure ci-dessous (Appel d'un sous-programme par un thread) montre
comment un thread peut appeler un sous-programme et comment celui-ci fait
référence à un code source grâce au mot clé properties.

 Data
Certains ports de communications de composant sont référencés comme « data » ou
« event data ». Il faut alors renseigner le type de donnée associé à ces ports. Ces
données sont implémentées comme les autres composants AADL. Tel qu’illustré à la
figure ci-dessous (Déclaration d'un type de donnée) où « Data_type » fait référence au
type « long », elles peuvent faire référence à des types de données d’un langage.

2.1.1.2 Les composants de la plateforme matérielle


Ces composants permettent de définir le support sur lequel va s’exécuter le logiciel
Page 90 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
 Bus
Les bus permettent aux différents composants matériels du système de communiquer
entre eux. Un composant doit avoir un droit d’accès au bus pour être branché dessus.
On peut voir sur la figure ci-dessous (Déclaration d'un bus), la déclaration d’un bus ainsi
qu’une requête d’accès présente à la déclaration d’un processeur.

 Processor
Le processeur est le composant matériel qui va exécuter le code logiciel. Plusieurs
processeurs peuvent être déclarés dans un système. L’utilisateur doit alors renseigner
sur quel processeur s’exécute chaque thread.
 Memory
Les mémoires permettent de définir des zones mémoires accessibles par tous les
threads du système.

2.1.1.3 Les composants hybrides


 Device
Les devices sont des composants en bordure du système. Ils sont représentés dans le
modèle, mais ne font pas partie du système à développer. C’est une famille de
composants, dont les capteurs et les actionneurs font partie, qui représente
l’environnement d’exécution de notre système.
 System
Le système global est déclaré comme un composant. Il crée des instances des
composants dont il a besoin et les relie ensemble. Il permet également de lier les
composants logiciels aux composants matériels. La figure ci-dessous (Implémentation
d'un système) montre un exemple de déclaration d’un système en AADL (1) et sa
représentation graphique (2).
Ces composants ne peuvent, ni être classés comme logiciels, ni comme matériels, car
ils sont présents sur les deux facettes du modèle.

Page 91 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

2.1.2 Propriétés
L’un des grands intérêts du langage AADL est de pouvoir associer des propriétés aux
différents composants d’un modèle. Ces propriétés peuvent se présenter sous
différents types : les propriétés de type énuméré, de type entier, de type entier avec
unité (e.g. 50 ms), etc. Le langage offre une grande panoplie de propriétés pour chaque
type de composant utilisé, mais bien que la banque de propriétés disponibles soit
importante, il est possible qu’un utilisateur ait besoin de propriétés plus spécifiques.
Dans ce cas, il lui est possible de définir ses propres propriétés.

2.1.2.1 Déclarations
La déclaration des propriétés pour un composant peut se faire dans la déclaration de
celui-ci, dans son implémentation ou dans les deux. Elle est précédée du mot clé «
properties » comme on peut le voir sur la figure ci-dessous (Déclaration de propriétés

Page 92 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
d'un thread) où l’on indique dans sa déclaration que le thread b est périodique et dans
son implémentation qu’il est exécuté toutes les 50 ms.

2.1.2.2 Property set


Tel qu’expliqué précédemment, si un utilisateur a besoin de propriétés spécifiques
pour un projet, il peut créer un fichier de définition de propriété (« property set ») dans
lequel il va définir de nouvelles propriétés ainsi que les différentes valeurs que peuvent
prendre ces propriétés, si celles-ci sont de type énuméré. Il doit ensuite indiquer à
quels types de composants ces propriétés sont destinées.
Pour utiliser un ensemble de propriétés défini par l’utilisateur, une description AADL
doit indiquer qu’elle va y faire appel grâce à la syntaxe suivante :
with Nom_property_set;
Ensuite, l’utilisation d’une des propriétés de l’ensemble se fait de la manière suivante:
Nom_property_set::Nom_propriété => valeur;

2.1.3 OSATE2
OSATE 2.0 (Open-Source AADL Tool Environment) est un outil libre basé sur IDE Eclipse
et peut être ajouté comme module d’extension à celui-ci.

2.1.3.1 Développement
Cet outil nous permet d’éditer du code AADL et de réaliser une analyse de celui-ci en
direct, permettant de faciliter la génération de code et la recherche de bugs. OSATE
permet, entre autres, d’analyser la consistance d’un flot de donné qui doit posséder le
même type de donnée.
Cet outil permet de générer un graphe pour faciliter la visualisation du système
développé. Il est également possible de créer et d’éditer un modèle directement à
partir de l’interface graphique pour des utilisateurs plus à l’aise avec ce type de
développement.

2.1.3.2 Tests
Le langage AADL permet de réaliser facilement des tests à haut niveau. Ces tests sont
très importants, car ils permettent de détecter très tôt des problèmes de conception
faisant ainsi économiser beaucoup de temps aux équipes de programmation. L’outil
OSATE 2 permet de réaliser bon nombre de ces tests préliminaires.
Page 93 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

2.2 SpaceStudio
SpaceStudio est un outil développé par la compagnie SpaceCodesign qui permet un
codéveloppement de la partie comportemental d’un système (i.e. le logiciel) et de sa
plateforme matérielle. Dans cette section, nous allons davantage mettre l’accent sur
l’utilisation de SpaceStudio qui va nous permettre de valider les spécifications à la fois
fonctionnelles et non fonctionnelles du système en créant un modèle exécutable
systemC et de réaliser l’implémentation du système au niveau RTL.

2.2.1 Implémentation comportementale du système


La première étape de conception d’un système sur la plateforme consiste à
implémenter la partie logicielle du système. Elle s’organise à travers deux types de
composants : les modules et les périphériques que nous nommerons devices dans la
suite de ce cours. Les modules sont des encapsulations aux threads du système alors
que les devices sont, tout comme dans le langage AADL, des composants en bordure
du système. Ces composants sont codés en SystemC qui permet de réaliser de
nombreuses abstractions ESL dans des fonctions qui sont des encapsulations gérées
par la plateforme.
Ces encapsulations sont très pratiques, car elles permettent d’exécuter les modules
aussi bien sur un processeur que comme un composant matériel sans avoir à modifier
les codes de ces modules.
Ces modules doivent donc implémenter un constructeur spécifique à la plateforme qui
va déclarer le thread qui sera exécuté par le module.
Pour échanger des données, ces modules doivent utiliser des fonctions spéciales qui
abstraient des appels à différentes structures matérielles suivant si les modules
s’exécutent sur un processeur ou en tant que composants matériels. Ces fonctions sont
appelées ModuleRead et ModuleWrite. Elles prennent comme arguments :
l’identifiant du module avec lequel la communication est établie, le comportement
d’attente du module (la communication peut être bloquante ou non), l’adresse où
recevoir le message ou à partir de laquelle l’envoyer et la taille du message.

2.2.2 Plateforme d’exécution

2.2.2.1 Création de la plateforme


SpaceStudio permet ensuite, grâce à une bibliothèque de périphériques matériels, de
configurer une plateforme d’exécution que l’on appelle « configuration ». D’un côté,
l’outil permet de sélectionner les modules et devices préalablement développés que
l’utilisateur veut intégrer dans la configuration, et de l’autre, il permet d’y intégrer les
composants matériels nécessaires au système.

2.2.2.2 Branchement de la plateforme

Page 94 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Une fois la plateforme peuplée de ses composants, l’utilisateur doit définir sur quel bus
brancher les composants. C’est également à cette étape que l’on va choisir si un
module est exécuté sur un processeur ou comme un composant matériel où les
modules BLOCK_METRICS et DEMUX sont branchés sur le bus AMBA_AXIBus_LT1, et
vont donc être.

2.2.3 Test d’exécution


Une fois les modules codés et la plateforme en place, SpaceStudio peut générer un
prototype virtuel du système. Avec ce prototype, il va être possible de procéder aux
tests d’exécution du système.

2.2.3.1 Test fonctionnel


Grâce à ce test d’exécution, il est possible de vérifier que toutes les contraintes
fonctionnelles du système sont satisfaites. Souvent, cette vérification fonctionnelle
sera effectuée grâce à un banc de test qui aura été codé dans un device pour interagir
avec le système.

2.2.3.2 Test non fonctionnel


L’outil SpaceStudio permet également de réaliser certaines analyses non
fonctionnelles en marge du test fonctionnel. Il permet, entre autres, d’observer les
accès mémoires qui ont eu lieu au cours de l’exécution, d’avoir accès à des statistiques
sur l’utilisation des bus de communication ou encore d’analyser l’occupation d’un
processeur par les différents threads qui tournent dessus.

3. Travaux pratiques : Simulation et expérimentation

Afin d’introduire le contexte logiciel et matériel d’un système embarqué ou cyber-


physique, nous prenons un petit exemple pratique basé sur une carte Arduino Uno. Le
but n’est pas de présenter la programmation sur microcontrôleur, mais d’en utiliser un
exemple concret afin de remonter par la suite aux méthodes de spécification et
conception qu’il est conseillé d’utiliser pour arriver à du logiciel embarqué sûr. Qui dit
embarqué dit utilisation de capteurs et actionneurs, les grandes familles de capteurs
et actionneurs sont introduites, en particulier les moyens de communication entre le
calculateur et ceux-ci. Ces moyens de communication donnent de l’importance à la
façon dont tout calculateur représente l’information, en binaire. Nous voyons donc la
représentation des données, et les principaux pièges tendus à l’ingénieur par le fait
qu’elle soit de taille finie.

Le système que nous voulons réaliser est un système de ventilation : nous mesurons la
température, et lorsque celle-ci dépasse une température de consigne, un ventilateur
est commandé proportionnellement à la différence de température entre la mesure et
la consigne. Nous souhaitons afficher sur une console différente informations
Page 95 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
mesurées, comme la température, la vitesse du ventilateur, et la valeur de commande
envoyée à celui-ci.
La température de fonctionnement devrait se situer entre 0 et 100 °C.

3.1. Montage expérimental


Pour la mesure de température, nous choisissons une sonde analogique de type
TMP36, dont la plage de fonctionnement est compatible avec notre température de
fonctionnement.
TMP36 : de la marque Analog Devices, les capteurs de température basse tension
 TMP36 sont des capteurs analogiques. Ceux-ci sont alimentés en voltage faible
(2,7 V à 5,5 V) et consomment peu de courant (~50 μA). Ils fournissent en sortie
une tension linéaire, proportionnelle à la température mesurée. À la
température de −50 °C, le capteur fournit 0 V en sortie, puis la tension augmente
de 10 mV par °C. Il nous faut lire une tension d’entrée variant entre 0 V et 1,75
V, correspondant linéairement à la température lue de −50 °C à +125 °C. Il offre
une précision de +/− 1 à 2 °C, suffisante pour notre application, et pour un coût
raisonnable (1,50 € si acheté à l’unité, et moins de 50 centimes en grandes
quantités).

Tension analogique versus signal numérique


Les signaux habituellement utilisés en informatique peuvent être de deux natures :
analogiques ou numériques. Un signal analogique se caractérise par un état instantané
évoluant dans le domaine continu, entre une valeur minimale et une valeur maximale.
Typiquement entre 0 V et 5 V ou entre 0 V et 10 V, ou encore entre deux seuils
spécifiques, comme pour la sonde TMP36 le signal analogique de sortie varie entre 0 V
et 1,75 V. Un signal numérique ne peut prendre qu’un ensemble limité de valeurs : on
parle aussi parfois de signal discret. Dans la plupart des cas, le signal numérique est
bivalent : il ne peut prendre que deux états, un état haut et un état bas (par exemple
0 V et 5 V ou bien 0 V et 12 V). Dans ce cas, l’information est codée en utilisant le temps
: par exemple sur un PWM, le rapport entre durée du front haut et durée du front bas
encode une information, ou bien sur la liaison série RS-232C l’état pendant un temps
bit (dont la durée est égale à l’inverse du débit) permet de représenter une information
binaire (pour un signal bivalent transmis à 9 600 bauds, chaque bit est encodé par
l’envoi d’un signal haut ou bas durant un 9 600 e de seconde).

Le ventilateur sera un ventilateur de processeur de type quatre fils, récupéré sur un


ordinateur. Ce ventilateur est conforme à la spécification Intel (septembre 2005,
révision 1.3).
 Ventilateur de processeur quatre fils : possède deux connecteurs pour
l’alimentation (12 V et masse), un connecteur pour la consigne de vitesse,
acceptant un signal PWM à 25 kHz, et un connecteur en drain ouvert envoyant
une impulsion PWM par demi-tour du ventilateur.
Page 96 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

Signal PWM (Pulse Width Modulation)


La modulation par largeur d’impulsion consiste à faire varier un signal discret entre les
états hauts et bas pendant des durées définies pour transmettre des données ou de la
puissance. Un signal PWM se caractérise par son rapport cyclique (durée de l’état haut
par rapport à la durée de l’état bas) et sa fréquence, c’est-à-dire l’inverse de sa période,
constituée de la somme de la durée de l’état haut et de l’état bas (voir figure ci-
dessous). On retrouve ce type de signaux en modélisme pour commander des
servomoteurs ou pour les transmissions de la radio commande. Le PWM peut aussi
être utilisé pour « simuler » un signal analogique entre la valeur basse et la valeur
haute, car après filtrage (passe-bas), le rapport cyclique donne de 1) et la valeur basse
(rapport cyclique de 0 ou proche de zéro). C’est une façon de générer, à bas coût, une
tension analogique à partir d’un générateur de signaux numériques. un signal qui peut
évoluer de façon continue entre la valeur haute (rapport cyclique de 1) et la valeur
basse (rapport cyclique de 0 ou proche de zéro). C’est une façon de générer, à bas coût,
une tension analogique à partir d’un générateur de signaux numériques.

Signal PWM de fréquence 25 kHz


La figure suivante illustre la manière dont une sortie PWM permet de reproduire un
signal d’allure sinusoïdale à partir d’une modulation de largeur d’impulsion dont le
rapport cyclique suit la valeur d’une sinusoïde positive de fréquence 1 kHz. On observe
que le signal résultant comporte un certain nombre de paliers qui dépendent du sur-
échantillonnage de la sortie PWM (nombre de cycles PWM par période d’une
milliseconde, ici fixé à huit). On observe également un déphasage entre le sinus de
sortie et le signal souhaité, lié à la présence d’un filtre passe-bas (d’ordre 2 dans
l’exemple). Le filtre passe-bas supprime les transitoires du signal PWM (hautes
fréquences) pour ne laisser passer qu’une moyenne du signal entrant (basses
fréquences). Cette moyenne est faite sur une durée caractéristique du filtre, liée à sa
fréquence de coupure et à son facteur de qualité. Il faut donc trouver un compromis
entre un bon filtrage des hautes fréquences (bruit), le retard de phase induit et la
complexité du filtre (ordre).

Page 97 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Génération d’un signal sinusoïdal à 1 kHz à l’aide d’un PWM à 8 kHz et d’un filtre
passe-bas d’ordre 2

Il nous faut donc un système de contrôle permettant de lire une entrée analogique
(capteur de température), une entrée PWM (rotation du ventilateur), et d’écrire du
PWM en sortie à une fréquence de 25 kHz (commande du ventilateur). Une connexion
de type série ou USB permettrait de réaliser l’affichage initialement sur un PC.
Nous choisissons une carte microcontrôleur Arduino Uno, munie d’entrées-sorties,
parmi lesquelles nous pouvons trouver notamment six entrées analogiques, et une
douzaine d’entrées-sorties numériques. Ces dernières nous permettront de lire et de
générer des signaux PWM.
 Arduino Uno : carte matérielle embarquant un microcontrôleur huit bits
ATmega328P à 16 MHz équipé de 32 ko de mémoire flash. La carte intègre
notamment 14 entrées/sorties numériques (dont six sont compatibles PWM),
six entrées analogiques multiplexées, et une liaison série. Le montage
expérimental 1 est donné sur la figure ci-dessous. La sortie analogique (fil
orange) de la sonde TMP36 est reliée à l’entrée analogique A0 du
microcontrôleur. Pour son alimentation, elle doit également être connectée à la
masse et à la sortie 5 V du microcontrôleur. La commande PWM (fil bleu) du
ventilateur est liée à la broche 3 INT1 du microcontrôleur, alors que la sortie
tachymètre (fil vert), lié à la broche 2 INT0, est montée avec une résistance de
tirage de 10 kΩ, de façon classique pour un circuit en drain ouvert (voir
encadré). Contrairement à la sonde, l’alimentation du ventilateur se fait en 12
V (fils jaune et noir). Le microcontrôleur est quant à lui directement alimenté

Page 98 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
par le cordon USB relié au PC sur lequel nous effectuerons le développement,
et sur lequel l’affichage se réalisera.

Un peu d’électronique pour les nuls


Montage à drain ouvert : le signal PWM tachymètre du ventilateur n’est pas généré
directement par le ventilateur, en réalité, la sortie tachymètre du ventilateur (fil vert)
est branchée en sortie d’un transistor. Selon que le transistor est ouvert ou fermé, la
sortie est donc soit reliée à la masse, soit à l’alimentation. On utilise donc une
résistance de tirage, typiquement assez élevée, de façon à limiter le courant et ainsi
protéger l’entrée de l’Arduino, puisque selon la loi d’Ohm, ce courant est proportionnel
au rapport de la tension d’alimentation (ici 5 V) sur la résistance (ici
10 kΩ). Plaque d’essai : une plaque d’essai permet de brancher facilement des
composants électroniques. Sur la figure ci-dessous, les connecteurs des deux lignes
supérieures et des deux lignes inférieures sont reliés par ligne. Les lignes A, B, C, D, E
(respectivement F, G, H, I, J) de connecteurs sont reliées par colonne. Ainsi, par
exemple, A1, B1, C1, D1, E1 sont reliés.

Montage expérimental du système de ventilation

3.2. Programme de contrôle


Arduino propose un environnement de développement (IDE – Integrated Development
Environment) relativement simple d’utilisation, mais qui n’offre que des
fonctionnalités basiques de développement.
Nous utiliserons le langage C, avec l’interface de programmation (API – Application
Programming Interface) native d’Arduino. Le principe d’un programme C développé
pour Arduino est le suivant : à la place d’un sous-programme principal nommé main(),
un programme Arduino possède un point d’entrée sous forme d’un sous-programme
nommé setup() . Ce sous-programme est appelé juste après que la plateforme soit
Page 99 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
initialisée, et doit initialiser tout ce qui doit l’être pour l’application utilisateur. Ensuite,
le sous-programme loop() est appelé en boucle. Il faut noter que ce système de
programmation (setup() puis loop() appelé en boucle) est spécifique à l’API Arduino,
comme nous le verrons en utilisant d’autres API dans la suite du cours.
Exceptionnellement, nous travaillerons directement sur le programme C, sans d’abord
le spécifier fonctionnellement ou exprimer l’architecture logicielle et matérielle du
système. Cela nous permettra dans la suite immédiate d’introduire simplement des
éléments d’un langage dédié (que l’on appelle un DSL pour Domain Specific Language)
à la spécification et la conception de systèmes. Ce langage est outillé par le logiciel
Capella (https://www.polarsys.org). Capella a été initialement développé par et pour
la société Thales, qui l’a ensuite ouvert au public via la fondation Polarsys. Il s’agit d’un
logiciel libre, publié sous licence EPL (Eclipse Public Licence). Capella met en œuvre la
méthode de spécification et de conception basée sur les modèles Arcadia, dont Thales
et le consortium Clarity font la promotion. Ce cours ne couvre pas l’ensemble de la
méthode Arcadia, qui vise à intégrer tous les acteurs impliqués dans la conception de
systèmes industriels complexes (ingénieurs commerciaux, analystes, programmeurs,
architectes systèmes, instrumentiers, etc.). Nous utiliserons uniquement un sous-
ensemble des diagrammes proposés par Capella, car l’outil est à ce jour, la solution
ouverte et libre basée modèle la plus aboutie. Cependant, Capella ne fournit que peu
d’éléments de modélisation pour la projection des fonctions sur le système embarqué.
Nous utiliserons donc un autre DSL, en l’occurrence AADL, outillé par le logiciel libre
Osate (http://osate.org/), disponible sous licence CPL (Common Public License), pour
cette partie. Enfin, même si Capella propose des machines à états à la UML, leur
implémentation étant partielle à l’heure où ces lignes sont écrites, nous utiliserons un
outil spécifique pour les statecharts : Yakindu SCT
(https://www.itemis.com/en/yakindu/state-machine/), sous licence propriétaire, mais
gratuit pour un usage non commercial. Les trois outils sont basés sur la plateforme libre
Eclipse (https://www.eclipse.org/).

Les programmes et tout support numérique utiles sont disponibles sur le site internet
http://www.dunod.com. Il est conseillé à ce niveau de télécharger le matériel
numérique afin de pouvoir compiler, tester, et potentiellement modifier les
programmes.

3.2.1 Définition des constantes importantes et des variables globales du programme


Il est d’usage de définir sous forme de constantes les éléments d’entrées-sorties que
nous utiliserons afin de n’y faire référence qu’une seule fois (à la définition des
constantes) dans le programme. En effet, cela nous rend moins dépendants du
matériel, et des connexions effectuées. Nous avons ici trois connecteurs d’entrée-
sortie utilisés. Nous les définissons comme des constantes entières. Ainsi,
VentilateurPin est une constante entière (mot-clé const), à laquelle on affecte le littéral
3 . L’entrée analogique 0 bénéficie d’une constante A0 prédéfinie dans l’API Arduino.
Page 100 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
const int TemperaturePin = A0;

const int VentilateurPin = 3;

const int tachymetrePin = 2;

Représentation de l’information
Toute information numérique est représentée en binaire, c’est-à-dire en base 2. En
base décimale, que nous utilisons tous les jours, la base est 10, ce qui nous laisse les
dix chiffres 0 à 9 pour représenter chaque multiplicateur de puissance de 10. Ainsi, le
nombre 123 se lit 1 × 10 2 + 2 × 10 1 + 3 × 10 0 , et est donc représenté par 123 en base
décimale. En binaire, il n’y a que deux chiffres, 0 et 1. Un chiffre binaire s’appelle un
bit, pour BInary digiT. Les bits permettent de représenter le nombre 123 comme 1 × 2
6
+ 1 × 2 5 + 1 × 2 4 + 1 × 2 3 + 0 × 2 2 + 1 × 2 1 + 1 × 2 0 , ce qui se lit 1111011 en base
binaire. Afin de distinguer les bases, nous utiliserons en préfixe la lettre « b » pour les
nombres donnés en binaire. Le nombre 123 se représente donc b1111011 en binaire.

Représentation finie de l’information


La mémoire d’un calculateur est bornée. Les calculs sont effectués par l’unité
arithmétique et logique du processeur. Les opérandes et les résultats sont stockés dans
des « cases mémoire » appelées registres qui sont de taille finie. Leur taille définie celle
d’un mot mémoire, généralement multiple de huit bits. Un groupe de huit bits s’appelle
un octet. Les architectures des ordinateurs utilisent des mots mémoire d’un à huit
octets (64 bits), par conséquent, il en va de même pour les langages de programmation
qui proposent d’utiliser des variables numériques dont la taille peut varier entre un et
huit octets. Sur un octet, on peut représenter des valeurs allant de b00000000 à
b11111111, ce qui correspond à des valeurs allant de 0 à 255 (soit 2 8 = 256 valeurs
différentes). Nous voyons donc différents problèmes qui ont dû être réglés : la
représentation des nombres signés (négatifs ou positifs), la représentation des
nombres fractionnaires, des nombres réels, et les problèmes de débordement. Nous
aborderons ces points plus tard dans ce cours lorsque nous nous trouverons face à ces
problèmes.

Le fait qu’Arduino lance un sous-programme loop() en boucle nous oblige, lorsqu’une


variable doit être mise à jour en fonction de son ancienne valeur dans cette boucle,
soit à la déclarer en variable locale statique, soit à la déclarer comme une variable
globale : dans les deux cas, cette variable est mise dans le tas et pas dans la pile du
sous-programme, ce qui permet de la conserver même après la terminaison du sous-
programme pour un usage ultérieur.

Rémanence des variables, pile et tas

Page 101 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Les variables déclarées hors de tout sous-programme sont en général globales, c’est-
à-dire visibles de tout sous-programme. Elles sont, de plus, conservées au même
endroit de la mémoire pendant toute la durée du programme. Au contraire, les
variables déclarées dans un sous-programme sont temporaires, elles n’existent que
pendant la durée du sous-programme. Ainsi, dans notre sous-programme loop() , si
nous déclarons localement (c’est-à-dire à l’intérieur du sous-programme) une variable
température, celle-ci est perdue à la fin du sous-programme. Lors de la prochaine
exécution du sous-programme loop() , c’est une nouvelle variable qui sera fraîchement
créée, et elle ne contiendra pas la valeur de la variable de l’exécution précédente du
sous-programme. Une variable locale peut être rendue persistante, en utilisant le mot-
clé static lors de sa déclaration. Ce comportement se comprend d’autant mieux lorsque
l’on connaît le modèle mémoire des programmes. La mémoire d’un programme mono-
tâche est (de façon réelle ou virtuelle) découpée en trois segments (voir figure ci-
dessous). Le code (c’est-à-dire les instructions élémentaires du programme,
représentées en binaire), supposé être statique, est mis dans le segment de code
(certains systèmes d’exploitation le contraignent à être en lecture seule). Le tas
contiendra les variables dont la durée de vie est égale à celle du programme, c’est-à-
dire les variables globales, et les variables statiques de sous-programme. Le tas va aussi
héberger la mémoire allouée dynamiquement (new , malloc , etc.). La pile, à l’instar
d’une pile d’assiettes, est de nature « dernier arrivé, premier retiré » : sur une pile, on
empile (on ajoute des assiettes sur une pile d’assiette, ou une donnée au sommet
d’une pile) et on dépile (on retire l’assiette du sommet de la pile d’assiettes, ou une
donnée du sommet d’une pile). Le fait d’empiler a pour effet d’augmenter la taille de
la pile, et de faire monter son sommet (notons que comme la pile est représentée
inversée sur la figure ci-dessous, le sommet descend, mais c’est un point de détail
d’implémentation, cela ne change rien au comportement de la pile), alors que le fait
de dépiler produit l’effet inverse. La pile est donc caractérisée par son contenu, mais
seule l’adresse de son sommet est mémorisée. Lors de l’appel d’un sous-programme,
on va commencer par empiler l’adresse de retour du sous-programme (c’est-à-dire
l’adresse de l’instruction qui devra être exécutée après la terminaison du sous-
programme) de façon à ce que le système sache ce qu’il devra faire à la fin du sous-
programme. Ensuite, on empile tous les paramètres du sous-programme, ce qui
permettra au sous-programme d’accéder à ses paramètres en allant à un certain
décalage du sommet de pile. Enfin, toutes les variables locales sont empilées. Ce qui
est intéressant, c’est qu’à la fin du sous-programme, il suffit de dépiler (ce qui se traduit
juste par le changement de l’adresse du sommet de pile) pour remettre la pile dans
l’état dans lequel elle était avant appel du sous-programme, et reprendre l’exécution
à l’adresse de retour. Ce mécanisme permet ainsi d’enchaîner les appels de sous-
programmes très simplement, et même de faire facilement de la récursivité (sous-
programme qui s’appelle lui-même, qui s’appelle lui-même, etc.). En contrepartie de
cette simplicité et flexibilité, toute variable locale est perdue (puisque dépilée) à la fin
du sous-programme.
Page 102 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

Modèle mémoire classique d’un programme mono-tâche

La sonde de température est assez sensible aux variations de tension, en effet, nous
avons vu qu’une variation de 10 mV correspond à 1 °C. Une faible variation de tension
liée à une erreur aura donc un impact important sur la température mesurée. Nous
introduirons donc un filtre très simple de température : le filtre exponentiel de Poisson.
Ainsi, si la première mesure de température est notée T0, nous considérerons que la
température considérée à la mesure courante est donnée par T i = (1 − λ) Ti − 1 + λT où
Ti − 1 est la température considérée à la mesure précédente, et T est la mesure
effectuée. Le paramètre λ est un facteur d’oubli : lorsqu’il vaut 1, le filtre considère la
mesure instantanée comme étant la température courante, alors que lorsqu’il a une
valeur faible, les variations de température sont absorbées. Ce type de filtre lisse les
mesures et réduit le bruit lié aux erreurs, mais en contrepartie diminue la réactivité du
système. Afin de programmer ce filtre très simple, nous avons besoin de conserver la
dernière température lue, ce qui va être fait dans la variable temperature.
float temperature ;

Les flottants et la norme IEEE 754


Dans la plupart des systèmes, il est nécessaire de représenter des grandeurs
fractionnaires. Bien entendu, la représentation étant de taille finie (sur un nombre fini
d’octets), la représentation de nombres réels est impossible. On est donc amené à
utiliser des représentations potentiellement arrondies des nombres fractionnaires. Là,
il y a deux possibilités : lorsque l’on connaît parfaitement le domaine de variation du
nombre, et la précision voulue, et on utilise des représentations en virgule fixe, à savoir
des entiers avec unité non unitaire (typiquement fractionnaire). Nous verrons cette

Page 103 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
représentation lorsque nous parlerons des convertisseurs analogique-numérique.
Cependant, si on dispose de peu d’informations concernant le domaine de variation du
nombre, et/ou la précision voulue, on utilise les nombres à virgule flottante, plus
simplement appelés flottants. Ces nombres, normalisés dans la norme IEEE 754,
permettent de représenter des grandeurs avec une précision variable dépendant de la
valeur du nombre. Si le nombre est petit, on souhaite en général une précision très
importante, mais s’il est grand, on peut souvent se contenter d’une précision bien
moindre.
Les flottants représentent donc les nombres en les décomposant à l’instar de la
notation scientifique utilisée pour les nombres : par exemple un nombre pourrait
s’écrire 4,3456 × 10 −7 . Les flottants reprennent ce principe, mais en binaire. Ils existent
en différentes tailles, mais les plus répandus sont les flottants simple précision sur 32
bits (float ) et les flottants double précision sur 64 bits ( double ). Un flottant 32 bits est
représenté tel que sur la figure ci-dessous : le bit de poids fort est le bit de signe (1
pour moins, 0 pour plus), puis il y a huit bits représentant l’exposant, et 23 bits
représentant la mantisse. À l’instar de la notation scientifique selon laquelle il y a un
unique chiffre non nul avant la virgule, le flottant présente avant la virgule un chiffre
non nul, qui est donc nécessairement 1. Puisqu’il est toujours égal à 1, ce bit est « caché
» (c’est-à-dire qu’il n’est pas représenté) afin de gagner en domaine de représentation.
Un nombre flottant se lit donc : -1 signe × 1,mantisse × 2 exposant .
Problème : on souhaite pouvoir représenter des grands et des petits nombres, on veut
donc des exposants positifs et négatifs, mais il n’y a pas de signe à l’exposant. Dans la
norme, l’exposant est dit « biaisé » : on l’interprète en lui soustrayant 127. Ainsi, un
exposant à 127 se lit 0, et le plus grand exposant représentable est 254 – 127 = 127
alors que le plus petit représentable est 1 – 127 = −126. Nous verrons que les exposants
représentés par 0 et 255 ont un sens particulier.
Problème : le 0 ne se représente pas, par conséquent, certaines valeurs binaires ont un
sens particulier : ainsi, si la mantisse et l’exposant sont nuls, on considère que le
nombre est nul (notons qu’il existe +0 et −0).
Problème : si la mantisse est non nulle, alors le plus petit nombre non nul en valeur
absolue serait 1,000...0001 × 2 −126 . Afin de permettre une représentation fine autour
de zéro, il existe donc une représentation dite dénormalisée (en opposition à la
représentation dite normalisée présentée jusqu’ici). Si la valeur de l’exposant n’est
constituée que de zéros, alors le bit caché est considéré comme valant 0 et l’exposant
vaut −126 (comme lorsque l’exposant est représenté par 1). Ainsi le plus petit nombre
non nul en valeur absolue est 0,000...001 × 2 −126 = 2 −149 ce qui vaut
environ 1,4 × 10 −45 .
Il existe aussi des représentations pour l’infini, et les erreurs (Not a Number ou NaN),
ainsi qu’une arithmétique particulière prenant en compte les nombres, l’in- fini, et les
erreurs.
La valeur maximale (255) de la représentation de l’exposant est réservée aux
représentations de l’infini et des erreurs, par conséquent le plus grand nombre
Page 104 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
normalisé a un exposant de 254 – 127 = 127. Le plus grand nombre représentable est
donc 1,111...111 × 2 127 ce qui vaut environ 3,4 × 10 38 . Il faut cependant bien avoir en
tête le fait qu’à cet exposant, deux nombres représentables successifs ont un écart de
2 −23 × 2 127 = 2 104 soit environ 2 × 10 31 . La perte de précision à cet exposant est donc
colossale.

Flottant 32 bits dans la norme IEEE 754

Enfin, un tableau dans lequel nous placerons la durée des traitements est déclaré
globalement afin de ne pas avoir à le passer en paramètre à chaque sous-programme.
Ce type de programmation n’est pas très sûr, mais n’est ici utilisé que pour la phase de
mise au point et ne sera pas présent dans le programme final.
// Tableau utilisé pour stocker les durées des parties du
// programme
// 0: lecture analogique de température et calculs
// 1: lecture TPM
// 2: envoi sur le port série
unsigned long durees[3];

3.2.2 Lecture analogique de température


La température mesurée sera donnée en volts, sous forme d’un entier, par la fonction
de l’API Arduino analogRead() . Il est assez rare, dans une API, que la lecture d’une
entrée analogique renvoie un entier, et de nombreuses API renvoient le voltage lu sous
forme d’un flottant. Malgré les apparences, le renvoi sous forme d’entier est, à notre
sens, souhaitable, car la résolution du convertisseur analogique numérique est
discrète, alors qu’un flottant peut entraîner une perte de précision. L’entier doit être
interprété sous la forme d’un point fixe. Pour simplifier, un point fixe est un entier avec
unité non unitaire.
L’Arduino Uno possède un convertisseur dix bits, lié à une entrée [0-5 V]. Cela signifie
qu’une lecture de 5 V correspondrait à la valeur 1 024, et que l’unité du point fixe
renvoyé par analogRead() est le 1/1 024 e de volt. Si l’on souhaite connaître la mesure
en volts, il nous faut donc opérer analogRead(A0)*5/1024.0 .
Page 105 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

Convertisseur analogique numérique


Un convertisseur analogique-numérique (CAN) convertit un signal analogique
(évoluant dans le domaine continu) en donnée numérique, donc discrète. Il est
caractérisé notamment par sa résolution en bits. Ainsi, le CAN de notre Arduino Uno
possède une résolution de dix bits, permettant de coder N = 2 10 = 1 024 valeurs
différentes. Par défaut, la tension de référence utilisée est [0-5 V], ce qui donne 5 V/1
024 unités = 4,88 mV/unité. Pour notre sonde TMP36, qui a une résolution deltaV = 10
mV/°C, cela signifie que, du fait de la discrétisation de la tension analogique d’entrée,
deux mesures ont un écart minimal d’environ 0,5 °C.
Notons que cela est inférieur à la précision du capteur, cependant cela peut être un
problème dans une application où la variation de température, même fine, est
importante. En effet, la précision absolue du capteur est supérieure à la résolution du
CAN, cependant, on peut avoir un peu plus confiance en la variation du capteur qu’en
la lecture absolue de température, dans ce cas la résolution du CAN peut être un
problème. Il est possible de changer la référence de mesure analogique, et l’Arduino
Uno en possède une alternative qui est de [0-1,1 V]. Si l’on choisit cette référence, nous
avons toujours 1 024 valeurs possibles, mais pour coder cette fois 1,1 V, ce qui
correspond à 1,1 V/1 024 unités = 1,07 mV/unité. En choisissant cette référence, nous
sommes capables de distinguer 0,1 °C d’écart en entrée.
Cependant, cela restreint le domaine de fonctionnement de notre application : la
sonde TMP36 fournit une tension comprise entre 0 V et 1,75 V pour une température
variant de Tmin = −50 °C à 125 °C, par conséquent, comme nous ne pouvons alors lire
que 1,1 V au maximum, nous ne pouvons lire les températures que jusqu’à 65 °C. Une
solution alternative serait d’utiliser une tension externe en tension de référence : il est
possible sur un microcontrôleur ATmega (type de celui qui équipe notre Arduino),
d’utiliser une référence quelconque entre 0 V et 5 V pour la lecture analogique. Si nous
utilisions une référence externe de 1,75 V, nous obtiendrions une résolution liée à la
conversion analogique numérique correspondant à 0,17 °C, tout en conservant un
domaine de fonctionnement [−50 °C à 125 °C]. Ainsi la figure ci-dessous montre sur
trois courbes les valeurs de 100 températures mesurées toutes les 50 ms avec les
références de 5 V, 1,1 V et 1,75 V. Les mesures ont été effectuées en intérieur, avec
une seconde d’écart entre les campagnes de mesures, qui duraient cinq secondes
chacune. Par conséquent nous devrions lire des valeurs similaires. La conversion entre
mesure de tension d’entrée analogique et température a été réalisée par l’opération :
((référence/N)*mesure)/deltaV + Tmin.
Cependant, nous pouvons constater des différences absolues de températures. Cela
n’est pas étonnant, la conversion étant très sensible à la référence, une petite erreur
sur la tension de référence entraîne une différence de température calculée. Nous
voyons donc qu’il est important de calibrer le capteur : si nous connaissons la
température exacte, nous pouvons calculer plus exactement la tension de référence
une fois pour toute. Le second point à observer est que les variations de température
Page 106 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
sont relativement précisément mesurées, et d’autant plus que la référence est faible,
ce qui permet de profiter au maximum de la résolution. Ainsi, avec une référence de 5
V, la différence minimale entre deux températures est bien plus importante qu’avec la
référence de 1,1 V.

Mesures de températures effectuées sur la TMP36 avec des références différentes

Points fixes
La valeur renvoyée par analogRead() est typique de ce qu’on appelle un nombre à
virgule fixe, ou point fixe. Ce nombre s’interprète comme un entier avec une unité qui
n’est pas unitaire, ici, l’unité est le 5/1 024 e de volts (avec la référence 5 V). Certains
langages de programmation, comme Ada, proposent des éléments syntaxiques
permettant au compilateur de vérifier que le développeur utilise ses points fixes de
manière consistante. En C, le langage ne permet pas la définition de points fixes, et il
est de la responsabilité du programmeur d’en assurer la consistance.

Types de données de base


La plupart des langages de programmation s’inspirent largement du langage C pour la
taille des données. Cependant, la taille des types de base varie en fonction de
l’architecture du processeur et potentiellement du système d’exploitation s’exécutant
sur celui-ci. Les architectures de microprocesseur sont classifiées en catégories selon
que les entiers de base int et les adresses (pointeurs) soient 16, 32 ou 64 bits. Ainsi on
nomme ces architectures à base de quatre lettres « I » pour int, « L » pour long , « LL »
pour long long , « S » pour short , et « P » pour pointeur. Une architecture LP64 propose
des entiers longs (type long) et des pointeurs 64 bits, les entiers classiques int étant 32
bits.
Le tableau ci-dessous donne la taille des entiers et pointeurs dans des architectures
existantes. Par exemple, les architectures Microsoft Windows 64 bits sont
généralement LLP64, alors que les architectures Unix 64 bits sont généralement ILP64.
À l’exception du type char, la taille des types varie d’une architecture à une autre, il est
bon de ne pas faire d’hypothèse sur la taille de représentation d’un type de base, et

Page 107 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
l’opérateur sizeof() doit toujours être utilisé lorsqu’on a besoin de la taille d’un type ou
d’une variable scalaire.

Remarque :char signifie caractère, car historiquement, le code ASCII encodant les
caractères américains était exprimé sur sept bits, auquel on adjoignait un bit tel que
chaque octet ait une parité paire, ce qui permettait de détecter des erreurs de
transmission entre le clavier et l’unité centrale des premiers ordinateurs. Ce code a
ensuite été étendu à huit bits, ajoutant ainsi 128 caractères et symboles possibles.
L’encodage des caractères est un défi, et la famille de normes Unicode s’y intéresse,
avec des caractères pouvant être codés sur un à quatre octets (en UTF-8, par exemple).

Taille des entiers et pointeurs dans des architectures classiques

Page 108 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chapitre 5: Architecture matérielle, Système d’exploitation et Programmation des
systèmes multitâches

1. Introduction
Au cœur de la très grande majorité des produits électroniques actuels se trouvent
enfouis un (souris, montre, carte monétique, etc) voire plusieurs processeurs (voiture,
avion, etc). Un système embarqué, peut d'ailleurs interagir avec plusieurs sous
systèmes embarqués (un ordinateur et une souris par exemple). Différentes familles
de processeurs cohabitent sur le marché (MCU, GPP/MPU, AP/MPU, DSP, MPPA, FPGA,
GPU, etc), chacune répondant à des besoins et exigences (application/supervision ou
calcul/algorithmique, consommation, coût, encombrement, performance, etc). MCU
(Micro Controller Unit ou microcontrôleur) est l'architecture processeur la plus
répandue en volume sur le marché.

Un système numérique de traitement de l'information peut souvent être représenté


en couches matérielles comme logicielles (figure ci-dessous). Ce modèle représente
grossièrement les dépendances des différentes fonctionnalités matérielles et
logicielles entre elles (application, bibliothèques, pilotes, périphériques internes et
externes, etc) et donc le chemin de l'information dans le système (montante/entrante
ou descendante/sortante). L’objectif premier restant de développer une application
logicielle, répondant à un besoin et supervisant le système matériel dédié.
Contrairement à un ordinateur cherchant la généricité (système d'exploitation multi-
applicatifs, interfaces utilisateur génériques et standards, etc), un système embarqué
est développé pour répondre spécifiquement et de façon optimale à un besoin.

2. Architecture matérielle
Un système embarqué comprend un processeur, sa mémoire, ses interfaces d'entrée-
sortie interconnectés par des bus (figure ci-dessous). Cette partie correspond à
l'architecture matérielle classique d'un ordinateur et est plus ou moins sophistiquée
Page 109 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
en fonction des besoins de performance du système. Dans les versions les plus simples,
on retrouve des architectures matérielles proches de celles des systèmes à
microprocesseur des années 1980, avec néanmoins souvent la présence
d'accélérateurs matériels spécialisés pour une fonction donnée.

Un MCU (Micro Controller Unit) ou microcontrôleur est une famille de processeur


numérique présente sur le marché de l’électronique. Le premier MCU produit et
commercialisé date de 1971 par Texas Instruments. Cette famille de processeur
possède notamment comme particularité d’intégrer sur une même puce de silicium
(on chip) l’ensemble des éléments (CPU, bus, mémoires et périphériques) faisant d’elle
un processeur complet sur puce, contrairement aux ordinateurs où les composants
silicium électroniques (GPP/MPU, mémoires vive DRAM et de masse HDD/SSD, chipset,
ec) sont distincts et portés sur une carte mère (circuit imprimé).
Les MCU sont dédiés et spécialisés aux applications exigeant un faible encombrement
spatial (processeur complet intégré sur puce), une faible consommation énergétique
(souvent mono CPU à qq10-100MHz) et un faible coût financier (entre de qq0,1€ à
qq1€ l’unité). Il s’agit des processeurs les plus fabriqués en volumes dans le monde
chaque année avec près de 25 milliards d’unités en 2020 (source IC Insigths). Il s’agit
de composants numériques de stockage, d’échange et de traitement de l’information.
Rappelons les rôles de chaque entité d’un processeur architecturé autour d’un CPU :
 CPU (Central Processing Unit) - Traiter l’information : Composant chargé de
récupérer séquentiellement par copie (fetch) une à une les instructions du
programme binaire exécutable (firmware) présent en mémoire. Une fois
récupérée, chaque instruction est décodée (decode), exécutée (execute) puis le
résultat sauvé dans la machine (writeback). Hormis lorsqu’il est forcé en veille,
un CPU réalisera sans arrêt les étapes séquentielles suivantes
Fetch/Decode/Execute/WriteBack. Le pipeline matériel d’un CPU correspond à
sa capacité à réaliser ces traitements en parallèle. Il existe plusieurs modèles
architecturaux de fonctionnement de CPU (RISC/CISC,
Page 110 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Harvard/VonNeumann/Hybrid, Scalar/Superscalar/VLIW, etc). Tous seront
découverts en formation dans la suite du cursus.
 Mémoire - Stocker l’information : La mémoire est chargée de stocker
l’information. L’information peut être de deux natures différentes dans la
machine, instructions du programme (code) ou données (data)
- Mémoire programme : mémoire non-volatile (persistante), elle sera
souvent nommée historiquement mémoire Flash sur MCU. Elle sera le plus
souvent accessible en Lecture seule par le CPU à l’usage (ReadOnly). Les
technologies les plus répandues sont les mémoires flash NOR et flash NAND.
- Mémoire donnée : mémoire volatile le plus souvent de technologie SRAM
sur MCU. Elle sera accessible en Lecture et Ecriture par le CPU à l’usage
(Read/Write).
 Périphériques - Échanger/Convertir/Traiter l’information : Les fonctions
matérielles spécialisées périphériques à l'ensemble CPU/Mémoire, plus
communément nommées ''périphériques'', jouent généralement l’un des trois
rôles suivants dans le système : communiquer ou échanger l’information (par
protocole de communication), convertir l’information (du domaine analogique
vers numérique) ou traiter l’information (fonction de traitement matérielle
spécialisée)

3. Architecture logicielle
L’architecture logicielle est le système de commande de l’ensemble du dispositif.
Sans le système d’exploitation (SE, Operating System, OS), le système informatisé n’est
qu’une boîte inutilisable. Le système d’exploitation fait l’interface entre le matériel et
le logiciel (figure ci-dessous) : il présente aux programmes une machine virtuelle,
relativement indépendante du matériel sous-jacent

Rôle et mode de fonctionnement de l’architecture logicielle :


 répondre aux stimuli du monde extérieur, en exécutant des traitements soumis
à des contraintes temporelles également fournies par l’environnement,
Page 111 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
 elle ne décide pas de la base de temps, comme dans les cas des systèmes temps
partagé, c’est un système réactif : les contraintes temporelles sont imposées par
l’environnement,

Un système réactif est en interaction constante avec son environnement, il en reçoit


des signaux et répond par des signaux en sortie en exécutant des fonctions soumises à
des contraintes temporelles fortes.

Le logiciel de ces OS est réparti sur plusieurs unités de traitement (l’unité principale et
des unités annexes). Ces OS sont trop complexes pour être gérés par un seul
programme sur l’unité de traitement centrale. Une gestion multitâche est donc
nécessaire sur cette dernière et par conséquent un système d’exploitation est souvent
utilisé avec ces OS. Le logiciel de l’unité de traitement centrale est écrit avec un langage
de haut niveau tel que le C/C++. Les logiciels des unités de traitement annexes sont
souvent trop spécifiques et donc écrits avec à la fois un langage de haut niveau C/C++
et le langage d’assemblage.

4. Réseaux et bus de terrain


Le modèle OSI est utilisé dans le fonctionnement de TCP/IP et découpe plus finement
les couches réseau encapsulées en 7 étapes qui peuvent être appliquées à tous les
réseaux (et simplifié en 4 étapes pour le TCP/IP comme ci-dessous) :

Page 112 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chaque couche correspond à une tâche précise, de la plus simple à la plus complexe.
Les couches sont encapsulées, comme des enveloppes mises les unes dans les autres.

Le terme bus de terrain est utilisé par opposition au bus informatique. En effet, le bus
de terrain est en général beaucoup plus simple, du fait des faibles ressources
numériques embarquées dans les capteurs et actionneurs. Il est également plus
robuste face aux perturbations externes.

5. Systèmes d’exploitation
5.1 Les contraintes de temps et les systèmes embarqués
La gestion du temps est l'un des problèmes majeurs des systèmes d'exploitation. La
raison est simple : les systèmes d'exploitation modernes sont tous multitâches or ils
utilisent du matériel basé sur des processeurs qui ne le sont pas, ce qui oblige le
système à partager le temps du processeur entre les différentes tâches. Cette notion
de partage implique une gestion du passage d'une tâche à l'autre qui est effectuée par
un ensemble d'algorithmes appelé ordonnanceur.

Un système d'exploitation classique comme UNIX, LINUX ou Windows utilise la notion


de temps partagé par opposition au temps réel. Dans ce type de système, le but de
l'ordonnanceur est de donner à l'utilisateur une impression de confort tout en
s'assurant que toutes les tâches demandées sont finalement exécutées. Ce type
d'approche entraîne une grande complexité dans la structure même de l'ordonnanceur
qui doit tenir compte de notions comme la régulation de la charge du système ou la
date depuis laquelle une tâche donnée est en cours d'exécution. De ce fait, on peut
noter plusieurs limitations par rapport à la gestion du temps.

Tout d'abord, la notion de priorité entre les tâches est peu prise en compte, car
l'ordonnanceur a pour but premier le partage équitable du temps entre les différentes
tâches du système (on parle de quantum de temps ou tick). Notez que sur les
différentes versions d'UNIX dont LINUX, la commande nice permet de modifier la
priorité de la tâche au lancement.

Ensuite, les différentes tâches doivent accéder à des ressources dites partagés ce qui
entraîne des incertitudes temporelles. Si une des tâches effectue une écriture sur le
disque dur, celui-ci n'est plus disponible aux autres tâches à un instant donné et le délai
de disponibilité du périphérique n'est donc pas prévisible.

En outre, la gestion des entrées/sorties peut générer des temps morts car une tâche
peut être bloquée en attente d'accès à un élément d'entrée/sortie. La gestion des
Page 113 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
interruptions reçues par une tâche n'est pas optimisée. Le temps de latence - soit le
temps écoulé entre la réception de l'interruption et son traitement - n'est pas garanti
par le système.

Enfin, l'utilisation du mécanisme de mémoire virtuelle peut entraîner des fluctuations


importantes dans les temps d'exécution des tâches.

5.2 Temps partagé et temps réel


Le système est dit à Temps Partagé lorsqu'un quota de temps est alloué à chaque
processus par l'ordonnanceur. C'est notamment le cas des systèmes multi-utilisateurs
qui permettent à plusieurs utilisateurs d'utiliser simultanément sur une même
machine des applications différentes ou bien similaires : le système est alors dit
«système transactionnel». Pour ce faire, le système alloue à chaque utilisateur une
tranche de temps.

Dans les systèmes classiques, le temps est partagé entre les tâches de manière
équitable. Alors que dans les systèmes temps-réel, les tâches doivent être exécutées
dans les délais impartis. On entend souvent parler de Temps Réel dès que l'on parle de
système embarqué. En fait, un système embarqué doit généralement respecter des
contraintes temporelles fortes (Hard Real Time) et l'on y trouve enfoui un système
d'exploitation ou un noyau Temps Réel (Real Time Operating System, RTLinux, QNX,
VxWorks, etc).

Le Temps Réel est un concept un peu vague et chacun a sa propre idée sur la question.
On pourrait le définir comme : Un système est dit Temps Réel lorsque l'information
après acquisition et traitement reste encore pertinente.

Plus précisément, cela veut dire que dans le cas d'une information arrivant de façon
périodique (sous forme d’une interruption périodique du système), les temps
d'acquisition et de traitement doivent rester inférieurs à la période de rafraîchissement
de cette information. Un temps maximum d'exécution est garanti (pire cas) et non un
temps moyen. Pour cela, il faut que le noyau ou le système Temps Réel :

• Soit déterministe : les mêmes causes produisent les mêmes effets avec les mêmes
temps d'exécution.

• Soit préemptif : la tâche de plus forte priorité prête à être exécutée doit toujours
avoir accès au processeur.

Page 114 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Ce sont là des conditions nécessaires mais malheureusement pas suffisantes pour
affirmer qu'un système embarqué est Temps Réel par définition.

5.3 Notion de temps réel


Une idée reçue est de mélanger Temps Réel et puissance de calcul du système
embarqué. On entend souvent : Etre temps Réel, c’est avoir beaucoup de puissance :
des MIPS, des MFLOPS. Ce n’est pas toujours vrai. En fait, être Temps Réel dans
l’exemple donné précédemment, c’est être capable d’acquitter l’interruption
périodique (moyennant un temps de latence de traitement d’interruption imposé par
le matériel), traiter l’information et le signaler au niveau utilisateur (réveil d’une tâche,
libération d’un sémaphore…) dans un temps inférieur au temps entre deux
interruptions périodiques consécutives.

On est donc lié à la contrainte durée entre deux interruptions. C'est donc bien le
process extérieur à contrôler qui impose ses contraintes temporelles au système
embarqué et non le contraire. On est donc lié à la contrainte de délai entre deux
interruptions générées par le processus extérieur à contrôler.
Si cette durée est de l'ordre de la seconde (pour le contrôle d'une réaction chimique
par exemple), il ne sert à rien d’avoir un système à base de Pentium IV ! Un simple
processeur 8 bits du type microcontrôleur Motorola 68HC11, Microchip PIC, Scenix,
AVR... ou même un processeur 4 bits fera amplement l'affaire, ce qui permettra de
minimiser les coûts sur des forts volumes de production.
Si ce temps est maintenant de quelques dizaines de microsecondes (pour le traitement
des données issues de l'observation d'une réaction nucléaire par exemple), il convient
de choisir un processeur nettement plus performant comme un processeur 32 bits Intel
x86, StrongARM ou Motorola ColdFire.
L'exemple donné est malheureusement idyllique (quoique fréquent dans le domaine
des télécommunications et réseaux) puisque notre monde interagit plutôt avec un
système électronique de façon apériodique.
Si ce temps est maintenant de quelques dizaines de microsecondes (pour le traitement
des données issues de l’observation d’une réaction nucléaire par exemple), il est alors
nécessaire de choisir un processeur nettement plus performant comme un processeur
32 bits (processeurs ARM, ColdFire..). Dans le pire des cas, le traitement en Temps Réel
sera réalisé en logique câblé tout simplement.

Il convient donc avant de concevoir le système embarqué de connaître la durée


minimale entre 2 interruptions ; ce qui est assez difficile à estimer voire même
impossible. C’est pour cela que l’on a tendance à concevoir dans ce cas des systèmes
Page 115 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
performants et souvent surdimensionnés pour respecter des contraintes Temps Réel
mal cernées à priori. Ceci induit en cas de surdimensionnement un surcoût non
négligeable…

Il est évident que la structure des systèmes temps réel dépendra de ces fameuses
contraintes. On pourra diviser les systèmes en deux catégories :
 Les systèmes dits à contraintes souples ou molles (soft real time). Ces systèmes
acceptent des variations dans le traitement des données de l'ordre de la demi-
seconde (ou 500 ms) ou la seconde. On peut citer l'exemple des systèmes
multimédia : si quelques images ne sont pas affichées, cela ne met pas en péril
le fonctionnement correct de l'ensemble du système. Ces systèmes se
rapprochent fortement des systèmes d'exploitation classiques à temps partagé.
Ils garantissent un temps moyen d'exécution pour chaque tâche. On a ici une
répartition égalitaire du temps CPU entre processus.
 Les systèmes dits à contraintes dures (hard real time) pour lesquels une gestion
stricte du temps est nécessaire pour conserver l'intégrité du service rendu. On
citera comme exemples les contrôles de processus industriels sensibles comme
la régulation des centrales nucléaires ou les systèmes embarqués utilisés dans
l'aéronautique. Ces systèmes garantissent un temps maximum d'exécution pour
chaque tâche. On a ici une répartition totalitaire du temps CPU entre tâches.

Les systèmes à contraintes dures doivent répondre à trois critères fondamentaux :


 Le déterminisme logique : les mêmes entrées appliquées au système doivent
produire les mêmes effets.
 Le déterminisme temporel : une tâche donnée doit obligatoirement être
exécutée dans les délais impartis, on parle d’échéance.
 La fiabilité : le système doit être disponible. Cette contrainte est très forte dans
le cas d'un système embarqué car les interventions d'un opérateur sont très
difficiles voire même impossibles. Cette contrainte est indépendante de la
notion de temps réel mais la fiabilité du système sera d'autant plus mise à
l'épreuve dans le cas de contraintes dures.

Un système temps réel n'est pas forcément plus rapide qu'un système à temps partagé.
Il devra par contre satisfaire à des contraintes temporelles strictes, prévues à l'avance
et imposées par le processus extérieur à contrôler. Une confusion classique est de

Page 116 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
mélanger temps réel et rapidité de calcul du système donc puissance du processeur
(microprocesseur, microcontrôleur, DSP).
En résumé, on peut dire qu'un système temps réel doit être prévisible ; les contraintes
temporelles pouvant s'échelonner entre quelques micro-secondes (μs) et quelques
secondes.
La figure suivante permet d'illustrer la notion de temps réel sur le cas particulier de
l'exécution d'une tâche périodique. Idéalement, une tâche périodique doit être
exécutée toutes les m secondes (son temps d'exécution reste inférieur à m). Dans le
cas d'un système non temps réel, un temps de latence apparaît avant l'exécution
effective de la tâche périodique. Il varie fortement au cours du temps (charge du
système...). Dans le cas d'un système temps réel, ce temps de latence doit être borné
et garanti inférieur à une valeur fixe et connue à l'avance. Si ce n'est pas le cas, il y a un
défaut de fonctionnement pouvant causer le crash du système. Les éditeurs de
systèmes temps réel donnent généralement cette valeur qui est fixe (si le système est
bien conçu) quelle que soit la charge du système ou du nombre de tâches en fonction
du processeur utilisé.

5.4 Les principaux systèmes temps réels

Page 117 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le but de cette section est d’effectuer un rapide tour d’horizon des principaux
systèmes d'exploitation utilisés dans les environnements embarqués. Il convient avant
tout de préciser les différences entre noyau, exécutif et système d'exploitation temps
réel :
 Un noyau temps réel est le minimum logiciel pour pouvoir faire du temps réel :
ordonnanceur, gestion de tâches, communications inter-tâches, autant dire un
système plutôt limité mais performant.
 Un exécutif temps réel possède un noyau temps réel complété de
modules/bibliothèques pour faciliter la conception de l'application temps réel :
gestion mémoire, gestion des E/S, gestion de timers, gestion d'accès réseau,
gestion de fichiers. Lors de la génération de l'exécutif, on choisit à la carte les
bibliothèques en fonction des besoins de l'application temps réel. Pour le
développement, on a besoin d'une machine hôte (host) et de son
environnement de développement croisé (compilateur C croisé, utilitaires,
debugger) ainsi que du système cible (target) dans lequel on va télécharger (par
liaison série ou par le réseau) l'application temps réel avec l'exécutif.
 Un système d'exploitation temps réel est le cas particulier où l'on a confusion
entre le système hôte et le système cible qui ne font plus qu'un. On a donc ici
un environnement de développement natif.

5.4.1 VxWorks et pSOS


VxWorks est aujourd'hui l'exécutif temps réel le plus utilisé dans l'industrie. Il est
développé par la société Wind River (http ://www.windriver.com) qui a également
racheté récemment les droits du noyau temps réel S626, un peu ancien mais
également largement utilisé. VxWorks est fiable, à faible empreinte mémoire,
totalement configurable et porté sur un nombre important de processeurs (PowerPC,
68K, CPU32, ColdFire, MCORE, 80x86, Pentium, i960, ARM, StrongARM, MIPS, SH,
SPARC, NECV8xx, M32 R/D, RAD6000, ST 20, TriCore). Un point fort de VxWorks a été
le support réseau (sockets, commandes r..., NFS, RPC...) disponible dès 1989 au
développeur bien avant tous ses concurrents. VxWorks est également conforme à
POSIX 1003.1b.

5.4.2 QNX
Développé par la société canadienne QNX Software (http ://www.qnx.com), QNX est
un système temps réel de type UNIX. Il est conforme à POSIX, permet de développer

Page 118 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
directement sur la plateforme cible et intègre l'environnement graphique Photon,
proche de X Window System.

5.4.3 μC/OS et μC/OS II


μC/OS, développé par le Canadien Jean J. Labrosse, est un exécutif temps réel destiné
à des environnements de très petite taille construits autour de micro-contrôleurs. Il est
maintenant disponible sur un grand nombre de processeurs et peut intégrer des
protocoles standards comme TCP/IP (μC/IP) pour assurer une connectivité IP sur une
liaison série par PPP. Il est utilisable gratuitement pour l'enseignement (voir
http://www.ucos-ii.com).

5.4.4 Windows CE
Annoncé avec fracas par Microsoft comme le système d'exploitation embarqué qui tue,
Windows CE et ses cousins comme Embedded Windows NT n'ont pour l'instant pas
détrôné les systèmes embarqués traditionnels. Victime d'une réputation de fiabilité
approximative, Windows CE est pour l'instant cantonné à l'équipement de nombreux
assistants personnels ou PDA.

5.4.4 LynxOS
LynxOS est développé par la société LynuxWorks http://www.lynuxworks.com qui a
récemment modifié son nom de par son virage vers LINUX avec le développement de
Blue Cat. Ce système temps réel est conforme à la norme POSIX.

5.4.5 Nucleus
Nucleus est développé par la société Accelerated Technology Inc.
(http://www.acceleratedtechnology.com). Il est livré avec les sources et il n'y pas de
royalties à payer pour la redistribution.

5.4.6 eCOS
Acronyme pour Embeddable Configurable Operating System, eCOS fut initialement
développé par la société Cygnus, figure emblématique et précurseur de l'open source
professionnelle, aujourd'hui rattachée à la société Red Hat Software. Ce système est
adapté aux solutions à très faible empreinte mémoire et profondément enfouies. Son
environnement de développement est basé sur LINUX et la chaîne de compilation GNU
avec conformité au standard POSIX.

Page 119 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
5.4.7 RTLinux ou Real Time Linux
RTLinux est une variante du noyau Linux considérée comme un système temps réel par
sa capacité de traiter le noyau Linux comme un thread, Il peut dès lors gérer le système
GNU/Linux dans son ensemble, voire une chaîne d'acquisition ou des robots comme
de simples tâches préemptibles.
Puisque le noyau LINUX n'est définitivement pas un noyau temps réel, la meilleure
solution est de la faire cohabiter avec un noyau auxiliaire basé sur un vrai
ordonnanceur temps réel à priorités fixes. Les tâches temps réel sont gérés par ce
noyau et le traitement des autres tâche est délégué au noyau LINUX, lui-même
considéré comme une tâche de plus faible priorité (ou Idle task) par le noyau temps
réel. Le schéma ci-dessous décrit l'architecture du système à double noyau. Les
interruptions matérielles sont captées par le noyau temps réel. Si l'interruption ne
correspond pas à une tâche temps réel, elle est traitée par le noyau LINUX.

5.4.8 RTAI
RTAI (de l'anglais « Real Time Application Interface ») est une extension libre du noyau
Linux lui apportant des fonctionnalités temps réel dures. Le projet est toujours
maintenu et distribué depuis l'origine selon les termes de la licence GNU LGPL, et sous
la GPL pour la portion de code concernée par l'implémentation RTLinux. RTAI supporte
les architectures x86, PowerPC, ARM, MIPS. RTAI utilise logiciel Adeos.
Page 120 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

Du fait de l’optique de développement interne, l'architecture actuelle de la distribution


RTAI apparaît comme plus complexe tant au niveau de la définition de l'API (syntaxe et
nombre d'appels) et de la position par rapport aux licences (GPL et LGPL). Il est clair
aussi que RTAI est rapidement apparu aux yeux des responsables du projet RTLinux
(Yodaken et Barabanov) comme un redoutable concurrent, sachant que RTLinux avait
lui une vocation commerciale. Suite à la mise en place du brevet logiciel sur RTLinux, la
position de RTAI est devenue quelque peu inconfortable et jusqu’à la refonte récente
de RTAI autour du micro-noyau ADEOS (pour remplacer la couche initiale RTHAL), le
brevet logiciel FSMlabs apparaissait comme une «épée de Damocles» au-dessus de
RTAI.

La structure de RTAI est proche de celle de RTLinux. De même, les fonctionnalités du


type FIFO de communication ou mémoire partagée sont également disponibles avec
RTAI. Cependant, les développeurs de RTAI ont récemment fait un effort particulier sur
une extension appelée LXRT (/LQX; 5HDO 7LPH) permettant de développer des tâches
temps réel dans l’espace XWLOLVDWHXU et non plus dans l’espace noyau. Ce dernier
point est extrêmement intéressant tant au niveau de la licence (il n’y a plus d’embarras
avec la GPL contrairement au cas de RTLinux) que de la facilité de développement car
nous savons que développer dans l’espace noyau est relativement plus complexe.

6. Système LINUX embarqué temps réel


Forts des arguments concernant l'open source, il est normal d'être tenté par
l'utilisation de LINUX comme système temps réel. Outre les avantages inhérents à
l'open source, la fiabilité légendaire de LINUX en fait un candidat idéal.
Malheureusement, LINUX n'est pas nativement un système temps réel. Le noyau LINUX
fut en effet conçu dans le but d'en faire un système généraliste donc basé sur la notion
de temps partagé et non de temps réel.
La communauté LINUX étant très active, plusieurs solutions techniques sont cependant
disponibles dans le but d'améliorer le comportement du noyau afin qu'il soit
compatible avec les contraintes d'un système temps réel comme décrit au début de
l'article. Concrètement, les solutions techniques disponibles sont divisées en deux
familles :
 Les patchs dits « préemptifs » permettant d'améliorer le comportement du
noyau LINUX en réduisant les temps de latence de ce dernier. Ces modifications
ne transforment pas LINUX en noyau temps réel « dur » mais permettent
d'obtenir des résultats satisfaisants dans le cas de contraintes temps réel «
molles ». Cette technologie est disponible auprès de différents projets open
source et elle est également supportée commercialement par divers éditeurs
spécialisés dont le plus connu est l'américain MontaVista

Page 121 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
(http://www.mvista.com). La notion de noyau préemptif est intégrée dans le
noyau de développement 2.5.
 Le noyau temps réel auxiliaire. Les promoteurs de cette technologie considèrent
que le noyau LINUX ne sera jamais véritablement temps réel et ajoute donc à ce
noyau un véritable ordonnanceur temps réel à priorités fixes. Ce noyau
auxiliaire traite directement les tâches temps réel et délègue les autres tâches
au noyau LINUX, considéré comme la tâche de fond de plus faible priorité. Cette
technique permet de mettre en place des systèmes temps réel « durs ». Cette
technologie utilisée par RTLinux et son cousin européen RTAI. RTLinux est
supporté commercialement par FSMLabs (http://www.fsmlabs.com) qui a des
relations chaotiques avec la communauté open source à cause du brevet logiciel
qui couvre l'utilisation de ce noyau auxiliaire. Pour cette raison, le projet RTAI
qui n'est pas associé à une entité commerciale tend à utiliser une technique
similaire mais ne tombant pas sous le coup du brevet

6.1. Les patchs préemptifs


Cette section présente les deux principaux patchs permettant d'améliorer les
performances du noyau LINUX 2.4 au niveau du temps de latence pour la prise en
compte d'une interruption. Le document décrit la méthode d'application des patchs
puis commente les résultats obtenus avec des outils de mesures spécialisés.

6.1.1 Différente méthodes


Cette étude se limitera aux patchs les plus utilisés dans l'environnement LINUX :
 Le patch Prempt Kernel maintenu par Robert M. Love et disponible sur
http://www.tech9.net/rml/linux. Le principe du patch est d'ajouter
systématiquement des occasions d'appel à l'ordonnanceur et donc de minimiser
le temps entre la réception d'un évènement et l'appel à la fonction schedule()
(ordonnanceur LINUX).
 Le patch Low latency maintenu par Andrew Morton et disponible sur
http://www.zip.com.au/~akpm/linux/schedlat.html. Le principe est un peu
différent car au lieu d'opter pour une stratégie "systématique", les
développeurs du patch ont préféré effectuer une analyse du noyau afin
d'ajouter des "points de préemption" subtilement placés dans les sources du
noyau afin de "casser" des boucles d'attente trop longues.

Il faut noter que l'étude s'applique uniquement au noyau 2.x (dernière version stable
disponible à ce jour). Des versions similaires du patch Prempt Kernel sont intégrées au
noyau de développement 2.x. Une fusion des deux patchs est peut être envisageable
dans le futur noyau 2.x (information sans garantie mais évoquée dans certains
interviews de Robert M. Love). De même, l'éditeur MontaVista Software diffuse une

Page 122 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
version de noyau 2.4 incluant un patch préemptif très similaire à celui de Robert M.
Love (qui travaille d'ailleurs chez MontaVista !).

6.1.2 Procédure du patch d’un système LINUX


La procédure est similaire pour les deux patchs :
 Extraire les sources du noyau LINUX dans le répertoire /usr/src. Dans notre cas
cela donne un répertoire /usr/src/linux-2.4.20 que l'on peut suffixer par le type
de patch. On peut ensuite positionner le lien linux-2.4 sur cette arborescence.
# cd /usr/src
# mv linux-2.4.20 linux-2.4.20_kpreempt
# rm -f linux-2.4; ln -s linux-2.4.20_kpreempt linux-2.4
 Récupérer le patch correspondant à la version du noyau, puis appliquer le patch:
# cd /usr/src/linux-2.4
# patch -p1 < un_repertoire_de_stockage/patchfile
 Configurer le noyau LINUX en activant les options habituelles du noyau non
patché ainsi que les options spécifiques du patch. Avant d'appliquer le patch il
est important de vérifier le bon fonctionnement du noyau non patché sur votre
matériel.

Il faut ensuite configurer puis compiler le noyau avec la procédure habituelle :


# make xconfig
# make dep; make clean; make bzImage; make modules

6.1.2 Configuration du noyau patché preempt kernel


Il est conseillé d'utiliser le paramètre EXTRAVERSION défini au début du Makefile du
noyau, soit dans ce cas :
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 20
EXTRAVERSION = -kpreempt
Ce qui permet de suffixer l’arborescence des modules suivant le type de noyau (ici
kpreempt) et donc de faire cohabiter plusieurs versions du noyau 2.4.20 patché sur le
même système.
Ensuite il convient de vérifier l'option de noyau préemptif (CONFIG_PREEMPT) en
utilisant make xconfig et en validant l'option dans la rubrique « processor type and
features » comme indiqué sur la figure ci-dessous.

Il est également nécessaire de valider le support RTC (Real Time Clock) car certains
outils de mesure de latence utilisent le device /dev/rtc.

Page 123 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Enfin il est nécessaire de valider l'utilisation du DMA (Direct Memory Access) sur le bus
PCI coté noyau ce qui normalement fait par défaut. L'utilisation du DMA permet
d'améliorer fortement les performances puisque le processeur n'est plus sollicité.

Une fois le noyau compilé, on peut l'installer par :


# cp arch/i386/boot/bzImage /boot/bzImage-2.4.20_kpreempt
# make modules_install
puis ajouter une entrée supplémentaire dans le fichier /etc/lilo.conf (ou /etc/grub.conf
suivant le chargeur utilisé). Dans le cas de LILO cela donne :
image=/boot/bzImage-2.4.20_kpreempt
label=linux20_kp
read-only
root=/dev/hda1
Il faut ensuite valider cette nouvelle entrée en tapant :
# lilo

6.1.2 Configuration du noyau patché Low latency


La configuration est très similaire sauf que l'on utilisera le suffixe lowlat. La validation
de l'option CONFIG_LOLAT est également dans la rubrique processor type and features

La deuxième option permet de débrayer dynamiquement l'option en manipulant le


système de fichier virtuel/proc, nous ne l'utiliserons pas pour l'instant.

6.1.3 Outils de mesure utilisés


Pour effectuer les mesures, nous utilisons principalement l'outil Latency_graph-0.2
disponible sur http://www.linuxdj.com/latency-graph. Nous avons légèrement modifié
le programme de test testlatency.c afin d'utiliser des sorties graphiques PNG (la libgd
ne supporte plus le GIF pour des questions de licence) et de pouvoir spécifier le nom
du fichier de sortie. Le principe de l'outil de mesure est de démarrer deux timers (30ms
et 60 ms) et de mesurer la dérive de ceux-ci par rapport à la période attendue. Les
mesures intéressantes sont obtenues en stressant le système, le plus souvent par des

Page 124 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
accès disque répétitifs. Dans notre cas, nous avons utilisé un petit script nommé
stress.sh basé sur la commande dd.
#!/bin/sh
while [ 1 ]
do
echo "Creating file..."
dd if=/dev/zero of=foo bs=1M count=50
sync
echo "Removing file..."
rm -f foo
sync
done

Ce script crée puis efface de manière répétitive des fichiers de 50 Mo. Une fois le
script lancé depuis une console, on pourra exécuter le test en tapant dans une autre
console :

testlatency -f 2.4.20_stock_stress.png qui produit une courbe de résultats au format


PNG.

Nous utiliserons également ponctuellement le programme realfeel2 inclus dans le


package realfee12 disponible sur le site du patch Low latency. Ce programme produit
un historique des temps de latence sur un nombre de points donné. On l'utilisera
comme suit :

realfeel2 --samples 100000 2.4.20_stock_stress.hist

6.1.4 Mesures effectuées

Le système utilisé est basé sur un AMD Duron 900 MHz, équipé de 128 Mo de RAM,
d'un disque IDE récent (mais bas de gamme !) et de la distribution Red Hat 7.3. Bien
entendu, le résultat absolu de la mesure est très dépendant de l'architecture matérielle
du système. Le but est ici d'observer une tendance dans les résultats.

Avant d'effectuer les tests, il convient de vérifier grâce à la commande hdparm si les
accès disque utilisent le DMA que nous avons validé coté noyau.

# hdparm /dev/had
/dev/hda:
multcount = 16 (on)
I/O support = 0 (default 16-bit)
Page 125 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
unmaskirq = 0 (off)
using_dma = 0 (off)
keepsettings = 0 (off)
nowerr = 0 (off)
readonly = 0 (off)
readahead = 8 (on)
geometry = 3648/255/63, sectors = 58615258, start = 0
busstate = 1 (on)

Nous pouvons positionner le DMA ainsi que deux autres paramètres d'optimisation
(cependant moins importants) avec la ligne de commande suivante:

# hdparm -d 1 -c 1 -u 1 /dev/hda
/dev/hda:
setting 32-bit I/O support flag to 1
setting unmaskirq to 1 (on)
setting using_dma to 1 (on)
I/O support = 1 (32-bit)
unmaskirq = 1 (on)
using_dma = 1 (on)

Les options utilisées sont décrites ci-dessous dans un extrait du man hdparm:

 “-d “ Disable/enable the "using_dma" flag for this drive.

 “-u “ Get/set interrupt-unmask flag for the drive. A setting of 1 permits the
driver to unmask other interrupts during processing of a disk interrupt, which
greatly improves Linux' s responsiveness and eliminates "serial port overrun"
errors.

 “ -c “ Query/enable (E) IDE 32-bit I/O support. A numeric parameter can be used
to enable/disable 32-bit I/O support.

6.1.5 Noyau 2.4.20 standard

Page 126 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Nous effectuons tout d' abord une mesure sur un noyau 2.4.20 standard. Si le système
n'est pas stressé, nous obtenons logiquement le résultat suivant

Par contre lorsque le système est stressé par le script stress.sh on observe des
irrégularités sur les courbes (36 et 66 ms).

Page 127 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Pour se convaincre de l'utilité du DMA, la courbe ci-dessous présente le résultat de la
mesure lorsque le DMA n'est pas validé par hdparm. Le résultat se passe de
commentaires !

6.1.5 Noyau 2.4.20 avec patch preempt kernel

Avec le patch preempt-kernel, nous obtenons la courbe suivante :

Page 128 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Le résultat est très bon malgré un petit "glitch" au milieu de la courbe. Si nous utilisons
le programme realfeel2 sur le même système, nous obtenons le fichier d'historique
suivant sur 100000 itérations :

0.0 99828
0.1 118
0.2 5
0.3 2
0.5 3
0.6 2
0.7 1
1.1 1
2.4 1
2.5 5
2.6 5
2.7 2
2.8 4
2.9 2
3.4 1
4.0 1
6.3 1
9.5 1
11.4 1
11.9 1
12.0 1
12.1 1
12.2 1
12.3 1
12.5 1
12.7 1
12.9 1
13.3 1
13.4 2
13.6 1
13.7 1
14.3 1
15.1 1
Page 129 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
15.2 1

Soit une latence maximale de 15 ms mais avec très peu de points supérieurs à 1 ms.

6.1.6 Noyau 2.4.20 avec patch Low latency

Avec ce patch appliqué, nous obtenons la courbe suivante :

Le résultat est parfait. Si nous utilisons le programme realfeel2 sur le même système,
nous obtenons le fichier d'historique suivant sur 100000 itérations :

0.0 99858
0.1 134
0.2 5
0.3 3

Le patch Low latency semble être plus efficace que Preempt kernel. Ceci étant dit, des
études plus approfondies sur des cas réels permettront également de valider la
stabilité des noyaux modifiés s’ils sont soumis à de fortes sollicitations pendant un
grand intervalle de temps.

Page 130 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
7. Programmation des systèmes multitâches

Un système d’exploitation est multitâche (multitasking) s’il permet d’exécuter, de


façon apparemment simultanée, plusieurs programmes informatiques (processus).
La simultanéité apparente est le résultat de l’alternance rapide d’exécution des
processus présents en mémoire (notion de temps partagé et de multiplexage).
Le passage de l’exécution d’un processus à un autre est appelé commutation de
contexte.
Ces commutations peuvent être initiées par les programmes eux-mêmes (multitâche
coopératif) ou par le système d’exploitation (multitâche préemptif). Tous les systèmes
utilisent maintenant le multitâche préemptif.
Le multitâche n’est pas dépendant du nombre de processeurs présents physiquement
dans l’ordinateur : un système multiprocesseur (ou multi-cœur) n’est pas nécessaire
pour exécuter un système d’exploitation multitâche.
Le multitâche coopératif n’est plus utilisé (cf. Windows 3.1 ou MAC OS 9). Unix et ses
dérivés, Windows et MAC OS X sont des systèmes basés sur le multitâche préemptif.
Le multitâche permet de paralléliser les traitements par l’exécution simultanée de
programmes informatiques. Exemples de besoins :
 permettre à plusieurs utilisateurs de travailler sur la même machine.
 utiliser un traitement de texte tout en naviguant sur le Web.
 transférer plusieurs fichiers en même temps.
 améliorer la conception : écrire plusieurs programmes simples, plutôt qu’un
seul programme capable de tout faire, puis de les faire coopérer pour effectuer
les tâches nécessaires.
La préemption est la capacité d’un système d’exploitation multitâche à suspendre un
processus au profit d’un autre.
Le multitâche préemptif est assuré par l’ordonnanceur (scheduler ), un service de l’OS.
L’ordonnanceur distribue le temps du processeur entre les différents processus. Il peut
aussi interrompre à tout moment un processus en cours d’exécution pour permettre à
un autre de s’exécuter.
Une quantité de temps définie (quantum) est attribuée par l’ordonnanceur à chaque
processus : les processus ne sont donc pas autorisés à prendre un temps non-défini
pour s’exécuter dans le processeur.

Dans un ordonnancement (statique à base de priorités) avec préemption, un processus


peut être préempté (remplacé) par n’importe quel processus plus prioritaire qui serait
devenu prêt.
Page 131 sur 144
Université de Dschang
Faculté des Sciences
Master Pro

Multitâche : exécution en parallèle de plusieurs tâches (processus ou threads).


Commutation de contexte : passage de l’exécution d’un processus à un autre.
Multitâche préemptif : mode de fonctionnement d’un système d’exploitation
multitâche permettant de partager de façon équilibrée le temps processeur entre
différents processus.
Ordonnancement : mécanisme d’attribution du processeur aux processus (blocage,
déblocage, élection, préemption).

Un processus (process) est un programme en cours d’exécution par un système


d’exploitation.
Un programme est une suite d’instructions permettant de réaliser un traitement. Il
revêt un caractère statique.
Une image représente l’ensemble des objets (code, données, …) et des informations
(états, propriétaire, ...) qui peuvent donner lieu à une exécution dans l’ordinateur.
Un processus est donc l’exécution d’une image. Le processus est l’aspect dynamique
d’une image.
Un fil d’exécution (thread) est l’exécution séquentielle d’une suite d’instructions.

7.1 Rôle du système d’exploitation


Page 132 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
Un système d’exploitation multitâche est capable d’exécuter plusieurs processus de
façon quasi-simultanée.
Le système d’exploitation est chargé d’allouer les ressources (mémoires, temps
processeur, entrées/sorties) nécessaires aux processus et d’assurer son
fonctionnement isolé au sein du système.
Un des rôles du système d’exploitation est d’amener en mémoire centrale l’image
mémoire d’un processus avant de l’élire et de lui allouer le processeur. Le système
d’exploitation peut être amené à sortir de la mémoire les images d’autres processus et
à les copier sur disque. Une telle gestion mémoire est mise en oeuvre par un algorithme
de va et vient appelée aussi swapping.
Il peut aussi fournir une API pour permettre leur gestion et la communication inter-
processus (IPC).

7.2 États d’un processus


L’un des rôles primordiaux des systèmes d’exploitation multitâches (c’est le cas
aujourd’hui de la quasi-totalité des systèmes d’exploitation) est d’assurer l’exécution
de plusieurs programmes en parallèle.
Un programme en cours d’exécution s’appelle un processus. Un processus est une
instance de programme (il peut y avoir plusieurs processus d’un même programme,
par exemple, plusieurs processus du même traitement de texte). À chaque fois qu’un
programme est exécuté, un processus est créé. Il se voit attribuer de la mémoire, tout
ou partie de son code et de ses données est chargé en mémoire centrale, et il est
caractérisé par le système d’exploitation grâce à un Bloc de Contrôle de Processus
(BCP) contenant diverses informations (numéro d’identification, mémoire allouée,
fichiers ouverts, temps d’exécution, état...). Les états d’exécution d’un processus sont
représentés sur la figure ci-dessous.

Un processus en exécution s’exécute séquentiellement sur le processeur. Lorsqu’il fait


une instruction bloquante (une entrée/sortie par exemple), il se retrouve bloqué et ne
peut plus utiliser le processeur jusqu’à ce que l’événement attendu ait lieu. Dans ce
cas, il se retrouve dans l’état prêt (cela signifie qu’il attend de pouvoir s’exécuter sur le
processeur). Lorsque le système d’exploitation le décide, un processus en exécution
peut être préempté, c’est-à-dire passer de l’état exécuté à l’état prêt. Remarquons
qu’il existe d’autres états possibles, comme l’état suspendu, dans lequel on peut
plonger un processus, jusqu’à sa reprise qui le remet dans l’état prêt, ainsi que l’état
endormi, dans lequel un processus peut se trouver lorsqu’il décide d’attendre pendant
un certain temps.

Page 133 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Techniquement, la préemption se déroule de la façon suivante (figure ci-dessous) : une


interruption particulière, l’horloge temps réel (HTR), est utilisée par le système
d’exploitation. Périodiquement (la durée d’une période s’appelle un quantum),
l’interruption horloge a lieu. L’ISR qui a lieu fait partie du système d’exploitation : elle
sauvegarde alors dans le bloc de contrôle de processus l’état d’exécution du processus
(l’état des registres), puis restaure dans le processeur l’état des registres de l’un des
processus prêt que le système d’exploitation choisit. Ce qui caractérise un processus
en exécution s’appelle un contexte. La préemption consiste donc en un changement
de contexte. La commutation de contexte est réalisée par une routine spécifique du
système d’exploitation appelée dispatcher. Souvent, dans les micro- processeurs, le
dispatcher est implémenté de façon matérielle.
À chaque quantum de temps, le système d’exploitation prend donc la main grâce à une
ISR, interrompant ainsi le processus exécuté, et peut décider de le préempter, c’est-à-
dire d’élire un autre processus. Dans les systèmes d’exploitation, l’ordre de grandeurs
du quantum de temps est de l’ordre de 10 à 100 ms, alors que dans les systèmes temps
réel, on peut arriver à 1 ms, voire même en dessous.
Il faut remarquer que le temps d’exécution du système d’exploitation et du dispatcher
peut ne pas être négligeable au regard du quantum de temps choisi. Le pourcentage
du temps processeur utilisé par le système d’exploitation pour gérer les processus
Page 134 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
s’appelle le surcoût processeur ou overhead. Sur la figure ci-dessous, cet overhead est
visible sur la ligne SE du diagramme de Gantt. Typiquement, sur un système
d’exploitation classique, il y a plusieurs centaines d’interruptions par seconde (gestion
de l’horloge, du réseau, des périphériques et bus d’entrées/sorties...) pour un
overhead inférieur à 1 % du temps processeur.

L’image d’un processus comporte du code machine exécutable, une zone mémoire
pour les données allouées par le processus, une pile ou stack (pour les variables locales
des fonctions et la gestion des appels et retour des fonctions) et un tas ou heap pour
les allocations dynamiques (new, malloc).

Page 135 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

Ce processus est une entité qui, de sa création à sa mort, est identifié par une valeur
numérique : le PID (Process IDentifier).
Chaque processus a un utilisateur propriétaire, qui est utilisé par le système pour
déterminer ses permissions d’accès aux ressources (fichiers, ports réseaux, ...).

7.3 Processus lourds vs processus légers


Multitâche moins coûteux pour les threads (processus léger) : puisqu’il n’y a pas de
changement de mémoire virtuelle, la commutation de contexte (context switch) entre
deux threads est moins coûteuse que la commutation de contexte obligatoire pour des
processus lourds.
Communication entre threads plus rapide et plus efficace : grâce au partage de
certaines ressources entre threads, les IPC (Inter Processus Communication) sont
inutiles pour les threads.
Programmation utilisant des threads est toutefois plus difficile : obligation de mettre
en place des mécanismes de synchronisation, risques élevés d’interblocage, de famine,
d’endormissement.
Processus : programme en cours d’exécution. C’est l’exécution d’une image composée
de code machine et de données mémoire.
Contexte : image d’un processus en mémoire auquel s’ajoute son état (registres, ...).
Processus lourd : c’est un processus « normal ». La création ou la commutation de
contexte d’un processus a un coût pour l’OS. L’exécution d’un processus est réalisée
de manière isolée par rapport autres processus.
Processus léger : c’est un thread. Un processus lourd peut englober un ou plusieurs
threads qui partagent alors le même contexte. C’est l’exécution d’une fonction (ou
d’une méthode) au sein d’un processus et en parallèle avec les autres threads de ce
processus. La commutation de thread est très rapide car elle ne nécessite pas de
commutation de contexte.

Le noyau d’un système d’exploitation est vu comme un ensemble de fonctions qui


forme l’API.

Page 136 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chaque fonction ouvre l’accès à un service offert par le noyau. Ces fonctions sont
regroupées au sein de la bibliothèque des appels systèmes (system calls) pour
UNIX/Linux ou WIN32 pour Windows.
POSIX (Portable Operating System Interface) est une norme relative à l’interface de
programmation du système d’exploitation. De nombreux systèmes d’exploitation sont
conformes à cette norme, notamment les membres de la famille Unix.

7.4 L’API Win32


L’API Windows est orientée « handle » et non fichier. Un handle est un identifiant
d’objet système.

7.5 L’API System Calls


L’API System Calls d’UNIX est orientée « fichier » car dans ce système : TOUT est
FICHIER !

Page 137 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Un descripteur de fichier est une clé abstraite (c’est un entier) pour accéder à un
fichier, c’est-à-dire le plus souvent une ressource du système.

7.6 API WIN32 vs System Calls

7.7 Création dynamique de processus


Lors d’une opération fork, le noyau Unix crée un nouveau processus qui est une copie
conforme du processus père. Le code, les données et la pile sont copiés et tous les
fichiers ouverts par le père sont ainsi hérités par le processus fils.

Page 138 sur 144


Université de Dschang
Faculté des Sciences
Master Pro

7.8 Exécution d’un nouveau processus


Rappel : après une opération fork, le noyau Unix a créé un nouveau processus qui est
une copie conforme du processus qui a réalisé l’appel.
Si l’on désire exécuter du code à l’intérieur de ce nouveau processus, on utilisera un
appel de type exec : execl, execlp, execle, execv ou execvp.
La famille de fonctions exec remplace l’image mémoire du processus en cours par un
nouveau processus.

7.9 Généalogie des processus

Page 139 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Chaque processus est identifié par un numéro unique, le PID (Processus IDentification).
Un processus est créé par un autre processus (notion père-fils). Le PPID (Parent PID)
d’un processus correspond au PID du processus qui l’a créé (son père).
7.10 Synchronisation des processus

On ne peut présumer l’ordre d’exécution de ces processus (cf. politique de


l’ordonnanceur).
Il sera donc impossible de déterminer quels processus se termineront avant tels autres
(y compris leur père). D’où l’existence, dans certains cas, d’un problème de
synchronisation.
La primitive wait permet l’élimination de ce problème en provoquant la suspension du
processus appelant jusqu’à ce que l’un de ses processus fils se termine.

7.11 Opérations réalisables sur un processus


Création : fork
Exécution : exec
Destruction : terminaison normale, auto-destruction avec exit, meurtre avec kill ou
Ctrl-C
Mise en attente/réveil : sleep, wait, kill
Suspension et reprise : Ctrl-Z ou fg, bg
Changement de priorité : nice

7.12 Les threads


Les systèmes d’exploitation mettent en oeuvre généralement les threads :
 Le standard des processus légers POSIX est connu sous le nom de pthread. Le
standard POSIX est largement mis en oeuvre sur les systèmes UNIX/Linux.
Page 140 sur 144
Université de Dschang
Faculté des Sciences
Master Pro
 Microsoft fournit aussi une API pour les processus légers : WIN32 threads
(Microsoft Win32 API threads).
En C++, il sera conseillé d’utiliser un framework (Qt, Builder, commoncpp, boost, ...)
qui fournira le support des threads sous forme de classes prêtes à l’emploi. La version
C++11 intégrera le support de threads en standard.
Java propose l’interface Runnable et une classe abstraite Thread de base.

7.13 Modèle de programmation


Un constat : Chaque programme est différent. Cependant, certains modèles communs
sont apparus.
On distingue généralement 3 modèles :
 Modèle répartiteur/travailleurs ou maître/esclaves : Un processus, appelé le
répartiteur (ou le maître), reçoit des requêtes pour tout le programme. En
fonction de la requête reçue, le répartiteur attribue l’activité à un ou plusieurs
processus travailleurs (ou esclaves).
 Modèle en groupe : Chaque processus réalise les traitements concurremment
sans être piloté par un répartiteur (les traitements à effectuer sont déjà connus).
Chaque processus traite ses propres requêtes (mais il peut être spécialisé pour
un certain type de travail).
 Modèle en pipeline : L’exécution d’une requête est réalisée par plusieurs
processus exécutant une partie de la requête en série. Les traitements sont
effectués par étape du premier processus au dernier. Le premier processus
engendre des données qu’il passe au suivant.

7.15. Programmation C, Ada et LabVIEW


Nous avons de présenter l’implémentation de systèmes de contrôle-commande à
travers trois langages de programmation :

Page 141 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
 le langage C, car parmi les représentants des langages impératifs, c’est le
langage le plus répandu pour l’implémentation de systèmes de contrôle-
commande. De plus, il est le langage de référence pour les systèmes
d’exploitation, et est à la base de différentes normes comme POSIX et
OSEK/VDX ;
 le langage Ada, recommandé dans les systèmes à haut niveau de sûreté ;
 le langage LabVIEW, langage graphique flots de données, est quant à lui très
utilisé dans le contrôle de procédés industriels.
Cette section n’a pas pour objectif de présenter exhaustivement les normes et
langages sus-cités, mais de les présenter dans le but d’implémenter une spécification
fonctionnelle.

7.15.1. Le langage C
Le langage C a vu le jour à la fin des années 60. Son rôle initial était de permettre la
portabilité de la majeure partie du code d’un système d’exploitation d’une architecture
matérielle à une autre. En 1973, il est utilisé avec succès pour écrire un système
d’exploitation. Depuis, son utilisation n’a cessé de croître et il est le langage utilisé dans
l’implémentation de la majeure partie des systèmes d’exploitation. C’est aujourd’hui
encore l’un des langages de programmation les plus utilisés.
Le langage C est un langage de type impératif (en opposition aux langages déclaratifs,
fonctionnels, flots de données ou orientés objets) compilé. Il est faiblement typé, à
compilation séparée. Le langage C est sensible à la casse (majuscules/minuscules).
Le langage C dispose d’une bibliothèque exceptionnelle de composants logiciels, et la
quasi-totalité des langages de programmation peuvent s’interfacer avec le langage C.
Le langage C est fait pour le multiprocessus, mais pas pour le multitâche, ce qui
explique l’émergence de différentes normes temps réel dont POSIX est le représentant
le plus répandu.
Le langage C est assez proche de la machine, comparé aux langages modernes. Cet
inconvénient est cependant un atout indéniable lorsque l’on doit faire de la
programmation bas niveau, comme dans la programmation des entrées/sorties
spécifiques aux applications de contrôle-commande.
Le langage C est un langage de programmation normalisé. Aujourd’hui, des centaines
de compilateurs C et environnements de développement associés existent, aussi bien
en logiciel libre (le plus connu étant GNU C Compiler, GCC) qu’en logiciel commercial.

7.15.2. Le langage Ada

Page 142 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
L’idée du langage Ada naît au milieu des années 70 sous l’impulsion du département
de la défense américain du constat suivant : il n’y avait pas de langage « universel »
pour la programmation des systèmes embarqués. La diversité des langages utilisés sur
les différents projets coûtait cher en validation, formation, maintenance, etc.
Un concours a alors été lancé et parmi les quatre propositions de langages finalistes
(représentés anonymement par 4 couleurs), le langage green a été choisi. Il porte le
nom d’Ada en mémoire du premier programmeur au monde : Augusta Ada Byron. Ada
est un langage impératif à typage fort, compilé, modulaire, à compilation séparée.
Il permet le traitement des exceptions, et la généricité. Tout a été mis en œuvre pour
qu’il soit le plus sûr possible. De plus, il est nativement multitâche : en langage Ada,
une tâche est un type que l’on peut instancier. Ada est insensible à la casse
(majuscules/minuscules). Sa première version a été normalisée en 1983: elle
présentait des lacunes notamment au niveau des facilités de communication entre les
tâches (seul le rendez-vous avec données existait). La seconde version, Ada 95, permet
la programmation objet et surtout toute forme de communication asynchrone et
synchronisation grâce à l’introduction de moniteurs (objets protégés).
Ada est un langage normalisé. Plusieurs compilateurs Ada existent sur la plupart des
plateformes. Le plus connu des compilateurs libres est GNAT.

7.15.3. Le langage LabVIEW


Le langage LabVIEW est un des rares représentants des langages flots de données. C’est
un langage graphique, typé, modulaire, et en tant que langage flots de données, il est
naturellement parallèle.
Contrairement à C et Ada, LabVIEW est un environnement de développement
propriétaire, développé par la société National Instruments. LabVIEW se base sur le
langage G (il semble que cela soit la seule implémentation de ce langage).
LabVIEW est un langage relativement récent, puisqu’il a fait son apparition sur
Macintosh au milieu des années 80. Initialement, il était dédié à la programmation
d’instruments virtuels utilisant des cartes d’acquisition de la société National
Instruments. L’exemple typique d’un instrument virtuel, souvent repris pour présenter
l’intérêt initial de LabVIEW, est un oscilloscope logiciel se basant sur une carte
d’acquisition multifonctions : l’oscilloscope est composé d’un certain nombre de
fonctionnalités internes, et d’une interface utilisateur. De même, tout programme ou
sous-programme LabVIEW est représenté par une interface graphique, nommée face
avant et une description du fonctionnement interne sous forme de flots de données,
nommée diagramme.

Page 143 sur 144


Université de Dschang
Faculté des Sciences
Master Pro
Depuis, le langage LabVIEW a évolué et s’est élargi au fil des versions successives,
jusqu’à devenir un langage complet de programmation, plaçant LabVIEW parmi les
langages les plus agréables à utiliser pour les applications de contrôle-commande.

Références bibliographiques
6. Pierre Ficheux, Linux embarqué, Ed. Eyrolles, 2005.

7. Ch. Bonnet, I. Demeure. Introduction aux systèmes temps réel. Edition HERMES

8. J. Ganssle. The Art of Designing embedded Systems. Editions Butterworth-


Heinemann.

9. Addison-Wesley. Introduction to the SAE Architecture Analysis & Design


Language. 2012.

10. Cottet Francis, Grolleau Emmanuel, Gérard Sébastien, Hugues Jérôme,


Ouhamou Yassine and Tucci Sarah. Systèmes temps réel embarqués:
spécification, conception, implémentation et validation temporelle. 2014.

Page 144 sur 144

Vous aimerez peut-être aussi