こんにちわ。備忘録も兼ねてArudinoのスレッドのお話です。
別々のスピードでステッピングモーターの動作をやらせたいってことがあって、それ故Arudino上でスレッドを立ててみました。
github.com
以上今回のやっつけソースです。
そもそもArudinoにはスレッドの機構は存在はしないのですが、組み込み機器の考えの中にはRTOS(リアルタイムオペレーションシステム)を使うスレッドの組み込み機器とRTOSを使わない(ポーリング型(いわゆるイベント駆動型)プログラミング)の組み込み機器があります。その後者を簡単にするために"protothreads"というライブラリがあります。
protothreads
要参照。
要は今回のはprotothreadsをarudino向けにラップしたやつの紹介ということになります。
さてここからがこのエントリの本題で備忘録です(遠い目)
(オレオレ)リファレンス
struct pt {
lc_t lc;
};
構造体型pt。それだけ
PT_INIT(pt);
/*実態は
#define PT_INIT(pt) LC_INIT((pt)->lc)
ってなっておりlc.hでincludeされている"LC_INIT(lc)"でその使用するスコープ変数の状態を初期化している
*/
Protothread を初期化する。
PT_THREAD(name_args);
/*実態は
#define PT_THREAD(name_args) char name_args
名前を引数として呼ぶって感じですね。
*/
protothread (ちなみにCで記述されてる)の宣言部分らしい。
PT_BEGIN(pt)
/*実体は
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
"LC_RESUME(lc)"はlc.hで記述されてて意味どおりスレッドの再開をするってこと。つまるところスレッドの開始ということになる。
*/
protothread の開始の宣言。
PT_END(pt)
/*実体は
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
PT_INIT(pt); return PT_ENDED; }
"LC_END(lc);"はlc.hで記述されててそのスコープでの使用の終了をマークしてる関数。
*/
Protothread の終了を宣言。
PT_END(pt)
/*実体は
#define PT_WAIT_UNTIL(pt, condition)
do {
LC_SET((pt)->lc);
if(!(condition)) {
return PT_WAITING;
}
} while(0)
" LC_SET(lc);"はlc.hで記述されててそのスコープでの使用を設定する関数。正確に言うとその状態に保存をかける関数。
*/
protothread の宣言したスコープのスレッドで止まる。つまり機能的にはwait関数。
PT_EXIT(pt)
/*実体は
#define PT_EXIT(pt)
do {
PT_INIT(pt);
return PT_EXITED;
} while(0)
*/
protothread の宣言したスコープを終了させる。
PT_SCHEDULE(f)
/*実体は
#define PT_SCHEDULE(f) ((f) < PT_EXITED)
*/
protothreadをスケジュールをするために使うぽい。具体的にはprotothread が終了した場合0を返す。
PT_YIELD(pt)
/*実体は
#define PT_YIELD(pt)
do {
PT_YIELD_FLAG = 0;
LC_SET((pt)->lc);
if(PT_YIELD_FLAG == 0) {
return PT_YIELDED;
}
} while(0)
*/
このprotothread(スレッド)が終わるまで待つ。
片方でデータ通信しててそのデータをもう一つのスレッドで仕事したい時に使うとでも言えばイメージがつく。
PT_YIELD_UNTIL(pt, cond)
/*実体は
#define PT_YIELD_UNTIL(pt, cond)
do {
PT_YIELD_FLAG = 0;
LC_SET((pt)->lc);
if((PT_YIELD_FLAG == 0) || !(cond)) {
return PT_YIELDED;
}
} while(0)
*/
このprotothread(スレッド)の指定した条件が true に評価されるまで待つ。
以上おまけでした。間違えがあったら教えてくれると助かります。