ダメダメなタスク設計
MAINタスクは全体制御という事を間違って解釈した例でもあり、この構成で正常に動作しているのであれば奇跡というしかないタスク構成です。
#どこがダメなんでしょう?
このタスク構成からでは機構制御そのものをMAINタスクで行おうとしていると読み取れます。
全体制御とはユニット全体としての状態遷移とその制御を行う事で機構制御を行う事ではありません。
SENSタスクから入ってきた情報からMOTORタスクへのモーターの動作要求やSOLタスクへソレノイドへの動作要求を行おうとしているのでしょうけど、そもそもSENSタスクからMAINタスクへのセンサ情報の更新通知がタイムクリティカルな構成(時間重視の構成)ではないので、非常にセンサ情報の更新にバラツキが出て来ます。
それに対してMOTORタスクやSOLタスクへの動作要求を出していては機構制御はボロボロです。
ソレノイドを引いてフラッパー動作で媒体の行き先を変えるような機構だったとすれば、極端な例だと媒体が通り過ぎた後にフラッパーを引いて行き先を変えるような事になり、機構制御としては成り立ちません。
#通信タスクについてもなんだかなぁと・・・
そもそも、この構成で通信プロトコルを何処で実装しようと考えてるのか読み取れませんけど、最悪の場合MAINタスクで実装しようと考える人もいます。(実例は見てきました・・・)
こうなると、iTronでマルチタスクを利用してプログラム開発を行っているメリットがまったくありません。
COM1タスクとCOM2タスクでUARTを使い、全く違うデバイス、またはユニットを制御してる場合は、まぁいいとしても、もしもハードウェア設計上でピンのアサインを一つのデバイス、またはユニットを送信はUART1、受信はUART2に割り付けないといけない場合などはこういうタスク構成では通信プロトコルは何処で実装するんでしょうかね?
また、通信タスクの下に送信タスクと受信タスクを作るという設計になっていますが、"オレ流タスク設計"では推奨していません。
割り込みで最小限の事だけして後はタスクに任せようと思っているのでしょうけど通信のレスポンスが悪くなるのと流用が面倒(と思ってる)、タスク構成が複雑になる、タスク優先度設計が複雑になる等のデメリットしか感じないからです。
こういう設計の場合で私が見てきた限りでは割り込み関数無いでは割り込みフラグだけクリアして受信タスクに通知するケース(ケース1)、割り込み処理内で割り込みフラグのクリアと受信レジスタから受信データをリングバッファに格納すうケース(ケース2)があります。
1. ケース1の場合の不具合例
タスクの優先順位や受信FIFO数によって、受信バッファがフルになる等の不具合が発生する。そしてタスクの優先順位を場当たり的に変更してデバッグ機では問題なくても他の試作機や量産機、接続先のユニットによっては同じ様に受信バッファフルのエラーが発生してしまう。
2. ケース2の場合の不具合例
リングバッファの位置変数をセマフォなので排他処理もせずに管理してしまい、タスク、もしくは割り込み処理内でリングバッファの位置変数が正確ではなくなる。 もちろん、割り込み処理内では排他処理でwai_sem()やtwai_sem()待つ事は出来ないので割り込み処理内で無駄にシステムコールをコールする事になり結果的に割り込み処理が(時間的に)長くなる。
とまぁ、タスク設計でも一番アカン、アンチパターンの例を紹介しました。
オレ流での推奨は RTOSにおけるタスク設計(もちろんオレ流) を参考にして下さい。