Microcontrôleur – Chapitre 2 – Le processeur

Le processeur est un composant complexe et incontournable. Après son invention à la fin de la Seconde Guerre Mondiale, sa taille a fortement diminué (de plusieurs dizaines de mètres de large à quelque millimètres) pour donner naissance au microprocesseur dans les années 1970.

Depuis, la densité de transistors présente au sein d’un processeur n’a cessé de croitre au point de doubler tous les deux ans (selon la célèbre loi de Moore). Ainsi les processeurs actuels (en 2015) contiennent un million de fois plus de transistors que les premiers microprocesseurs mis sur le marché quarante ans auparavant.

Le processeur d’un microcontrôleur est caractérisé par :

  • son architecture qui lui fournira un jeu d’instructions ainsi qu’une taille de registre (8bit, 16bit, …)
  • ses registres internes
  • la cadence de son horloge, qui peut être configurée de quelque kHz à plusieurs dizaines de MHz.

Les instructions disponibles peuvent être en nombre très variable selon les architectures. Elles sont en générales très primaires ; il s’agit :

  • d’opérations arithmétiques et logiques qui peuvent être effectuées sur les registres internes du processeur ou sur les mémoires ou entre les deux
  • d’opérations sur des adresses pointant vers des secteurs de mémoire
  • des sauts d’exécution vers des endroits de la mémoire

L’horloge

Un microcontrôleur possède généralement un cristal interne (quartz), qui jouera le rôle d’horloge par effet piézoélectrique. Il est souvent possible d’exploiter à la place un cristal externe, notamment pour utiliser des fréquences plus élevées que le cristal interne.

L’horloge va cadencer le processeur ; un tic correspondra à une instruction élémentaire. Une fréquence basse ralentira forcement l’exécution d’un processus, et empêchera d’utiliser des protocoles nécessitant une fréquence plus élevée. Elle permettra néanmoins de consommer beaucoup moins d’énergie. Une fréquence élevée permettra d’être plus efficace mais consommera plus d’énergie, ce qui peut également dégager de la chaleur.

Certains microcontrôleurs permettent de modifier leur fréquence pendant l’exécution ; c’est une fonctionnalité très intéressante qui permet d’économiser énormément d’énergie en mettant le montage en veille, en attendant par exemple une interruption (appui sur un bouton, détection de lumière, …). La fréquence passera alors à quelques kilohertz, remontant à plusieurs MHz lors d’une utilisation active.

La fréquence peut également être amplifiée par un mécanisme appelé « boucle à verrouillage de phase » ( PLL ; Phase-locked loop en anglais). On peut attendre ainsi des fréquences très élevées (2 à 10 fois la fréquence maximale), au prix de la stabilité et de la fiabilité du microcontrôleur.

Les registres

Il faut bien différencier ici deux concepts :

– les registres internes du processeur

– les registres externes en mémoire

On parlera dans les deux cas de registres, mais on se réfèrera la plupart du temps a des registres externes.

les registres internes

Un registre (interne) est un emplacement de mémoire particulier au sein du processeur. La quantité de registres est très limitée (quelques dizaines tout au plus). Leur taille est une constante du processeur ; un processeur 16-bit aura des registres de 16 bits.

Il y a plusieurs registres internes significatifs :

  • le compteur ordinal : il s’agit du registre qui pointe vers l’instruction en cours
  • le registre d’instruction : il contient l’instruction en cours
  • les registres « données » : leur utilité est principalement de charger des données qui vont être manipulées dans les prochains cycles, afin de minimiser le temps de traitement
  • les registres « adresses » qui font office de pointeurs vers des zones de la mémoire
  • (il existe beaucoup d’autres types que je ne détaillerai pas ici)

Dans le cadre du développement sur microcontrôleur, leur utilisation est totalement transparente, sauf à vouloir utiliser des commandes assembleurs brutes.

les registres externes

Ces registres, stockés en mémoire, sont liés à l’état d’un composant ou d’un périphérique de façon directe. Ils peuvent être en accès libre, en lecture seule ou en écriture seule.

Dans le cadre d’un microcontrôleur, les registres commandent directement les principales fonctionnalités ; par exemple :

  • changer l’état d’une broche reviendra à changer un bit dans un registre
  • récupérer la valeur d’un compteur reviendra à lire un registre
  • écrire dans la mémoire reviendra à écrire dans un registre l’adresse dans laquelle on souhaite écrire, afin que le registre suivant dans lequel on écrira la valeur pointe vers ce secteur de la mémoire
  • lire une valeur analogique reviendra à écrire dans un registre pour déclencher l’évaluation d’un échantillon, attendre qu’un bit dans un autre registre atteigne une valeur particulière, et enfin lire un troisième registre (voire un quatrième registre selon la résolution) pour récupérer la valeur de l’échantillon
  • communiquer sur un port série reviendra à configurer une liaison dans plusieurs registres, puis à veiller un registre d’état de l’entrée de la liaison, pour enfin lire un registre de données jusqu’à ce que le registre d’état indique que la communication est terminée.

Vous l’aurez compris, les registres sont indispensables pour piloter un microcontrôleur.

Si vous voulez vous en convaincre, je vous encourage à lire les sources fournies avec les principales bibliothèques de développement pour microcontrôleur. Vous remarquerez, par exemple, que la fonction C utilisée pour changer la valeur d’une sortie va pointer vers un alias qui se contentera de changer la valeur d’un registre en particulier, ledit alias n’étant rien d’autre qu’une adresse en mémoire qui changera selon le modèle de microcontrôleur choisi lors de la compilation.

les registres de configuration

On les trouve très souvent sous le nom de « fuses » (fusibles) dans les documentations, car, historiquement, il s’agissait de petits fusibles rassemblés au sein d’une grille. On appliquait une tension de 12V à ceux que l’on voulait faire « claquer ». Cela rendait leur écriture définitive. Ils ont depuis été remplacés par de simples cases en mémoire.

Les registres de configuration sont utilisés pour configurer le comportement du microcontrôleur dès la mise sous tension ; on y trouvera des paramètres comme :

  • la configuration de l’horloge (interne ou externe)
  • la protection en écriture et/ou lecture
  • le comportement du watchdog
  • l’activation du débogage
  • l’activation de la broche RESET

Ces registres doivent parfois être configuré à part. Il est important de prendre toutes les précautions en les manipulant ; car une erreur de configuration pourrait rendre le microcontrôleur inutilisable.

Les bus internes

Pour assurer la communication du processeur avec sa RAM, sa ROM et ses périphériques, trois bus sont reliés:

  • le bus d’adresses, où le processeur va indiquer l’adresse qu’il souhaite accéder (en écriture ou en lecture)
  • le bus de données transporte les données selon l’adresse demandée
  • le bus de contrôle, qui permet aux périphériques d’annoncer une interruption et au processeur d’indiquer la direction (écriture ou lecture) d’une opération

Ici aussi, tout est transparent, mais il est toujours intéressant de savoir qu’ils existent.

Les interruptions

Ce concept est important à saisir, car une fois correctement exploitées, les interruptions vont permettre d’effectuer des opérations en réaction à un évènement particulier :

  • un appui sur un bouton
  • l’expiration d’un délai
  • la réception de données sur un bus de communication
  • la fin d’activité d’un périphérique
  • le déclenchement explicite d’une interruption

Les opérations ainsi déclarées dans une interruption permettront d’économiser énormément de cycles au processeur ; car il n’aura pas besoin de gérer de façon logicielle l’éventualité de ces évènements. Ceci permettra également d’alléger considérablement le code source, et même souvent le programme envoyé au microcontrôleur.

Comme dit un peu plus haut, les interruptions transitent sur le bus de contrôle. Une fois arrivée au processeur, celui-ci interrompt son exécution en cours, et exécute une routine particulière déclarée explicitement (par le développeur) ou implicitement (par exemple un chien de garde ou watchdog chargé de redémarrer un microcontrôleur en cas d’état figé). Une fois sa routine terminée, il reprend l’exécution ou il s’était arrêté (ou non, selon ce que décide le développeur). Chaque processeur possède son catalogue d’interruptions disponibles, il est donc nécessaire de se référer à la documentation pour comprendre chaque cas d’utilisation.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *