Académique Documents
Professionnel Documents
Culture Documents
.
Les Microcontrôleurs 32 bits : le choix Cortex-M
Le noyau processeur d’un microcontrôleur est b eaucoup moins complexe que celui d’ un système
informatique ordinaire (Ordinateur), à conso mmation élect rique plus faible (qq milliwatt en
fonctionnement et de l ’ordre du m icrowatt en veille ) et également moins performant : Il supporte
environs une centaine d’instructions (transferts d e données, sauts, opérations logi ques si mples,
décalages, et les opérations arith métiques) et fonctionne à des fr équences relativement basses variant
de quelques dizaines de MHz à quelques centaines. Ceci permet de limiter la consommation en énergie
du circuit.
Ces circuits à prix réduits à grandes quantités (moins de 1$ pour 10000 pi èces) sont d’une gr ande
utilité pour les applications embarquées qui ont plus besoin d’un grand nombre de lignes d’E/S pour la
commande, l’acquisition ou la communication que d’une capacité de traitemen t élevée. Ils per mettent
ainsi la conception de cartes de co mmandes, de petites tailles et avec des rapports prix/qualité
exceptionnels, pour un gr and nom bre de sy stèmes embarqués (Machines à laver, sy stèmes GPS,
climatiseurs, cartes à puce, automates programmables, contrôleurs d’ascenseurs, variateurs de vitesse,
etc..). Ils couvrent le plus large spectre du domaine des applications em barquées avec des ventes qui
ont atteint les $26 billions en 2007.
Même si les µc 8 bits (relativem ent à la largeu r du bus et taille des registres) se sont im posés
longtemps ; l’étendue des domaines d’application des µc, le besoin croissant en capacité de traitement
et en comportement temps réel ont incité les constructeurs à proposer des µc 16 et particulièrement 32
bits beaucoup plus performants.
En effet, l es ventes ( en %) de s microcontrôleurs 32 bits ont énorm ément p rogressé lors de la
dernière décennie et sont passées de moins de 1% en 2000, à 30% en 2006 pour atteindre les 38 % en
2009 « figure 2 » et on prévoit que cette croissance continuera durant les prochaines années [1].
Microcontrôleurs 8 bits
Microcontrôleurs 16 bits
Microcontrôleurs 32 bits
Ventes en %
La m ajorité des fabricants de m icrocontrôleurs opt ent pour l ’intégration d ’un processor core
préconçu, sous forme d’un IP « Intellectual Property », dans leurs circuits et l ui ajoutent les mémoires
et les entrées/sorties nécessaires pour les applications ciblées.
Parmi les processor cores (IP) les plus utilisés dans les microcontrôleurs 32 bit s, on trouve ceux
de la société ARM (Advanced Risc Machines) ; qui grâce à son nouveau processeur Cortex-M, s’est
imposé co mme leader d es fournisseurs de processeu rs 32 bits pour les applications em barquées
« figure- 3 ».
3 ------ ARM ------ PowerPC ------ x86 ------ SuperH ------ MIPS
Ventes en Billions de dollars
0
2007 2008 2009 2010 2011 2012 2013
Figure 3 : Evolution des ventes des cœurs 32 bits pour les applications embarquées
La société ARM a été créée en 1990 p ar associa tion (joint-vent ure) de Apple Co mputer, Acorn
Computer Group et VLSI Technolog y. Contrairement aux autres sociétés travaillant dans le domaine
des se mi-conducteurs, AR M ne fabrique pas de s pr ocesseurs et les vend dire ctement, mais elle l es
conçoit et v end leur lic ence sous forme d’IP à des partenaires qui les intègrent dans leurs
microcontrôleurs et processeurs. Aujourd’hui, les partenaires d’ARM vendent annuellement plus que 2
billions de circuits à base de noyaux ARM dont l’architecture et le jeu d’instructions ont évolué depuis
la première version ARM-v1 (deve nue obsolète ainsi que les ar chitectures ARM-v2 et v3) jusqu’ à la
version actuelle ARM-v7, appelée également Cortex « figure 4 ».
v7-A (Cortex-A)
(profil Applications)
v7-R (Cortex-R)
(profil Real-Time)
v7-M (Cortex-M)
(profil
Microcontrôleurs)
Contrairement aux architectures préc édentes, Cortex intègre entre autres la gestion des
interruptions et des exceptions ce qui permet une plus grande transparence et souplesse au niveau de la
programmation ainsi qu ’un portage de code plus sim ple. En effe t, ch aque constructeur de
microcontrôleurs basé s su r les génér ations précéden tes ét ait obligé de concev oir sa propre solution
pour la gestion des i nterruptions, ce qui rendait l ’utilisation d’un out il de développement standard
impossible, la programmation moins transparente et évidement le code difficilement portable.
Les cœurs C ortex portent la désignation Cortex- XN, ou X désigne le profil au quel appartient l e
cœur et N son degré de performance qu i varie entre 0 (le moins performant) et 9 (le plus performant).
On distingue 3 profils « figure 5 » propres à l’architecture ARM-v7 ou Cortex et qui sont :
Le profil A (séries Cortex-A) : destiné pour fair e tourner des applications complexes telles que
les sy stèmes d’exploitation embarqués (Symbian, Linux, Wi ndows CE) nécessitant une pui ssance
de traite ment élevé e et un sy stème d e gestion de mémoire vi rtuelle (MM U). Les proc esseurs
appartenant à ce profil peu vent fonctionner avec des fréquences de 2GHz et avec une perfor mance
de 2,5 DMIPS 1/MHz) et c ontiennent des acc élérateurs SI MD (Single Instruction/ Multi ple Data)
ainsi que la technologie Jazelle per mettant l’exécution rapide de langages interprétés tel que Java.
On les trouve dans des pro duits tels que les télé viseurs numériques haute défini tion, les terminaux
mobiles.
1
Dhrystone MIPS : Performance de traitement du processeur en Millions d’Instructions par Seconde obtenue par
exécution du benchmark Dhrystone
Le profil R (s éries Cortex-R) : destiné principalement aux applications te mps réel à contraintes
très sévères et exigeant une haute fi abilité et un tem ps de r éponse faible. L es processeur s de ce
profil contiennent également une unité additionnelle pour le calcul en vir gule flottante et sont
utilisés à titr e d’ exemple dans les disq ues durs, les appareils photo num ériques, le do maine d e
l’automobile (systèmes de freinage).
….2000
Cortex-A
ARM/Thumb
fonctionnement (MHz)
Thumb-2
GIC
Fréquence de
MMU
475
Neon (SIMD)
DSP
Cortex-R VFP
Jazelle
375
Thumb/Thumb-2
Cortex-M GIC
13 stages Pipeline
Multi-core (1-4)
MPU
Thumb-2
FP Unit
NVIC
8 stages Pipeline
MPU
6,5 DMIPS/mW
3 stages pipeline
12,5 DMIPS/mW
Le profil M (série s Cortex-M) : optim isé p our des applications néces sitant une basse
consommation en énergie, un coût réduit et un com portement déterm iniste pour le traitement des
interruptions. C’est le profil qui est destiné à être intégré dans les microcontrôleurs.
Cette famille de processeurs Cortex-M a fa it converger la majorité des constructeurs de
microcontrôleurs, pour la prem ière fois, vers une architecture co mmune. Déjà 28 sociétés (dont 6
parmi le top 10) ont opté pour un cœur Cortex-M (ST-Microelectronics, Luminary Micro (maintenant
faisant partie de Texas Instruments) NXP, Atmel, Zilog, Samsung, etc…).
Jusqu’à ce jour (fin 2012), ARM a lancé les versions 4 versions C ortex-M : Cortex-M0, M1,
M3 et M4 (Cortex-M1 est dédié à être implémenté sur FPGA et non sur des microcontrôleurs) « Figure -6 ».
Les process eurs Cortex-M0, M3 et M4 sont tous des proces seurs 32 bits , ont la m ême
architecture, mais destinés à des applications différentes:
Le Cortex-M0 (0,9 DMIPS) est adapté aux applications à trè s faible coût, pas très exigeantes en
performance ( même s’il reste beaucoup plus performant que les processeurs 16 bits) et avec un nom bre
limité d’entrés/sorties.
Le Cortex-M3 (1,25 DMIPS) vise les applications néces sitant une performance assez élevée tout
en gardant le coût réduit.
Le Cortex- M4 (1,25 DMIPS + Floating Point + SIMD2) vise les applications de traitement de
signal qui nécessitant une performance très élevée et des calculs en virgule flottante. Il offre des
performances semblables à celles des DSP (Digital Signal Processor).
Au niveau des instructions, les processeurs Cortex-M assur ent une co mpatibilité ascendante :
toutes les instructions du Cortex-M0 (56 dont la majorité sont codées sur 16 bits) sont é galement
supportés par le Corex-M3 (une centaine). Toutes les instructions du Cortex-M3 sont supportées par le
Cortex-M4 qui ajoute, en plus, les instructions rela tives à l’ unité de calcul en virgule flotta nte et à
l’architecture SIMD2.
A part ça, un programme écrit en ‘C’ peut être exécuté sur n’importe quel processeur (M0, M3
ou M4), m ais évidement avec des performances di fférentes : c’ est le co mpilateur qui se charge
d’adapter le code ‘C’ au processeur cible.
2
SIMD (Single Instrcu tion Multiple Data) : Il s’ag it d’une arch itecture qu i permet d ’exploier l’UAL afi n
d’effectuer p lusieurs o pérations (additions, so ustractions ou multiplications) en même temps, sur de s donnée s
différentes.
Cortex-M, n’est pas un simple ‘Processor core’, mais plutôt un processeur. En effet, en plus du
noyau (UAL + UC), il intègre un certain ensem ble de com posants « Figure -7 »: un contr ôleur
d’interruptions, un Tim er Système, un système de débogage, une unité de protection ainsi qu’un
bus d’interconnexion en matrice permettant l’accès simultané à plusieurs zones mémoires ( puisque
Cortex-M à une architecture Harvard).
L’unanimité des constructeurs pour les processeurs cortex-M est due principalement aux raisons
suivantes :
portabilité: Tous les microcontrôleurs basés sur le Cortex-M ont, en plus d’ une compatibilité au
niveau des jeux d ’instructions, le même contrôleur d’interruptions et le même Timer pour les OS
temps réel (Sy sTick). Par conséquent, un pr ogramme développé pour un microcontrôleu r d u
fabriquant A peut être p orté sur un au tre du fabriq uant B, surto ut que ARM fournit les mêmes
drivers pour les périphériques intégrés au Cortex-M.
Coût : En effet, le critère primordial qui incitait les développeurs de systèmes embarqués à opter
pour les MCUs 8 bits était le prix. Avec les Cortex-M, les prix des MCUs 32 bits a
considérablement baissé et sont pratiquement dans le même ordre que les MCUs 8 bits.
Efficacité én ergétique : Les MCUs, co mme tous les processeurs embarqués et à usage général,
sont connus pour être flexibles au prix d’une c onsommation élevée en énergie de l’or dre de 1 à 3
MIPS/mW. Avec Cortex-M3, o n atteint une efficacité de 12, 5 MIPS/mW « figure- 8 ». En plus, il
supporte des modes basse consommation ainsi qu’une activation sélective des périphériques.
Flexibilité
Consommation
Adaptation au temps rèel: Ceci est assuré par l’intégration d’un contrôleur d’interruptions gérant
les priorités et le sauvegarde du contexte matériellement ce q ui perm et d’avoir une ré ponse
déterministe et rapide aux événements externes. En plus, le Cortex-M intègre dans son jeu
d’instructions, quelques unes qui s’exécutent d’une manière atomique.
Débogage p uissant: Grâce à un m odule de débogage intégré aux pr ocesseurs Cortex-M et qui
permet de fixer un certain nombre de Breakpoints et watchpoints.
Chapitre 1 :
Présentation du Cortex-M3
1- Introduction
Le noy au du Cortex-M3 est un proces seur RISC (Reduced Instruction Set Architecture) 3 2
bits : Il contient un chemin de données (data path : registres + largeur des bus données et code) 32 bits.
Il se ba se sur un pipeline à 3 étage s (Fetch, Decode et Execute) et possède un e architecture Harvard,
c'est-à-dire qu’il contient deux bus distincts : Data Bus pour le transfert des données et Code Bus pour
les instructions « Figure -1 ». Ceci per met d’accéder en mêm e temps aux i nstructions et aux données,
et par conséq uent une augmentation de la pe rformance puisque l’ accès aux données n’ affecte pas le
pipeline.
Cortex-M3 Processor
Noyau CM3
(Cortex-M3 Core)
et logique (ALU) +
Unité Arithmétique
Unité de recherche
d’instructions
(Fetch unit)
d’interruptions
Système de
décodage
Registres
débogage
Unité de
Contrôleur
(NVIC)
Interface Mémoires
Le nom bre de lignes d’adress es est également de 32 ce qui permet l’ accès à un espace
d’adressage unique de 4 GO (232 octets).
Une application embarquée déployée sur un microcontrôleur ( ou tout système embarquée) est
constituée d’un ensemble de bouts de codes. Ces bouts de codes peuvent être :
- Exécutés suit e au décl enchement d’ une interrup tion (événe ment). Dans c e cas, on parle de
gestionnaire d’interruption (Interrupt Handler) ou de Routine d’interruption ( ISR : Interrupt Service
Routine). Dans le reste du document on utilisera les termes Handler et ISR.
- Exécutés en fonction de l’évolution de l’état du système (code de démarrage dans main( ), tâches
utilisateur en arrière plan, etc..).
Ainsi, et en fonction du t ype de co de exécuté, le Cortex-M3 se trouve dans l ’un de deux
modes :
Mode « Handler » : Quand le processeur exécute des Handlers d’interruptions.
Mode « Thread »: quand le processeur exécute des programmes , autres que les Handlers
(programme principal, tâches utilisateur).
Après le démarrage, le Cortex-M3 exécute main ( ) et est par défaut en mode Thread. Le
passage en mode Handl er s e fait a utomatiquement quand un Handler e st exécuté s uite au
Mode
Handelr
Mode
Thread
Le Cortex-M3 peut attrib uer aux appli cations, en f onction de l ’état du bit 1 du registre de
contrôle (control [1]), deux niveaux de privilège:
Niveau « Privileged » si control [ 1] = 0: le programme peut utiliser toutes les instructions et
peut accéder à toutes les ressources du processeur.
Ces niveaux de privilège offrent plus de sécu rité et de robustesse. En eff et, quand un
programme « UnPrivileged » se trom pe, il sera dans l’im possibilité de m odifier les registres et les
zones mémoire protégés. Ceci est utilisé par les OS em barqués pour protéger les données OS des
applications utilisateur, et éviter une corruption des données ou même un crash du système.
Quand le Cortex-M3 est en mode Handler , les codes exécutés ont to ujours le nive au
« privileged », indépendamment de la valeur du bit du registre de contrôle.
Quand le Cortex-M3 est en mode Thread , les c odes exécuté s peuvent avoir le niveau
« privileged » ou « unprivileged », en fonction de la valeur du bit 1 du registre de contrôle.
Le tableau suivant récapitule les combinaison « mode cortex /niveau de privilège » possibles.
Pour les transitions entre ces combinaisons, ils doivent respecter les règles suivantes :
1. Au démarrage du système (après reset), le bit control[1] = 0 et par conséquent toutes les parties de
code ont le ni veau « Privileged » par défaut. Ainsi, o n est dans mode Thread/ Niveau privileged.
(puisque Le Cortex-M3 est en mode Thread après reset).
2. A la suite d’une interruption, le Cortex-M3 passe directement à mode Handler/ Niveau privileged.
A la fin du Handler, il retourne au mode Thread avec le niveau de privilège initial (avant Handler).
Remarque : sauf si le Handler modifie l’état du bit control[1]. Voir règle 4)
3. Un programme ayant le niveau « Unprivileged » n’a pas le droit d’accéder au registre de contrôle
et ne peut en aucun cas changer le niveau de privilège.
4. Un programme ay ant le niveau « Privileged » peut changer le niveau de p rivilège des codes
exécutés en mode Thread, en modifiant l’état du bit control[1].
La figure suivante donne les transitions possibles, tout en respectant les règles citées.
Contrôle [1] = 0
2
Retour d’Int 2 Interruption
Interruption
Retour d’Int 1
Contrôle [1] = 1 4
UnPrivileged /
Thread Mode Privileged /
Thread Mode
Non autorisé 3
3- Registres
- R0 – R12 : 12 registres 32 bits à usage général qui peuvent être utilisés pour l’ exécution de
n’importe quelle opération (arithmétiques, logiques, transfert).
1
- R13 : il s ’agit du registre pointeur de pile (Stack Register ). En effet, étant donné que le
Cortex-M3 utilise deux piles (Pile principale et Pile process), il s’agit de deux registres matériellement
distincts, mais superposés :
MSP (Main Stack Pointer) : ce registre MSP est utilisé pour pointer sur la pile principale.
PSP (Process Stack Pionter), ce registre PSP est utilisé pour pointer sur la pile pile de process.
Par défaut, la pile principale est utilisée et par cons équent le pointeur MSP. Pour le choix de la pi le
PSP, il faut passer par registre de contrôle (ci-dessous).
- R14 : il s ’agit du registre de lien ( LR : Link Register) qui permet de stocker l’ adresse de
retour (à placer dans PC) quand une fonction ou un Handler est appelé.
- R15: il s ’agit du registre com pteur programme ( PC : Program Counter) qui indique l’ adresse
de l’instruction à exécuter par le processeur.
Address Instruction
2 Main ( )
3
1 0x00002000 ….
7
0x00002004 ….
0x00002008 call func1( )….
0x0000200C ….
4 ………
5 func1 ( ) {
0x0000F014 ……..
6
0x0000F018 …….
0x0000F01C }
1
Une Pile (stack) est une mé moire LIFO (Last In First out) o ccupant une partie d e la RAM et u tilisée po ur
passage de paramètres entre fonctions ou pour sauvegarder temporairement les contenus des registres de l’UAL.
Alors, les contenus des registres LR (R14) et PC (R15) évoluent comme suit « Tableau -2 »:
PC (R15) LR (R14)
1) On commence par exécuter main ( ). PC contient l’adresse
0x00002000 -
0x00002000
2) Après l’exécution d’une instruction, PC est automatiquement
incrémenté de 4 (correspondant à 4 octets = 32 bits = la taille d’une 0x00002004 -
instruction)
3) Même chose que l’étape précédente. 0x00002008 -
4) L’exécution de l’instruction à l’adresse à 0x00002008 provoque un
saut
PC va pointer sur la destination du saut (0x0000F014) 0x0000F014 0x0000200C
LR va sauvegarder l’adresse que devrait contenir PC après le retour
de func1 (0x0000200C)
5) Le processeur continue l’exécution de func1. LR reste intact. 0x0000F018 0x0000200C
6) La dernière instruction d’une fonction est une instruction de retour 0x0000F01C 0x0000200C
7) Après l ’instruction de retour, le co ntenu de LR est récupéré dans
PC. Le processeur continue l’ exécution de main ( ) a u point ou il a été 0x0000200C -
interrompu.
PSRs (Program Status Registers) : Registre de statut du programme qui contient au nombre de 3
- ASPR (Application PSR): Registre d’état relatif à l’exécution du programme.
- ISPR (Interrupt PSR) : Registre d’état relatif à l’interruption en cours.
- ESPR (Execution PSR) : Registre d’état qui do nne des informations sur l’instruc tion en cours
(mode thumb ou ARM et si elle est atomique).
Ces 3 registres 32 bits peuvent être acc édés séparément ou bien être combinés pour construire
un registre unique 32 bits : xPSR « Figure -4 »
Champ Description
N Negative : un 1 indique que le résultat de la dernière instruction est négatif
Z Zero : un 1 indique que le résultat de la dernière instruction est nul.
C Carry : un 1 indique que le résultat de la dernière instruction a généré une retenue (carry)
V Overflow : un 1 indique que le résultat de la dernière instruction a dépassé la taille prévue.
ICI/IT Interrupt-Continuable Instruction : l’instruction en cours ne peut être interrompu.
T Toujours à 1 : exécution des instructions en mode Thumb
Exception
Indique le numéro de l’interruption que le processeur est entrain de servir.
number
Registre de contrôle : Un registre de 2 bits ; le bit 1 i ndique le ni veau de privilège des codes
exécutés en m ode thread (Parag. 2); le bit 0 indique le pointeur à utiliser (MSP or PSP) et par
conséquent la pile.
* Au démarrage et après reset, le poniteur MSP (main stack) est utilisé par défaut.
4- Gestion de la pile
Le Cortex-M 3 peut utiliser deux piles : pile principale ( Main Stack) pointée par le registre
MSP et pile process ( Process Stack) pointée par le registre PSP « Figure - 5 ». L ’objectif de
l’utilisation de deux piles distinctes est la protection des données critiques « e.g. celles gérées par un
OS » des accès par des applications utilisateur (parag ).
Mais, au démarrage et après un reset, uniquement la pile Main Stack est utilisée.
Adresses
+
(par défaut) MSP
Main Stack
PSP
Process Stack
Mémoire
Application
(code + data)
-
La taille des données à mettre dans ou à récupérer à partir des piles du Cortex-M3 doit être
obligatoirement de 32 bits (taille datapath). Ainsi, chaque donnée occupe 4 octets et par conséquent 4
adresses.
Pour les deux piles la gestion de la pile est ‘full descending’ :
- A l’initialisation le pointeur de pile pointe sur le haut de la pile (Adresse supérieure +4).
- Pour chaque opération PUSH (empilement) qui co nsiste à sauvega rder une do nnée dans la pile :
le pointeur e st d’abor d in crémenté de 4, ensuite la donnée est écrite dans l’em placement mém oire
pointée par le pointeur.
- Pour chaque opération POP (dépilement) qui consiste à récupére r une donnée à partir de la p ile :
la donnée pointée par le pointeur est lue, ensuite le pointeur est incrémenté.
L’exemple suivant montre l’évolution d’une p ile (l’adresse du haut de pile est 0x00002100) :
la fonction main ( ) passe à la fonction sum( ) le s contenus des registr es R0 et R1 par la pile. La
fonction sum récupère l es 2 données à partir de l a pile, calcule la so mme et sauvegarde le résultat
dans la pile. Au retour à main, le résultat est récupéré à partir de la pile.
Main ( ) 0
….
Pile
R0 10 Adresse R0 = 10
Sum { SP 0x00002104 -
0 R1 8 R1 = 8
3 POP R2 0x00002100 -
1 Push R0
0x000020FC -
2 Push R1 4 POP R3 R2 = -
0x000021F8 -
Call sum ( ) R3 R2+R3 0x000021F4 - R3 = -
6 POP R0 5 PUSH R3 0x000021F0 -
…. }
1 2
Pile Pile
Adresse R0 = 10 Adresse R0 = 10
0x00002104 - 0x00002104 -
SP 0x00002100 10
R1 = 8
0x00002100 10
R1 = 8
0x000020FC -
SP 0x000020FC 8
R2 = - R2 = -
0x000021F8 - 0x000021F8 -
0x000021F4 - R3 = - 0x000021F4 - R3 = -
3 4
Pile Pile
Adresse R0 = 10 Adresse R0 = 10
0x00002104 -
SP 0x00002104 -
SP 0x00002100 10
R1 = 8
0x00002100 10
R1 = 8
0x000020FC 8 R2 = 8 0x000020FC - R2 = 8
0x000021F8 - 0x000021F8 -
0x000021F4 - R3 = - 0x000021F4 - R3 = 10
5 6
Pile Pile
Adresse R0 = 10 Adresse R0 = 18
0x00002104 -
SP 0x00002104 -
SP 0x00002100 18
R1 = 8
0x00002100 18
R1 = 8
0x000020FC - R2 = 8 0x000020FC - R2 = 8
0x000021F8 - 0x000021F8 -
0x000021F4 - R3 = 18 0x000021F4 - R3 = 10
3) Pop R2 : le contenu de la pile p ointé par SP est tr ansféré vers R2. Ensuite, SP est
incrémenté de 4 (0x00002100).
4) Push R3 : le contenu de la pile pointé par SP est transféré vers R3. Ensuite, SP est
incrémenté de 4 (0x00002104).
5) Push R3 : le pointeur SP est décrémenté de 4 (0 x00002100), le contenu de R3 (18=8+10)
est écrit dans l’adresse pointée par SP.
6) Pop R0 : le contenu de la pile p ointé par SP est tr ansféré vers R0. Ensuite, SP est
incrémenté de 4 (0x00002104).
5- Organisation de la mémoire
Le noyau Cortex-M3 ay ant une architecture Harvard, il possède deux Bus : un bus code pour
récupérer les instructions et un bus data pour récupérer les données.
Les bus possèdent chacu n 32 lignes d’ adresses, par conséquent le noy au Cortex-M3 est
capable d’accéder à un espace d’adressage total de 2 32 octets = 4 GO.
Les 32 lignes d’adresses (ainsi que les registres) permettent d’accéder à une mémoire avec des
mots (taille d’une case de la mémoire) de 32 bits, soit 4 octets.
Puisque l’unité d’adressage est toujours l’octet, chaque mot de la mémoire (32 bits = 4 Octets)
occupe 4 adresse s: le 1 er mot de la mémoire ( mot 0) occupe l’ adresses 0, le 2 ème mot (mot1) occupe
l’adresse 4, etc… « Figure- 7 a) ».
Même si physiquement l’accès à une mémoire ne se faut que par mot (32 bits dans ce ca s), on
peut identifier chaque octet (Parag. 6.1). Dans ce cas, le plan d’adressage est le suivant « figure -7 b) ».
Adresses
Bit :31 …….. 0 31………24 23 …… 16 15 ………8 7 ………..0
0xFFFFFFFC 0xFFFFFFFF 0xFFFFFFFE 0xFFFFFFFD 0xFFFFFFFC
…….
… ………
…. ……..
mot 2 0x00000008
mot 1 0x00000004 0x00000007 0 x00000006 0x00000005 0x00000004
mot 0 0x00000000 0x00000003 0 x00000002 0x00000001 0x00000000
a) b)
Figure -7 : Plan d’adressage d’une mémoire de 4 GO a) par mot de 32 bits - b) par octet
Microcontroller
RAM(EX)
1 GO
6000 0000
Peripheral
MUX
0,5 GO
System Bus 4000 0000
RAM (EX)
0,5 GO
2000 0000
MUX
Code zone
D-code Bus ROM/RAM
(EX) 0,5 GO
0000 0000
MUX
SWD/JTAG
(Debug) I-code Bus
(EX) : peut contenir du code
Bus Matrix exécutable (des instructions)
(with
Bitbanding,
Alignement) Interface pour le charg ement
des programmes
Les bus I-code et D-code sont respectivement la continuité des bus Code et Data du noyau.
Ces bus ne peuvent accéder qu’à la zone inférieure (0x00000000 à 0x20000000 = 0,5 GO) qui
est destinée à contenir du code exécut able du programme ainsi que les données (vari ables
déclarées du programme). Générale ment, les c onstructeurs placent une m émoire Flash dans
cette zone.
2
Le bus DATA peut accéder à la totalité des zones mémoire.
System bus peut véhiculer, selon les bits de sélection, le bus Code ou Data.
Ce bus peut accéder pratiquem ent à la totalité de la zone m émoire supérieure ( 0x20000000
à 0xFFFFFFFF ~= 3,5 GO) qui est subdivisée en plusieurs espaces :
- Mémoire RAM interne.
- Zone des périphériques ajoutés par le constructeur du microcontrôleur (convertisseur
A/N, Timer, port Ethernet, etc..).
- Mémoire RAM externe (à connecter au microcontrôleur).
- Zone de périphériques externes qui peuvent être connectés au microcontrôleur.
- Enfin, une zone dédiée au constructeur pour placer son propre Firmware.
Il faut noter, que toutes ces zones peuvent être accédées pour lire ou écrire des données (Data
bus). Mais, u niquement les zones mémoires RAM peuvent conte nir du co de exécutable ( car les seules
accédées par le bus Code. Mais la vitesse de transfert des instructions est infère ure à la zone code).
Internal Peripheral Bus : c’est un bus interne au process eur Cortex-M3 et permet au noy au
d’accéder aux registres des périphériques internes (NVIC, Systick, Debug, etc..). Ces registres
occupent une zone de 1 MO (0xE0000000 à 0xE0100000).
En plus du multiplexage des bus, le Bus Matrix intègre également d’autres fonctionnal ités :
Data Alignement, Bit Banding, etc..
Etant donné que l’ accès à une mém oire ne se fa it que par mot (32 bits) correspondant à une
case mémoire, les données stockées devr aient être a lignées, c.a.d qu’ une donnée doit être placée dans
une case mémoire 32 bits quelque soit sa taille. La F igure suivante montre un exemple d’accès aligné
aux données dans une mémoire 32 bits.
On voit bien, qu’une grande partie de la mémoire est perdu. Ce gaspillage n’e st pas perm is
dans des systèmes embarqués ou la taille disponible de la mémoire est limitée.
C’est pourquoi, le Cortex-M3 est équipé d’un Bus matrix qui est capable de gé rer l’accès aux
données de manière non alignées « Figure -10 ».
Figure -10 : Accès non alignée aux données dans une mémoire 32 bits
On voit bien que les données sont mises l’une après l’autre sans se préoccuper de les placer au
début d’ une case mémoire. On peut mê me divi ser une donnée (uint32_t a) sur 2 cases mémoires
différentes. Ceci est également vrai pour les instructions qui peuvent être de 16 ou 32 bits (Parag 8).
L’accès est transparent pour le programmeur (ainsi qu’au noyau CM3), c’est le Bus Matrix qui
s’occupe de lire la case (ou les cases) et d’extraire la donnée (ou l’instruction) demandée.
Il s’agit d’une technique permettant de lire l’état d’un bit ou de modifier sa valeur en une seule
instruction.
En effet, la façon conventionnelle pour modifier la valeur d’un bit i d’une variable ou une case
mémoire x passe en 3 instructions. L’exemple suivant montre comment mettre à 1 un bit i :
I
x .. … … bi .. b 2 b1 b0 1- Lire x :
1
x Reg
Reg .. .. bi .. .. b 1 b0
x .. … … 1 .. b2 b1 b0 3- Ecriture dans x :
Reg x
Ces lecture et modifications de bits sont fré quentes dans les sy stèmes e mbarqués et surtout
temps réel ; ou les états des tâches et des sémaphores sont représentés par des bits.
Avec cette fa çon, un problè me peut se poser : entre la prem ière instruction et la deuxième ou
bien entre les instructions 2 et 3, un Handler ou une tâche pourrait être lancé e t changer l’ état de la
variable x. Ceci peut causer la corruption des données et un dysfonctionnement du système.
Pour palier à ce problème et exécuter ces instructions d’un façon atomique (sans interruption),
l’idée était soit d’ utiliser un sémaphore pour pr otéger la partie du code ou bi en la désacti vation des
interruptions avant l’exécution des instructions. Dans le deux cas, la solution es t pénalisante en ter me
de performances du système.
Le Cortex-M3 pro pose deux zones de 1MO pouvant être accédées directement bit par bi t :
ces zones sont appelées Bit-Band Region.
L’accès à un bit ne se fait pas directement, mais se fait par accès à une case mémoire ‘alias’ de
32 bits : L’écriture d’une valeur (0 ou 1) dans cette case mémoire provoque directement l’écriture de
la même valeur dans le bit correspondant.
L’ensemble des cases mémoires ‘alias’ correspondants aux bits d ’une zone Bit-Band Region
est appelé zone Bit-Band Alias. On trouve ainsi deux zones Alias de 32 MO chacune (1MO*32).
Les deux zones Bit-Band Region et Bit-Band A lias du Cortex-M 3 sont dispo nibles dans les
zones RAM et Peripheral « Figure 12 ».
0x43FF FFFF
Alias
Peripheral (32 MO)
0,5 GO 0x4200 0000
0x23FF FFFF
0x400F FFFF
Alias Bit-Band Region
RAM
(32 MO) (1 MO) 0x4000 0000
0,5 GO
0x2200 0000
0x200F FFFF
Bit-Band Region
(1 MO)
0x2000 0000
Figure -12 : adresses de bases et taille des zones Bit-Band & Alias
Figure -13 : Correspondance entre bits de la Bit-Band Region et mots de la zone Alias
Pour avoir l ’adresse absolue du m ot, il suffit d’additionner l’adresse de base de la zone Alias
Alias_Base : Alias_Adress = Alias_Base + Bit_Band_Offset*32 + i*4
RAM Peripheral
Bit-Band Base Address 0x2000 0000 0x4000 0000
Alias Base Address 0x2200 0000 0x4200 0000
Exemple : Quelle est l’adresse absolue du mot de la zone Alias doit être utilisé pour m odifier
le bit 15 de la case mémoire 0x40000300
L’adresse 0x4000 0300 correspond à une région Bit-Band de l’espace Peripheral. On a donc:
Une fois un programme compilé et chargé dans la mémoire d’un système à base du CortexM3,
la mémoire aura la structure suivante « Figure -14 »:
Le premier mot placé à l’offset 0 est occupé par l’ adresse de la pile (Main Stack). Le reste des
premiers 1024 octets sont occupés par les adresses des ISRs : Table des vecteurs d’interruptions.
L’espace suivant la table des v ecteurs d’interruptions est utili sés par les code des ISRs : le
code de l’ISR1 (déclenché par un reset) est placé directement à l’adresse 1024.
Ensuite vient le(s) programme(s) tournant en arrière plan tel que le Main.
Enfin, est pla cée la mémoire pile (Main Stack ). Contrairement aux codes, l’ adresse de début
d’une pile correspond à son adresse supérieure. La taille de la pile étant fixé par le programmeur avant
la compilation
Etant donné que lors de la co mpilation, les taill es des codes et de la pile so nt connues, le
compilateur va initialiser le m ot 0 avec l’adresse de la pile @MStack et l a table avec l es adr esses
correspondantes des ISRs
Memory
Ctrl Adress Offsetc
Reset
@MStack
Adr. Main Stack
Processor
Data
Main
ISR i
@_Main
…
saut
ISR2
ISR 1 = Boot code
(Reset_Handler) 1024 0x0000 0100
@_ISR 255
1020 0x0000 00FF
Table des …….
Vecteurs @_ISRi
d’interruptions 4i
(255 vecteurs) …………….
……………
8 (0x00000008)
Int 1 = Reset @_ISR1 = 0x00000100
4 (0x00000004)
MSP = @MStack
Address base 0 (0x00000000)
8- Instructions Cortex-M3
L’architecture d’un jeu d’instructions ( ISA : Instruction Set Architecture) d’un processeu r
définit la taille (ou les tailles) des i nstructions ainsi que les formats possibles (la di vision de
l’instruction en cha mps) et les valeur s binaires que peut prendre chaque chaque cha mp et leurs
signification.
La figure suivante est un exe mple d’une inst ruction ARM de 16 bits (Ins truction 1 6 b its
Thumb). Qui permet d’eff ectuer une addition du contenu du registre R1 et d ’un une valeur immédiate
sur 8 bits :
Même si ce format présente un avantage quant à la taille, il ne permet d’utiliser que 8 registres
du processeur, et uniquement deux opérandes : puisque le regi stre R1 joue le rôle de source et
destination.
Pour contourner ces limites, des instructions 32 bits ont été introduites. L’instruction
ADD R8, R3, # 200 (R8 R3 + 200)
permet d’utiliser tous les registres, deux registres différents comme source et destination et enfin une
valeur immédiate sur 12 bits. Le format de l’instruction est comme suit :
ADD
L’uti lisation du champ COND per met d’ exécuter la co mparaison et l’ opération en un seul
cycle, contrairement aux autres processeurs (tel que X86) qui utilisent des instructions différentes pour
les comparaisons et les opérations.
Il faut noter q ue le processeur est informé du résultat de l’opération précédente par l e biais du
registre d’état xPSR (Parag. 3 – Tableau -3).
- S (Set Flag Status) : C’est un bit qui indique si l’instruction doit mettre à jour ou non le registre
d’états. Au niveau de la syntaxe, il faut ajouter un S à l’instruction :
ADDS : Le processeur effectue une addition et ensuite met à jour le registre d’ état. Pour les
modifications faites après une opération (voir parag 8.2)
ADD : Le processeur effectue une addition sans modifier le contenu du registre d’état. Po
Le fait d’util iser des instructions 16 et 32 bits conjointement n’est pas nouv eau pour les
processeurs ARM. Mais, pour les anciennes architectures (v4, v5) il était indispensable de basculer
d’un m ode 16 bits à un mode 32 bits et vice versa par soft (u ne instructio n de comm utation). Ceci
cause une baisse des performances du processeur.
Pour l’ architecture v7 (Cortex), les instructions ARM 32 bits ont été délaissé es, et de
nouvelles instructions Thumb 32 bits ont été introduites. Ces instructions ont été choisies de telle sorte
que le processeur, en analy sant les 16 prem iers bits, reconnaisse auto matiquement s’il s’agit d’une
instruction 16 bits ou 32 bits. Ainsi, le processeur n’est plus obligé de basculer d’un mode à l’autre.
L’ensemble des instructions 16 bits T humb et 32 bits Thum b forment : le jeu d’instructi on
Thumb-2. Cortex-M n’utilise qu’une partie des instructions Thumb 32 bits.
D’après AR M, Le jeu d’ instructions Thumb-2 perm et d’optimiser l’utilisation de l’espace
mémoire san s dégrader le s perfor mances puisqu’on n’ est plus obligé de basculer entre modes de
fonctionnement « figure 17». Des benchmarks réalisés donnent une performance de 1,2 DMIPS/MHz,
c'est-à-dire le Cortex-M3 e xécute, en moy enne, une instruction en moins d’un cycle horloge (1/1,2 =
0,833 cycle) .
C’est le compilateur qui doit ensuite décider : si l’instruction peut être codée sur 16 bits, alors
il va choisir un format 16 bits, sinon il va devoir utiliser un format 32 bits.
Mais, il est possible d’i mposer au com pilateur d e choisir un format préci s en utilisant les
suffixes W (Wide : 32 bits) et N (Narrow : 16 bits). Dans ce cas, le com pilateur va essay er de coder
l’instruction au for mat choisi. En cas d’impossibilité, il génère u ne erreur. C es suffixes sont utilisés
comme suit :
ADD .W (coder l’addition sur 32 bits)
ADD .N (coder l’addition sur 16 bits)
Le processeur Cortex ayant une architecture RISC, toutes les opérations de traitements portent
sur des registres ou des valeurs i mmédiates. Uniquement les opérations de transfert peuvent accéd er à
la mémoire.
On présentera quelques instructions des différents types de traitements.
Instructions de transfert
Instruction Description
MOV Rd, #valeur Rd valeur
MOV Rd, Rn Rd Rn
LDRB Rd, [Rn, #offset] Lire un byte de la case mémoire d’adresse Rn+offset
LDRH Rd, [Rn, #offset] Lire 16 bits (Half Word) de la case mémoire d’adresse Rn+offset
LDR Rd, [Rn, #offset] Lire un mode de 32 bits de la case mémoire d’adresse Rn+offset
STRB Rd, [Rn, #offset] Ecrire le byte poids faible de Rd dans la case mémoire d’adresse Rn+offset
STRH Rd, [Rn, #offset] Ecrire 16 bits poids faible de Rd dans la case mémoire d’adresse Rn+offset
STR Rd, [Rn, #offset] Ecrire le contenu de Rd dans la case mémoire d’adresse Rn+offset
Push Rs Transférer le contenu de Rs vers la case mémoire de la pile (@R13 -4)
Pop Rd Transférer le contenu de la case mémoire de la pile (@R13) vers Rd.
Instructions arithmétiques
SMULL Même que UMULL , mais pour une multiplication signée (S : signed).
Instructions logiques
Une grande partie des opér ations (instructions présentées) peuvent être exécutées d’une façon
conditionnelle. Dans ce cas, la syntaxe de l’instruction devient :
L’opération n’est exécutée que si la condition COND est vérifiée. La condition COND est
relative au résultat de l’instruction précédente qui est souvent (mais pas toujours) une comparaison :
et elle est mémorisée dans un ou plusieurs bits du registre d’état « Figure -18 ».
N Z C V
Ces bits sont mis à jour après l’exécution de chaque instruction en fonction du résultat obtenu.
Le tableau suivant donne quelques exemples d’instructions et leurs effets sur les bits du registre d’état.
* l es i nstructions 32 bits Thum b-2 ne m ettent pas à jo ur aut omatiquement l es bi ts du re gistre d ’état. Il faut
obligatoirement ajouter le suffixe S (State) , sinon les bits ne seront pas mis à jour.
En ce qui concerne les conditions COND, 16 sont dispo nibles. On présente ci-dessous
quelques unes.
L’exemple suivant m ontre l’utilisa tion des instructions conditionnell es. Le code ‘C’équivalent est
donné.
Code ‘C’ Code Assembleur
If (x = = 0) cmp R0, #0
{
x = y+1 ; ADDEQ R0, R1, #1
}
else
{ ADDNE R1, R0, #1
y = x +1 ;
}
// En supposant que R0 contient x et R1 y
Instructions de saut
Ces instructions permettent de faire un saut ve rs une adresse, ou bien vers une fonction. Le
saut peut être inconditionnel (Tableau -11).
Instruction Description
B Branch : faire un saut vers une adresse (un Label ou étiquette dans un programme)
Branch with Link : faire un saut et sauvegarder l’adresse de retour dans le registre LR (R14).
BL
Cette instruction est utilisée pour faire appel à une fonction
Ou bien conditionnel, c.a.d que le saut ne sera effectué que si la condition spécifiée est remplie.
Instruction Description
B [COND] Branch si COND vraie. COND peut être l’une des expressions du « Tableau -10 »
Thumb-2 offre également une instruction qui combine le saut et la co mparaison pour gagner
en nombre d’instructions et en vitesse d’exécution « Tableau -13 ».
Instruction Description
CBZ Compare & Branch if Zero : faire une comparaison et faire un saut si égale à 0
CBNZ Compare & Branch if Not Zero : faire une comparaison et faire un saut si différent de 0.
Ainsi l’appel à la fonction func1 est exécuté 10 fois. Au niveau d’un programme assem bleur,
on ne peut utiliser les adr esses pour faire des sauts (on ne les connaît pas), mais plutôt des label s
(étiquettes). C’est ensuite au compilateur et à l’éditeur de lien de les remplacer par les adresses.
Chapitre 2
Entrées Sorties GPIO du STM32 :
Présentation & Programmation par accès aux registres
Par Damergi Emir
1. Introduction
AFIO Enable
(Pin Remapping if Enabled)
Chaque port GPIO possèd e son propre signal d’horl oge et contient des registres de contrôle
qui déterminent le mode de fonction nement des pins ( Parag. 2) ainsi que des r egistres permettant de
lire l’état binaire des pins en entrée et d’imposer l’état des pins en sortie.
Ces pins sont égale ment reliés aux différe nts périphériques du microcontrôleur (USART,
Timer, ..) à t ravers l’ AFIO (Auxiliary Function Input Output). L’AFIO permet de multiplexer les
connexions entre pins et périphériques. Il offre ainsi une flexibilité au niveau du choix du pin à utiliser
pour véhiculer un signal donné. Quand l’AFIO est désac tivé, les connexions par défaut entre pins et
périphériques sont établies. Une fois l’AFIO activé, il est possible de remapper (m ultiplexer) les pins
(voir Chapitre AFIO).
Figure -2- Structure d’un Port GPIO (Une seule cellule est représentée parmi les 16)
Les IO du STM32 sont de type Five Volt Tolerant (FT), c'est-à-dire qu’ils peuvent supporter
une tension d’entrée de 5V sans dommage ou dysfonctionnement.
Des r egistres occupant des adres ses de la zone BitBanding et pouvant être accédés co mme
mots de 32 bits :
Un registre d’ entrées (Input Data Register : IDR) de 32 bits. Les 16 bits poi ds faible étan t
utilisés pour la lecture des valeurs logiques issues des 16 pins du port.
Un registre de sorties (Output Data Register : ODR) de 32 bits. Les 16 bits poids faible étant
utilisés pour imposer les valeurs logiques au niveau des 16 pins du port.
Un registres de Mise à 1 ( Bit Set Reset Register : BSRR) et un registre de remise à 0 et (Bit
Reset Register : BRR). Par le biais de ces registr es, il est possible de changer l’ état d’un ou
plusieurs bits du registre ODR, et par conséquent les sorties GPI Os, en en un seul cycle : on
parle d’accès atomique [voir paragraphe ].
2 registres de configurati on ( Control Register High /Low : CRH/CRL) perm ettant de
déterminer le sens, le mode de fonctionnement et la fréquence de commutation des GPIOs. A
cette fin, 4 bits sont utilisés pour chaque IO, et donc 64 bits (4*16) pour la totalité des 16 IOs
d’un GPIO. D’où la nécessité d’utiliser 2 registres de 32 bits.
Les différentes configurations possibles en fonction des valeurs des 4 bits sont données dans le
tableau1. A l’initialisation, tous les IO sont configurés en ‘Input Floating’.
Output 01 10 Mhz
00 10 2 Mhz
Sorties à partir du Push-Pull
11 50 Mhz
registre ODR Output 01 10 Mhz
01 10 2 Mhz
Open-Drain
Sorties
11 50 Mhz
Alternate Function 01 10 Mhz
10 10 2 Mhz
Sorties à partir des push-pull
11 50 Mhz
périphériques Alternate Function 01 10 Mhz
(Alternate Functions) 11 10 2 Mhz
open drain
11 50 Mhz
Pour la lecture du conten u des registres d’en trée IDR des ports GPIO, il est possible de lire
l’état d’un bit unique en une seule instruction (1 cycle) en utilisant le mécanisme du Bitbanding.
Pour l’écriture dans les registres de sortie ODR, même si ce s registres font partie de la zone
BitBanding, le microcontrôleur STM32 offre un mécanisme plus performant pour la mise à jour de la
valeur d’un ou plusieurs bits en un seul cy cle. Ceci est assuré par l’utilisation des registres B SRR et
BRR.
Supposons que le registre ODR contient la donnée suivante (0x8F0B)
b31 b16 b15 ……… …… b0
1 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1
Et qu’on veut mettre à 1 les valeurs des bits b14, b13 et b2 qui sont à 0. Dans ce cas, il suffit d’écrire
dans le registre BSRR les bits correspondants ( b 14, b 13 et b 2 ) à 1 in diquant qu’on veut mettre à 1
les bits du registre ODR :
Au départ le registre ODR contient avec la valeur (0x8F0B) et BSRR avec 0x0000 :
b31 b16 b15 ……… …… b2 b1 b0
BSRR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ODR 0x8F0B
ODR 1 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1
ODR 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1
On trouve que les bits correspondants dans ODR ont été également mis à 1, et ceci en u n
cycle (Une instruction) uniquement. Ceci aurait pris 3 cycles (3 bits) avec la technique Bitbanding.
De même, si on veut mettre des bits à 0 (exemple : les bits b0, b1 et b15), c’est le registre de reset
BRR qu’on doit utiliser en mettant à 1 les bits correspondants :
b31 b16 b15 ……… …… b2 b1 b0
BRR 0x8003 BRR 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
ODR 0 1 1 0 1 1 1 1 0 0 0 0 1 1 0 0
Prenons le cas ou on doit faire clignoter deux Leds connectées au pin3 et 4 du port GPIOA
(figure suivante)
Pour les registres ODR, BSRR et BRR, ce sont les bits ayant les positions 3 et 4 dans chaq ue
registre qui agit directement sur PA3 et PA4.
Pour les registres de configuration qui ont la structure présentée ci-dessous, il s’agit des 4 bits
12..15 du registre CRL qui vo nt permettre de config urer le foncti onnement de PA3 et les 4 bits du
suivants du registre CRL 16..19 pour PA4.
Pour l’activation de l’horloge du port GPIOA, c’est le bit 2 du registre RCC_APB2ENR (voir
figure ci-dessous) qui doit être mis à 1.
* : On aurait pu utiliser le registre ODR, mais on a utilisé les registres BSRR et BRR pour m ontrer l’accès atomique à un bit
sans changer les valeurs des autres bits de ODR.
Donc, l’instruction C ne prend que 3 c ycles (3 instructions asse mbleur) et l’ opération d’accès
en écriture des deux bits 8 et 9 (STR r0, [r1, #0x10]) ne prend qu’un cy cle (une instruction). L’accès
se fait donc d’une façon atomique.
Certes, cette approche est optimale au niveau de la taille du code généré, mais il faut connaître
un grand nom bre de détails (adres ses des registre s, leur structure, etc.…); ce qui est pénible et
demande un long temps de développement.
Pour accélérer le développement, ST offre une « Firmware Library » contenant l’ensemble de
drivers permettant un acc ès plus si mple et tr ansparent aux périph ériques du microcontrôleur STM32.
Les paragraphes suivants détailleront l a structure générale de cette librairie ainsi que la façon de
l’utiliser.
Chapitre 3
ST Firmware Library: Présentation &
Application à la programmation des GPIOs
Par Damergi Emir
1. Introduction
Pour facilit er l’uti lisation des fonc tionnalités offertes par les périphériques des
microcontrôleurs STM32 et accélérer le développem ent des applications, ST fournit La librairie
« STM32Yxxx_StdPeriph_Driver 1» permettant un accès tr ansparent à la partie matérielle du circuit
(périphériques, contrôleur d’interruptions, ..).
Cette librairi e est cens ée respecter le standard de programmat ion appelé CMSIS (Cortex
Microcontroller Software Interface Standard). CMSIS a été déf ini par ARM avec un ensemble de
fabricants de circuits intégrés et de développeurs de co mpilateurs visant à faciliter le portage et la
réutilisation des applicati ons écrites en langage ‘C’ pour les microcontrôleurs se basant sur un coeur
Cortex-M. Néanmoins, la portabilité des programmes, écrits en ‘C’, entre les microcontrôleurs à bas e
du Cortex-M est loin d’être assurée.
La librairie F irmware respectant le st andard CMSIS est une colle ction de fichiers source en
langage c (.c) ou en assembleur (.s) et de fichiers entête (.h) qui jouent rôle d’une couche intermédiaire
entre l’application utilisateur et le Hardware. Sa structure est présentée dans la figure suivante.
1
Yxxx indiquant la famille du STM32 (L1xx pour la famille L1, F10xx pour la famille F1, F2xx pour la
famille F2 et F4xx pour la famille F4).
Application
User
OS
(Firmware Library)
Figure 1 -
Comme partie des fonctionnalités CMSIS, ARM fournit la couche logicielle suivante
disponible pour divers compilateurs :
Couche d’a ccès aux périphériqu es noyau (Core Peripheral Functions ) : contient les
définitions, les adres ses et les fonctions d’ accès aux différents registres du CPU e t des
périphériques du no yau (core peripherals) conte nus dans Cortex même : le contrôleur
d’interruptions NVIC, l e timer sy stème Systick, le bus matrix, etc. Ces définitions et fonctions se
trouvent au niveau des fichiers core_M3.c et core_M3.h.
Couche d’accès aux péri phériques hors noyau (Device Peripheral Functions): permettant une
manipulation transparente des périphériques (port parallèle, série, Conversion A/N et N/A, Timer,
etc..).
On trouve ai nsi les fichiers ay ant le f ormat stm 32Yxxx_ppp.c et .h Chaque fichier étant
relatif à l’un des p ériphériques du m icrocontrôleur (ppp étant remplacée par l’ab réviation du
périphérique). La liste suivante pr ésente le s princ ipaux périphé riques de la f amille des
microcontrôleurs STM32
Pour une application n’utilisant pas le mécanisme d’interruptions, les premières parties du
code élémentaires nécessaires et communes à toute application sont :
La définition des variables (structures) relatives aux périphériques.
Activation des signaux d’horloges attaquant les périphériques.
La détermination des valeurs des différentes propriétés des périphériques.
L’initialisation des périphériques avec les valeurs déterminées.
Ces différentes parties faisant généralement partie du fichier main.c. (voir diagramme suivant)
system_stm32f10x.c
/* #include "stm32f10x_can.h" */
/* #include "stm32f10x_crc.h" */
#include "stm32f10x_PPPi.h"
Déclarer les
variables relatives
aux périphériques Main.c
activés
#include "stm32Yxxx.h"
PPP1_InitTypeDef PPP1_InitStructure
………………………………………..
PPPi_InitTypeDef PPPi_InitStructure
Activer le signal
……
d’horloge
……
int main (void)
{
Pour chaque périphérique
Initialiser le
périphérique
PPPi_Init (&PPPi_InitStructure)
Il est à noter que pour l ’activation du si gnal horloge, x (dans APB xPeriph_ppp) peut prendre
les valeurs 1 ou 2 (relativement aux bus APB1 et AP B2) et que l’activation des signaux d ’horloge des
périphériques connectés au même bus peut être faite en une seule ligne :
RCC_APBxPeriphClockCmd (RCC_APBxPeriph_PPP1 |…|…|…| RCC_APBxPeriph_PPPn
,Enable)
On se concentre dans cette partie sur le périphérique GPIO et principalement sur les fonctions
Setbits( ) et Resetbits( ) qui permettent respectivement de mettre à 1 un ens emble de bits passés en
paramètres ou de les remettre à 0.
startup_stm32Yxxx. s stm32Yxxx_conf.h
stm32f10x_gpio.c stm32f10x_rcc.c
+. h +. h
System_stm32Yxxx. c
+. h
stm32f10x.h
On se concentre dans ce q ui suit sur le Firmware développé p our la fam ille F1. Même si les
autres versions (L1, F2 et F4) présentent quelques différences, le principe reste le même.
A) Le fichier startup_stm32F10x.s, est un fichier écrit en assem bleur et dévelo ppé par
ARM, per met d’ initialiser les registres du processeu r Cortex après le dém arrage, les zones mém oire
ainsi que les fréquences de fonctionne ment des h orloges internes du m icrocontrôleur. Ce fichier
accède directement au Hardware ou fait appel aux fonctions de system_stm32f10x.
/* #include "stm32f10x_adc.h" */
/* #include "stm32f10x_bkp.h" */
/* #include "stm32f10x_can.h" */
/* #include "stm32f10x_cec.h" */ Il faut décommenter les fichiers e ntête
/*#include "stm32f10x_exti.h"*/ relatifs aux périphériques à inclure dans le projet.
#include "stm32f10x_gpio.h" Dans notre cas, on d oit i nclure
/* #include "stm32f10x_i2c.h" */ stm32f10x_gpio.h.
/* #include "stm32f10x_iwdg.h" */
stm32f10x_rcc.h est relatif au périphérique
/* #include "stm32f10x_pwr.h" */
RCC (Reset & Clo ck C ontrol) qu i doit être
#include "stm32f10x_rcc.h"
/* #include "stm32f10x_rtc.h" */ toujours in clus p uisqu’il p ermet d ’activer les
/* #include "stm32f10x_sdio.h" */ autres périphériques en utilisant des fonctions du
/* #include "stm32f10x_spi.h" */ ficher stm32f10x_rcc.c
/* #include "stm32f10x_tim.h" */
/* #include "stm32f10x_usart.h" */
/* #include "stm32f10x_wwdg.h" */
/*#include "misc.h" */
Description physique des structures des périphériques : les registres dans l’ordre et leurs tailles
typedef struct
{
__IO uint32_t CRL;
La structure d’un GPIO : les registres dans l’ordre et leurs
__IO uint32_t CRH;
tailles. Ainsi
__IO uint32_t IDR;
CRL est un re gistre en écriture et lecture (IO) de
__IO uint32_t ODR;
taille 32 bits et occupant l’adresse de base
__IO uint32_t BSRR;
CRH occ upe l ’adresse de b ase +4 ( 32 bi ts = 4
__IO uint32_t BRR;
__IO uint32_t LCKR; octets). Et ainsi de suite.
}
GPIO_TypeDef;
typedef enum
{ GPIO_Speed_10MHz =0x01,
GPIO_Speed_2MHz = 0x02,
GPIO_Speed_50MHz = 0x03
} GPIOSpeed_TypeDef;
2- Des co llections d e valeurs po uvant être
attribuées aux éléments des structures (typedef enum).
typedef enum Ainsi, GPIOMode_TypeDef énum ère les
{ GPIO_Mode_AIN = 0x0, valeurs p ossibles qu ’on peut at tribuer au x modes de
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28, configuration GPIO_mode.
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
} GPIOMode_TypeDef;
#include "stm32f10x_gpio.h"
………………..
………………. Ces commentaires respec tent un format
standard qui s era ex ploité p ar l a sui te par un
/* @brief Sets the selected data port bits. outil permettant de générer automatiquement un
* @param GPIOx: where x can be (A..G) to select the GPIO.
fichier d’aide relatif aux fonctions du Firmware.
* @param GPIO_Pin: specifies the port bits to be written.
On a :
* can be any combination of GPIO_Pin_x where x can be (0..15).
@brief : une description de la fonction
* @retval None */
@param : Pour chacun des paramètres passés à
la fo nction, une i ndication s ur l es valeurs
possibles à utiliser.
@retval : une description des valeurs de retour.
Finalement, pour développer une application permettant d’allumer deux Leds connectées aux
pins 3 et 4 du GPIOA (exemple du chapitre précédent), le code source sera le suivant :
/* --------Includes -------------------*/
#include "stm32f10x.h"
/*----------------- Declaration of the GPIO structure (for configuration) ---------------*/
GPIO_InitTypeDef GPIO_InitStructure;
int main(void)
{
/*---------- Enable the GPIOA Clock. This function is included in stm32f10x_rcc.c------------ */
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA, ENABLE);
Chapitre 5
Cortex-M3 : Gestion des interruptions
1. Introduction
La gestion des interruptions, pour les processeurs Cortex-M3, est assurée par le contrôleur
d’interruptions NVIC (Nested Vector Interupt Controller). Le NVIC est étroitement couplé au no yau
du processeur et intègre lui-même un Timer système Systick « Figure -1 ».
Le fait d’intégrer le NVIC au noyau CM3 permet, d’une part, d’améliorer les performances du
traitement des interruptions en a ccélérant la co mmunication entre le contrôleur et le noy au. D’ autre
part, les codes développés ainsi que les sy stèmes d’ exploitation temps réel peuvent être facilement
portés entre microcontrôleurs à base d u processeur Cortex-M3, puisque la stru cture des reg istres du
NVIC (et du Systick) ainsi que leurs adresses et la même pour tous.
Cortex-M3
Système de débogage
NMI
Contrôleur
d’interruptions Processor Core
(NVIC)
Périphériques (Registers + UAL +
Decode + Fetch units)
SysTick
Up to 240 Interrupts Interface Mémoires
Up to 14 Exceptions
MPU
Le NVIC peut avoir jusqu’à 255 entrées pour les requêtes d’interruptions:
Une entrée NMI (Non Maskable Interrupt) : Cette interrup tion, contrairement aux autres, ne peut
être maquée par soft. Pour la majorité des µc, cette entrée est reliée au chien de garde (Watchdog).
Jusqu’à 14 e ntrées pour l es exceptions (interruptions synchrone s) générées p ar les co mposants
internes du process eur Cortex-M3 (exem ples : UAL suite à un O verFlow, Bus suite à un a ccès
erroné, Systick, etc..).
Jusqu’à 240 entrées pour des interruptions externes génér ées par les périphériques du
microcontrôleur (série, Ethernet, ADC, etc..).
Chaque interruption est identifiée par numéro i, qui correspond à l’entrée au niveau du NVIC,
et per met par conséquent de déter miner l’ adresse contenant l’ adresse du Han dler dans la table des
vecteurs d’in terruptions : pour les exceptions, ce num éro est figé. Mais, pour les inte rruptions
externes, l’attribution du numéro dépend du constructeur du µc.
A chaque interruption, est associ é un niveau de priorité de -3 à 255 (-3 étant la priorité
maximale). Ce niveau de priorité est configurable, sauf pour les trois premières.
Le tableau suivant donne les paramètres des exceptions ainsi qu’une description de chacune.
Les étapes de déroulem ent d’une interr uption sont communes à tous les systèm es
(processeur + contrôle ur d’interruptions). Quand une requête d’ interruption autorisée est
déclenchée par un périphérique, le contrôleur force l e processeur à la s ervir et les étapes suivantes se
succèdent :
Sauvegarde d’un certain nombre de registres (généralement Program Counter et le registre d’état)
dans la pile, et parallèl ement, il récupè re l’ adresse de la routine relative à l’ interruption (phase
PUSH).
Exécution du Handler associé à l’interruption.
Une fois l’exécution de la routine est term inée, les contenus des regi stres sauvegardés sont
récupérés à partir de la pile (phase POP).
Le Cortex-M3 respecte ces étapes. Mais grâce à son architecture (Harvard), et à celle du NVIC
qui est en plus couplé au noyau, des améliorations sont à noter :
La sauvegarde et la récupération d’un grand nombre de registres pendant les phases PUSH et POP.
Ces opératio ns se font d’une façon com plètement automatique (matéri elle) sans intervention de
l’utilisateur qui n’est plus obligé de gérer les registres au niveau des Handler « Figure -2 ».
La sauvegarde des registre s se fait parallèle ment à la récupération de l’ adresse du Handler
(architecture Harvard). Ce qui écourte considérablement le te mps des phases PUSH et PO P à 12
cycles « Figure -2 ».
Possibilité d’interrompre l’exécution des instructions multi cycles (load et store), ce qui am éliore
le temps de latence.
IRQ i
12 cycles 12 cycles
Quand une interruption i se déclench e alors que le proces seur est entrain de servir un e
interruption j de plus hau te priorité, alors l’i nterruption i est mise en atte nte jusqu’ à ce que le
processeur termine l’exécution du Hanler i.
Les autre s pr ocesseurs (tel que ARM7, x86), effectuent une phase POP à la fin de chaque
Handler, avant de commencer un no uveau cy cle pour l ’interruption j (P USH, Handler, POP)
« Figure :- 3 ».
Niveau de priorité
IRQ j
IRQ i
Instant possible de IRQ i
Tout compte fait, les données r écupérées lors de la p hase POP1 sont les mêmes qui vont êtr e
sauvegardés lors de la phase PUSH 2. Par conséque nt, cette méthode d’enchaînement d’interruptions
cause une perte de temps sans aucun intérêt.
Tail Chainig
Le Cortex-M3 évite cette perte de temps en utilisant une technique qui élimine les deux phases
PUSH et POP inutiles et les re mplace par une phase unique appelé « TC : Tail Chaining » qui ne
dure que 6 c ycles. Durant cette phase, uniquem ent une récupéra tion de l’ adresse du Han dler i est
effectuée. La pile ainsi que les registres étant intouchés « Figure -4 ».
- Niveau de priorité +
IRQ j
IRQ i
Instant possible
de IRQ i
Preemption (Préemption)
Dans la figure 4, la phase Tail Chaining s’eff ectue quand l’interruption se décl enche avant l a
fin du Handler en cours (ISR j).
Et si l’ interruption se déclench e après la fin de l’ exécution de H andler et pendant le c ycle
POP « Figure -5 » ?
Dans ce cas de figure, le Co rtex-M3 prévoit la technique « Preemption » qui arrête
immédiatement le cy cle POP. En fait, étant donn ée que le cy cle POP ne fait que restaurer les
données de l a pile ver s l es r egistres sans les écra ser, alors son arrêt ne cau se aucune perte de
données. Une fois le c ycle POP arrêté, un c ycle TC permet la récupération de l ’adresse du Handler
à exécuter « Figure -5 ».
Cette technique est utilisée indépendamment des niveaux de priorité des deux interruptions.
IRQ j
IRQ i
Instant possible de IRQ i
1 à 12 6
cycles cycles
7 à 18 cycles
Quand une requête d’interr uption se déclenche alors que le proces seur est entrain d’exécuter
un Handler d ’une i nterruption m oins prioritair e, alors le Handler est suspendu pour servir
l’interruption plus priorit aire. Ensuite, le pro cesseur continue l’exécution du Handler suspendu
« Figure -6 ». On parle d’interruptions imbriqués (Nested Interupts).
- Niveau de priorité +
IRQ j
IRQ i
Ce co mportement n’est pas spécifique au Cort ex-M3, on le trouve dans tous les sy stèmes.
Mais les nouveautés introduites au niveau du Cortex-M 3, c ’est dans le cas o u l ’interruption j pl us
prioritaire se déclenche pendant le cycle PUSH déclenché par l’interruption i.
La plupart des processeurs (ARM7, x86) traitent la nouvelle interruption j indépendamment du
moment de son déclenchement et de la même façon décrite dans la figure 6: Le cy cle PUSH en cours
se poursuit jusqu’à sa fin, ensuite un nouveau cycle PUSH est lancé « Figure -7 ».
- Niveau de priorité +
IRQ j
Instant possible de IRQ j
IRQ i
On voit bien que les deux phases PU SH succe ssives ne font que sauvegarder les mêmes
données dans la pile. Un seul cycle PUSH serait suffisant.
Dans ce cas, ou l’interruption prioritaire arrive en retard par rapp ort à la moins prioritaire, l e
Cortex-M3 prévoit la technique « Late Arrival » : Il co mmence l’exécution du Handler de
l’interruption j (prioritaire), directement après la fin d’un cycle PUSH « Figure -8 ».
IRQ j
Instant possible de IRQ j
IRQ i
Chapitre
Cortex-M3 (STM32 – F1) : Structure du NVIC &
Programmation des Interruptions
Par Damergi Emir
1. Introduction
Avant de présenter la stru cture du NVI C, rappelons que le déclenche ment d’une interruption
relative à un périphérique donné, nécessite « Figure -1 »:
- L’autorisation de l’i nterruption au ni veau du NVIC. Pour chacune des e ntrées
d’interruptions, un bit est dédié à cette fonction. C ’est également au niveau du NVIC que le niveau de
priorité est attribué à chaque interruption.
- La programmation du Pé riphérique en auto risant l ’envoi de req uêtes d’interr uptions
IRQ à la suite d’un éventement dépendant de la fonction assurée par le périphérique (récept ion d’une
donnée pour le port série, conversion d’un échantillon pour le DAC, etc…).
Cortex-M3
NVIC
Peripheral Proc.
Priority Core
IRQ Enable INT Enable
INT condition IRQ
Set
(Event) EVENT FLAG Set INT
clear INT PEND
clear
Dans ce chapitre, on ne présentera que la structure du NVIC ainsi que sa programmation. Pour
les périphériques (DAC, TIMER, etc..), consulter les chapitres correspondants.
ISERx : Interrupt Set Enable Register (32 bits) : chaque bit de ce regist re per met d’ autoriser
l’interruption correspondante quand il est mis à 1.
ICERx : Interrupt Clear Enable Register (32 bits): chaque bit de ce regist re permet d’interdire
l’interruption correspondante quand il est mis à 1.
ISPRx : Interrupt Set Pedning Register (32 bits) : La mise à 1 d’un bit de ce registre active
(déclenche) une interruption (m et l’interruption en état pending). Généralement, ce bit n’ est pas m is
par software, mais par un périphérique « Figure -1 ».
ICPRx : Interrupt Clear Pedning Register (32 bits) : La mise à 1 d’ un bit de ce registre met
l’interruption en état ‘ not pending’. Ce bit est mis automatiquement à 1 par le matériel (lo gique de
contrôle du NVIC) après avoir commencé l’exécution du Handler associé à l’interruption. Mais, il peut
être également accédé par soft.
Quand deux interruptions demandent d’être s ervies, alors le proces seur commence par la plus
prioritaire.
Mais, si une interruption i est entrain d’ être servie et qu’une autre j est dé clenchée, alo rs
l’interruption i en cours n ’est préem pté (suspendue) que si l’i nterruption j a un ni veau d e priorité
‘Preemption Prirority’ supérieur.
Donc, une interruption ne peut préempter (suspendre) une autr e d u même groupe de priorité
« Preemption Priority », même si son niveau de priorité ‘subpriority’ est supérieur.
Il faut préciser que si deux interrupti ons ont les mêmes ‘Preem ption Priority’ et ‘SubPriority’
alors c’est celle ayant le numéro (entrée au niveau du NVIC) le plus élevé qui est prioritaire.
La configurat ion des nive aux de priorité est effectuée à travers les registres I PR (Interrupt
Priority Register). ARM a prévu 8 bits pour chaque interruption et par conséquent jusqu’à 256 niveaux
possibles.
La famille F1 de STM32 n’utilise que 4 bits pe rmettant ainsi jusqu’à 16 ni veaux de priorit é.
L’interprétation de la valeur des 4 bi ts dépend d u cham p PRIGROUP « bits 10..8 de Application
Interrupt and Reset Control Register : AIRCR ».
AIRCR
…. … … 10 : 9 : 8 … … bit
PRIGROUP
Ces bits déterminent le nombre de bits, parmi les 4, utilisés pour la Preemption Priority et pour
la SubPriority. Et par conséquent, le nombre de groupes et de niveaux d’interruptions par groupe.
NVIC_PriorityGroup étant une valeur 32 bits, et peut être l’un des paramètres suivants :
Par défaut, la table des vecteurs d’interruptions est logée à l’adresse 0x00. Cette table contient
les adresses des ISRs (Interrupt Service Routine ou Handler) associées aux interruptions.
Le Cortex-M3, suit le même principe mais les vecteurs d’interruptions commencent à partir de
l’adresse 0x04 (ISR1). L’adresse 0x00 étant utilisée pour sauvegarder la valeur d’initialisation du MSP
(Main Stack pointer) « Figure -2 ».
En plus, il est possible de reloger la table à une autre partie de la mémoire. L’ adresse à
laquelle la table devrait être relog ée, doit être placée dans le registre VTOR (Vector Table Offset
Register) « Figure -2 ».
L’offset des vecteurs d’interruptions (emplacement des adresses des ISRs) res te le même par
rapport à l’ adresse de base VTOR : Ainsi, l’adresse du Handler rel ative à l’ interruption i ( @ISRi) se
trouve à l’adresse VTOR + 4*i « Figure -2 ».
Memory
c
Main Prog
@_Prog
ISR i @_ISRi
…
…
Offset
Adresse
ISR1
Table des Vecteur s @_ISR1
d’interruption
……. …
@_ISRi 4i VTOR + 4*i
……………. ……
…………… …..
8 (0x00000008) VTOR + 8
Base Address = @_ISR1 4 (0x00000004) VTOR + 4
VTOR Register @_MSP 0 (0x00000000) VTOR
typedef struct {
uint8_t NVIC_IRQChannel : Il s’agit d’une valeur sur 8 bits qui identifie le numéro de l’interruption
à configurer. Ces numéros sont figés matériellement. La liste des sources de requêtes d’interruptions ainsi
que leurs numéros pour la famille F1 est donnée à la fin du chapitre « tableau -4 »
uint8_t NVIC_IRQChannelSubPriority : C’est une valeur sur 8 bits indiquant le niveau de priorité
attribué à l’interruption au sein du groupe « voir tableau 3 ».
} NVIC_InitTypeDef ;
La fonction de la FWL permettant de configurer le NVIC avec les param ètres définis au
niveau de la structure NVIC est : NVIC_Init ( & NVIC_InitStruct )
Une fois une interruption se déclenche, le Handler associé est exécuté. L’ adresse du Handler
étant récupérée à partir de la table des vecteurs d’interruptions.
Le Handler lui-même, n’est qu’une fo nction écr ite en C, donc comment est il possible de
déterminer que la fonction X correspond au Handler de l’interruption i.
Pour déterminer la fonction correspondant à un Handler, ARM et ST fournissent un fichier de
démarrage (startup file) dé crit la structure de la ta ble des vecteurs d ’interruptions. Cette table fixe un
nom pour chaque Handler d’interruption «Figure -3».
DCD .........
DCD ......... …….
…
DCD .........
@_ISR i 4i
…. …………….
DCD OTG_FS_IRQHandler …. ……………
@_ISR 2 0x00000008
@_ISR1 0x00000004
__Vectors_End @_MSP 0x00000000 Base Address =
VTOR Register
Ainsi, l’utilisateur n’a que de choisir le nom correct de la fonctio n pour qu’elle soit identifiée
comme étant un Handler, et que son adresse soit st ockée dans l a table des v ecteurs d’ interruptions.
Cette tâche est assurée par les outils de compilation (Keil, IAR, gcc, etc..).
Une liste compète des noms standard des Handler est donnée dans le tableau 4 du parag 5.
Si par exem ple, on veut associer un Handler à l’ interruption relative à la mé moire Flash, le nom du
Handler soit porter le nom FLASH_IRQHandler :
void FLASH_IRQHandler ( )
{ …….. // Code à exécuter
…….. }
Peripheral
NVIC
IRQ Enable
Une fois l’interruption commenc e à être ser vie, le pendin g bit (NVIC) est rem is à 0
automatiquement par Hardware. Mais, le bit d’état reste à 1, ce qui provoque un déclenchement d’une
nouvelle interruption, même si aucun événement ne s’est déclenché (voir chapitre ).
Ainsi, c’est au niveau du Handler que le bit d’état doit être remis à 0. Dans la FWL de ST, des
fonctions permettent de remettre à 0 ces bits. Ces fonctions possèdent la syntaxe :
periph_ClearITPendingBit ( bit d’état )
Même si la fonction p orte le no m ClearITPendingB it ( ), c’ est le bit d’ état (FLAG) qui est
remis à 0 et non pas le pending bit du NVIC.
void ………_IRQHandler ( )
Etant donné que le nombre d’entrées d’interruptions, au niveau du NVIC est li mité (68 pour le
STM32 –F1), plusieurs événem ents d’un périphériqu e peuvent se partager la même interruption. On
parle d’une interruption globale.
Ceci est réalisé en appliquant une opé ration de OU logique aux bits d’états des différents
événements « Figure -5 ». Il suffit que l’un des événements se déclenche pour activer la requête IRQ.
Peripheral
IRQ Enable
INT condition
Set
(Event N) EVENT FLAG N
If ( periph_GetITStatus ( …..FLAG N) )
{ .......
periph_ClearITPendingBit (……)
}
}
Le tableau suivant « tableau - 4 » do nne la liste des valeur s à attribuer aux paramètres
NVIC_IRQChannel ainsi que les n oms des Handlers à utiliser. Ces int erruptions ne sont pas
disponibles pour toutes les références du STM32 –F1.
Chapitre 6
Le Bloc EXTI :
Contrôleur d’Interruptions Externes et d’ Evènements
1. Introduction
Comme déjà cité dans le chapitre précédent, le contr ôleur d ’interruptions NVIC peut traiter
jusqu’à 256 sources d’ interruption. 20 parm i ces s ources d’ interruptions sont les sorties du bloc ou
contrôleur EXTI (EXTernal Interrupt/event Controller): on parle de lignes EXTI.
To Interrupt
Controller
4
(NVIC)
Or EXTI
From AFIO/GPIO
Events 16 (default : GPIOA)
Generation
2. Le contrôleur EXTI
Le contrôleur EXTI perme t de configurer ces lignes de telle sorte à générer, en fonction du
changement de leur niveau logique:
- des demandes d’interruptions au NVIC.
- ou bien des événements : impulsion sur un IO.
Il permet de déterminer quelles lignes doivent être utilisées pour générer des i nterruptions (ou
événements) ainsi que les conditions devant les décl encher. Ce module est toujours actif et il consiste
en un ensemble de registres 20 bi ts (1 bit pour chaque ligne EXTI) et de la logique combinatoire (voir
figure ci-dessous).
Le contrôleur EXTI contient des registres communs au deux modes de fonctionnement (A) :
Rising trigger selection register (EXTI_RTSR) : L’écriture d’un ‘1’ dans un bit i, configure
le « Edge Detect Circuit » pour générer un ‘1’ en cas de détection d’ un front montant sur la
ligne correspondante EXTIi.
Falling trigger selection register (EXTI_FTSR) : L’écriture d’un ‘1’dans un b it i, configure
le « Edge Detect Circuit » pour générer un ‘1’ en cas de détection d’un front descendant sur la
ligne correspondante EXTIi.
Il est possible d’utiliser les deux conditions, citées ci-dessus, en même temps : un front
montant ou descendant génère un ‘1’.
Software interrupt event register (EXTI_SWIER) : Un ‘1’ dans un bit de ce registre permet
de simuler une activité sur la ligne correspondante, mêm e si le s conditions de déclenchement
ne sont pas valides (aucun changement du niveau de la ligne correspondante).
Pour la partie responsable de la génération des événements (C), il s’agit d’un registre :
Event mask register (EXTI_EMR) : Un bit m is à 0 masque et désactive la génération
d’événements de la ligne correspondante. Un ‘1’ permet de l’autoriser et d’exciter par
conséquent le «Pulse Generator» qui génère une impulsion sur un pin IO.
NewState : pouvant pre ndre l es val eurs: ENAB LE (a ctivation de l a sort ie d ’impulsion) o u b ien
DISABLE.
Cette fonction permet de sélectionner le pin à utiliser pour la génération de l’impulsion, avec
GPIO_PortSource : pouvant prendre l’une des valeura GPIO_PortSourcex (x= A, B, C, D ou E).
GPIO_PinSouce : pouvant prendre l’une des valeurs GPIO_PinSourcex (x=0, 1,2,…..14, ou 15)
EXTI_LINE: Specifies the EXTI lines to be enabled or disabled. This parameter can be one ore
any combination (Logic OR) of EXTI_Lines:
EXTI_Mode: Specifies the mode for the EXTI lines. This par ameter can be a value of
EXTIMode_TypeDef:
typedef enum
{
EXTI_Mode_Interrupt = 0x00, //Configurer les lignes EXTI en mode interruption
EXTI_Mode_Event = 0x04 //Configurer les lignes EXTI en mode événement
} EXTIMode_TypeDef;
EXTI_Trigger : Specifies the trigger signal active ed ge for the EXTI lines. This
parameter can be a value of EXTIMode_TypeDef:
typedef enum
{
EXTI_Trigger_Rising = 0x08, // Décelenchemet sur front montant
EXTI_Trigger_Falling = 0x0C, // Décelenchemet sur front descendant
EXTI_Trigger_Rising_Falling = 0x10 // Décelenchemet sur front montant ou descendant
} EXTITrigger_TypeDef;
EXTI_LineCmd : Specifies the new state of t he selected EXTI lines. Th is parameter can
be set either to ENABLE or DISABLE.
Exemple1 : Le code suivant permet de configurer les lignes EXTI 0 & 4 en mode interruption
avec déclenc hement sur front montant, EXTI6 sur front descendant (On n’i ndiquera pas l e code
permettant la configuration des IOs et des signaux d’horloge):
Remarque : On n’est pas obligé de déclarer les paramètres EXTI_Mode et EXTI_LineCmd une deuxième fois
puisqu’ils ont déjà les valeurs adéquates.
Exemple2 : Le code suivant permet de configurer les lignes EXTI 1 et 7 en mode évenement avec
déclenchement sur front montant, avec génération d’une im pulsion sur le pi n PB7 ( On n’indiquera
pas le code permettant la configuration des IOs et des signaux d’horloge):
Chapitre
Transfert de données : Le contrôleur DMA
1. Introduction
Dans l es systèmes à proc esseurs, la c ommunication avec l’ extérieur se fait à traver s des
périphériques (d’ interfaces) d’ entrées/sorties intégrés « I/O Peripherals, (USART pour l a
communication série, l’ADC pour l’acquisition des signaux analogiques, etc..). On se trouve ainsi dans
la nécessité de faire des transferts fréquents de données (Figure 1):
1- D’un périphérique vers la mémoire ‘de données’ pour être traitées par le processeur
2- D’un périphé rique vers u n autre ( exemple : convertir un signal analogiq ue avec l’ADC et
transférer le résultat de la conversion vers l’interface de co mmunication série (USART) pour
l’envoyer à un autre système.
3- De la mémoire ‘de données’ vers un périphérique (exemple : le contenu d’une trame à envoyer
sur liaison réseau Ethernet).
4- D’une m émoire à une mé moire (la mémoire s ource peut être elle- même la mémoire
destination).
3
1
Bridge
Figure – 1 :
Dans le cas de figure, ou le processeur est le seul responsable de toutes les tâches, il doit
interrompre le traitement en cours pour effectuer le transfert qui s’exécute en plusieurs cycles. Prenons
l’exemple du transfert des données se t rouvant dans la mémoire vers le périphérique réseau pour être
encapsulées dans une trame Ethernet et transmises. (Figure 2) :
Bridge
Data bus Periphera Bus
Figure -2 :
3. Le contrôleur DMA
Le contrôleur DMA, considéré comme étant un périphérique par le processeur, est lui-m ême
un processeur à usage unique (SPP : Single Purpose Processor) dont la tâche est l’accès séquentiel en
lecture et écriture aux mémoires de données et aux registres des périphériques.
Un contrôleur DMA est capable de gérer un certain nom bre de canaux. Un canal ét ant une
connexion configurable entre deux périphériques caractérisés par les paramètres suivants :
- Les signaux pouvant déclencher le transfert : généralement, ils sont issus de l ’un des
périphériques. (Un transfert peut être également lancé par soft)
- Les adresses source et destination du transfert.
- La taille des données à transférer.
Ainsi, le contrôleur DMA devrait ainsi disposer:
- Pour chaque canal, d’un ensemble de registres pour la sauvegarde des adresses source,
destination, taille des données ainsi que l’état du transfert en cours.
- D’un bus (lignes d’adresses, de données et de contrôl e) pour l’accès aux mémoires de
données et aux registres des périphériques.
- Des signaux de requête ( Req : Request) issus des périphériques susc eptibles de
demander un transfert et de notificatio n ( Ack : Acknowledgm ent) vers ces mêmes
périphériques pour notifier la réception de la requête.
- Des registres de configur ation po ur d éterminer les canaux actifs, leurs niveaux de
priorité, etc….
- Des registre(s) (Buffer) pour stocker tem porairement les donné es à transférer de la
source vers la destination. Il peut s’agit d’un simple registre ou bien d ’une mémoire
FIFO dont la taille peut aller de quelques à quelques dizaines de Kilooctets.
- D’une logique d’ arbitrage pour déterminer le canal ay ant droit à l’ accès au bus si
plusieurs canaux demandent un transfert en même temps.
DMA
Channel N
Signaux de requ ête Channel. Signaux de notification
(Req) d e tra nsfert issus Channel. (Ack) vers les
des péri phériques p our périphériques dem andant
Channel 1
demander un transfert. un transfert
@source
@destination
Taille
Etat transfert
Buffer
Figure -3 :
Ainsi, pour une architecture Harvard, la st ructure du s ystème devient comme présenté ci-
dessous (Figure 4) : le processeur n’ est plus le seul ayant accès a u bus ‘données’ , il y’a également le
contrôleur D MA qui peut accéder à n’ importe quell e zone mé moire ou registre périphérique du bus
‘données’ : on parle de maître « Master ». La mémoire et le s périphériques étant appelé s esclaves
« Slaves ».
Transfert Requests to DMA
Arbitration
Bridge
Data Bus Peripheral Bus
Figure – 4 :
Il faut noter que dans ce c as, ou plusieurs maîtres accèdent au bus, une technique d’ arbitrage
doit être utilisée pour gérer l’accès. Généralement, les bus actuels utilisés dans les systèmes embarqués
(tel que le bus AHB utilisé dans les microcontrôleurs STM32), i ntègrent cette technique d’a rbitrage
qui peut consister en une si mple gestion de nivea ux de priorités ou en un m ultiplexage temporel plus
évolué (round robin).
Toute opérati on de transfert met en jeu un certain nom bre de signaux ( voir figure 5) q ui
devraient assurer la synch ronisation des actions des différents composants du système impliqués dans
l’opération de transfert.
DMA
Controller DACK (Data ACKnowledgment)
Peripheral
Bus
Arbiter
Figure – 6 :
Cet échange de signaux respecte un ordre chronologi que précis (voir ci-dessous). Une fois, le
DMAC et le(s) périphérique(s) configu ré(s), l’opération de transfert co mmence automatiquement dés
le déclenchement de l’événement attendu.
DREQ (Periph) 1 5
2
HREQ (DMAC)
3 7
HLDA (Bus Arbiter)
6
DMAC Bus Access
8
4
DACK (DMAC)
Figure – 7 ;
4) Le contrôleur DMA accède alors au bus pour co mmencer le tran sfert et informe en
même temps le périphérique en activant le signal DACK.
5) Le périphérique désactive la demande de requête DREQ.
6) Le contrôleur DMA continue le transfert jusqu’à ce que
7) Le contrôleur de bus désac tive le signa HLDA pour l’inf ormer que le bus n’est plus
libre. Alors le contrôleur DMA désactive la demande d’accès HREQ.
8) Le contrôleur DMA libère le bus et désactive l e signal DACK pour notifier au
périphérique que le transfert s’est terminé. Ainsi, le périphérique peut demander d’autres transferts.
Selon la duré e de la phase d’ accès bus (6) et par conséquent le nom bre d’ unités de données
transférées, on distingue deux modes de transfert :
Block mode : Dans ce mode, le DMA occupe le bus jusqu’à transférer tout un bloc de données. Le
processeur reste dans ce cas bloqué (Figure 8).
Single Mode : dans ce mode, le contrôleur DMA ne peut alors transférer qu’un e unique unit é de
données. Pour l’ unité suivante, le périp hérique doit soumettre une nouvelle demande de r equête.
Dans ce cas, la bande passante du bus est partagée entre DMAC et processeur. Ce mode est appelé
également « bus stealing ».
i : 1 Taille { Code
1- Read data from: Mémoire (@src) Bus
DMA
2- Write data to : Périph (@dest) (Chan i)
3- @src++, @dest++ } Processeur
3
Mémoire
Ethernet
Remarque : dans le mode single, i=1 (pas de
1
étape 3) 2
Bridge
Figure -8 :
Le contrôleur DMA qu’on vient de décrire permet d’effectuer des transferts de n’importe quel
périphérique (ou zone mém oire) ve rs n ’importe quelle zone mémoire (ou périphérique). Ce type de
contrôleurs DMA est dit à usage général (General Purpose) : GP-DMA.
Ces contrôleurs doivent accéder deux fois au bus pour effectuer un transfert : une fois pour la
lecture à partir de la source et une deuxième fois pour l ’écriture dans la destination. Ceci est très
DMA DMA
Mémoire (Chan i) Periph. Mémoire (Chan i) Periph.
DMA
intégré
a b
Figure -9 : Transfert entre mémoire et périphérique Ethernet
a) avec GPDMA (2 transferts) b) avec DMA dédié intégré (1 transfert)
On voit bien que parallèle ment au tra nsfert des données de la mé moire au périphérique, le
processeur peut continuer à accéder à la mémoire ‘code’ par le bus ‘code’ et exécuter le programme.
Toutefois, le processeur peut avoir besoi n de données se trouvant dans la mémoire ‘données’
et doit par conséquent accéder au bus ‘données’ pa rallèlement au DMA. Dans ce cas, c’est la
technique d’arbitrage, intégrée au bus ‘données’, qui doit gérer ce conflit.
Il se peut donc, que le processeur doive attendr e quelques cy cles, mais même dans ce cas le
l’apport du DMA et le gain en performances reste toujours assez important.
Pour le cas traité, on a supposé une architecture Harvard (ce qui est le cas de la majorité des
processeurs embarqués), ou le processeur dispose d’un bus pour l’accès à la zone code et un autre bus
pour l’accès au données.
On peut se demander, si l’ utilisation d’un DMA peut avoir le même int érêt dans une
architecture Von Neuman, ou un seul bus est utilisé pour l’accès au code et aux données ?
Il est clair que le conflit d’ accès au bus entre pr ocesseur et DMA devrai t se poser pl us
fréquemment que dans le cas d’une architecture Harvard, mais même dans ce cas une amélioration des
performances peut être atteinte.
En effet, les processeurs disposent généralement d’une mémoire cache qui contient une copie
d’une partie du code à ex écuter et des données à tra iter et il est ainsi possible pour le processeur de
continuer à exécuter le co de disponible dans la mémoire cache pendant que le DMA accède au bus et
effectue le transfert.
Et même, dans le cas ou, le code à exécuter n’est pas disponible dans la mémoire cache, ou
bien le processeur ne dispose pas d’ une mémoire cache, alors le processeur devrait arrêter l’exécution,
mais sans êt re obligé d’ effectuer les opérations pé nalisantes de sauvegarde et de récupération de
contexte (voir paragraphe 2). Au moins ça de gagné.
Chapitre 8
Contrôleurs DMA à usage général (GP-DMA) dans les
microcontrôleurs STM32 (Famille F1)
1. Introduction
Comme tous les systèmes à processeurs, les m icrocontrôleurs STM32 (fa mille F1) sont dotés
de contrôleurs DMAs :
1 GP-DMA pour les low density et medium density devices.
2 GP-DMA pour les High density devices.
4 po ur les connectivity line devices : 2GP-DMA et 2 contrôle urs DMA dédiés (SP-DM A)
respectivement aux transferts vers et depuis les périphériques de communication Ethernet et USB.
Ces Contrôleurs DMA se partagent avec le Cortex-M3 un bus e n m atrice (multi AHB bus
matrix) et pe rmettent diffé rentes co mbinaisons de transfert entre mémoires et périphériques ( Figure
1).
1
Chapitre 8 Le Contrôleur DMA
Bus masters
Transfer
GP GP Ethernet USB Requests
Cortex-M3 DMA DMA DMA DMA From Periphs
System 1 2 To DMAs
Instructions Bus
Data Bus
APB1
Peripherals
AHB
Periph. APB2
Peripherals
Embedded SRAM
System SRAM (2K) Bus slaves
D Data only
Flash
I Instructions only
Data + Instructions
Figure -1 :
On voit bien que le processeur cortex-M3 peut accéder aux instructions dans les mé moires
Flash, SRAM système (system SRAM) et la SRAM embarquée (embedded SRAM).
Pour les données, elles p euvent se trouver dans les différentes mém oires cit ées ainsi qu’au
niveau des périphériques et peuvent être accédées aussi bien par le processeur que par les 2 DMAs.
Donc en bien choisissant les em placements de sto ckage des données, les maîtres et les
esclaves i mpliqués dans les transf erts, on peut éviter au maximum les conflits d’ accès à une même
ressource et par conséquent atteindre des performances optimales.
DMA 1 : disponible dans toutes les versions de la famille F1 et il est capable de gérer jusqu’à
2
Chapitre 8 Le Contrôleur DMA
7 canaux possédant des ni veaux de priorités matérielles fixes (Fixed hardware priority) par défaut
(Figure 3) qui peuvent être reconfigurés par soft.
Les périphériques pou vant émettre une requête de transfert a ux différents canaux sont
nombreux (Figure 3), mais un instant donné un seul périphérique par canal est autorisé à émettre
une requête. Le transfert ne peut commencer si le signal de requête et le canal sont actifs
Pour effectuer un transfert d’une mémoire à un autre, c’est le signal MEM2MEM qui doit être
activé, et ceci ne peut se faire que par programmation «soft » (Figure 3). Dans ce cas le tr ansfert
sera lancé directement si le canal est actif.
DMA 2 : disponible dans toutes les versions de la famille F1 à l’exception des « low density
devices» qui ne contiennent que le DMA1. Le DM A 2 a les mêmes propriétés que le DMA 1
et est capable de gérer jusqu’à 5 canaux (Figure 4).
3
Chapitre Le Contrôleur DMA
En plus des registres (2 par DMA) permettant d e gérer les interruptions (paragraphe 5),
Chaque Canal contient 4 Registres (Figure 5):
DMA_CPARx (DMA Channel x Peripheral Address Register) : c’est un registre 32 bits qui
contient l’ adresse d’ un registre d’ un périphérique ( ou d’un emplacement mémoire si on
effectue un transfert mémoire à mémoire) représentant l’adresse source ou bien destination du
transfert en fonction du sens du transfert déterminé par le registre DMA-CCRx
DMA_CMARx (DMA Channel x Memory Address Register) : c’est un regi stre 32 bits q ui
contient l’ adresse d’ un e mplacement mémoire ( ou d’un registre d’un périphérique si on
effectue un transfert de périphérique à périphérique) représ entant l’ adresse so urce ou bien
destination du transfert. Ceci dépend du sens du transfert qui peut être déterm iné par le
registre DMA-CCRx.
1
x dénotant le numéro du canal, donc de 1 à 7 pour le DMA1 et de 1 à 5 pour le DMA2
4
Chapitre Le Contrôleur DMA
transférer, donc un m aximum de 65535 unités. L’ unité pouvant ê tre 8, 16 o u 32 bits et est
déterminée également par le registre DMA_CCRx.
DMA (Channel x)
DMA_CMARx DMA_CPARx
DMA_CNDTRx
Enable
Data
size
Mémoire Periph.
DMA_CRRx
Transfer Direction
Bridge
Figure -5 :
Dans cette p artie, on présentera parallè lement les re gistres des D MA et la signification de
leurs contenus ainsi que structures et fonctions de la librairie Firmware ST permettant de les manipuler
d’une façon transparente. Ceci per met de choisir e ntre une progra mmation par acc ès dir ecte aux
registres ou bien en utilisant la librairie ST.
Ci-dessous, une corre spondance entre les différents paramètres d e la structure
DMA_InitTypeDef relative au DMA ( faisant partie de la librairie Firmaware ST) et le contenu des
registres présentés précédemment. On présentera ensuite la signification des paramètres.
typedef struct {
Registre DMA_CPAR_x
uint32_t DMA_PeripheralBaseAddr; 31………….0 Bit // voir parag3 (DMA_CPARx)
Registre DMA_CMAR_x
uint32_t DMA_MemoryBaseAddr; 31………….0 Bit // voir parag3 (DMA_CMARx)
Registre DMA_CNDTRx
31….......…16 15.…..…….0 Bit
Toujours à 0
uint32_t DMA__BufferSize; // voir parag3 (DMA_CNDTRx)
5
Chapitre Le Contrôleur DMA
Registre DMA_CCRx
1 1 1 1 1
31…….15 9 8 7 65 4 321 0 bit
4 3 2 1 0
Interrupts
ENABLE
ENABLE
Not used
Channel
MSIZE
PSIZE
Pririty
MINC
mem2
CIRC
PINC
Level
mem
DIR
// Voir
parag 5
uint32_t DMA_M2M;
uint32_t DMA_Priority;
uint32_t DMA_MemoryDataSize;
uint32_t DMA_PeripheralDataSize;
uint32_t DMA_MemoryInc;
uint32_t DMA_PeripheralInc;
uint32_t DMA_Mode;
uint32_t DMA_DIR;
} DMA_InitTypeDef;
DMA_InitTypeDef DMA_InitStructure ;
// la valeur DISABLE
6
Chapitre Le Contrôleur DMA
Pour chacun des para mètres, on prése nte ci-dessou s la significa tion ainsi que les val eurs
possibles qu’il peut prendre.
Propriété Bit (s) Signification
(Firmware Library) DMA_CCRx
La valeur permet de déterminer si le transfert doit être
DMA_M2M Bit 14
effectué entre 2 mémoires ou non
DMA_CPARx
2
Si les tailles des zones source et destination sont différentes, consulter Paragraphe 6
7
Chapitre Le Contrôleur DMA
Remarques :
- Le changement d’une propriété (donc l’accès à un registre) ne peut se faire que si le canal est désactivé.
8
Chapitre Le Contrôleur DMA
Chaque canal DMA peut être configuré pour générer une in terruption po ur un ou un e
combinaison des 3 événements suivants:
Transfer Error (TE) : Une erreur de t ransfert s’est produite. Ca peut être à cause d’un accès
à une zone mémoire ré servée, ou un problème d’accè s au bus , etc… En c as d’ erreur de
transfert, le canal sera automatiquement désactivé par hardware.
Half Transfer (HT) : La moitié des données a été transférée (DMA__BufferSize/2 unités).
Transfer Complete (TC) : La totalité des données a été transférée (DMA__BufferSize unités).
L’ activation de ces sources d’interruptions se fait par la mise à 1 des bits correspondants (Bits
3,2 et 1) dans le registre de configuration DMA_CCRx, un 0 pour les désactiver :
……4 32 10 bit
TEIE HTIE TCIE
Au niveau de la librairie Firmware ST, la fonction permettant d’accéder à ces bits est :
En plus de ces bits, deux registres par DM A sont utilisés pour la gestion des so urces
d’interruptions :
9
Chapitre Le Contrôleur DMA
1- Le registre DMA_ISR (DMA Interrupt Status Register) qui contient l’état des sources
d’interruptions (IF : Interrupt Flag) de to us les can aux du DMA (4 bits pour chaque canal) et ne peut
être accédé qu’en lecture :
DMAy Channelx
Interrupt Enable
bit
OR
OR & INT
& & (NVIC)
Donc, pour qu’une interruption relative à un canal x donné se déclenche, il faut que :
Le canal DMA soit activé (bit EN du registre DMA_CCRx).
Au moins, une parmi les sources d’interruptions autorisées (bits TEIE, HTIE, TCIE du registre
DMA_CCRx), se déclenche.
L’interruption relative au canal so it autorisée au niveau du NVIC. Ceci se fait par mise à 1 du
bit correspondant dans le r egistre de masquage du NVIC (ou bien en passant par la structure
NVIC_InitStructure avec NVIC_IRQChannel = DMAy_Channelx_IRQn y : le nr du DMA ;
x : le nr du canal) « voir chapitre »
10
Chapitre Le Contrôleur DMA
Par conséquent, lors du déclenche ment d’ une interruption relative à un canal x, on ne peut
déterminer di rectement la source de l’ événement a ctif puisque toutes les 3 activent la même lign e
d’interruption au niveau du NVIC. Il faut donc commencer par consulter le registre DMA_ISR pour
déterminer connaître quelle source parmi celles autorisées a déclenché l’interruption.
Pour la lecture de l’ état d’une source d’interruption d’un canal x, soit on accède directe ment
au bit (le registre fait partie de la zone Bit Banding), ou bien on peut utiliser une fonction de la STM32
Firmware Library :
DMA_GetITStatus ( uint32_t DMA_IT )
Une fois l’interruption servie, il faut rem ettre à 0 la source d’interruption da ns le registre
DMA_ISR. Mais, étant d onné que ce registre ne peut être accéd é qu’en lecture, l’opération d’écriture
se fait par le biais d’un autre registre (voir paragraphe suivant).
2- Le registre DMA_IFCR ( DMA Inte rrupt Flag Clear Register) qui a exactement la même
structure que le registre DMA_ISR (Figure 8). La mise à 1 d’un b it du registre DMA_IFCR a comme
effet de remettre à 0 le bit correspondant dans le registre DMA_ISR.
11