は、プロセッサがWFI命令から目覚めさせるの三つの条件があります。
- 非マスク割り込みが発生し、その優先度が現在の実行優先度よりも大きい場合(つまり、割り込みが取られます)
- PRIMASKによってマスクされた割り込みは、デバッグエントリ要求である
- を保留にします。
WFI命令が実行されたときに起床条件のいずれかが真である場合、事実上NOP(スリープ状態にはならない)です。
割り込みが保留されていないことを確認するために、それはそれを行う必要があるコードです。通常は、割り込み要求がアサートされずに必要な保留ビットがクリアされるように、割り込み要因が満たされていることを確認することを意味します。あなたは保留中のレジスタで読んで保留中のものを見ることができますが、割り込みハンドラは通常休止状態になるように任されています。
ほとんどのシステムでは、WFIの実行直前または直後にいくつかの作業が必要であることに注意してください。たとえば、WFIで睡眠をとることを決定する前に、追加の作業があるかどうかを判断するために行わなければならないテストがあります。そのテストとWFIの実行は、PRIMASKが1に設定されているクリティカルセクションで実行されます(上記のオプション2を実行しています)。これにより、テストとWFIの間に割り込みが入らず、ウェイクアップ後に完了する必要がある追加の操作(通常はクロッキングを含む)がある場合に割り込みが発生しないことが保証されます。ウェイクアップ後、PRIMASKは0(クリティカルセクションを終了)に戻され、保留中の割り込みが発生します。
また、ARMがWFIの直前にDSB命令を実行して、プロセッサがスリープ状態になる前にデータ操作が終了することを保証することをお勧めします。すべての状況で厳密に必要なわけではありませんが、状況が変わった場合に備えてそれを見落としてください。
非常に完全な回答をいただきありがとうございます。しかし、私はネイティブの英語/腕の話し手ではありません。マスクされた(PRIMASKによる)と保留中の割り込みの違いは何ですか? WFIをクリティカルセクションに入れることは、ハンドラが実行されるのを防ぐだけですが、割り込みはまだ保留中です。したがって、クリティカルセクションは、ケース2がWFIをNOPに変換するのをどのように防ぎますか? – Julien
WFIが実行されているときに上記のいずれかの条件が当てはまる場合、プロセッサはスリープ状態にはなりません。これはあなたが望むものです。さもなければ、重要な出来事を見逃すかもしれません。 PRIMASKを1に設定する目的は、WFIより前に実行されたテストやコードが途切れることのないようにすることです。追加の作業があるかどうかを割り込みが判断するのが一般的です。そのテストは割り込みの可能性なしに実行する必要があります。ただし、テストが行われた後に割り込みが保留になると、WFIはNOPになり、PRIMASKを0に戻すと割り込みが発生します。 –