Les processeurs n'interrogent pas les interruptions, du moins pas dans un sens logiciel. En ce qui concerne les logiciels, les interruptions sont des événements asynchrones. Ce qui se passe, c'est que le matériel de la CPU reconnaît la demande d'interruption, qui est une entrée électrique sur une ligne d'interruption, et, en réponse, annule l'exécution normale des événements pour répondre à l'interruption. Dans la plupart des processeurs modernes, ce qui se passe ensuite est déterminé par une poignée de main matérielle particulière au type d'unité centrale, mais la plupart d'entre eux reçoivent un certain numéro de l'appareil d'interruption. Ce nombre peut être 8 bits ou 32 ou autre, selon la conception de la CPU. La CPU utilise ensuite ce numéro d'interruption pour indexer dans la table de vecteurs d'interruption, afin de trouver une adresse pour commencer l'exécution de la routine de service d'interruption. Une fois cette adresse déterminée (et le contexte d'exécution actuel est sauvegardé en toute sécurité dans la pile), la CPU commence à exécuter l'ISR.
Lorsque deux périphériques partagent une ligne de demande d'interruption, ils peuvent provoquer l'exécution de différents ISR en renvoyant un numéro d'interruption différent pendant ce processus d'établissement de liaison. Si vous avez suffisamment de nombres de vecteurs disponibles, chaque dispositif d'interruption peut utiliser son propre vecteur d'interruption. Mais deux périphériques peuvent même partager une ligne de demande d'interruption et un vecteur d'interruption, à condition que l'ISR partagé soit assez intelligent pour retourner à toutes les sources possibles de l'interruption donnée, et vérifier les registres d'état pour voir quel périphérique a demandé le service .
Un peu plus en détail
Supposons que vous ayez un système composé d'une unité centrale de traitement et contrôleur d'interruption, et un dispositif d'interruption. Dans l'ancien temps, il s'agissait de dispositifs physiques séparés, mais maintenant tous les trois peuvent même résider dans la même puce, mais tous les signaux sont toujours là à l'intérieur du boîtier en céramique. Je vais utiliser un CPU powerPC (PPC) avec un contrôleur d'interruption intégré, connecté à un périphérique sur un bus PCI, comme exemple qui devrait bien fonctionner.
Supposons que le périphérique soit un port série qui transmet des données. Un pilote de port série typique chargera un paquet de données dans le FIFO du périphérique, et le processeur peut effectuer un travail régulier pendant que le périphérique fait son travail.Généralement, ces périphériques peuvent être configurés pour générer une demande d'interruption lorsque le périphérique est à court de données à transmettre, de sorte que le pilote de périphérique peut revenir et alimenter davantage.
La logique matérielle dans le périphérique s'attend à un accusé de réception d'interruption de bus PCI, à quel point, deux choses peuvent se produire. Certains périphériques utilisent 'autovectoring', ce qui signifie qu'ils s'appuient sur le contrôleur d'interruption pour s'assurer que la routine de service correcte est sélectionnée. D'autres auront un registre, que le pilote de périphérique va préprogrammer, qui contient un vecteur d'interruption que le périphérique placera sur le bus de données en réponse à l'accusé de réception d'interruption, pour que le contrôleur d'interruption prenne le relais. Un bus PCI ne dispose que de quatre lignes de requête d'interruption. Notre périphérique série devra donc en faire une. (Peu importe ce qui est actuellement, il dépend généralement de l'emplacement.) Ensuite, le contrôleur d'interruption (par exemple PIC/APIC), qui décidera s'il faut acquitter l'interruption en fonction des bits de masque qui ont été réglés ses propres registres. En supposant qu'il acquitte l'interruption, il obtient alors le vecteur du dispositif d'interruption (via les lignes de bus de données), ou peut, si tel est le cas, utiliser une valeur «conservée» fournie par le propre pilote de l'APIC. Jusqu'à présent, le CPU a été parfaitement inconscient de toutes ces choses, mais c'est sur le point de changer.
Maintenant, il est temps pour le contrôleur d'interruption d'attirer l'attention du cœur du processeur. Le CPU aura son propre bit (s) de masque d'interruption qui pourrait l'amener à ignorer la requête du PIC. En supposant que le processeur est prêt à prendre des interruptions, il est maintenant temps que l'action réelle démarre. L'instruction courante doit généralement être retirée avant que les ISR puissent commencer, donc avec les processeurs pipelinés c'est un peu compliqué, mais il suffit de dire qu'à un moment donné dans le flux d'instructions, le contexte du processeur est sauvegardé dans la pile et le matériel ISR -determiné prend le relais. Certains cœurs de processeur ont plusieurs lignes de requête et peuvent commencer à réduire le routage ISR via une logique matérielle qui fait passer le pointeur d'instruction de l'UC à l'un des rares gestionnaires de niveau supérieur. Le vieux 68K, et peut-être d'autres l'ont fait de cette façon. Le powerPC (et je crois, le x86) a une seule entrée de requête d'interruption. Le x86 lui-même se comporte un peu comme un PIC, et peut obtenir un vecteur du (des) PIC externe (s), mais le powerPC saute juste à une adresse fixe, 0x00000500.
Dans le code PPC, le code à 0x0500 va probablement sauter immédiatement à quelque part dans la mémoire où il y a assez de place pour un code décisionnel sérieux, mais c'est toujours la routine de service d'interruption. Cette routine ira d'abord au PIC et obtiendra le vecteur, et demandera également au PIC de cesser d'affirmer la requête d'interruption dans le coeur du CPU. Une fois que le vecteur est connu, l'ISR de niveau supérieur peut faire référence à un gestionnaire plus spécifique qui s'occupera de tous les dispositifs connus pour utiliser ce vecteur. Le gestionnaire spécifique au vecteur parcourt ensuite la liste des périphériques affectés à ce vecteur, en vérifiant les bits d'état d'interruption dans ces périphériques, pour voir lesquels ont besoin de service. Lorsqu'un périphérique, tel que le port série hypothétique, est détecté comme défaillant, l'ISR de ce périphérique prend les mesures appropriées, par exemple, charger les données FIFO suivantes dans un tampon du système d'exploitation dans la FIFO de transmission du port. Certains périphériques abandonnent automatiquement leur demande d'interruption en réponse à l'accès, par exemple, l'écriture d'un octet dans la FIFO de transmission peut entraîner la désactivation de la ligne de demande par le périphérique du port série. D'autres appareils nécessiteront un bit de registre de contrôle spécial pour basculer, définir, effacer, what-have-you, afin de supprimer la demande. Il y a des millions de périphériques d'E/S différents et aucun d'entre eux ne semble jamais le faire de la même manière, il est donc difficile de généraliser, mais c'est généralement le cas. Maintenant, évidemment, il y a plus à dire - qu'en est-il des priorités d'interruption? ce qui se passe dans un processeur multi-core? Qu'en est-il des contrôleurs d'interruption imbriqués? Mais j'ai assez d'espace sur le serveur. J'espère que cela aide.
Merci Jeff. Bien que ma question soit toujours là. Je comprends qu'il y a un numéro d'interruption utilisé pour trouver ISR. Puis ma question suivante était de savoir comment le CPU est alors fourni avec ce numéro? Cela arrive-t-il par bus de données ou comment? Où les APIC se situent-ils dans l'image pour les appareils partageant des IRQ? Votre message a été très utile pour me rappeler l'utilisation des registres d'état des appareils. Merci beaucoup. –
Belle explication Jeff. Merci encore pour les efforts. J'ai eu des pensées similaires, comme s'il pouvait y avoir une structure arborescente pour gérer les interruptions. Mais maintenant je sais que d'autres pensent également de la même manière et vous avez fait un bon commentaire à ce sujet. Merci encore. –
Une petite question. _Interrupt vector_ est juste un nombre qui est une entrée de la table de vecteur d'interruption pour obtenir l'adresse de ISR. Alors, comment est-ce un ** Vector **? ** Le numéro d'interruption ** est correct. – Shashwat