Télécharger le fichier original (Mémoire de fin d’études)
Évolutions des Systèmes embarqués
Nouveaux systèmes intelligents et connectés
Si l’on prend le cas du domaine automobile, depuis près de trente ans l’industrie n’a cessé de faire évoluer la façon de concevoir les véhicules et notamment leurs systèmes sous-jacents. Comme illustré avec le diagramme 1.1, la transition s’est faite de modifications purement mécaniques vers des évolutions électriques, puis électroniques et de plus en plus intelligentes. Les systèmes de divertissement du consommateur ont été les premiers, dans le milieu des années 1920, à introduire des composants électroniques au sein des véhicules sous la forme de récepteurs radio à lampes ! Si l’apparition de transistors, dans les années 1950, a contribué à l’amélioration des capacités techniques des appareils et à la diffusion massive des autoradios au sein des automobiles, le concept de base a peu évolué jusqu’à la fin des années 1970. L’introduction des premiers systèmes de navigation dans les années 1980, puis des systèmes multimédia dans les années 2000 a changé la donne. Désormais, l’ancienne façade de l’autoradio devient un écran de commande nommée head unit et concentre 70% du code du véhicule. Les voitures se sont modernisées avec l’ajout de calculateurs dédiés à des fonctions internes ou des services. Le développement des technologies de l’industrie 4.0 mène à une augmentation exponentielle du logiciel embarqué dans l’automobile au cours des 15 dernières années [Blanchet 2016], avec la présence de plus de 50 calculateurs embarqués dans certains modèles [Juliussen 2022]. Les contrôles mécaniques et autres systèmes électriques « simples » cèdent la place au monde du numérique. Les équipements électroniques et logiciels se multiplient au sein du véhicule pour l’aide à la conduite (Advanced Driver-Assistance System – ADAS) et l’ajout de services [Schmidt 2010]. De fait, le système multimédia moderne a un rôle qui va bien au-delà de celui du simple autoradio : il devient l’interaction principale entre le consommateur et le véhicule et devient un critère de choix prépondérant à l’achat.
Ainsi, du simple Système Anti-blocage des roues (ABS), on a introduit des Assistants à la Conduite tels que le Freinage d’Urgence (Emergency Braking System) ou encore le Système de Gestion de Ligne (Lane Support System) qui permet à la fois l’Avertissement de Dépassement de Ligne (Lane Departure Warning), l’Assistant de Maintien de Ligne (Lane Keeping Assist) et le Maintien de Ligne d’Urgence (Emergency Lane Keeping)… et il ne s’agit là que de 2 fonctionnalités supplémentaires ! En parallèle, la voiture devient de plus en plus automatisée, voire autonome. Elle gagne en connectivité avec la prise en compte de données extérieures possiblement avec un lien direct au cloud pour proposer une diversité de services : météo, divertissement, trafic routier, pour n’en citer que quelques exemples. Les systèmes embarqués deviennent par conséquent aussi connectés. On parle de communications car-to-car entre véhicules ou car-to-infrastructure entre véhicule et infrastructures routières par exemple.
Cette ouverture du système à son environnement est à double tranchant. D’une part cela offre de nouveaux horizons de fonctionnalités et optimisations de conduite, avec des possibilités d’évolutivité simplifiée. Mais d’autre part la complexité va grandissante avec les enjeux d’ingénierie que cela implique.
De façon plus générale, le contexte industriel actuel fait émerger de nouvelles techno-logies basées sur des logiciels de plus en plus complexes et performants. Cela est rendu possible via l’émergence d’architectures matérielles toujours plus puissantes et performantes. Ces améliorations permettent le développement et la mise en application de nouvelles tech-nologies comme les réseaux de communication sans fil haute performance ou encore l’usage d’intelligences artificielles. On retrouve ainsi un nombre grandissant de fonctionnalités di-rectement embarquées dans l’automobile, l’avion, le train pour répondre à la fois à de nouveaux besoins fonctionnels : assistance à la conduite/pilotage, tableaux de bord, etc. et à des besoins de confort d’usage : info-divertissement, connectivité, automatisations…
D’un point de vue logiciel, les mises à jour de systèmes embarqués incluent à la fois de nouvelles fonctionnalités critiques pour le bon fonctionnement du système, mais aussi l’ajout de fonctions moins critiques. Ces mises à jour de services non essentiels amplifient la multiplicité des niveaux de criticités du logiciel embarqué et donc la cohabitation entre sous-systèmes critiques et sous-systèmes non-critiques que l’on pourrait qualifier de « confort ».
Nouvelles architectures Matérielles
D’un point de vue matériel, il y a de fortes convergences sur les architectures employées dans les différents domaines. Historiquement, on retrouvait en premier lieu des calculateurs monocœurs. Cependant, les diverses évolutions d’exigences ont fait apparaître des limites en capacité de calcul. La montée en fréquence de fonctionnement atteint un seuil maximum à cause de l’augmentation de température et la consommation que cela implique. De fait les processeurs ne peuvent dépasser un certain seuil de température de fonctionnement (typiquement au-delà de 90°C) sans risque de dégradations irréversibles. Par ailleurs, l’aug-mentation du nombre de transistors qui composent les processeurs arrive aux abords des limites physiques : la taille de gravure du silicium arrive au même ordre de grandeur que la taille des atomes de silicium dont elle est composé. De fait, jusqu’à récemment encore, la Loi de Moore [Thompson 2006] sur la puissance des processeurs s’est vérifiée. Des pre-miers microprocesseurs Intel en 1971, avec quelques milliers de transistors de 10 µm, l’on est aujourd’hui à plus de 1 milliards de transistors de près de 10 nm. Mais à l’aune d’une gravure proche des 2 nm, on environne les dimensions de 10 à 15 atomes et les effets de la physique quantique entrent en jeu. Par conséquent, l’on se dirige vers les limites des technologies actuelles pour poursuivre ces améliorations de puissance. Pour ces raisons, le plus grand levier de progression disponible aujourd’hui repose sur la parallélisation des unités de calcul, et donc la notion de calculateur multicœur, qui est apparue dès les an-nées 1950 [Smotherman 2005]. Les fondeurs s’orientent vers des processeurs où la montée en puissance est assurée par la multiplication des unités de calcul (dit « cœurs ») parallèles dans le processeur. On passe ainsi de monocœurs toujours plus petits et compacts à des duals/quadri cœurs… et l’on va aujourd’hui jusqu’à des supercalculateurs à plus de 128 cœurs.
Tous ces changements se visualisent parfaitement avec l’évolution des caractéristiques des processeurs au fil des années en Figure 1.2, tel qu’agrégé par K. Rupp [Rupp 2020]. Ces évolutions sont les bienvenues dans tous les secteurs concernés, allant du grand public dans les ordinateurs, téléphones et autres multimédias jusqu’aux applications industrielles en passant par les usages de serveurs réseaux et centres de calculs.
Il existe divers types d’architectures matérielles parmi les évolutions multicœurs que l’on retrouve aujourd’hui. On pourrait de façon simple différencier entre les multicœurs classiques, les manycœurs et à l’extrême ce que l’on connaît sous le nom de GPU, les processeurs graphiques. Multicœurs « classiques » Les calculateurs multicœurs « classiques » disposent d’un cer-tain nombre d’unités de calculs (« cœurs »), auxquelles sont adjointes diverses zones mémoires (cache, RAM, ROM). Le tout est piloté par des contrôleurs et bus de transfert de don-nées pour interconnecter les cœurs, les cellules mémoires et les entrées/sorties. Dans les versions les plus récentes, des modules dédiés peuvent être ajoutés pour des fonctionnalités spécifiques comme le chiffrement.
Il existe des variations d’architectures que l’on peut notamment distinguer entre d’une part les multicœurs basés sur le cache (comme celui susmentionné) qui sont prédominants et d’autre part les multicœurs basés sur scratchpad, c’est-à-dire des mémoires locales dédiées à chaque cœur. On peut voir la différence fondamentale de structure entre ces deux variations sur la Figure 1.3.
Les architectures à Scratchpad mettent à disposition des mémoires à haut débit dédiées à chaque cœur. Toutes les ressources sont le plus possible séparées entre les unités de calcul. Les modèles d’exécution de tâche sont en général très cadrés avec trois phases d’exécution (Chargement mémoire, exécution et déchargement) pour maîtriser le modèle d’exécution du logiciel. Les architectures Scratchpad sont alors des solutions en elles-mêmes aux problèmes d’exécution parallèle de code sur les calculateurs multicœurs pour éviter les problèmes d’interférences. Ce type d’architecture matérielle qui évite les interférences par design limite en revanche les possibilités d’intégration du logiciel. Étant donné que chaque cœur ne dispose que d’un espace cache réduit, il faut veiller à ce que toutes les tâches exécutées sur un même cœur ne provoquent pas de débordement de ce cache, au risque de demandes d’accès à la mémoire principale qui seraient inacceptables.
À l’inverse, les architectures basées sur le cache se veulent polyvalentes et comptent sur des mécanismes de contrôle logiciel pour optimiser l’utilisation des ressources. La mémoire est partagée à différents degrés entre les cœurs. De façon à décongestionner les accès mémoire et accélérer ces dernières, une hiérarchie mémoire est mise en place, associant des espaces mémoire progressivement plus petits et rapides en fonction de leur proximité au processeur. Il s’agit ici de trouver un équilibre entre coût de la mémoire et vitesse d’accès aux données. En effet, cette dernière dispose de trois caractéristiques antagonistes :
— la latence – temps d’accès aux données,
— la bande passante – débit de données accessible,
— la taille mémoire – espace mémoire disponible (pour un coût donné).
Un espace mémoire pourra être soit de petite taille, mais rapide au niveau de son temps d’accès, soit de grande taille et plus lent comme schématisé dans la Figure 1.4b. On a par conséquent au plus proche des cœurs les registres, de taille très limitée (octets) mais au temps d’accès très rapide : ils sont la base pour toutes les opérations effectuées par le processeur. À l’opposé, la mémoire principale, de très grande taille (Go/To) pour laquelle tous les cœurs doivent passer par un bus commun pour y accéder. C’est donc la mémoire la plus lente d’accès, mais aussi la moins coûteuse. Plusieurs intermédiaires ont été mis en place entre ces deux types de mémoire. Il s’agit typiquement de niveaux de cache qui peuvent être non partagés, c’est-à-dire propres à chaque cœur ou bien commun à tous. Le dernier niveau de cache, partagé, est classiquement appelé LLC (Last Level Cache ) et donne la limite entre les espaces mémoire limités en cache avec des accès rapides d’une part et la mémoire principale qui va provoquer de grands ralentissements d’autre part. On retrouve ainsi avec l’exemple de la Figure 1.4a un cas de calculateur multicœur basé sur le cache, avec 8 cœurs, des niveaux de cache mémoire séparés (L1 et L2) et partagé (L3) ainsi que le bus d’accès à la mémoire principale.
La gestion du contenu de ces caches (en lecture et écriture) est géré par une politique d’accès mémoire. Cette politique est essentielle à un usage efficace des caches du fait de leur espace limité qui demande à faire des choix sur son usage. Cela est peu documenté par les constructeurs, et chacun aura son propre algorithme. La méthode de base la plus répandue étant empirique, par principe de localité temporelle [Durrieu 2014] et spatiale [Wilkes 1965], où l’on considère que plus une donnée a été récemment accédée, plus elle a de chance d’être à nouveau utilisée. De même si une donnée est sollicitée, alors les données proches spatialement ont aussi plus de chance d’être utilisées. Nous n’irons pas plus dans les détails sur les politiques de gestion d’accès à la mémoire. Il faut garder à l’esprit qu’elle est plutôt subie par les industriels qui intègrent le matériel dans leurs systèmes. Pour un processeur donné on aura certaines performances de calcul et accès mémoire, et il faudra mettre en comparaison les performances « par défaut » d’un logiciel sur une architecture matérielle donnée face au même logiciel avec l’ajout de la surcouche de contrôle d’exécution apportées par l’intégrateur pour limiter les interférences.
Calculateurs manycœurs Les calculateurs manycœurs sont des microprocesseurs incluant un grand nombre de cœurs dans l’objectif primaire d’une plus grande capacité d’exécution de code parallèle. Pour ce faire, les cœurs peuvent être spécialisés avec la ré-duction des instructions réalisables et optimisations à des tâches spécifiques. La structure d’accès mémoire des cœurs est organisée sous forme de grille de bus de données qui intercon-nectent à la fois tous les cœurs entre eux et l’accès mémoire. C’est la différence fondamentale avec les multicœurs qui possèdent en général des cœurs identiques (processeur homogène) et un unique bus d’accès mémoire, pour de bonnes performances à la fois en série et en parallèle. Les architectures manycœurs grâce à leurs spécificités demandent des méthodes de programmation appropriées pour pouvoir être pleinement exploités. Cela augmente le niveau de complexité de développement, mais au bénéfice d’une forte amélioration des performances.
Les GPUs (Graphic Processing Unit) sont un cas particulier de manycœurs à présent très répandus pour des usages variés [Owens 2008]. Cette forte expansion des GPU est due non seulement à leurs capacités de rendu graphique, mais surtout à leurs capacités de programmation parallèle poussée au maximum. Un grand nombre de domaines, notamment dans la recherche, y voient donc un microprocesseur d’usage général à hautes capacités de calcul parallèle. Les GPU sont efficaces du fait qu’ils permettent de réaliser le même calcul sur un très grand nombre de données différentes (typiquement calculs matriciels) pour obtenir tout autant de résultats en sortie. Il s’agit d’un modèle dit SIMD – Single-Instruction, Multiple-Data. Là où les multicœurs conventionnels sont plus polyvalents, les GPU se focalisent sur la réalisation de tâches identiques en parallèles, ils restent donc spécialisés pour des types de tâches spécifiques, en complément de processeurs plus polyvalents. On peut mentionner comme exemples le deep learning pour l’apprentissage d’intelligences artificielles ou encore le minage de cryptomonnaies pour les blockchains.
Dans le cadre de ces recherches, nous nous focaliseront sur le dénominateur commun le plus utilisé dans les architectures électriques et électroniques, qui est donc le processeur multicœur basé sur le cache.
Risques et Problématique
Dans le cadre du contexte automobile, on se dirige vers un nouveau paradigme, où la voiture n’est plus un système mécanique sur lequel on adjoint du logiciel, mais à l’inverse un superordinateur multifonctionnel auquel on implante des roues et un moteur. Les systèmes automobiles sont ainsi devenus des systèmes cyberphysiques qui entrent en interaction à la fois avec les utilisateurs et l’environnement. On distingue deux grands domaines de logiciels embarqués dans le véhicule. Tout d’abord l’info-divertissement, qui réunit les systèmes multi-médias et autres affichages non nécessaires à l’usage primaire du véhicule. Et deuxièmement les calculateurs enfouis qui réalisent des fonctions essentielles qui ne sont pas nécessairement visibles de l’utilisateur, telles que le contrôle moteur. Pour soutenir ces besoins émergents, il est nécessaire de se baser sur des architectures matérielles plus puissantes comme les multi-cœurs. Cependant, cette disruption apporte de nouveaux enjeux, notamment de sécurité, vie privée, mais aussi sur la prédictibilité et la sûreté de fonctionnement du système à cause de sa complexification. Cela fait donc évoluer les systèmes embarqués dans un environnement profondément à risques, mais qui en plus s’accompagne de contraintes fortes. Nous nous devons donc d’introduire ici les notions de Sûreté de fonctionnement nécessaires à l’analyse.
Sûreté de Fonctionnement Informatique
La sûreté de fonctionnement (SdF) d’un système informatique est « la propriété qui permet à ses utilisateurs de placer une confiance justifiée dans le service qu’il leur délivre, le service étant le comportement du système perçu par un utilisateur, cet utilisateur étant un système (informatique, humain, environnemental) qui interagit avec le premier. » [Laprie 1996]. C’est donc la capacité d’un système informatique de répondre de manière correcte, confor-mément aux spécifications fonctionnelles, à une requête d’un autre système. La sûreté de fonctionnement est définie en fonction de trois notions principales : a) les attributs qui définissent les propriétés assurées, b) les entraves qui caractérisent les circonstances indési-rables mais prévues, c) et les moyens qui précisent les techniques permettant au système de fournir son service. Selon les services souhaités par l’utilisateur, ce dernier peut vouloir accentuer certaines propriétés pour assurer le bon fonctionnement du système. Ainsi la sûreté de fonctionnement englobe les attributs suivants :
— La disponibilité – la capacité d’être prêt à délivrer le service correct ;
— La fiabilité – l’assurance de continuité d’un service correct ;
— La sécurité-innocuité – l’assurance de non-propagation de conséquences catastro-phiques à l’utilisateur ou l’environnement ;
— L’intégrité – l’assurance de non-altération du système ;
— La maintenabilité – l’aptitude à la réparation et à l’évolution du système.
Ces attributs permettent d’une part d’exprimer les propriétés devant être respectées par le système, et d’autre part d’évaluer la qualité du service délivré vis-à-vis de ces propriétés. Les aspects de sécurité, au sens de la confidentialité –c’est-à-dire la non-divulgation d’information non autorisée– et des attaques face à des actions malveillantes indésirables, ne seront pas abordés dans cette thèse.
Les entraves à la sûreté de fonctionnement sont les défaillances, les erreurs et les fautes. Une défaillance est une transition d’un service correct vers un service incorrect. Un service est considéré incorrect s’il n’est pas conforme à la spécification ou si la spécification ne décrit pas avec précision la fonction du système. Étant donné qu’un service consiste en une séquence d’états externes du système (observés par l’utilisateur), la survenue d’une défaillance signifie qu’au moins un des états externes s’écarte de l’état correct du service. La déviation est liée à une erreur, qui représente la partie de l’état interne du système pouvant entraîner une défaillance, dans le cas où elle atteint l’interface du service du système. La cause déterminée ou présumée d’une erreur est appelée une faute. La Figure 1.5 représente ce lien de cause à effet. Le fait de prévenir la causalité entre fautes est défaillances pour le bon fonctionnement se désigne par la méthode de silence sur défaillance. C’est-à-dire qu’une faute ou une erreur n’aura pas plus de conséquences et ne provoquera pas outre de défaillance, ou inversement.
Table des matières
Introduction
1 Enjeux des Systèmes Embarqués Complexes
1.1 Évolutions des Systèmes embarqués
1.1.1 Nouveaux systèmes intelligents et connectés
1.1.2 Nouvelles architectures Matérielles
1.2 Risques et Problématique
1.2.1 Sûreté de Fonctionnement Informatique
1.2.2 Systèmes temps-réel et Ressources partagées
1.2.3 Problématique et Objectifs
1.3 Contraintes et Hypothèses
1.3.1 Contexte industriel Automobile
1.3.2 Standards industriels et Concept de Criticité
1.3.3 Contraintes d’intégration
1.4 Grandes approches du domaine
1.4.1 Mécanismes de contrôle
1.4.2 Mécanismes Réactifs
1.5 Contribution de la thèse et objectifs
2 État de l’Art
2.1 Vue d’ensemble des systèmes à criticité mixte
2.1.1 Entre garanties et optimisation
2.1.2 Solutions Matérielles et Logicielles
2.1.3 Contrôle Statique et Dynamique
2.2 Mécanismes de contrôle réactif
2.2.1 Contrôle réactif spatial
2.2.2 Contrôle réactif temporel
2.3 Positionnement des travaux
3 Principe et architecture
3.1 Modèle basé sur des chaînes de tâches
3.1.1 Notion de Criticité
3.1.2 Modèle de Tâche et Chaînes de tâches
3.2 Mécanisme de Surveillance et de Contrôle
3.2.1 Méthode d’anticipation
3.2.2 Passage en Mode Dégradé
3.3 Architecture Logicielle
3.3.1 Task Wrapper Component (TWC)
3.3.2 Core Control Component (CCC)
3.3.3 Définition des constantes de Contrôle
3.4 Application industrielle
3.4.1 Spécification fonctionnelle
4 Protocole et démarche expérimentale
4.1 Principe Général et Objectifs
4.2 Protocole de conception d’un cas de test
4.2.1 Profil des tâches
4.2.2 Profil du cas de test et Chaîne de tâches
4.3 Protocole d’Implémentation et Calibration
4.3.1 Spécification des paramètres de Contrôle
4.3.2 Calibration du Mécanisme de Contrôle
4.4 Protocole expérimental global
5 Implémentation, Résultats et Analyse
5.1 Plateforme de développement
5.1.1 Plateforme Matérielle
5.1.2 Support Logiciel
5.2 Logiciel Applicatif
5.2.1 Benchmark MiBench
5.2.2 Charge de test
5.2.3 Implémentation de la plateforme expérimentale logicielle
5.3 Application du Protocole Expérimental à MiBench
5.3.1 Phase de Conception
5.3.2 Phase de Configuration du mécanisme
5.3.3 Phase de Validation et Analyses
Conclusion
Perspectives
Publications
Annexe
Bibliographie
Résumé