Vous êtes sur la page 1sur 11

Interruptions et STM32

Issam Outassourt, Alexis Robert

Fonctionnement des interruptions

Contrôleur d’interruptions présent dans le cœur ARM Cortex-M

NVIC : Nested Vectored Interrupt Controller

Gère les priorités entre interruptions

Gère la sauvegarde/restauration des registres

Le tout de façon optimisée (tail chaining, stack pop pre-emption, late arrival)

Le fabriquant du micro-contrôleur peut y greffer ses interruptions (ex : UART, DMA, EXTI), le cœur ayant aussi ses propres interruptions (ex : Hard Fault)

Le tout de façon commune entre tous les cœurs ARM afin de faciliter le

portage des RTOS (idem pour le timer SysTick)

Groupe de priorités et sous-priorités

Le Cortex-M possède un registre de priorité sur 8 bits pour chaque

interruption : 255 niveaux de priorité

Divisé en deux parties : group priority & sub priority

Façon de splitter configuré dans le registre PRIGROUP

Erreur courante : priorité maximale = 0, priorité minimale = 255

Group priority définit si une interruption peut interrompre une

interruption courante (pré-emption)

Sub priority définit qui s’exécutera en premier si deux interruptions du même group priority arrivent en même temps

EXTI, sa vie, son œuvre

On a vu les interruptions venant de l’extérieur du cœur ARM mais lancées par le reste du microcontrôleur. On veut lancer une interruption depuis l’extérieur : EXTI (EXTernal Interrupts)

Exemple : Boutons poussoir, réveil si trafic réseau, …

Permet de lancer une interruption en front montant et/ou descendent

Séquence les informations via l’horloge APB2

Réveille le cœur ARM de veille

Résout le problème du polling

Permet de mettre en veille le cœur pour n’être réveillé que si quelqu’un agit avec le périphérique

Soulage le scheduler du RTOS

Périphérique fourni par ST

Sources d’interruptions

GPIO

Périphériques autres pour réveiller le cœur

Ethernet

USB OTG

Horloge RTC

Les sources se configurent dans les registres de AFIO (sur STM32F1)

• Ethernet • USB OTG • Horloge RTC • Les sources se configurent dans les registres
• Ethernet • USB OTG • Horloge RTC • Les sources se configurent dans les registres

Configuration des EXTI

1.

Configurer EXTI

a) Régler le masque des évènements générant des interruptions : EXTI_IMR

b) Régler le masque raising/falling trigger : EXTI_RTSR / EXTI_FTSR

2.

Configurer la source dans AFIO

Régler le registre AFIO_EXTICRx

3.

Activer le périphérique AFIO

Activer son horloge dans le périphérique RCC

4.

Configurer le NVIC Activer l’interruption et régler la priorité

Interruptions sous ChibiOS

Types d’interruptions

NMI (non maskable interrupts), FI (fast interrupt), RI (regular interrupts)

Une machine à états

Transitions sur appel de fonctions ou sur interruptions

Configuration

Définition des handlers d’interruptions

Initialisation du vecteur d’interruptions

Exemple pratique

Faire changer l’état d’une LED depuis un bouton (via EXTI)

Structure d’un IRQ handler

CH_IRQ_HANDLER(myIRQ) { //myIRQ : IRQ Identifier

CH_IRQ_PROLOGUE();

/* IRQ handling code, preemptable if the architecture supports it.*/

chSysLockFromIsr(); /* Invocation of some I-Class system APIs, never preemptable.*/ chSysUnlockFromIsr();

/* More IRQ handling code, again preemptable.*/

CH_IRQ_EPILOGUE();

}

CH_FAST_IRQ_HANDLER(myIRQ){

}

EXTI : le handler

static void extcb1(EXTDriver *extp, expchannel_t channel) { palTogglePad(GPIOD, GPIOD_LED4);

}

EXTI : Configuration

Options générales :

EXT_CH_MODE_DISABLED

EXT_CH_MODE_RISING_EDGE

EXT_CH_MODE_FALLING_EDGE

EXT_CH_MODE_BOTH_EDGES

EXT_CH_MODE_AUTOSTART

EXT_MODE_GPIO[A-I] spécifique à STM32

/* Configure EXTI */

static const EXTConfig extcfg = {

{

 

{EXT_CH_MODE_BOTH_EDGES | EXT_MODE_GPIOA, extcb1},

{EXT_CH_MODE_DISABLED, NULL},

},

};

//main

extStart(&EXTD1, &extcfg);

EXTI : le main

int main( void ) { halInit(); // Initialise la HAL chSysInit(); // Initialise ChibiOS

palSetPadMode(GPIOD, GPIOD_LED4, PAL_MODE_OUTPUT_PUSHPULL);

extInit(); // Initialise le driver EXTI

extStart(&EXTD1, &extcfg); // Règle les registres EXTI

extChannelEnable(&EXTD1, 0); // Démarre EXTI

while (1 ) {}

}