EFM Gekkoコントローラー(http://energymicro.com/)を使用したバッテリー駆動ソフトウェアの開発を検討しており、実行するのに役立つものがない場合はコントローラーをスリープ状態にしたいと考えています。この目的には、WFI(割り込み待ち)命令が使用されます。割り込みが発生するまでプロセッサをスリープ状態にします。
何かをどこかに格納することでスリープが行われた場合、ロード専用/ストア専用操作を使用して次のようなことができます。
//何かが起こるとdont_sleepに2がロードされます //メインループを少なくとも1回繰り返します。割り込みの場合 //次のステートメント中に2にリセットされる原因となります。 //割り込みはその後に発生したかのように振る舞います。 store_exclusive(load_exclusive(dont_sleep)>> 1); while(!dont_sleep) { //次のステートメントとstore_exclusiveの間に割り込みが発生した場合、スリープしない load_exclusive(SLEEP_TRIGGER); if(!dont_sleep) store_exclusive(SLEEP_TRIGGER); }
load_exclusive操作とstore_exclusive操作の間に割り込みが発生すると、store_exclusiveをスキップし、システムがもう一度ループを実行するようになります(割り込みがdont_sleepを設定したかどうかを確認します)。残念ながら、Gekkoはスリープモードをトリガーするために書き込みアドレスではなくWFI命令を使用します。のようなコードを書く
if(!dont_sleep) WFI();
「if」と「wfi」の間に割り込みが発生し、dont_sleepを設定するリスクが発生しますが、wfiは先に進み、とにかく実行されます。それを防ぐための最良のパターンは何ですか?PRIMASKを1に設定して、WFIを実行する直前に割り込みがプロセッサに割り込まないようにし、すぐにクリアしますか?または、より良いトリックがありますか?
編集
私はイベントビットについて疑問に思っています。一般的な説明では、マルチプロセッサのサポートを目的としているようですが、次のようなものが機能するかどうか疑問に思っていました。
if(dont_sleep) SEV(); / *次のWFEはイベントフラグをクリアしますが、スリープはしません* / WFE();
don't_sleepを設定するすべての割り込みもSEV命令を実行する必要があるため、「if」テストの後に割り込みが発生すると、WFEはイベントフラグをクリアしますが、スリープ状態にはなりません。それは良いパラダイムのように聞こえますか?