Previous: 9.1.3. タスクの構成 |
Up: 9.1.3. タスクの構成 |
Next: 9.1.3.2. 優先順位 |
各周辺回路をコントロールするためのタスクが必要ですが、このマウスは自律的にコントロールする場合と、無線で他律的にコントロールする場合とがあります。それぞれのコントロール方式は内容が全く異なっていますから、全く別のタスクとして実装する方が簡単です。そこで各タスクを切り替えられるように、簡易のステートマシンを実装しました。ステートマシンというのは、複数の状態を持ち、各状態の間を一定の条件で遷移する仕組みを持っているもののことです。
今回の実装では各状態はそれぞれ独立したタスクとして実装します。このサンプルでは以下のようにタスクを作成しました。
State_Initial関数 |
OSスタート直後の状態 |
State_Hetro関数 |
他律動作モード時の動作を規定 |
State_Auto関数 |
自律動作モードの動作を規定 |
各状態用関数はStateTaskType型構造体の配列としてポインタ、タスク名、タスクハンドラを格納し、タスク毎に番号を付けておきます。ここでは配列の番号をそのままタスクの番号として扱っています。
StateTaskType StateTaskArray[] = ? { ???? ?{State_Initial,???? (signed portCHAR *)"State:Initial", 0}, // 0 ????? {State_Hetro,?????? (signed portCHAR *)"State:Hetero",? 0}, // 1 ????? {State_Auto,??????? (signed portCHAR *)"State:Auto",??? 0}, // 2 ? }; |
状態の遷移を発生させるイベントにも番号を付けておきます。
typedef enum { ? EVENT_NO_CHANGE = 0, ? EVENT_STATE_CHANGE_NEXT = 1, ? EVENT_STATE_CHANGE_PREVIOUS = 2, } Event_Type; |
どの状態の時のどのイベントが発生するかによって、遷移する先の状態が異なりますが、これを2次元配列にまとめました。各行が元の状態(の関数の番号)、各列が発生したイベント、要素が遷移先の状態(の関数の番号)です。
uint16_t TaskEventTable[][3]? = ? { ????? {0,1,1}, // 0 ????? {1,2,1}, // 1 ????? {2,1,2}, // 2 ? }; |
そしてこれらの遷移を実際に行わせるため、prvTask_State_Control関数をタスクとして実行します。このタスクは起動時に自動的に0番の状態用関数をタスクとして起動します。その後はキューでイベント番号が送信されてくる度に、現在のタスクから、イベント番号から導かれるタスクに切り替えます。キューが送信されてくるまでの間は、Blocked状態で待ちます。
今回は簡単に実装したかったのでこういった形になっていますが、デストラクタ(タスク終了時の処理)を規定したり、サブステート(ある状態の中でさらに複数の状態が遷移する状態)を規定したりできるようになるとさらに実用的になるでしょう。
Previous: 9.1.3. タスクの構成 |
Up: 9.1.3. タスクの構成 |
Next: 9.1.3.2. 優先順位 |