web-dev-qa-db-fra.com

Méthode basée sur l'interrogation ou l'interruption

Quand faut-il utiliser une méthode d'interrogation et quand utiliser une méthode basée sur les interruptions? Existe-t-il des scénarios dans lesquels les deux peuvent être utilisés?

35
Karthik Balaguru

Si l'événement d'intérêt est:

  1. Asynchrone
  2. Urgent
  3. Rare

alors un gestionnaire basé sur une interruption serait logique.

Si l'événement d'intérêt est:

  1. Synchrone (c’est-à-dire que vous savez quand vous y attendre dans une petite fenêtre)
  2. Non urgent (c'est-à-dire qu'un intervalle d'interrogation lent n'a pas d'effets pervers)
  3. Fréquent (c.-à-d. Que la majorité de vos cycles de sondage créent un "hit")

alors le scrutin pourrait être un meilleur ajustement.

D'autres considérations doivent être prises en compte si vous écrivez un pilote de périphérique pour un système d'exploitation ou si vous écrivez simplement du code bare metal sans support de thread. Dans des situations de bricolage, le processeur boucle souvent lorsqu'il n'est pas occupé, il peut donc aussi interroger quelque chose.

53
Amardeep AC9MF

Les interrogations doivent être évitées autant que possible, car elles consomment généralement de nombreux cycles du processeur inutilement (sauf si (a) vous n'allez interroger que pendant une courte période ou (b) vous pouvez vous permettre de dormir pendant une durée raisonnable dans votre boucle d'interrogation. ). Le gaspillage de cycles du processeur nuit non seulement aux performances, mais il augmente également la consommation d'énergie, ce qui peut poser problème pour les applications intégrées alimentées par batterie.

15
Paul R

Lorsque vous décidez de voter ou d'interrompre, vous devez bien comprendre la nature de l'événement que vous essayez de suivre et votre réponse.

Les interruptions ne nécessitent aucun traitement lorsque rien ne se passe, mais requièrent toute votre attention lorsque quelque chose se passe. Si l'événement est externe et a des contours bruyants ou des impulsions rapides, cela peut entraîner des maux de tête importants avec les interruptions, vous devez faire attention à la configuration des interruptions.

Dans cet exemple, la routine d'interruption répond à un faisceau laser devenu clair et se prépare à un événement où il est bloqué: 

   BEAM_INTR_EN = TRUE;   /*re-enable the beam interrupts*/

   /*Set the beam interrupt for the next clear to blocked event*/
   BEAM_INTR_Edge = CLEAR_TO_BLOCKED;
   BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/

Ce code comporte deux points faibles: 1) Si le faisceau laser est à nouveau bloqué avant que l’indicateur d’interruption ne soit effacé (BEAM_INTR_FLAG = FALSE;). L'interruption aura été manquée et le code ne sera plus synchronisé avec l'état du faisceau laser. 

2) Lors de la configuration des interruptions dans la routine d'arrière-plan ou pour une priorité supérieure à la priorité, ce code est activé, des précautions doivent être prises lors de l'activation de l'interruption. Si l'indicateur d'interruption était déjà défini (de manière incorrecte) avant son activation, la routine d'interruption serait appelée de manière incorrecte dès qu'elle serait activée et peut-être pour le mauvais Edge. 

Le moyen le plus simple de corriger 1) est de vérifier une fois que vous avez configuré l’interruption. Si elle s’est produite, forcez une interruption. Pour corriger 2) déplacez l'activation des interruptions sur après la double vérification: 

   /*Set the beam interrupt for the next clear to blocked event*/
   BEAM_INTR_Edge = CLEAR_TO_BLOCKED;
   BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/

   /*Double check beam state to see if it has already gone blocked*/
   if (BEAM_STATE == BEAM_BLOCKED)
   {
      BEAM_INTR_FLAG = TRUE; /*Force the interrupt to re-enter the ISR after exiting*/
   }
   BEAM_INTR_EN = TRUE;    /*re-enable the beam interrupts*/

Le forçage de l'interruption fait que le système fonctionne avec la même machine à états, en la forçant simplement manuellement pour couvrir l'angle mort.

Fondamentalement:

   Set the Edge to detect the next interrupt event
   Clear the interrupt flag
   if (the event has already occurred)
   {
      Set the interrupt flag to force the interrupt
   }
   Enable the interrupt

Si le temps de réponse à un événement doit être cohérent (par exemple, 1 ms +/- 10 après que la ligne d'entrée est devenue haute, transmettez le signal de l'événement), les interruptions sont généralement préférables.

Si le temps de réponse à un événement doit être dans un certain délai (par exemple, dans un délai de 1 ms lorsque la ligne d'entrée devient haute, transmettez le signal d'événement), une interruption sera préférable.

Le problème des interruptions est que vous devez commencer à penser au threading et que deux morceaux de code peuvent accéder aux mêmes données en même temps.

Les interruptions sont également utiles pour permettre aux processeurs de passer en mode faible consommation (veille/repos, etc.) en attendant que quelque chose se produise.

Cela dit, les interrogations peuvent donner des réponses très serrées aux événements s’il n’ya qu’une chose à faire par le processeur. Le matériel d’interruption prend souvent plusieurs cycles pour répondre à un événement, alors qu’une boucle d’interrogation serrée suffit.

Si l’événement n’a pas d’importance critique du point de vue de la synchronisation et peut être bruyant (par exemple, une pression sur un commutateur), la scrutation permet un filtrage simple sans rater les transitions à long terme. Une erreur courante consiste à interroger plusieurs fois lors de la configuration:

void fnInitialiseSystem(void)
{
   if (MODE_INPUT == MODE_A) /*First polling of the MODE_INPUT*/
   {
      PR2 = PR2_MODE_A;
   }
   else
   {  
      PR2 = PR2_MODE_B;
   }
   OpenTimer2( TIMER_INT_ON &
               T2_PS_1_1     &
               T2_POST_1_8   );

   if (MODE_INPUT == MODE_A) /*Second polling of the MODE_INPUT*/
   {
      CurrentMode = MODE_A;
      PROBE_INT_Edge = CLEAR_TO_BLOCKED;
   }
   else
   {  
      CurrentMode = MODE_B;
      PROBE_INT_Edge = BLOCKED_TO_CLEAR;
   }
}

Dans l'exemple ci-dessus, MODE_INPUT est un commutateur externe. Si les deux heures auxquelles MODE_INPUT est interrogée sont différentes, le comportement est inattendu. Lors de la lecture de ces types de signaux, il est préférable d'utiliser le filtrage pour décider de l'état à long terme de l'entrée et effectuer des actions sur la version filtrée.

Par exemple, avec un commutateur anti-rebond, il suffit de vérifier un commutateur régulièrement (toutes les 1 ms?) Et si un certain nombre d'entre eux (par exemple 16) sont différents (commutateur fermé) de la version filtrée (commutateur ouvert), mettez à jour le résultat et effectuez l'action requise. . Faites attention avec le repliement du signal, un signal oscillant peut sembler stable!

Un exemple d'utilisation d'interrogation et d'interruption concerne, encore une fois, l'utilisation d'une entrée qui ne change pas souvent, mais qui est bruyante lorsqu'elle le fait. Encore une fois, un commutateur en est un bon exemple: le code peut configurer une interruption pour vérifier un changement d'état du commutateur, lorsqu'une interruption se produit, le commutateur peut être interrogé régulièrement jusqu'à ce que l'état du commutateur soit "stable" (soit modifié). état ou retour à ce que c'était). Cela donne l’avantage d’avoir une surcharge de traitement lorsque rien ne se passe et un filtrage du bruit lorsque quelque chose se passe.

8
fluffyben

Parfois, vous devez réellement utiliser les deux. Par exemple, si les événements sont sporadiques mais surviennent à grande vitesse; vous devrez peut-être d'abord répondre à une interruption, puis avant de réactiver l'interrogation d'interruption pour voir si un autre événement s'est déjà produit, évitant ainsi une partie de la surcharge liée à la commutation du contexte d'interruption. Je crois que l'interface réseau Linux fonctionne dans ce mode.

7
simon
4
Karthik Balaguru

la réponse courte consiste à utiliser la méthode d'interruption lorsque l'interrogation est trop lente. (Par trop lent, je veux dire si l'interrogation perd des données, la méthode d'interruption est nécessaire)

3
KevinDTimm

De nombreuses contraintes de conception peuvent guider la décision. Mon application a une combinaison d'interruption et d'interrogation:

  • Les sources d'horloge externes et internes déclenchent des interruptions - il est essentiel de timestamper les deux avec précision afin que nous puissions les synchroniser. 
  • Les messages série entrants déclenchent des interruptions. Les FIFO de réception doivent être réparés avant qu’ils ne débordent.
  • Les messages sortants déclenchent des interruptions lorsque la FIFO est partiellement vide - elle doit être remplie avant d’être submergée. 
  • Les sémaphores de l'ISR sont interrogés en arrière-plan. Cela a 2 avantages:
    • Le calcul nécessaire pour gérer les événements entrants peut être long; si elle était laissée dans les ISR, elle pourrait retarder les autres ISR au-delà des délais impartis.
    • Les événements peuvent être séquencés. Par exemple, une boucle d'interrogation peut garantir que le calcul X a toujours lieu entre la collecte de données ADC et l'analyse du message entrant, même si le message arrive un peu plus tôt que prévu.
3
AShelly

Les interruptions sont préférables lorsqu'une faible latence est requise. Si vous interrogez pour une condition N fois par seconde, vous découvrirez en moyenne cette condition dans le temps, une moitié de 1/N après qu'elle se soit réellement produite.

La scrutation est parfois préférée lorsqu'un timing déterministe absolu est requis. De par leur nature même, les interruptions peuvent survenir à des moments imprévisibles et compliquent grandement l’analyse de la synchronisation, alors qu’avec les systèmes interrogés, il est relativement facile de faire des déclarations prouvables sur le respect des délais.

3
JustJeff

Fondamentalement, le mode interrogé est utilisé au cas où le mode interruption ne serait pas disponible pour des raisons matérielles ou logicielles. Le mode d'interruption est donc préférable en termes de consommation d'énergie, de performances, etc. (d'accord avec Paul R). Le mode interrogé est également utilisable lors du prototypage, pour les cœurs sans périphérique requis et à des fins de test. 

3
pmod

Toujours utiliser une interruption. De cette façon, vous ne perdez jamais de données. Dans les applications pilotées par événement ou threadées, même les signaux les plus lents doivent être pilotés par interruption.

La seule fois où vous devriez utiliser la scrutation est lorsque vous utilisez un planificateur et que les tampons de votre matériel sont suffisamment profonds pour ne pas perdre de données.

3
Gerhard

Le mode d'interrogation peut être utile dans les systèmes comportant des événements à haute fréquence, où le temps système associé à l'entrée et à la sortie de gestionnaires d'interruptions utilise plus de cycles de processeur que la simple interrogation. Par exemple, la scrutation peut être utilisée dans un routeur IP pour maximiser la bande passante du processeur disponible pour le traitement des paquets.

2
ukembedded

Il est bien préférable d’utiliser Interrupt based design par rapport à polling basedcar les interrogations reposent sur des erreurs car elles s’attendent à ce que les données soient renvoyées à chaque interrogation. Maintenant, vous pourriez dire que je vais contourner le cas où un seul sondage m'a renvoyé une erreur, mais pourquoi diable gâcher tous les cycles du processeur en interrogeant quelque chose alors qu'il pourrait aussi bien renvoyer une erreur ?? Et s’attendre à ce que le sondage échoue, c’est le scénario du produit.

Interrupt based designs est d'autant plus logique lorsqu'il y a beaucoup de couches de fonctions impliquées dans un seul sondage. Pour moi, c’est une pratique courante: voudriez-vous continuer à demander (polling) à votre ami encore et encore tous les jours s’il dispose des informations dont vous avez besoin OR voudriez-vous simplement lui dire que interrupt moi lorsque vous avez les informations avoir besoin. Je pense que nous faisons la bonne chose dans la vie quotidienne mais ne réalisons pas.

Mais interrupt based architectures une fois implémenté nécessite une solide compréhension du publish-subscribe design principle. Et, lorsque cela est fait dans les domaines d'application, ils nécessitent que la partie du code qui envoie les interruptions soit vraiment bien écrite. Ce bien car il réduit la complexité à un endroit aussi.

Outre ce qui précède, voici les autres avantages que l’architecture basée sur la polling vous offre gratuitement:

  • Asynchrone
  • Convient bien en cas d'événements peu fréquents/mises à jour
  • Mettre à jour uniquement lorsqu'il existe des scénarios de données disponibles
  • Meilleure gestion et gestion des erreurs
  • Meilleure utilisation des cycles du processeur
  • Meilleure durée de vie de la batterie
  • Garde les auditeurs libres de la complexité en dessous

Chaque fois que vous concevez sw & vous avez ce choix, vous devez toujours choisir une conception basée sur interrupt par rapport à polling, car une conception basée sur interrupt peut se remplir pour une situation basée sur polling à l'aide d'écouteurs, mais une conception basée sur une interrogation ne peut jamais répondre à l'exigence nécessitant interrupt conception.

Voici une brève matrice de comparaison:

                     -INTERRUPT-      -LOOP-
Speed                  fast            slow
Eficiency              good            poor
CPU waste              low             high
multitasking           yes             no
complexity             high            low
debugging              +/- easy        easy
critical in time       excellent       poor
code bloat             low impact      high impact
0
Game_Of_Threads

Vous ne voulez pas que votre hôte attende dans la boucle occupée pendant une longue période, et l'interrogation peut également devenir inefficace lorsque des données sont fréquemment vérifiées, ce qui n'est pas souvent le cas. Donc, si l'hôte et le périphérique sont tous les deux rapides, la scrutation est rapide. 

0
Jake Cook

Voir, nous avons 5 méthodologies principales:

1) aveugle

La CPU vérifie toutes les x ms pour les données. Broche de contrôle ETC 12.

2) Polling (Occupé/Attendre)

La CPU vérifie et attend toujours que Flag soit levé, comme UART levant un drapeau après le transfert d'un paquet. Toujours vérifier le registre des drapeaux. (Meilleur temps de réponse) mais le processeur ne peut rien faire d’autre.

3) interruption:

La CPU fonctionne normalement. En cas d’interruption, elle passe du contexte à l’ISR. si la broche 18 a vu un bord tombant, effectuez ISR (1). Temps de réponse pas mal et le processeur peut tout faire pendant que le ISR n'est pas actif. Faites-le avec des applications urgentes que vous ne savez pas quand cela pourrait arriver.

4) Sondage périodique:

Le processeur fait son travail, mais toutes les secondes, il vérifie la broche 11. Blind ne fait rien entre les deux. Le pire temps de réponse, pas les applications urgentes, faites-le quand vous ne faites pas confiance au matériel augmentera l'interruption. il peut être créé en utilisant une interruption de minuterie.

5) Accès direct à la mémoire.

Approche d'interfaçage avancée. Transfère les données directement de/vers la mémoire . L’entrée sera lue directement dans la mémoire. La sortie sera écrite directement de la mémoire . Les deux utilisent un contrôleur.

0
M.Noufale