割り込みマスクせずにwfi命令を使うと

以前、wfi命令で割り込みを待つときには割り込みマスクをする話を書いた。

wfi命令で割り込みを待つ意味

フラグがなければwfi命令で割り込み待ちする場合、

フラグがないことを確認した後に割り込みが発生してフラグが立ったらうまくいかないので、

割り込みマスク→フラグ確認→wfi命令→割り込みマスク解除 の順番でやらないといかんねという話である。


で、本当にそうなるんかいとICEでブレークポイントを置いて実験をしてみた。

そしたら、確かに割り込み処理の復帰先がwfi命令の場所になってしまい、

さらにその次の割り込みが来るまで待たされるケースがあることが確認できた。

というわけで、ちゃんと割り込みマスクしてwfi命令しないといけませんねと。


ただ、割り込みの復帰先を書き換えてやれば問題は回避できるんだなと。

  1. 休止状態のフラグを立てる
  2. 処理するべきフラグが立っていたら休止状態のフラグを消して処理に遷移する
  3. 何もフラグがなければwfi命令を実行して休止する
  4. 割り込みハンドラで1.のフラグを確認し、休止状態の場合は割り込みの復帰先を2.にする

こんなことをやれば割り込みマスクをしなくても正しく動くはず。


何でこんな話を書いたのかというと、ある種の割り込みをマスクする期間を作りたくないという話があって、

割り込み処理の仕様上、最低限のレジスタ退避の間だけはマスクせざるを得ないが、

それ以外は可能な限り割り込みマスクせずにやりたいねと。

でも、wfi命令って割り込みマスクしないと正しく使えないよね、

と気になって、上のようなことを試して気づいたわけである。


ただ、実際のシステムでこういうプログラムを書くのかというと、

それはよくわからないんだけど。休止でwfi命令を使わない可能性もある。

(元々そういう処理をしてなかったし、電力的にシビアなシステムではない)