Pages: 1 [2]   Go Down
Author Topic: [RESOLU] accès vecteurs sur arduino  (Read 1774 times)
0 Members and 1 Guest are viewing this topic.
Bretagne
Offline Offline
Edison Member
*
Karma: 10
Posts: 1296
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si la oc fait 450 pages, c'est qu'il y a une raison, et je reconnais que je passe presque plus de temps à lire la doc qu'à programmer. Du coup, j'ai installé un second écran sur mon PC, un pour programmer, l'autre pour afficher la doc en même temps, c'est super pratique!



Donc, page 18 du PDF de l'ATMEGA2560, on peut lire :

En quelques mots (lexique : ISR = Interrupt Sub-Routine = routine d'interruption) :

1 - le bit qui autorise toutes les INT est mis à 0 dès qu'une INT se produit, et remis à 1 à la sortie de l'ISR.
2 - dans ce cas, si une (ou plusieur) INT se produit, le flag de cette INT est mis à 1, et l'ISR correspondante s'exécutera à la sortie de l'ISR qui était en cours. Dans le cas de plusieurs INT, elles seront exécutées dans l'ordre de priorité qu'annonçait fdufnews.
3 - On peut cependant, dans l'ISR, le remettre à 1 pour autoriser une nouvelle interruption. Dans ce cas, si une interruption se présente, elle interrompt l'ISR en cours le temps de s'exécuter, et si 10 INT s'imbriquent, peu importe, elles sont traitées dans l'ordre d'arrivée en interrompant tout de suite la précédante.
4 - il existe deux types d'INT, celles qui ont un flag et qui seront exécutées, même dix ans après, tant qu'on n'est pas sorti de l'ISR précédente. Et celles qui ne s'éxécuteront que si la condition de l'INT est encore vérifiée au moment où c'est leur tour.
5 - Rien n'est conservé lors d'une INT à part l'adresse programme de retour, pas même le registre de statut (peut-être gênant sur les opérations 16 ou 32 bits : le bit de retenue peut être modifié dans l'ISR?) Il revient au programmeur de s'assurer des bonnes sauvegardes au démarrage de son ISR.

Il me semble avoir lu qu'il n'y a pas de limite de pile (stack, la base des sauvegardes lors d'appels de fonctions ou ISR), sauf la taille de la RAM. Si on utilise beaucoup de variables et beaucoup d'appels de fonctions, alors il se peut que la pile déborde sur les variables en RAM, et là, tout est mort. La pile démarre au dernier emplacement de la RAM et descend vers le début, d'où cette possibilité de "collision", mais ce serait la seule contrainte.

Un appel d'ISR par INT occupe 5 cycles d'horloge (soit 312.5ns) et autant pour le retour, ce qui dans certains cas doit être pris en compte...

voilà donc quelques infos supplémentaires... ci-dessous le texte original en anglais.
Quote
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed. There are basically two types of interrupts. The first type is triggered by an event that sets the Interrupt Flag. For these interrupts, the Program Counter is vectored to the actual Interrupt Vector in order to execute the interrupt handling routine, and hardware clears the corresponding Interrupt Flag. Interrupt Flags can also be cleared by writing a logic one to the flag bit position(s) to be cleared. If an interrupt condition occurs while the corresponding interrupt enable bit is cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the flag is cleared by software. Similarly, if one or more interrupt conditions occur while the Global Interrupt Enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the Global Interrupt Enable bit is set, and will then be executed by order of priority.
The second type of interrupts will trigger as long as the interrupt condition is present. These interrupts do not necessarily have Interrupt Flags. If the interrupt condition disappears before the interrupt is enabled, the interrupt will not be triggered.
When the AVR exits from an interrupt, it will always return to the main program and execute one more instruction before any pending interrupt is served.
Note that the Status Register is not automatically stored when entering an interrupt routine, nor restored when returning from an interrupt routine. This must be handled by software. When using the CLI instruction to disable interrupts, the interrupts will be immediately disabled. No interrupt will be executed after the CLI instruction, even if it occurs simultaneously with the CLI instruction.
Logged

Bretagne
Offline Offline
Edison Member
*
Karma: 10
Posts: 1296
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bon, on va dire "résolu" dans la mesure où j'ai ma réponse :

On ne peut accéder aux vecteurs d'interruption qu'à la programmation, puisque la table des vecteurs se trouve dans la flash, à un endroit pas facilement trouvable (dépend des fusibles et de quelques registres)...
Logged

Made in Belgium
Offline Offline
God Member
*****
Karma: 0
Posts: 756
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yop,
On en apprend des choses.  smiley-surprise
Et si j'ai bien compris le vecteur d’interruption correspond on va dire à un simple tableau (vecteur) sur lequel on boucle constamment d'où les priorité suivant la place dans ce "tableau", si une de ses valeurs est à 0 la boucle est interrompue (mais on peux la relancé à n'importe quel moment) et on appel la fonction correspondante à cet emplacement (vecteurs d'adresses de ses fonctions ?)
Tout ça parait logique en fait, merci pour ses recherches très instructives.

Quote
Du coup, j'ai installé un second écran sur mon PC, un pour programmer, l'autre pour afficher la doc en même temps, c'est super pratique!

Ca fait quelques années que je ne travail plus que comme ça, l'essayer c'est l'adopter tellement c'est pratique.  smiley-cool smiley-wink
Logged


Bretagne
Offline Offline
Edison Member
*
Karma: 10
Posts: 1296
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Et si j'ai bien compris le vecteur d’interruption correspond on va dire à un simple tableau (vecteur) sur lequel on boucle constamment d'où les priorité suivant la place dans ce "tableau", si une de ses valeurs est à 0 la boucle est interrompue (mais on peux la relancé à n'importe quel moment) et on appel la fonction correspondante à cet emplacement (vecteurs d'adresses de ses fonctions ?)
Tout ça parait logique en fait, merci pour ses recherches très instructives.
Je ne sais pas trop comment ça fonctionne, mais il n'y a pas de boucle. La première int force le code suivant dès la fin de l'instruction en cours (même si c'est une instruction  nécessitant plusieurs cycles, elle sera exécutée en entier).
Code:
ASM:
  push PC   // sauvegarde compteur programme actuel
  cli           // désactivation des interruptions
  mov PC, int_vect  // pointeur programme sur le vecteur d'int (équivalent à un jmp)

// d'ici, on va directement à la routine d'interruption programmée par l'utilisateur
// et c'est ici que l'on revient grâce au "reti" à la fin de la routine d'int

  cbi int_flag   // clear flag de l'int
  sei         // réactivation des int
  pop PC  // rappel du compteur programme donc retour là où on en était avant l'int.
plus loin dans la flash, au beau milieu du code
Code:
int_vect:
  sei          // à mettre d'entrée de jeu si l'on veut autoriser les autres interruptions pendant la routine ISR...
  usercode          // code de l'ISR...
  reti  // retour d'interruption.

Dans le premier code, on l'on distingue deux parties (une avant la routine ISR, une autre après), chacune de ces parties occupe 5 coups d'horloge (les fameuses 312.5ns).

Ce qu'il faut savoir, dans le cas où une int arrive pendant que l'on en traite déjà une, elle est sauvegardée par son flag qui reste à 1. une fois sorti du premier code ci-dessus, une instruction du programme en cours est traitée avant de relancer la procédure ci-dessus, car ce n'est que pendant que l'on traite une instruction que l'on peut détecter qu'un des flags d'int est à 1.
Logged

Made in Belgium
Offline Offline
God Member
*****
Karma: 0
Posts: 756
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C'est surtout le fait de parler de vecteur et priorité ascendante dans celui-ci qui me fais pensé (imaginé) une boucle, disons que si j'avais du réalisé un tel système niveau soft c'est comme ça que j'aurais procédé.
On pourrais faire notre propre système d'interruption sur toute les entrées du microcontrôleur, une simple boucle sur les trois registres BCD, au moindre changement d'un bit de l'un deux on appel une fonction dans un tableau d'adresse correspondante.  smiley-lol (idée d'un module alarme pour le système domotique avec un code extrêmement réduit )
Dans tout les cas même si j'ai pas compris le fonctionnement au plus bas du bas niveau (hard), on a compris leurs utilisations et leurs contraintes grâce à toi.  smiley-wink  
« Last Edit: February 13, 2012, 08:05:25 am by osaka » Logged


Pages: 1 [2]   Go Up
Jump to: