[tech] 割込みと WFI 命令を使った sleep の実装 | Wed, Feb 26. 2014 - 氾濫原 で WFI 命令があるのでそれ使えばよさそうみたいなことを書いたけど、Which architectures support the WFI instruction? を読んでいたら、Raspberry Pi が WFI 命令をサポートしていないことに気付いてしまった……

Raspberry Pi は ARMv6K というアーキテクチャの ARM1176JZ-F というプロセッサらしい。無印の ARMv6 は WFI 命令をサポートしない。ただ、ARM1176JZ-F は別の方法で使うことができる。

いろいろ書いてあってややこしいが、重要なのはここ

ARMv6K and ARMv6T2 include the WFI instruction, meaning that these processors do not cause an undefined instruction exception when the WFI instruction is executed. However, the ARM1136J(F)-S rev 1 and ARM1176JZ(F)-S (architecture ARMv6K), as well as the ARM1156T2(F)-S (architecture ARMv6T2) treat the WFI as a NOP, and implement the CP15 method for entering "wait for interrupt" mode.

なので、WFI 命令は NOP として扱われてた…… 気を使って NOP でも普通に動くコードを書いた結果気付きにくいバグを作っていた。

mov r1, #0;
mcr p15, #0, r1, c7, c0, #4;

とすれば WFI 相当のことができるみたい。コプロセッサってなんだよって感じだけど、書いてある通り書いたらエラーはでなかった。

mcr 命令は ARM レジスタからコプロセッサへデータを転送する命令らしい。上の mcr 命令の場合

  • C15 (p15) コプロセッサの
  • レジスタ7 (c7) = レジスタ 7: キャッシュ管理機能 に対し
  • 割込み待ち (c0, #4 ) を転送する

転送する値はなんでもいい?のかな。r1 に転送する値を入れるけど 0 にしてる。mcr の第2引数もコプロセッサのオペコードっっぽいけどよくわからない。

  1. トップ
  2. tech
  3. 続・割込みと WFI 命令を使った sleep の実装
▲ この日のエントリ