• 30 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 18/07/2024

Introduction

L’objectif principal de ce chapitre est de vous familiariser avec ce qui constitue un microprocesseur. Quelles sont les briques de base d’une architecture ? Comment coexistent-elles et comment collaborent-elles pour que le petit morceau de code que vous avez écrit s’exécute sur votre machine ?

Il existe de multiples et subtiles variétés d’architectures. Nous ne considérerons ici que les éléments basiques que l’on rencontre dans un microcontrôleur et nous nous focaliserons sur leurs interactions. Par la suite nous ferons un très rapide et succinct tour d’horizon des grandes familles de processeurs et verrons pourquoi les microcontrôleurs offrent une bonne solution pour les systèmes embarqués.

Rappel sur les architectures de processeurs

Pour qu’un programme puisse s’exécuter dans le « cœur » d’un processeur, cela nécessite différentes briques. Avant tout, rappelons-nous qu’un processeur est une machine synchrone : cela veut dire qu’il existe une horloge qui donne le rythme de tout ce qui se passe.  Passons en revue rapidement ces quelques briques élémentaires et essentielles.

L’unité arithmétique et logique (ALU)

C’est la partie opérative du système. La seule vraiment capable de faire des calculs (au sens littéral du terme). Cependant, surtout sur un processeur dédié à l’embarqué, les capacités de calcul d’une ALU restent très limitées en terme de variété, même si elles peuvent s’exécuter très rapidement. Les opérations ordinaires d’une ALU sont : l’accès à la mémoire, les additions/soustractions, les multiplications/divisions et toute une flopée d’opérations logiques portant sur des bits (opération ET, opération OU, décalages, rotations, compléments, extractions,…). Classiquement toutes ces opérations ne se font que sur des entiers (8 bits, 16 bits ou 32 bits), ce qui limite d’autant plus les capacités de calcul. Il existe évidemment des architectures incluant des unités de calcul sur nombres réels (FPU : Floatting Point Unit) mais nous ne les considérerons pas dans ce cours car elles restent encore assez rares dans le monde de l’embarqué.

Une banque de registres

Généralement l’ALU ne communique pas directement avec la mémoire pour faire ses calculs. Pour gagner en rapidité et en efficacité, elle est connectée à des registres dont l’accès peut se faire en un seul cycle d’horloge. Ces registres sont :

  • soit à usage général, pour stocker toutes sortes d’informations alimentant les calculs,

  • soit spécifiques, dédiés à une tâche très précise.

Parmi ces registres spécifiques citons-en 3 incontournables :

  • un registre qui contient l’adresse courante du programme en cours. Au cours de l’exécution du code, il se modifie tout seul pour aller chercher la prochaine instruction que devra réaliser l’ALU. Il est très souvent dénommé PC (pour Program Counter),

  • un registre “de statut” qui renseigne sur l’état du processeur à un instant donné et qui est mis à jour en fonction de ce qui s’y passe. Entre autres informations essentielles pour un programme, on y trouve les « flags » c’est-à-dire des bits qui informent l’ensemble de la machine si la dernière opération exécutée par l’ALU a retourné une valeur nulle, une valeur négative… Remarquez que les structures algorithmiques classiques comme if-then-else, while, for, etc., sont réalisées au niveau du processeur à l’aide de ces flags,

  • un registre contenant une adresse accessible en mémoire vive pour stocker des informations temporaires mais vitales pour le bon déroulement de l’ensemble. Cet espace mémoire est la PILE système (nous y reviendrons plus tard) et ce registre est le plus souvent dénommé Stack Pointer (SP).

De la mémoire en lecture seule (ou souvent dite « morte »)

Constituée de composantes ROM (Read Only Memory) ou FLASH (comme les clés USB), ces mémoires ont surtout la capacité de conserver leurs contenus lorsque l’alimentation est coupée. Cette mémoire va donc naturellement contenir le code à exécuter.

Une case mémoire (typiquement un octet) détient donc une valeur et se différencie des autres cases par une adresse unique (codée en général sur 32 bits). Le registre PC présenté ci-dessus va donc contenir la valeur sur 32 bits de l’adresse où le processeur pourra lire la prochaine instruction à traiter.

La quantité de Flash qui équipe un microcontrôleur est très variable selon la version du processeur que vous aurez choisi.

De la mémoire « vive »

Communément appelée RAM (Random Access Memory) ce type de mémoire est accessible en lecture et en écriture par le processeur. Toutes les variables que vous créerez dans votre programme se retrouveront naturellement stockées dans ces éléments. Contrairement à la mémoire en lecture seule, lorsque ces boîtiers mémoires ne sont plus alimentés, ils perdent de facto leur contenu.

Comment peut-on alors créer des variables initialisées au démarrage de la machine ?

En effet cela suppose qu’à la mise sous tension, la case mémoire RAM contient dès le départ la bonne valeur. Cela devient possible parce que ces valeurs initiales vont être aussi stockées dans la mémoire en lecture seule permanente (ROM) et que le compilateur ajoute automatiquement un petit bout de code caché qui, lors de la phase d’initialisation du processeur, va simplement recopier ces valeurs figées dans les cases mémoire RAM qui correspondent aux variables utilisées par le programme. Par ce mécanisme simple les variables seront initialisées.

Une pile système

C’est une zone de la mémoire RAM prédéfinie au départ par le programme.  Comme il a été dit plus haut, cette zone est repérée (pointée) par un registre spécial (SP). Ce pointeur évolue au gré des écritures/lectures sur le principe d’une structure LIFO (Last In First Out: “dernier arrivé, premier sorti”). Le principe de cette structure de données est identique à celui d’une pile d’assiette dans un placard. Quand on enregistre une donnée (en écriture), on dépose une assiette (forcément en haut de la pile). Quand on a besoin d’une donnée (lecture), on prend celle qui est au-dessus. Les plus téméraires peuvent essayer de faire autrement mais c’est risqué. La dernière donnée déposée est donc la première donnée reprise, d’où le nom.

La présence d’une pile est essentielle à un processeur. Par exemple, lorsqu’une interruption arrive au processeur (dans la suite, vous verrez en détail ce qu’est une interruption, mais pour l’instant imaginez un signal qui demande à interrompre le traitement en cours par le processeur pour en exécuter un autre à la place. A la fin de l’interruption, le processeur reprend le traitement initial). Dans ce cas le processeur doit cesser ses calculs en cours et se brancher sur la partie de code qui va faire les choses urgentes demandées au processeur pour répondre à cette demande d’interruption. Pour ne pas perdre ses calculs en cours et savoir où les reprendre, il doit stocker toute une série d’informations qu'il pourra restaurer à la reprise. L’endroit où il les stocke est la pile système. Il écrit ses données essentielles dans un certain ordre sur la pile système et les récupère dans l’ordre inverse en utilisant le mécanisme de la structure LIFO.

Très schématiquement on peut donc représenter les différents éléments constitutifs d’un processeur comme suit :

Les éléments constitutifs d'un processeur
Les éléments constitutifs d'un processeur

Dans cette figure, on visualise les différentes interactions entre les éléments. Chaque case mémoire possède une adresse propre, c’est le seul moyen pour que le processeur puisse aller lire et écrire les données nécessaires à son fonctionnement : le codage du programme en cours d’exécution, les variables qu’il manipule et la pile système pour le bon séquencement de la machine. Sur ce schéma les valeurs des adresses sont uniquement illustratives et correspondent à ce que l’on peut rencontrer dans un STM32. Pour d’autres processeurs, ce mapping  mémoire peut être tout autre. Le mapping mémoire (memory map) est une sorte de table qui met en relation  les adresses manipulées par le code avec les éléments physiques du microcontrôleur comme la RAM ou les périphériques.

Les grandes familles de processeurs

Ce qui a été présenté dans la section précédente est assez général mais est tout de même globalement écrit sur la base du fonctionnement d’un microcontrôleur. Dans le monde des processeurs, il existe bien sûr d’autres architectures. Il est possible de trouver d’autres produits dont la finalité d’utilisation est en principe différente. Cependant les frontières entre ces grandes familles ne sont pas toujours très franches. De plus l’évolution extrêmement rapide des technologies compliquent l'établissement d'une vision hiérarchisée et ordonnée de cet ensemble. Passons tout de même rapidement en revue ces grandes familles sans entrer dans le détail, pour se faire une idée de ce qui peut correspondre à des processeurs utilisables en informatique embarquée.

Les microprocesseurs

Sous ce terme générique, tous les circuits programmables peuvent s’y retrouver. Il est cependant assez commun de considérer que cette dénomination concerne les puces que l’on rencontre dans les ordinateurs (PC, Mac, serveur…). Actuellement, pratiquement tous ces microprocesseurs sont multi-coeurs et intègrent plusieurs cœurs qui collaborent et/ou exécutent plusieurs traitements en parallèle. Les microprocesseurs sont des circuits puissants en terme de calcul. Ils possèdent des jeux d’instructions complexes qui leur permettent d’utiliser au mieux les ressources propres à l’informatique actuelle comme l’accès à Internet.  Leur puissance a un coût, notamment leur consommation électrique et la nécessité d’avoir a minima des radiateurs/ventilateurs pour dissiper l’effet Joule qu'ils génèrent.

Le leader du marché dans ce secteur est Intel qui équipe la majorité des PC et des Mac avec ses core ix actuels.

Même si rien n’est interdit dans l’absolu, ces processeurs sont peu adaptés pour l’embarqué. Leur utilisation est pratiquement inenvisageable sans disposer d’un système d’exploitation (Windows, Mac OS, Linux, etc.) performant qui gère entre autres choses le parallélisme des tâches (multitasking).

Les DSP (Digital Signal Processing)

Comme leur nom l’indique ces processeurs ont des architectures qui leur permettent de traiter du signal rapidement et efficacement. Ils vont par exemple permettre certaines formes de parallélisme de calcul au niveau de l’ALU pour améliorer les performances dans des traitements qui nécessitent l’utilisation de la transformation de Fourier. Ils possèdent également des périphériques d’entrées/sorties analogiques précis et rapides qui répondent aux besoins spécifiques des applications pour traiter des signaux (son, image,…).

Parmi les grands noms de l’industrie du semi-conducteur qui développe et commercialise des DSP, Texas Instrument est sans doute le plus connu.

Ces DSP sont donc utilisables pour l’embarqué, mais ils ciblent plus particulièrement les systèmes pour lesquels il existe des besoins spécifiques (modem, lecteur DVD,…)

Les microcontrôleurs

Ce sont les processeurs qui nous intéressent pour ce cours. Ce sont des processeurs moins puissants que les microprocesseurs, mais dont les capacités de calcul peuvent être relativement très élevées au regard des besoins. Les microcontrôleurs haut de gamme intègrent maintenant des unités de calcul en virgule flottante qui permettent leur utilisation, même avec de gros besoins en calcul. Il ne faut pas perdre de vue également que s’ils sont moins puissants, ils ont aussi nettement moins de choses à faire. A priori ils n’ont besoin que de gérer l’application dédiée du système embarqué.

Ce qui distingue les microcontrôleurs des processeurs classiques, c’est :

  • les différentes unités périphériques qui accompagnent le cœur: des entrées/sortie digitales, des unités de conversion analogique/numérique, des timers, des liaisons série de tout type (UART, CAN, I²C, Spi, USB…),

  • le fait qu’elles soient en plus intégrées ensemble au sein de la même puce

Les microcontrôleurs possèdent également de la mémoire morte et de la mémoire vive qui permettent de concevoir une électronique de commande quasiment réduite à la puce.

La frontière entre les microcontrôleurs et les processeurs de la famille DSP est très mince, et il est impossible de trouver un élément architectural déterminant pour distinguer de façon indiscutable ces deux univers.

ARM se place très bien sur ce secteur, comme nous le verrons dans le chapitre suivant, il ne fabrique pas de circuits. Il ne fait (et c’est déjà pas mal) que les concevoir pour vendre par la suite les licences liées à cette conception. STMicro et NXP sont de grands utilisateurs des architectures ARM.  En dehors d’ARM, Microchip avec ses PIC et Atmel avec ses AVR (arduino) sont des acteurs bien présents sur le marché.

On l’aura deviné: les microcontrôleurs sont LES processeurs utilisés dans le monde de l’embarqué. Ils sont conçus pour consommer le moins de courant possible, ce qui en fait leur force pour ce secteur d’activité.  Une des explications du succès d’ARM (dont les processeurs équipent près de 90% des smartphones) réside dans sa capacité à minimiser cette consommation, ce qui de facto augmente l’autonomie du système embarqué.

Les FPGA (Field-Programmable Gate Array)

Ce ne sont pas des processeurs à part entière… quoique. À la base les FPGA sont des circuits logiques programmables, ou plus exactement reconfigurables après leur fabrication. Ils diffèrent des autres familles présentées ci-dessus parce qu’ils ne sont pas directement programmables par le biais d’un programme informatique embarqué en mémoire morte. Ici c’est le matériel, c.-à-d. la multitude de connexion entre des fonctions logiques élémentaires, qui doit être « recâblé » pour réaliser l’application. Donc initialement un FGPA n’intègrent aucune ligne de code. Son gros atout est la rapidité de traitement pour des applications numériques bien spécifiques.

Là où les choses se compliquent : pour reconfigurer les FPGA, il faut tout de même utiliser un langage de programmation. Il est spécifique (VHDL, Verilog) et très proche du matériel. Le « compilateur » de ces langages va engendrer les circuits logiques associés et surtout l’ensemble du placement-routage qui permet de mettre en œuvre la reconfiguration dans le circuit.

Deuxième étage de complication : on peut réaliser un microcontrôleur sur FPGA en le programmant directement avec du VHDL et aussi trouver des FPGA qui intègrent directement un ou plusieurs cœurs de processeur pré-câblés (System on chip). L’utilisateur peut donc concevoir (co-design) la partie programmable qui tournera sur ce processeur intégré et déporter certaines fonctionnalités spécifiques en réalisant directement un circuit hors du processeur pour traiter ces fonctionnalités (a priori avec des performances accrues). En poussant au bout ce raisonnement, un utilisateur peut ainsi concevoir un équivalent de microcontrôleur, à la mesure exacte de ses besoins.

Dans cette famille de produits, Xilinx et Intel FPGA (anciennement Altera) font figure de leader. Pour ce qui est de l’utilisation dans le monde de l’embarqué, il s’agit là évidemment d’une solution séduisante et adaptée. Mais elle présente un degré de complexité aujourd’hui largement supérieure à des solutions basées sur un microcontrôleur existant. Il faut donc avoir de bonnes raisons pour opter pour cette voie.

À la suite de cette partie, vous êtes capable :

  • de décrire les principaux éléments qui constituent l'architecture d'un processeur ;

  • d'identifier les grandes familles de processeurs et d'en expliquer les principales différences.

Exemple de certificat de réussite
Exemple de certificat de réussite