さて、FreeRTOSで定周期処理をやろう。
こちらによると、vTaskDelay()で処理中に待たせる方法と、vTaskDelayUntil()でタスク自体を一定周期で起動する方法があるらしい。
vTaskDelay()は、その場でtick分待つだけなので、間に割込みされても、その分は気付かず、また戻ってきてから待つことになる。
それに対してvTaskDelayUntil()は、呼び出す周期を設定するようになっているので、割り込みされようとカウントしてくれるらしい。
「今から1秒寝ます!」と、「1秒ごとに目覚ましが鳴るので、それまで寝ます!」の違いか。
だいたいは後者の方が同じタイミングになって良いけど、その前の処理は次のタイミングの前に終わっていてほしい、というのはあるな。
1秒おきにA0ポートをADCして、2ビット落とした値をUART出力させるようにした(github)。
いやあ、ここまでに時間がかなりかかった。
ADCは連続モードで最初に開始させて、あとは取得するだけにしようとしたのだが、
- 連続モードにしても1回しか変換してくれない
- 値が変
と2つ問題があった。
どちらもFreeRTOSではなく、STM32の使い方だ。
前者は、おそらくEnd Of Conversion Selectionの設定だと思う。
リファレンスもではCONTビットを立てればよいように書かれていたのだが、デフォルトの「single channel conversion」のままだと、そちらが優先されて終わってしまうようなのだ。
ドキュメントで見落としたかな?
後者は・・・単純な設定ミスだ。
A0の設定をしていたつもりで、ずっとA1の方を設定していたので、オープンにしたままのA1から読み取っても毎回不定になっていたというだけだ。
いやぁ、ミステリー小説にありそうな、大元から違っている、というトリックですな。
1秒ちょうどか確認したいけど、TeraTermのログでは1秒くらいだけど、このくらいだとよくわからんですな。
もうちょっと処理がゴチャゴチャしていて、遅延しそうってくらいにならんとわからんだろうから、今回は深追いすまい。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。