2016-04-02 4 views
4

J'ai c code exécuté à partir de la RAM en faible puissance exécuter mode (donc l'interruption ne sont pas traitées). Ce mode activé par séquence de code:STM8 ASM exécuter en toute sécurité WFE

  • saut vers la RAM
  • SIM
  • mise hors tension flash interne et régulateur de puissance, passer à la source d'horloge à faible vitesse (LSE)
  • faire un travail avec le mode WFE (mode d'économie d'attente de puissance)
  • interrupteur du régulateur de puissance et flash, source de restauration d'horloge
  • RIM
  • saut à flasher

Donc il n'y a pas de problème avec l'instruction WFE décrite dans la feuille d'errata. Problème avec cette construction, il peut être cause de verrouillage du processeur dans mode d'économie d'attente de puissance pour toujours:

while nbit(TIM1_SR1,CC3IF) asm("wfe"); 

qui est le démontage comme:

000035 720252B602  BTJT  TIM1_SR1, #1, 0xB6 
00003A 728F   WFE 

événement de minuterie a un caractère probabiliste, et ce le code ne garantit pas que cela se produira après l'exécution de l'instruction WFE:

  • Instruction BTJT générée en 2 cycles, et longueur 5;
  • code exécuté de RAM peut être pas continue parce que "fetch" états pause exécution sur quelques cycles

J'utilise PM0044 manuel et à la page 26, il jolie table de contenu:

example code execution from RAM

Il y a 2 cas où l'exécution de code a calé à 3 cycles. Donc, je ne suis pas sûr que mon événement de réveil asynchrone ne se produira pas entre les instructions BTJT et WFE.

Existe-t-il des moyens d'assurer une séquence logique stricte (vérifier l'état> wfe> événement de réveil)?

+0

Ce que vous demandez n'est pas clair. Après l'exécution de l'instruction WFE, la CPU a déjà été réveillée par un événement et l'instruction suivante est exécutée. L'instruction suivante doit être une instruction JRA qui revient à l'instruction BTJT. La séquence est 1) bit de test et boucle de sortie si définie 2) attendre l'événement de réveil 3) passer à l'étape 1. Si vous avez programmé correctement les registres de contrôle WFE, cela devrait être l'équivalent de la séquence 1) bit de test et sortie loop if set 2) passe à l'étape 1. L'instruction WFE économise simplement l'énergie. –

+0

@ Ross, Est-ce vraiment comme tu penses? _Après que l'instruction WFE est exécutée, le CPU a déjà été réveillé par un événement et l'instruction suivante est exécutée._ Maintenant je crois que cette construction de code buggly, et la bonne façon est d'utiliser l'intrusion WFE seulement s'il y a une assez grande marge de temps. Et dans les cas plus complexes, ne l'utilisez pas après des événements de réveil concurrents. – imbearr

+0

Je suis sûr que cela fonctionne comme je l'ai décrit. Pendant l'exécution de l'instruction WFE, la CPU est endormie et attend un événement. Une fois l'exécution de l'instruction WFE terminée, la CPU ne dort plus et n'attend plus un événement. Il passe ensuite à l'exécution de l'instruction suivante, comme ce qui se passe normalement lorsqu'une instruction termine l'exécution. Cependant, je ne vois toujours pas quel est votre problème. donc nous ne parlons peut-être pas des mêmes choses. Quel problème pourrait résoudre une grande marge de temps? –

Répondre

1

solution trouvée par OP:

J'ai lu errata (grâce à Ross Ridge) quelques fois avec plus d'attention, ce qui est l'idée principale:

solution générale est d'assurer qu'aucune demande d'interruption ou L'événement se produit pendant l'exécution de l'instruction WFE ou le cycle de ré-exécution par un calendrier d'application approprié.

5

Si vos problèmes de lockup sont causés par les errata WFE je l'ai mentionné il devrait y avoir une solution plus facile que d'essayer d'obtenir « le calendrier d'application correcte ».

Le errata provided by STMicroelectronics lit:

Deux types de défaillances peuvent se produire:

Cas 1:
En cas instruction WFE est placé dans les deux MSB du mot de 32 bits dans la mémoire, un événement qui se produit pendant le cycle d'exécution ou le cycle de ré-exécution WFE (lors du retour du gestionnaire ISR ) provoquera une exécution de code incorrecte.

Cas 2:
Une requête d'interruption, qui se produit au cours du cycle d'exécution WFE entraîne une exécution de code incorrecte. Ceci est également valable pour le cycle réexécution WFE, en revenant d'un ISR gestionnaire

Cas n ° 2 ne devrait pas appliquer dans votre cas comme vous le dites « Interruptions ne sont pas traités parce que j'utilise faible mode de fonctionnement de puissance ". Si les interruptions ne peuvent pas se produire pendant l'instruction WFE, seule la panne décrite dans le premier cas pourrait être à l'origine de vos blocages.

Le cas 1 ne s'applique que si l'instruction WFE est dans un certain alignement dans un mot de 32 bits en mémoire. Donc, si vous pouvez vous assurer que l'instruction WFE n'apparaît jamais dans le code aligné de cette façon, vous ne rencontrerez pas cet échec. Si votre assembleur supporte une directive d'alignement, vous pouvez l'utiliser, peut-être avec une étiquette et un saut si l'assembleur n'insère pas de NOP. Cependant, une solution plus facile est donnée comme une « solution spécifique » dans errata:

Remplacer l'instruction WFE avec

 WFE 
    JRA next 
next: 

Cela semble contourner l'échec en mettant ce qui équivaut à un 2- octet NOP après l'instruction WFE. Ma supposition est que l'échec entraîne l'exécution par l'unité centrale de l'instruction immédiatement après l'instruction WFE, en sautant deux octets avant l'instruction (le cas échéant) au début du monde 32 bits suivant. Mettre un NOP de 2 octets dans l'espace ignoré signifie que cela n'a pas d'importance si la panne se produit ou non.

+0

il n'est pas si difficile de réviser le code pour assurer un bon timing, et c'est plus juste pour mon opinion. – imbearr