Je cherche à développer un logiciel alimenté par batterie en utilisant les contrôleurs EFM Gekko (http://energymicro.com/) et je voudrais que le contrôleur soit en veille chaque fois qu'il n'y a rien d'utile à faire. L'instruction WFI (Wait For Interrupt) est utilisée à cet effet; il mettra le processeur en veille jusqu'à ce qu'une interruption se produise.
Si le sommeil était activé en stockant quelque chose quelque part, on pourrait utiliser des opérations de chargement exclusif / magasin exclusif pour faire quelque chose comme:
// dont_sleep est chargé de 2 chaque fois que quelque chose arrive // devrait forcer la boucle principale à tourner au moins une fois. Si une interruption // se produit qui entraîne sa réinitialisation à 2 lors de l'instruction suivante, // le comportement sera comme si l'interruption s'était produite après. store_exclusive (load_exclusive (dont_sleep) >> 1); while (! dont_sleep) { // Si une interruption se produit entre la prochaine instruction et store_exclusive, ne dors pas load_exclusive (SLEEP_TRIGGER); si (! dont_sleep) store_exclusive (SLEEP_TRIGGER); }
Si une interruption devait se produire entre les opérations load_exclusive et store_exclusive, l'effet serait d'ignorer store_exclusive, ce qui obligerait le système à parcourir la boucle une fois de plus (pour voir si l'interruption avait défini dont_sleep). Malheureusement, le Gekko utilise une instruction WFI plutôt qu'une adresse d'écriture pour déclencher le mode veille; écrire du code comme
si (! dont_sleep) WFI ();
courrait le risque qu'une interruption puisse se produire entre le «si» et le «wfi» et définirait dont_sleep, mais le wfi irait de l'avant et s'exécuterait de toute façon. Quel est le meilleur schéma pour éviter cela? Réglez PRIMASK sur 1 pour empêcher les interruptions d'interrompre le processeur juste avant d'exécuter le WFI, et effacez-le immédiatement après? Ou y a-t-il une meilleure astuce?
ÉDITER
Je m'interroge sur le bit Event. D'après la description générale, il aimerait qu'il soit destiné à la prise en charge multi-processeur, mais se demandait si quelque chose comme ce qui suit pouvait fonctionner:
if (dont_sleep) SEV (); / * Rendra le drapeau d'événement WFE clair mais ne dormira pas * / WFE ();
Chaque interruption qui définit don't_sleep doit également exécuter une instruction SEV, donc si l'interruption se produit après le test "if", la WFE effacera l'indicateur d'événement mais ne se mettra pas en veille. Cela ressemble-t-il à un bon paradigme?