UKOnline

Aspect hardware

Comme précédemment annoncé, un système embarqué se compose de hardware et de software travaillant en étroite collaboration. Cette section brosse brièvement différents aspects hardware et choix qu'il existe dans le domaine des systèmes embarqués, les principaux composants que l'on peut retrouver ainsi que l'architecture globale du système embarqué.

Histoire

Commençons cette section sur les aspects hardware avec un petit interlude historique. Si l'on s'en réfère aux documents publiquement disponibles, on peut considérer que deux composants sont à l'origine des systèmes embarqués. Intel a produit le premier microcontrôleur commercial tandis que le premier microprocesseur a été créé pour la US Navy pour son avion de chasse Tomcat F-14.

Intel 4004

Le premier système embarqué commercial, ou tout du moins l'élément clé qui a permis son apparition, a été créé par Intel en 1971. Cette compagnie a introduit le premier microprocesseur sur une seule puce, l'Intel 4004. La compagnie japonaise Busicom désirait une série de circuits intégrés pour différentes calculateurs qu'elle proposait. La réponse d'Intel fut un microprocesseur à usage général, qui pourrait être utilisé pour tous les produits de la gamme de Busicom. Ce dernier permettait d'exécuter une séquence d'instructions placées dans une puce mémoire externe. Le hardware offre donc la puissance de calcul et le software définit la fonction calculée. La figure 6 montre l'Intel 4004 ainsi que le calculateur Unicom 141P, version OEM du 141-F, premier produit commercial à utiliser le premier microprocesseur d'Intel.

Intel 4004 et Unicom 141P
La variante D4004 du microprocesseur Intel 4004 est en céramique et fonctionne sur 4 bits avec une fréquence CPU maximale de 740 kHz. Il est composé de 2300 transistors et est distribué sous forme de DIP à 16 pins. Sa première utilisation commerciale a été pour le calculateur 141-PF de la firme japonaise Busicom.

Central Air Data Computer

Un peu avant l'Intel 4004, le premier microprocesseur a été développé pour l'US Navy de 1968 à 1970 et décrit dans un article (Architecture Of A Microprocessor, par Ray M. Holt, dans Computer Design Magazine (janvier 1971), pages 1–26) qui n'a été rendu public qu'en 1998. Ce microprocesseur, le MOS-LSI, a été conçu comme unité de calcul du Central Air Data Computer (CADC) utilisé dans l'avion de chasse Tomcat F-14. Son but consistait à évaluer des fonctions spécialisées en réponse à des stimuli fournis par des senseurs tels que la pression, la température, etc. afin de contrôler différents systèmes de l'avion et de présenter des données au pilote.

Boucle hardware

Le hardware est souvent utilisé dans une boucle présentée sur la figure 7, qui est la même utilisée dans la méthode de test “hardware in a loop” (HIL). Des stimuli extérieurs en provenance de l'environnement vont arriver sur le hardware qui réagira en produisant signaux en sortie. Le tout se répète dans une boucle environnement $\rightarrow$ senseur $\rightarrow$ système embarqué $\rightarrow$ actuateur $\rightarrow$ environnement $\rightarrow$ ...

On peut également voir sur la figure que l'unité de calcul centrale (CPU) peut interagir, au sein du système embarqué, avec différents éléments tels que des convertisseurs A/D et D/A (convertisseur analogique vers numérique et inversement : A/D pour Analog-to-Digital et D/A pour Digital-to-Analog), de la mémoire et d'autres unités de calcul de type FPGA ou ASIC (FPGA pour Field-Programmable Gate Array est un circuit intégré reprogrammable et un ASIC pour Application-Specific Integrated Circuit est au contraire spécifique à une fonction et non modifiable). Ces différents composants, périphériques à l'unité de calcul, sont détaillés plus loin dans la section.

Boucle hardware
Le hardware d'un système embarqué (cadre gris) est souvent utilisé dans un mode “hardware in a loop”, c'est-à-dire dans une boucle qui passe à travers le système embarqué et l'environnement.

Unité de calcul

Après l'apparition de l'Intel 4004 et du MOS-LSI, de nombreux autres types d'unités de calcul ont vu le jour, chacun ayant ses propres spécificités. Dans le monde des systèmes embarqués, il y a une pléthore de choix possibles pour déterminer l'unité de calcul qui sera utilisée.

Il y a tout d'abord le processeur, notamment caractérisé par son jeu d'instructions, c'est-à-dire l'ensemble des instructions qu'il est capable d'exécuter, par sa fréquence d'horloge (Hz) et au nombre d'instructions exécutables par secondes (MIPS). Ces deux dernières caractéristiques permettent d'établir ses capacités et sa puissance de calcul.

On retrouve également des circuits spécifiques qui implémentent des fonctions directement câblées en hardware. Ce deuxième type d'unité de calcul est moins générique, mais plus rapide, performant et généralement plus compact que les processeurs.

Plusieurs types d'implémentations sont possibles pour les unités de calcul, allant de systèmes plus génériques comme l'Intel 4004 vers des solutions beaucoup plus spécifiques. On distingue essentiellement quatre grandes catégories :

  • Le General Purpose Processor (processeur à usage général) (GPP) propose un jeu d'instructions assez large et varié permettant de réaliser beaucoup de choses. C'est le genre de processeur que l'on retrouve notamment dans les ordinateurs « traditionnels ».
  • L'Application-Specific Instruction set Processor (processeur dont le jeu d'instructions est spécifique à l'application) (ASIP) possède un jeu d'instructions qui est spécifiquement conçu pour un certain ensemble d'opérations.
  • Vient ensuite le hardware reprogrammable dont la fonction peut être modifiée après sa fabrication, une fois sorti d'usine donc. Pour être précis, il s'agit plus d'une reconfiguration que d'une reprogrammation étant donné que ce type d'unité de calcul n'exécute pas d'instructions.
  • Enfin, l'unité de calcul la plus spécifique est l'Application-Specific Integrated Circuit (circuit intégré propre à une application et spécialisé pour cette dernière) (ASIC) qui est un circuit intégré réalisant les fonctions nécessaires pour une application donnée.

Comme le résume la figure 8, on peut comparer ces différents types d'unités de calcul sur base de deux critères. Au plus l'unité de calcul sera générique, au plus grande sera la flexibilité qu'elle offre pour l'utiliser et la programmer mais par contre, au moins les performances et la consommation énergétique seront bonnes. Si ces deux derniers critères sont importants, il convient de se déplacer vers des unités de calcul plus spécifiques. Néanmoins, ces dernières ont un cout plus important, dû à la conception et au développement des circuits et dû au fait qu'ils ne peuvent pas forcément être produits en masse comme les processeurs à usage général (microprocesseur et microcontrôleur).

Les Application Specific Standard Product (ASSPs), cités précédemment, sont une version un peu plus générale que les ASICs. Il s'agit de circuits intégrés implémentant une fonction spécifique visant un large marché, contrairement aux ASICs qui combinent plusieurs fonctions pour offrir une solution précise pour un client. Enfin, les FPGA sont souvent utilisés comme plateforme de prototypage pour des ASIC.

Performance et flexibilité du hardware
Une unité de calcul générique sera plus flexible, mais au détriment de moins bonnes performances et d'une efficacité énergétique moindre, et inversement pour les unités de calcul spécifiques.

Architecture matérielle

L'architecture matérielle d'un système embarqué liste les composants le constituant ainsi que la manière avec laquelle ils sont agencés entre eux. Il existe plusieurs types de représentations possibles pour décrire une architecture matérielle, la plus courante et pratique étant un diagramme blocs, un peu comme celui de la figure 7. Ce type de diagramme comporte généralement :

  • Des blocs qui représentent les différents composants, unités ou sous-systèmes composant le système embarqué, selon le niveau d'abstraction désiré pour la description de l'architecture matérielle.
  • Des liens entres blocs qui représentent un contrôle, une commande, un échange d'information, avec éventuellement le type de communication utilisé, de nouveau selon le niveau d'abstraction désiré.

Voyons un exemple d'un système qui mesure la température d'une pièce pour activer un ventilateur si cette dernière est trop élevée. Un écran LCD est également présent pour afficher la température courante. La figure 9 montre le diagramme blocs de ce système.

On y voit, au centre, un microcontrôleur de type ARM7TDMI. Sur la gauche, un senseur de température LM35 est connecté comme entrée sur le microcontrôleur. En haut, on retrouve un écran LCD et sur la droite un driver moteur L293D. Ces deux composants sont connectés comme sorties du microcontrôleur. Enfin, tout à droite se trouve le moteur DC du ventilateur, contrôlé par le driver moteur.

Ventilateur contrôlé par la température
La température de la pièce est mesurée à l'aide d'un senseur LM35, est récupérée par un microcontrôleur LPC2378 qui décide d'activer ou non un moteur à partir d'un driver L293D, selon la température mesurée, affichée sur l'écran LCD.

Ce diagramme bloc de haut niveau permet de rapidement voir les composants qui constituent le système embarqué et les liens qui existent entre eux. On peut également voir le flux d'information, c'est-à-dire là où des données sont transférées entre composants.

On peut aller plus loin, et rentrer dans les détails des connexions entre les composants. Par exemple, on peut montrer les pins des différents composants et comment elles sont reliées entre elles. On obtient ainsi un schéma de montage ou de câblage qui vous permettra, notamment, de réaliser le système embarqué sur une plaque de prototypage.

On peut imaginer d'autres niveaux d'abstraction, où l'on présentera également des composants de plus bas niveau tels que des résistances, condensateurs, transistors, etc. L'important est de choisir le niveau adapté au public ciblé, et à ce que le diagramme doit communiquer.

Architecture type

La figure 10 montre l'architecture type d'un système embarqué. On y voit les principaux composants que l'on retrouve dans la plupart des systèmes embarqués; ils sont décrits dans la section suivante.

Deux ouvertures vers le monde extérieur sont présentes : le bus de périphériques et un port utilisé pour le debug des programmes. Pour le reste, outre le processeur, on peut voir qu'il y a des horloges, des mémoires, des dispositifs généraux, spécifiques et de communication. Ces composants sont reliés au processeur à l'aide de bus système pouvant être de différents types. Cette architecture type se retrouve, par exemple, sur des cartes telles que l'Arduino, la Raspberry Pi ou la BeagleBone Black, présentées plus loin dans ce livre.

Architecture type hardware
L'architecture type d'un système embarqué se compose d'un processeur, d'horloges, de mémoires, des dispositifs généraux, spécifiques et de communication.

Principaux composants

Un système embarqué étant destiné à une application spécifique, son hardware est spécialement conçu pour ce dernier. On élimine, par exemple, tout circuit superflu afin de réduire les couts engendrés par des ressources inutiles. De plus, plusieurs choix sont possibles pour l'unité de calcul à prendre. Voyons ici une série de composants ou sous-systèmes de l'architecture type d'un système embarqué.

Alimentation

Plusieurs options sont possibles pour alimenter en énergie un système embarqué. S'il ne doit pas être portable, on peut utiliser un adaptateur secteur AC/DC et sinon, il peut être alimenté par une batterie. Dans les deux cas, plusieurs plages de fonctionnement doivent être disponibles pour les éventuels besoins différents des composants d'un même système embarqué. On retrouve typiquement les quatre plages suivantes :

  • $5.0$ V $\pm0.25$ V
  • $3.3$ V $\pm0.3$ V
  • $2.0$ V $\pm0.2$ V
  • $1.5$ V $\pm0.2$ V

Un bon sous-système d'alimentation est important pour un système embarqué. Il doit notamment posséder les caractéristique suivantes :

  • Il doit fournir une tension la plus stable et lisse possible. Cela est important pour certains composants comme les ADCs qui nécessitent une tension constante pour que la conversion du signal analogique en numérique soit précise. Pour cela, il est intéressant de prévoir des régulateurs de tension.
  • Il doit fournir suffisamment de courant pour le fonctionnement du système embarqué et de ses composants. Cette contrainte peut notamment limiter le nombre de périphériques qui seront directement alimentés par le système embarqué.
  • L'alimentation doit être efficace, offrir de bonnes performances et la plus stable possible, étant donnés des variations de température et le fait que la circulation d'air peut être très limitée voire nulle.
  • Enfin, un découplage doit être mis en place entre certains composants qui doivent être alimentés séparément : l'horloge et les circuits de reset, les ports d'entrée/sortie externes et les timers. L'horloge et les circuits de reset ne doivent pas subir d'interférences radioélectriques. Les périphériques d'E/S peuvent dissiper plus de puissance que les unités internes du processeur. Enfin, les timers dissipent une puissance constante, même lorsqu'ils sont en mode attente.

Les systèmes basse tension sont construits à partir de portes Low Voltage CMOS (LVCMOS) et de Low Voltage Transistor-Transistor Logic (LVTTL). Il y a une relation inversement proportionnelle entre la tension opérationnelle et les délais de propagation dans les portes CMOS, ce qui tend à favoriser le $5$ V dans la plupart des systèmes embarqués, pour réduire ces délais. Néanmoins, passer la tension à $3.3$ V réduit la dissipation de puissance par deux. De plus, pour des systèmes à petite géométrie, le processeur et les circuits d'E/S génèrent moins de chaleur en 3.3 V, et peuvent dès lors être mis dans des plus petits packs.

Notez qu'il existe également des systèmes embarqués qui dépendent de leur hôte pour l'alimentation. Prenez l'exemple d'une carte graphique d'un ordinateur « traditionnel » qui sera alimentée, directement, par la carte mère à laquelle elle est branchée. Enfin, des plus petits systèmes nécessitant moins de puissance, comme les cartes à puce, peuvent être alimentés par une pompe de charge.

Horloge

L'horloge est le second composant essentiel, avec l'alimentation en énergie. En effet, elle est utilisée pour cadencer le fonctionnement du processeur et donc l'exécution des instructions. C'est à son rythme que le processeur répète inlassablement le cycle fetch-decode-execute, récupérant les instructions depuis la mémoire, les décodant et les exécutant.

Le circuit oscillateur d'horloge peut utiliser un crystal externe au processeur, un résonateur céramique associé de manière interne au processeur ou enfin un oscillateur externe sous la forme d'un circuit intégré rattaché au processeur. Le crystal offre la solution la plus stable en fréquence, mais doit être placé le plus près possible du processeur. À l'opposé, le résonateur céramique est interne au processeur, mais moins stable (dérive d'une dizaine de minutes par mois, comparé à entre une et cinq minutes pour le crystal). Enfin, le circuit intégré externe est beaucoup plus contrôlable, ce qui est notamment utile lorsque différents composants du système embarqué sont pilotés de manière concurrente.

Un système embarqué contient également des Real-Time Clocks (RTC), c'est-à-dire des circuits de timer. Elles sont utilisées par divers composants, notamment l'ordonnanceur de tâches dans le cadre d'un microprocesseur ou pour des systèmes temps réel.

Mémoire

Un autre type de composant que l'on retrouve dans tous les systèmes embarqués est la mémoire. Il existe de nombreux types de mémoire pouvant être permanentes ou volatiles, internes ou externes. Concernant les systèmes embarqués, on retrouve notamment les trois types suivants :

  • La Read-Only Memory (mémoire morte, ou mémoire à lecture seule) (ROM) est une mémoire permanente et en lecture seule utilisée pour stocker le programme exécuté par le système embarqué. Le processeur y récupère les instructions à exécuter. On y retrouve également d'autres données comme le code de démarrage et d'initialisation du système, des pointeurs vers une série de routines, etc.
  • La Random-Access Memory (mémoire vive, ou mémoire à accès aléatoire) (RAM) est une mémoire volatile utilisée comme mémoire de travail. Elle stocke les variables créées par le programme et est utilisée comme mémoire tampon d'entrée/sortie pour le traitement de son ou d'images, par exemple.
  • Enfin, l'Electrically Erasable Programmable ROM (mémoire ROM effaçable électriquement) (EEPROM) est une mémoire permanente, mais dont le contenu peut être modifié en flashant la mémoire à l'aide d'un procédé électrique. On l'utilise notamment comme mémoire cache, pour stocker une copie des instructions et données chargées à l'avance depuis une mémoire externe ou des résultats temporaires de calculs pour du traitement rapide.

Entrée/sortie

Le système embarqué doit être capable de communiquer avec des dispositifs externes, comme des senseurs, boutons et circuits transducteurs, à travers des ports d'entrée. Ces différents dispositifs sont identifiés par des ports possédant une adresse. Dans l'autre sens, la communication d'information vers le monde extérieur se fait via des ports de sortie. Des exemples de sorties sont les LEDs, écrans LCD, etc. Un port de sortie est également identifié par une adresse.

Un premier exemple très simple de périphérique est le port General Purpose Input/Output (entrée/sortie à usage général) (GPIO), illustré à la figure 11. Il permet de connecter directement le processeur avec le monde extérieur et d'autres dispositifs, produisant deux valeurs de tension pour chaque pin GPIO, c'est-à-dire une valeur binaire. Chaque pin GPIO peut aussi bien servir comme entrée, par exemple pour renseigner l'état d'un bouton au processeur, que comme sortie, par exemple pour allumer une LED.

Port GPIO
Un port GPIO expose plusieurs pins dont les directions et les valeurs sont contrôlées par des registres accessibles au processeur.

Plus précisément, un port est un dispositif capable recevoir des données provenant d'un périphérique, d'un processeur, d'un contrôleur extérieur pouvant ensuite être lues par le processeur. Dans l'autre sens, un port permet d'envoyer des données vers l'extérieur à partir d'instructions exécutées par le processeur. La connexion du port vers le processeur se fait via un bus, sur lequel un échange d'information se produit.

On distingue deux méthodes de transmission de données sur un bus. Pour un bus série, l'information circule bit à bit et pour un bus parallèle, plusieurs bits peuvent être transmis en même temps. Historiquement, les communications parallèles étaient plus rapides puisque l'on transférait plus d'information à la fois. Néanmoins, le cout et la complexité hardware additionnels (plus de fils, émetteurs et récepteurs plus complexes) ont rendu les communications séries plus populaires et plus efficaces avec l'augmentation des fréquences d'horloge. Aujourd'hui, le parallèle est limité à des communications entre composants physiquement proches, et le série pour des communications à plus longues distances.

Une autre caractéristique des bus est la manière avec laquelle le rythme de la communication se déroule. Dans un bus synchrone, la communication suit une horloge qui permet d'indiquer si une donnée est disponible et valide ou non. Les deux extrémités du bus doivent suivre la même horloge. Un bus asynchrone quant à lui va transmettre des balises sur le canal de communication, délimitant ainsi les données valides ou non. Ce type de bus est plus simple et bon marché, adapté à des communications à intervalles irréguliers. Son principal désavantage est la surcharge causée par les bits de contrôle. Un bus synchrone aura donc un plus gros débit, n'ayant pas cette surcharge.

Il existe plusieurs types de bus, qui sont décrits plus loin dans ce livre. On retrouve notamment les bus I$^2C$, SPI, CAN, USB et PCI qui diffèrent entre eux essentiellement de part le protocole de communication qu'ils proposent et de par leurs caractéristiques.

Support analogique

Enfin, terminons le tour des principaux composants avec le support du monde analogique. En effet, un système embarqué peut devoir lire une entrée analogique comme un son provenant d'un micro, par exemple, ou produire un signal analogique, par exemple pour contrôler un moteur. On parle alors de système hybride combinant les mondes discret numérique et continu analogique.

Pour produire une sortie analogique, on prévoit typiquement une unité Pulse Width Modulator (PWM) qui permet de construire un signal continu à l'aide d'états discrets. Dans l'autre sens, pour récupérer un signal analogique en entrée, on prévoit une unité Analog-to-Digital Converter (ADC) qui va discrétiser un signal continu pour en récupérer une séquence binaire.

Choix technologique

Que faut-il choisir comme technologie, au niveau hardware, pour un système embarqué ? Comme on l'a déjà vu précédemment, on a une palette de choix allant d'un système spécifique implémenté en ASIC à un système générique sous forme de processeur à usage général.

Lorsque l'on doit développer un système embarqué, il est moins couteux de démarrer avec un processeur général en implémentant les fonctions désirées en software. On se tournera donc vers un microprocesseur ou un microcontrôleur, que l'on pourra programmer au niveau software. Cette solution est plus flexible et moins chère, mais peut souffrir au niveau des performances. Une fois le processeur choisi, toute l'optimisation doit se faire au niveau logiciel et cela peut avoir un cout non négligeable.

Pour améliorer les performances, une solution consiste à remplacer le duo processeur-software par un circuit intégré de type ASIC, avec les mêmes fonctions implémentées en hardware. Cette solution est évidemment plus onéreuse et prendra beaucoup plus de temps de développement. Elle n'est pas flexible et il est très difficile, voire impossible, de modifier ou faire évoluer les fonctions implémentées.

Comme le résume la figure 12, avoir plus de flexibilité se fait au prix d'une plus grande consommation de puissance et d'énergie. Il faut savoir que des observations tendent à montrer qu'une fonction software consomme environ dix fois plus de puissance que la même fonction réaliser en hardware pur.

Flexibilité par rapport à puissance et consommation énergétique
La flexibilité offerte par la technologie utilisée est inversement proportionnelle à la puissance et à l'énergie consommée par le système embarqué, notamment à cause de la partie software (SW) à exécuter pour les processeurs.

Dans un cycle de développement général, on aura tendance à commencer par concevoir un prototype du système embarqué à réaliser avec une technologie plus flexible, c'est-à-dire basée sur un processeur. Cette flexibilité permet de tester et d'expérimenter différentes variantes des fonctions désirées pour le système embarqué. Une fois le prototype ainsi validé, on décidera de migrer tout ou une partie des fonctions en hardware pur en codant ces fonctions directement en ASIC, avec éventuellement une nouvelle phase de prototypage à l'aide de FPGAs.

La figure 13 apporte un autre point de vue. On peut y voir l'évolution du nombre d'opérations réalisables par Watt en fonction de la taille de la technologie utilisée, pour les ASICs, le hardware reconfigurable et les processeurs. Ce nombre d'opérations augmente bien évidemment lorsque les circuits intégrés diminuent en taille.

Ce que l'on voit également, c'est qu'en allant vers du hardware câblé pur, le gain obtenu est d'un ordre de grandeur (échelle logarithmique sur l'axe vertical). Enfin, on voit que les processeurs spécialisés comme les DSPs représentent le meilleur cas de la tranche processeurs, frôlant le hardware reprogrammable comme les FPGAs et que les microprocesseurs représentent le pire cas.

Taille par rapport au nombre d'opérations par watt
Diminuer la taille des circuits intégrés augmente le nombre d'opérations qu'il est possible de réaliser par watt consommé, peu importe le type d'implémentation choisi. Mais se tourner vers l'ASIC donnera toujours des meilleures performances que d'utiliser un processeur à usage général.