【GPIO】
組み込み系であればGPIOを全く使わないシステムなど恐らくないだろう。少なくとも稼働中表示(Lチカ)くらいはするのではないだろうか。にも拘わらずGPIOイベントまで標準でサポートしているRTOSってあんまりない気がする。現状を知らないので気がするだけで実際はそうでもないのかもしれないが、もし、そうだとすると、GPIOはHW依存だからサポートできないってことなのか、或いは、RTOSの機能を使って簡単に実装できるから勝手にどうぞってことなのか...
RTOSでGPIOポーリング処理ってそんなに簡単?
信号の取りこぼしを防ぐためにポーリング頻度を上げれば他タスクの動作に影響を与えてしまうし定期的にポーリングしようにもタイマー粒度と要求仕様が合わなかったりしてなかなかうまくはいかないケースが多いのではないだろうか?少なくともRTOSの作法に従った綺麗なタスク・デザインなど夢物語もいいとこだろう。
ということで、そろそろ本題に入ろう。
GPIOには入出力ピンがあるが、出力ピンはPWM等のHW連動により高速制御も可能となるので特に問題はないだろう。カウンター等と連動できる入力ポートも同様だ。
面倒なのは単純なデジタル入力ピンの読み取り。入力ピンは通常外部割込みが使えるようになっているのでそれを活用するしか方法はないのだが外部割込みが使えない入力ピンもたまにある。そういう入力ピンは対処のしようがないのでなかったことにしてしまおう。(-_-;)
外部割込みには、レベル割り込みとエッジ割り込みがあるが、レベル割り込みは少し特殊な用途で使う物であまり使われないだろうからこれもなかったことにしてしまおう。困ることはないと思う。たぶん。
エッジ割り込みには、立ち上がりエッジ(rising edge)、立下りエッジ(falling edge)、両エッジ(both edge)があるが、両エッジの割り込みを使うと割り込み処理にほんの少し手間をかけるだけでパルス幅も計測できてしまうので便利だ。あとはレベルやエッジで同期をとれるようにすると優先度の高いタスクを使って簡単かつリアルタイムかつエレガントに信号やパルス幅を取り込むことが可能となる。
【ピン同期機能の概要】
1 2 3 4 5 6 7 8 9 10 11 12 |
typedef enum { PCINT_WAIT_LEVEL_LOW, PCINT_WAIT_LEVEL_HIGH, PCINT_WAIT_EDGE_LOW, PCINT_WAIT_EDGE_HIGH, PCINT_WAIT_EDGE_BOTH, } PCINT_WAIT; uint8_t wait(PCINT_WAIT mode, int32_t timeout = WAIT_INFINITE); uint8_t value(void); uint32_t width(uint8_t level); |
RTOSでも外部割込みを使えば同様なことが出来るのだが独自に割り込みを管理しているRTOSなどではある程度精通した人でないと難しいのかもしれない。
というところでGPIOについては書くことが無くなってきたので次の話題へ移ろうと思ったが既にネタ切れしかかってる気がする。そろそろ最終章が近そうだ。
【セマフォ/ミューテックス】
セマフォ/ミューテックスは必要だけど特に拘る点もないので普通で良いだろう。って、何が普通なのかって突っ込みは無しで。
【イベント】
いつも、なんに使うのか悩んでしまうイベント機能。フラグ1個でいいならセマフォで代用できるし使い方を悩むくらいだから無しでいいか。
【メールボックス】
通信系が主だと必要なんだけど...メモリの少ないAVRには要らないかな。
さて、次回はお待ちかねの最終章になるか...
【関連する投稿】
理想のRTOSを自作する (1)
理想のRTOSを自作する (2)
理想のRTOSを自作する (3)
理想のRTOSを自作する (4)
理想のRTOSを自作する (5)
理想のRTOSを自作する (6)
理想のRTOSを自作する (7)
理想のRTOSを自作する (8)
理想のRTOSを自作する (9)
理想のRTOSを自作する (10)
理想のRTOSを自作する (11)