Skip to content

M4.1 Architecture

ch3 Architecture des Systèmes embarqués

diapo 4 Objectif Plan

diapo 5 Micro:bit v1 Cortex M0+ v2 Cortex M4

La carte est aussi programmable en javascript, en C, en scratch

diapo 6 Commençons par présenter les applications et problématiques liés aux systèmes embarqués

diapo 7 3.1 Applications et problématiques des systèmes embarqués

diapo 8 3.1 Applications et problématiques des systèmes embarqués - 2

Problématiques liées aux systèmes embarqués :

Fiabilité, Robustesse, respect des normes automobile ou militaire (T° de fonctionnement, compatibilité électro-magnétique), Performances (processeur 64 bits, FPU, Vitesse d’horloge…), Quantité de mémoire (données - RAM et programme – flash) disponible, Périphériques disponibles (précision des entrées analogiques, Ethernet, USB…),

Consommation, Coût (du composant, des outils de développement, des outils pour la fabrication), Encombrement (exemple : AirPod ou robot d’inspection des artères),

Disponibilité

Ces problématiques spécifiques aux systèmes embarqués amènent à des réponses technologiques particulières, où l'ensemble du système informatique est intégré sur une seule puce, le microcontrôleur. Certains microcontrôleurs orientés objets connectés sont relativement simples et sont ainsi un support moderne et concret adapté à l'introduction de certaines notions importantes de l'informatique. Nous les utiliserons pour présenter la gestion par le processeur des fonctions et des interruptions.

diapo 10 Le microprocesseur

Un microprocesseur est constitué essentiellement de la CPU présentée avant, avec ses registres, son unité de contrôle et son unité arithmétique et logique, le tout gravé sur un même circuit intégré.

2 circuits mémoire dans le même espace mémoire, les bits de poids fort du bus d'adresse servent à sélectionner le circuit concerné et les bits de poids faible à sélectionné le registre dans le circuit sélectionné.

Les entrées/sorties tout ou rien, nommées aussi GPIO pour Global Purpose Input Output, sont utilisées pour relier des signaux tout ou rien au processeur, comme un bouton ou une led.

Un périphérique, il peut être interne ou externe. Un périphérique possède des registres, par exemple un registre écrit par la CPU pour configurer le temps d'acquisition du convertisseur analogique numérique et un registre ou la CPU pourra lire la valeur convertis. Ces registres ont une adresse dans l'espace mémoire. Ils sont vu comme de la mémoire (périphérique mappé).

diapo 11 Le microprocesseur - 2 Cet arangement sur une carte électronique, nommée circuit imprimé, de différents circuits intégré est relativement simple avec les premiers microprocesseurs 4 ou 8 bits, voir 16 bits.

Dès que les bus augmentent en taille pour atteindre aujourd'hui 64 bits pour le bus d'adresse comme pour le bus de données, le nombre de broches des circuits, près de 200, fait que les cartes électroniques sont très complexes et de taille importante.

diapo 12 Le microcontrôleur Dès les années 80, la volonté de faire des circuits petits, simples et rapides à mettre en oeuvre, bon marché et économes en énergie amène à intégrer dans le même circuit intégré, les circuits de contrôle de l'horloge, voir l'horloge elle-même. Ces circuits, contrôlés par la CPU permettent de passer sur des horloges plus lentes (Low Power Oscillator) pour économiser l'énergie. la mémoire données la mémoire programme Lorsque mémoire programme et mémoire données sont intégrées, le circuit peut à lui-seul être un système informatique autonome. On parle alors de microcontrôleur. Sur ces microcontrôleurs ont été aussi ajoutées des périphériques d'entrées / sorties pour étendre leurs possibilités d'interactions avec divers capteurs et actionneurs.

diapo 12 Le microcontrôleur et ses entrées sorties Les bus données et adresses ne sortant plus à l'extérieur du microcontrôleur, il possède de nombreuses broches pour connecter ces capteurs et actionneurs. ....

diapo 22 Le Mediatek MT6750 est un processeur de smartphone de 2016. Difficile de trouver une documentation précise pour des processeurs plus récents. Les architectures annoncées pour les derniers Mediatek Helio, Apple A, Qualcomm SnapDragon ou Samsung Hexynos, plus performants, sont assez similaires. Ce n'est plus un microcontrôleur, la mémoire est à l'extérieur. Il possède bien plus qu'un processeur. Terme générique System on Chip.

Notons que pour se rapprocher de l'encombrement des microcontrôleurs, certains SoC (pas le MT6750) utilisent une technique originale : eMCP embedded MultiChip Package. La mémoire est installée sur le SoC, celui devant être conçu pour avoir son bus mémoire sur le dessus. Cela permet de limiter l'encombrement de l'ensemble et de les distances mémoire-processeur. Par contre, cela complexifie le refroidissement de l'ensemble.

diapo 25 3.3 Les appels de fonctions et la pile Intro Profitons de l'architecture relativement simple d'un microcontrôleur Cortex M0+, comme celle du nRF51822, pour mettre en évidence deux concepts importants en informatique, très utilisé sur les microcontrôleurs comme sur les microprocesseurs : les appels de fonctions et la pile d'une part et les interruptions d'autre part.

diapo 26 3.3 Les appels de fonctions - 1 Nous verrons dans le module suivant comment sur un système plus complexe, le système d'exploitation alloue de la mémoire aux processus. Sur un système embarqué très simple, avec peu de mémoire, on fonctionne sans système d'exploitation. On parle de système bare metal (métal brut). L'exemple suivant a été réalisé avec un microcontrôleur NXP LPC804 à coeur Cortex M0+. L'environnement de développement permet de lire à tout instant les valeurs des registres, de la mémoire programme et de la mémoire données, ce qui permet de bien comprendre l'utilisation de la pile. Le microcontrôleur a son programme dans les premières adresses de l'espace mémoire, en commençant à l'adresse 0 La mémoire donnée est située dans le plan mémoire entre les adresse 0x1000 0000 et 0x1000 1000.

Zoomons sur l'espace de la mémoire RAM. Les adresses basses, à partir de 0x1000 0000 serviront pour stocker les variables globales dont l'adresse est fixe tout au long du programme. C'est le tas, heap en anglais.

Un appel de fonction depuis le programme principal nécessite de stocker le contexte dans lequel est le processeur (ses registres, l'adresse de la prochaine instructions), pour pouvoir y revenir une fois la fonction terminée.

Pour cela les adresses hautes, depuis 0x1000 1000 en redescendant, seront utilisées pour stocker les variables locales de la fonction, le contexte du microcontrôleur (c'est-à-dire les valeurs de ses registres) lors d'un appel de fonction et les paramètres de la fonction. Le programme principal étant aussi une fonction, on trouve en bas de la pile les variables locales du programme. Pile se dit stack en anglais. Attention, sur le cortex M0+, la pile se remplit dans le sens des adresses décroissantes.

Pour l'usage de la pile, on utilise deux instructions spécifiques : PUSH pour envoyer des registres du contexte sur la pile et POP pour remttre ces valeurs de la pile vers les registres du processeur.

diapo 27 3.3 Les appels de fonctions - 2 En violet est entouré l'extrait du programme assembleur prinicipal, situé aux adresses de 0x4b6 à 0x4c0. Les lignes 124 et 125 correspondent aux lignes de langage C ayant permis de générer ce code assembleur. Les lignes 0x4b6 à 0x4bc correspondent à l'appel de la fonction. On observe d'abord une préparation des registres R0 et R3 puis l'appel de la fonction, via l'instruction de saut inconditionnel bl. Ce saut envoie vers l'adresse de la première instruction de la fonction. Au retour de la fonction, c'est l'instruction située à l'adresse 0x4c0 qui devra être exécutée.

Sur la droite, on montre les registres internes du microcontrôleur. Le registre 13 est nommé SP Stack Pointeur et indique le haut de la pile, visible tout à droite. La pile est ici présentée avec les grandes adresses en bas. En effet, elle croit vers les adresses décroissantes. La pile ne gère que des nombres 32 bits. On voit ainsi que la pile est occupée jusqu'à l'adresse 0x1000 0FD8

diapo 28 3.3 Les appels de fonctions - 3 On entre dans la fonction. L'instruction PUSH demande le stockage d'un registre du contexte : R7 et de LR, adresse de retour, une fois la fonction terminée. La pile remonte de 2 adresses. Le registre R7 est stocké dans la pile L'adresse de retour est stockée dans la pile. Notons que l'adresse de retour n'est pas 0x4c0 mais 0x4c1. Les instructions étant sur 16 bits, on ne peut avoir d'adresse impaire. Le dernier bit est utilisé pour indiquer si au retour du programme, la CPU sera en mode USER, avec des privilèges restreints, ou SUPERVISEUR. Cette notion sera expliquée dans le module sur les systèmes d'exploitation. Ici, il n'y a pas de système d'exploitation, le programme s'exécute en mode SUPERVISEUR.

diapo 29 3.3 Les appels de fonctions - 3 On ajoute ensuite 4 cases de 4 octets à la pile, en soustrayant 16 octets à la valeur du registre SP. Cette espace mémoire sert pour y stocker notamment les variables locales et les paramètres de la fonction.

diapo 30 3.3 Les appels de fonctions - 4 Une fois le code de la fonction effectuée, à la sortie de la fonction, la valeur de sortie est stockée dans un registre pour permettre un usage facile par le programme principal. On ajoute ensuite 16 à la valeur du pointeut pile pour faire libérer les 4 cases utilisées pendant le déroulement de la fonction.

diapo 31 3.3 Les appels de fonctions - 5 Enfin, pour remettre le contexte de la CPU dans l'état où il était avant le lancement de la fonction, On restaure R7 On envoie PC, le pointeur d'instruction à l'adresse de retour dans le programme principal 0X4C0. La fonction POP, en plus de rétablir ces valeurs fera redescendre le pointeur de pile à 0x1000 0FD8

Nous avons ainsi vu comment lors de l'appel d'une fonction utilise la pile pour stocker le contexte du processeur, ses paramètres et ses variables. Si une fonction appelle elle-même une fonction, le pile monte encore plus. La gestion de la pile est faite par le compilateur ou par l'interpréteur python. Si de nombreux appels de fonctions imbriqués ont lieu, la pile s'étend beaucoup et peut rejoindre le tas. C'est l'erreur Stack Overflow : débordement de la pile.

diapo 30 3.4 Les interruptions Intro Les fonctions que nous avons vues dans la partie précédente sont appelées par le programme principal. Un autre mécanisme autorise des signaux électriques à lancer ces fonctions et ainsi interrompre le déroulement du programme principal. Ce sont les interruptions. Elles sont très utilisées pour lancer périodiquement l'ordonnanceur du système d'exploitation par exemple, pour signaler la fin d'une lecture sur le disque dur ou l'arrivée d'un message via la carte réseau, etc...

Sur un système embarqué, les interruptions sont également très utilisées. Nous reprendrons donc le petit et pas trop complexe microcontrôleur NXP LPC804 à base de Cortx M0+ pour présenter le principe des interruptions en suivant l'évolution des valeurs des registres et de la mémoire.

diapo 33 Les interruptions - 1 L'application de notre exemple comprend 3 taches : L’affichage sur l’écran LCD qui est une tâche longue (de durée 5 ms) et peu prioritaire, elle se répète toutes les 500 ms L’échantillonnage d’une entrée analogique qui est une tâche courte (de durée 10 µs) prioritaire et se répétant toutes les 25 µs L’appui sur le bouton poussoir est un événement sporadique déclenchant un traitement de durée 2 µs. Le bouton est enfoncé au plus toutes les 50 ms.

diapo 34 et 35 Les interruptions - 2 Description de l'animation. La tache d'échantillonnage est prioritaire sur celle du bouton.

diapo 36 Les exceptions Regardons comment cela fonctionne. Le processeur dispose d'un certain nombre d'exceptions, numérotées On y trouve des exceptions logicielles, par exemple Hard Fault error qui intervient lors d'une division par 0 par exemple. Elles sont déclenchées par la CPU elle-même. On y trouve aussi des exceptions matérielles, nommées interruptions, qui sont déclenchées par des signaux extérieurs à la CPU, par des périphériques le plus souvent. A chaque exception correspond une case 32 bits dans laquelle on va indiquer l'adresse de la fonction à exécuter lors de l'apparition de cette exception. Cette adresse est nommé vecteur. Il pointe sur une fonction à exécuter. Lors d'un reset, si on souhaite redémarrer le programme principal, c'est son adresse qui sera dans la case 0x4. Dans la case 0xC, on peut indiquer l'adresse d'une fonction qui sera exécutée en cas d'erreur importante. Ce fut un célèbre affichage d'écran bleu "division par 0" pour Windows. Systick est un timer qui peut être utilisé pour lancer l'ordonnanceur d'un système d'exploitation. On notera alors dans cette case l'adresse de la fonction de l'ordonnanceur. Il sera alors lancé automatiquement à chaque période et pourra alors changer le processus en exécution.

diapo 37 Le contrôleur d'interruptions Chaque interruption peut être activée ou non. On dit alors qu'elle est masquée. De plus, une priorité est attribuée à chaque fonction d'interruption, certaines pouvant interrompre d'autres. La gestion des masquages et des priorités des interruptions est faite par un périphérique de la CPU nommé Contrôleur d'interruptions Vectorisées Imbriquées (NVIC : Nested Vectored Interrupt Controler) L'abréviation IRQ signifie Interrupt Request : demande d'interruption.

diapo 37 Exemple : l’interruption associée à une entrée Tout ou Rien Reprenons l'exemple d'une interruption lancée lors de l'appui sur un bouton. Elle est donc une fonction associée à l'interruption d'une entrée Tout ou Rien (GPIO). Cette fonction est ici nommée PININT0_IRQHandler. La première interruption associée à une entrée Tout Ou Rien est l'interruption numéro 24 donc l'exception numéro 40. L'adresse de la fonction doit être déposée à l'adresse du vecteur 40, c'est-à-dire 0xA = 160. En regardant dans la mémoire du microcontrôleur, on y trouve effectivement l'adresse 0x3D1, le 1 indiquant que l'interruption sera lancée en mode SUPERVISEUR.

diapo 37 Exemple : l’interruption associée à une entrée Tout ou Rien - 2 Pour cet exemple, le programme principal ne fait rien, il boucle sur lui-même, d'où l'instruction de branche vers sa propre adresse. On affiche à gauche le contexte de la CPU et l'état de la pile pendant le fonctionnement du programme principal. La pile est assez basse, en 0x1000 0FE0.

Sur la droite, on affiche la même chose au moment de l'appui sur le bouton poussoir. La fonction d'interruption s'est lancée, la pile est montée en 0x1000 0FB8, Tous les registres pouvant servir dans l'interruption, R0 à R3 et R7, sont sauvegardés sur la pile. On trouve également comme pour l'appel d'une fonction classique l'adresse de retour une fois l'interruption terminée.

diapo 38 Les systèmes embarqués ont des contraintes spécifiques (consommation, coût,…) et diverses ce qui amène à des architectures variées. Les System On Chip des smartphones regroupent plusieurs cœurs et de nombreux périphériques. Les microcontrôleurs sont des systèmes informatiques regroupés sur une même puce, certains relativement simples et ainsi utiles pour mettre en évidences des concepts d’informatique générale. Les fonctions utilisent une zone mémoire de taille variable, la pile, pour stocker le contexte avant leur lancement et leurs variables. Les interruptions sont des fonctions qui ne sont pas appelées mais lancées par un événement, par exemple par un périphérique.

Memoire donc tout binaire -> float ascii adressage en octet

exo sequentiel / combin exo taille des nombres

CPU Bus 8 bits bus adresse ?

Prog Binaire puis ASM puis C Pour ASM, on trouve Lecture/ecriture Mem ou dépalcement données calcul arithmétique calcul logique comparaisons branchement (if et boucles, appels sous-programmes)

Compilation : Convertit code source en code objet (langage machine) Lienn ave Machine du turing universelle Editions de liens : Rassemble les différents modules d'un prog

Systèmes embarqués

fonctions La pile Les interruptions Les Entrées sorties

IT Bien expliquer l'importance des registres et donc de la sauvegarde du contexte lorsqu'on change de tâche ou lorsqu'apparaît une interruption Matérielles et logicielles IRQ pour Interruption ReQuest

Pipeline issu de Intel : Each processor contains from one to hundreds of cores. Each core contains hardware to:

Fetch instructions.
Decode those instructions.
Schedule the instructions for execution.
Execute the instructions.
Fetch the data the instructions need.
Store the data the instructions produce.

mémoire le processeur lit la donnée dans le cache ; – si la donnée n’est pas présente, un défaut 5 de cache a lieu (cache fault 6 en anglais) ; – ce défaut de cache déclenche alors une action prédéterminée, en l’occurrence la copie de la donnée de la mémoire principale vers la mémoire cache ; – la donnée peut alors être lue par le processeur. L’échange de données entre la mémoire cache et la mémoire principale est simi- laire à l’échange de données entre la mémoire principale et la mémoire secondaire (généralement le disque dur) qui sera abordé dans le chapitre sur la gestion de la mémoire. Le même principe est aussi employé entre le cache primaire, logé directement au sein du processeur, et le cache secondaire, logé à l’extérieur. La plupart des processeurs possèdent même plusieurs zones de mémoire cache interne, parfois appelées cache de niveau 1, cache de niveau 2, etc. La plupart des périphériques et des contrôleurs de périphériques possèdent aussi de la mémoire cache pour accélérer les transferts et ce principe est donc très générique. Pourquoi utiliser cinq zones différentes de mémoire (registres, cache primaire, cache secondaire, mémoire principale et mémoire secondaire) ? On pourrait en effet imaginer que le processeur qui a besoin d’une donnée aille directement la chercher dans

Adresses physiques Nous avons défini à la section 1.2 le terme « adresse » comme une indexation des octets disponibles dans la mémoire principale de l’ordinateur. Nous appellerons désormais ce type d’adresse des « adresses physiques » dans la mesure où elles font directement référence à la réalité physique de la machine. Une adresse physique est donc un nombre qu’il suffit de passer au contrôleur de mémoire pour désigner une donnée stockée en mémoire. Bus adresse 64 bits ?

Pour la protection des zones mémoires : Adresses virtuelles En pratique, les ordinateurs n’ont jamais 4 Go de mémoire principale (adresses sur 32 bits) et une grande partie des adresses ne sert à rien. Une idée intéressante est d’utiliser tout l’espace d’adressage pour effectuer la gestion de la mémoire, puis de transformer au dernier moment l’adresse utilisée en une adresse physique. Par exemple, utilisons les 2 premiers bits d’adresse pour réserver des zones de mémoire au système. Ces 2 bits désignent 4 zones de 1 Go et nous allons réserver la zone 3 (11 en binaire) pour le système. Ainsi, toutes les données concernant le système d’exploitation auront une adresse de 32 bits débutant par 11 et il suffira donc de tester ces 2 premiers bits pour savoir si une donnée appartient au système ou pas. L’avantage de ce système est évident ! Mais la correspondance entre les adresses ainsi composées et les adresses physiques n’est plus assurée : les adresses de 32 bits commençant par 11 correspondent à des données stockées après les 3 premiers Go de mémoire... De telles adresses n’ayant pas de correspondance physique s’appellent des adresses virtuelles. Une adresse virtuelle est donc une représentation particulière de la zone occupée par un octet qui nécessite une transformation adaptée pour correspondre à une adresse physique. Cette transformation s’appelle la traduction d’adresses ou, par abus de langage, translation d’adresses. La conversion des adresses virtuelles en adresses physiques connues par les couches matérielles a lieu constamment pendant l’exécution des différents programmes utilisés sur l’ordinateur. Cette conversion doit donc être très rapide car elle conditionne la vitesse d’exécution des programmes. C’est pourquoi cette traduction est directement assurée par un composant électronique logé dans le processeur : la MMU

Chipset Les contrôleurs de périphériques En réalité, le processeur ne communique pas directement avec les périphériques : ceux-ci sont reliés à des contrôleurs de périphériques et c’est avec eux que le processeur dialogue. Un contrôleur peut gérer plusieurs périphériques et le processeur n’a pas besoin de connaître précisément ces périphériques : s’il souhaite, par exemple, écrire une donnée sur le disque dur, il le demande au contrôleur de disque dur et c’est ce dernier qui se débrouille pour effectivement satisfaire la demande du processeur. Le processeur transmet alors la donnée à écrire au contrôleur, le contrôleur la stocke dans une mémoire tampon qu’il possède et la transmettra au disque dur

Les bus de communication Le bus système, ou bus processeur, ou encore bus mémoire, souvent connu sous le nom de FSB (Front Side Bus) permet de connecter le processeur à la mémoire de type RAM ainsi qu’à d’autres composants (voir fig. 1.3). Les communications sur ce bus système sont gérées par un composant particulier de la carte mère : le NorthBridge. C’est ce composant qui conditionne souvent le chipset de la carte mère. Les communications avec des périphériques plus lents tels que les disques durs par exemple sont gérées par un autre composant : le SouthBridge. Le bus de cache ou BSB (Back Side Bus) réalise la connexion entre le processeur et la mémoire cache secondaire (cache L2 et cache L3) quand celle-ci n’est pas directement intégrée au processeur. Le bus PCIe (Peripheral Component Interconnect Express) permet la connexion de périphériques variés comme une carte video,. . . Cette nouvelle technologie, compatible avec l’ancien bus PCI, adopte un modèle de transmission par commutation de paquets (très proche du modèle réseau TCP/IP) sur une ligne série à la différence de l’ancien protocole parallèle dans lequel un composant monopolisait le bus pendant sa transaction