Interruptions et contrôleur GIC
Configurer une interruption Zynq de la source au processeur, écrire une ISR courte et analyser la latence.
Interruption et exception
Une interruption provient généralement d'un périphérique. Elle est asynchrone par rapport au programme en cours. Une exception est liée à l'exécution du processeur, par exemple une instruction invalide ou un accès mémoire interdit.
Le processeur sauvegarde un contexte minimal, identifie la cause, exécute une routine de service puis reprend le programme interrompu. Cette routine est appelée ISR, pour Interrupt Service Routine. La table des vecteurs fournit les points d'entrée associés aux exceptions.
Le chemin complet
Une interruption de timer traverse plusieurs niveaux.
- Le timer détecte l'événement et positionne un bit d'état.
- Le timer active sa sortie d'interruption si le masque local l'autorise.
- Le Generic Interrupt Controller, ou GIC, reçoit la requête.
- Le GIC vérifie l'activation, la priorité et la cible processeur.
- Le processeur entre dans le gestionnaire général.
- Le gestionnaire du GIC appelle l'ISR enregistrée pour cet identifiant.
- L'ISR acquitte la source, c'est-à-dire qu'elle efface la cause signalée, avant de rendre la main.
Activer uniquement le GIC ne suffit pas. La source doit également être activée dans le périphérique.

Initialiser le GIC
Le code utilise XScuGic. Il recherche la configuration, initialise l'instance, raccorde le gestionnaire du GIC au processeur puis active les exceptions.
XScuGic gic;
int gic_init(void)
{
XScuGic_Config *config;
int status;
config = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
if (config == NULL) {
return XST_FAILURE;
}
status = XScuGic_CfgInitialize(&gic, config, config->CpuBaseAddress);
if (status != XST_SUCCESS) {
return status;
}
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &gic);
Xil_ExceptionEnable();
return XST_SUCCESS;
}Raccorder un timer TTC
Le Triple Timer Counter est configuré en mode intervalle. Le calcul du préscaler et de la valeur d'intervalle part de la fréquence demandée. Le préscaler divise l'horloge avant qu'elle atteigne le compteur.
static volatile u8 update_flag;
static void tick_handler(void *reference)
{
XTtcPs *timer = (XTtcPs *)reference;
u32 status = XTtcPs_GetInterruptStatus(timer);
XTtcPs_ClearInterruptStatus(timer, status);
if ((status & XTTCPS_IXR_INTERVAL_MASK) != 0U) {
update_flag = 1U;
}
}La routine reste courte. Elle lit et acquitte l'état, puis pose un drapeau. Le calcul du chronomètre et l'affichage UART restent dans la boucle principale.
XScuGic_Connect(&gic, XPAR_XTTCPS_0_INTR, (Xil_InterruptHandler)tick_handler, &timer);
XScuGic_Enable(&gic, XPAR_XTTCPS_0_INTR);
XTtcPs_EnableInterrupts(&timer, XTTCPS_IXR_INTERVAL_MASK);Priorité, déclenchement et partage
Le GIC gère des interruptions privées et partagées. Une source peut être sensible au front ou au niveau. La configuration doit correspondre au comportement réel du périphérique.
Une interruption au niveau reste active tant que la cause n'est pas acquittée. Une ISR qui oublie cet acquittement est rappelée immédiatement. Une interruption sur front peut être perdue si la source produit une impulsion non conforme ou si la chaîne matérielle n'est pas correctement synchronisée.
Concevoir pour une faible latence
La latence commence à l'événement et se termine au début de l'ISR utile. Elle inclut le masquage temporaire, l'arbitrage du GIC, la sauvegarde du contexte et les défauts de cache.
Une ISR critique placée en DDR peut subir une forte pénalité au premier accès. Un système contraint peut placer certaines routines en OCM ou verrouiller des lignes en cache. Cette optimisation doit être mesurée. Elle ne doit pas remplacer une architecture correcte.
Les données partagées entre l'ISR et le programme principal doivent être déclarées volatile lorsqu'elles peuvent changer hors du flot normal. Pour une structure complexe, une section critique ou un mécanisme atomique peut être nécessaire.
Diagnostic
Si l'ISR ne s'exécute pas, vérifier dans cet ordre l'état du périphérique, son masque local, l'identifiant présent dans xparameters.h, la connexion au GIC, l'activation dans le GIC et l'activation globale des exceptions.
Si l'ISR s'exécute sans arrêt, vérifier l'acquittement de la source et le type front ou niveau.
Références officielles
Le guide du pilote SCU GIC décrit l'API et les types d'interruptions. L'exemple officiel XScuGic montre la séquence d'initialisation.
À retenir
Une interruption est une chaîne complète. Il faut configurer la source, le GIC et le processeur. L'ISR acquitte rapidement le périphérique et reporte le traitement long dans le programme principal. La latence dépend aussi de la mémoire et du cache.
Tester mes connaissances - Quiz du chapitre