2018年04月29日

Timerの精度(RPiベアメタルMicroPython)

昨日のTimerクラスの割り込み処理を使ったLチカはこんな感じになります。
Raspberry Pi Zero Wなので、GPIO47がボード上のLEDです。


このタイマ割り込みの精度はどの程度になるのか、測定してみました。
1000マイクロ秒(1msec)周期の割り込みをかけて、コールバック関数の中でそのときの時刻を測定します。
割り込み処理が実行される時刻が、割り込みが起こった時刻からどれくらい遅れるか統計を取ってみます。



Timer.compare_register()は、「次に割り込みが起きるタイミング」を示しています。System Timerでは、フリーランニングする1MHzクロックのカウンタ(utime.ticks_usec()を実現している64bitカウンタ)の下位32bitが、タイマのコンペアレジスタと一致したときに割り込みが起こります。

割り込みが起きるタイミング自体は、utime.ticks_usec()の計測値で見ればきっかり1000マイクロ秒間隔になります。
しかし、コールバック関数は割り込みハンドラ内ではなく、ハンドラの処理が終わった後に呼ばれますので、割り込みから割り込みハンドラの実行までにはオーバーヘッドがあり、その分遅延が出ます。

この遅延の量を、logへ蓄積していきます。
遅延の値は、「現在時刻 - (コンペアレジスタの値 - 1000)」になります。
「-1000」が付いているのは、Pythonで書いた割り込みハンドラが呼ばれたタイミングでは、既に割り込みが起きてコンペアレジスタの値が更新され、次回割り込みが起こるべきタイミングを示す値になっているからです。

試しに1000回測定してみた結果は以下のようになりました。

timer-accuracy.png

47	317
48 260
49 187
50 143
51 56
52 38


割り込みそのものからの遅延は50マイクロ秒前後です。
割り込みの間隔そのものは概ね5マイクロ秒以内の変動で納まっています。
今回は割り込みタスク以外にはwhileループしか走っていませんが、もっと重い処理(実行時間が長くかかるCの関数の実行)をさせればもちろん悪化する可能性はあります。
上の例はUSBキーボードのサポートをオフにして測定したものですが、USBキーボードを接続した状態だと以下のように少し変動が増えます。

timer-accuracy-with-usb.png

48	248
49 217
50 160
51 108
52 91
53 37
54 37
55 37
56 36
57 30


遅延の最大値が5マイクロ秒ほど増えています。
現在の実装では、割り込みハンドラの実行は特に優先されないので、定期実行するタスクが増えるほど、変動が増えていくと思われます。
ラベル:MicroPython
posted by boochow at 12:40| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
人気記事