仕事で、LEDを光らせる処理をC++で書いておりました。
通常は、定期的にLEDをオンオフさせる単純な光り方をさせているのですが、押されたボタンによって、優先度を高くして、ピカピカといった形で激しく光らせないといけません。
優先度は、低、中、高の3つを用意しておりました。
デフォルト状態では、優先度低のLEDの光り方をさせておいて、ボタンが押されると、ボタンに応じて優先度中の光り方や高の光り方で割り込むような形でLEDを光らせます。
優先度中や高の光り方が終わったら、デフォルトの優先度低の光り方に戻ります。
こういう処理をやりたかったのですが、優先度の処理をどうプログラミングするかについて少し悩んでおりました。
結局は、3つのタスクを用意して、優先度低のタスクがいつも動いており、もし優先度中や高のボタンが押されたら、それに該当するタスクが動くような処理をしました。
最終的には3つのタスクの内優先度が最も高い処理結果をLEDに引き渡すような作りにしました。
結果としては問題なく動いているのですが、大学の授業や社会人になってから学んだ本などでは、個人的にはですが、こういった処理の王道的なアルゴリズムといいますか、プログラミングの方法を見かけたことがありません。
なので、こういった優先度の処理に関する定番の方法や、もしくは、参考になる本などがありましたら、ご教示頂きたく質問させて頂いた次第です。
どうぞよろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
ご意見を拝見しました。
順序が前後しますが・・・
ここで、一番気になっていることとしては、こういった実装についても
言及している書籍などがあるかどうか、こういった処理の王道的な
アルゴリズムがあるかどうか?、という点です。
無いでしょうね。
ご要求の内容自体は、扱う範囲が小さすぎます。どちらかというと”小手先の実装方法”に過ぎないと思います。
アルゴリズムとかフレームワークといったような共通の考え方があるようには思えないです。
タイトルを「優先度の管理について」としましたが、ご意見を拝見したり
回答を書いている内に、単に優先度の管理の問題、というわけではない
気がしてきました。
優先度云々の話ではなくて、単に「LEDの点灯パターンの切り替えタイミング」じゃないですかね。
「いかなるタイミングでも優先度の高い方の点滅のさせ方をしたい!」というのであれば、また別の話になりますし。
この際に、できれば、状態Cの時の光り方を、最初からやり直すのではなくて、
状態Cが裏で動き続けていたような光り方から再開したいと思っておりました。
例示された例では、最小の単位時間が1秒ですから、タスク内で1秒毎に状態A/B/Cのそれぞれの状態についてON/OFFのどちらになるべきかを更新&保持しておいて(=点灯させたとしたら、いまON/OFFのどちらになるべきかを常に管理しておいて)、実際のLEDの点灯は状態A/B/Cのどれかに応じて現在のON/OFF状態を反映させる、という方法でいかがでしょうか。
あるいは、システムtickカウントを割り算でもすれば、状態A/B/Cそれぞれについて一意に現在のON/OFF状態が計算できそうでもあります。
状態Aの時に、優先度中のボタンが押されたら、状態Bには移りませんが、
状態AでのLEDの光り方が終わったら、状態Bには遷移したいです。
先に示した動作とは矛盾する部分が出てきそうですが、こちらのご要求にピッタリ合わせるなら、つぎのようになろうかと思います。
まず「状態AでのLEDの光り方が終わったら」とありますが、"始まり”と”終わり”を定義しないといけませんね。
おそらくは[ON→OFF]までが始まり~終わりの一連の動作になるのでしょうから、全体としては、
for(;;) {
on_off_time = 点滅周期判定
LED点灯
on_off_time秒待ち
LED消灯
on_off_time秒待ち
}
くらいで十分ではないですか?
これなら、どんなタイミングで状態A/B/Cが変わっても、変なところでLEDの点灯パターンが急に変わることはないと思います。
ただ、状態Cの長い周期の点滅期間に、状態Aが2秒発生し、その後すぐに状態Cに戻ったという場合は状態Aはなかったような点滅になってしまいます。そういうケースにどうなるべきか?については、別途方針を決めないといけませんね。
投稿2015/03/06 06:07
退会済みユーザー
総合スコア0
0
すみません、質問の骨子を読み違えていたようです。
「タスク」「優先度」から、タスクの使い方の話かなーと。
「優先度」は、LEDの点灯パターンに対する優先度ですね。
システム全体の要求仕様が分からないので何とも言えないのですが、そもそもLEDの点灯パターン優先度のために「キュー」を用意する必要はありますか?ご質問からは、そこが読み取れないです。
システムがある状態AにあるからLEDを速く点滅させ、システムが別の状態Bにあるからゆっくり点滅でよい、そういう考え方ではないですか?
あるいは、「緊急事態」みたいな状態を表すフラグがあってその状態のときはLEDを速く点滅させ、
そうでないときはゆっくり点滅でよいとか。
いずれにしても、これらの場合ではキューは必要ないと思います。
要は、システムの中で何かの「状態」が変化したときに、その時の状態を(総合的に)判断して、LEDに対して「速く点滅しろ」「遅く点滅しろ」と指示するのが普通のように思えます。その緊急状態が解消したら、また判断を下してLEDタスクに指示を出す、そういう感じです。
とにかく、要求仕様がわからないので何とも言えません。貴方のいう「優先度」って、何で決まるのでしょうか?最初のほうで「ボタンが押されたら・・・」とありましたけど、ボタンが押されたらLEDが速く(遅く)点滅するというのは結果的にそうなるだけであって、ボタンが押されたらシステム内の「何か」が変化して、その結果としてLEDの点滅パターンが変わるんですよね?
ご質問の内容だけではキューが必要かどうかは判断できないです。ここでいう優先度は、ただの条件判断のような気がします。
投稿2015/03/06 04:12
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
単純な処理だけに、"こうするべき"的な王道は無いように思います。
ですので、以下は「私だったらこうする(方法もある)」という程度に聞き流してください。
LEDの数は1つだけですよね?それなのに、タスクを3つも用意するというのは、ちょっとリソースがもったいないような気がします。
考え方をシンプルにして、「LEDを点滅させるタスク」を1つ用意するということで良いのではないでしょうか?つまり、そのタスクは「LEDを点滅させる」ことに特化したものということです。
そのタスクに対して、「点滅周期を速くしろ(遅くしろ)」というメッセージを送って、そのタスクに点滅間隔を変えさせればよいのではないでしょうか。
私なら、点滅周期を変えるくらいなら、メッセージ送信のような方法を取らず、単純に変数書き換え(=タスクはその変数を参照して点滅周期を決めている)くらいで済ましてしまうと思います。
参考になれば幸いです。
投稿2015/03/06 02:00
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/06 02:25
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/06 09:53