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?
Si l'événement d'intérêt est:
alors un gestionnaire basé sur une interruption serait logique.
Si l'événement d'intérêt est:
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.
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.
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.
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.
Voici quelques liens intéressants que j’ai découverts en analysant les méthodes de sondage et d’interruption - http://web.engr.oregonstate.edu/~traylor/ece473/lectures/interrupts.pdf - Très lien intéressant http://www.atarimagazines.com/compute/issue149/60_Interrupts_made_easy.php
http://www.electro-tech-online.com/micro-controllers/8440-interrupt-vs-polling.htmlhttp: //www.microchip. com/forums/m397196-print.aspxhttp://www.cs.huji.ac.il/course/2006/67630/Lectures/interrupts.pdf } _ http://sunsite.nus.edu.sg/LDP/LDP/tlk/node86.html
J'espère que c'est utile.
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)
De nombreuses contraintes de conception peuvent guider la décision. Mon application a une combinaison d'interruption et d'interrogation:
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.
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.
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.
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.
Il est bien préférable d’utiliser Interrupt based design
par rapport à polling based
car 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:
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
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.
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.