【ユーザタスクとは?】
PICROSの管理下で実際の機能を果たすためにユーザが作成し追加する機能
モジュールをタスクと呼ぶことにします。
PICROSは最大255個までのタスクを管理することが出来ます。以下に代表的
なタスクの構成例を示しますが、これだけに限定されている訳では無く、自由に
構成することが出来ます。
基本的にPICROSの管理下にあるタスクは、実行中になるとそのタスクを終了
しない限りPICROSには戻らないので、タスクの切替え(ディスパッチという)は
行われません。従って各タスクの実行時間は出来るだけ短くする必要があります。
この意味で完全なマルチタスクのOSではありません。
またデータを渡すことはPICROSは面倒を見ていないので、タスク間でのデータ
渡しはSTATIC変数などを使って共通変数として渡す必要があります。
【タスクの構成例1】
下図が最も単純な構成のタスク例で、例では何らかの割込みにより、タスク1が
Trigger Task関数により起動される場合を想定しています。
起動されたタスクが他に関係無く独立に実行可能で、1回だけ処理して直ぐ終了
して良い場合には、このような構成となります。
タスクに一度実行が移ると、タスクが終了しない限りPICROSのスケジューラには
戻らないので、そのタスクが終了するまで、他タスクを実行することが出来ません。
従って、タスクの実行時間は、出来る限り短くする必要があります。
また実行中タスクでExit_Task()関数を実行してから戻らないと、同じタスクの実行を
繰り返すことになってしまいます。
実際のコーディング例
このタスクが起動される度にPORTCの0,1が反転します。
【タスクの構成例2】
この構成例も多いと思われるタスク構成で、下図のようにタスクから別のタスクを
起動します。
あるタスクの処理が終わったら、次に別のタスクを実行したい時に、この構成とし、
次に起動したいタスクをRequest_Task関数で起動します。
実際に起動した相手に実行が移るのは、自分がExit_Task関数などで実行を終了
するか、待ち状態にしてタスクを終了させた後です。
実際のコーディング例
初期起動タスクの例で、TASK2,3,4,5の4つのタスクが初期起動されます。
【タスクの構成例3】
タスクを一定時間間隔で周期的に実行させたい場合の構成例で、下図のように
Wait_Timer関数を使います。Wait_Timer関数を実行後タスクを直ぐリターン終了させ
ます。この後はこのタスクはタイマー待ち状態となります。
内部インターバルタイマは10msecが基本インターバルで、タイマ0の割込み処理で
実現しています。
タイマの割込みはPICROS内部で処理され、指定した時間が経つと自動的にタイマ
待ちのタスクが実行待ち状態に遷移します。この後スケジューラにより最も優先順位
の高いタスクが実行中とされます。
この流れを毎回繰り返しますので、Wait_Timer関数で指定した時間間隔で周期的に
タスクが実行されることになります。
タスクは毎回リターン終了し、再起動の時には最初から実行されますので、中で
使用する変数で値を保持して継続させたい時には、変数を「STATIC変数」として
記憶可能な形式にする必要があります。
実際のコーディング例
これでPORTCに接続された発光ダイオードが0.1秒間隔で点滅を繰り返します。
【タスクの構成例4】
タスク間で同期を取って実行する必要がある場合の構成例で、下図のように
します。
タスクで待合せをする場合にはSupend_Task関数を使って待合せるタスクを
指定します。この後このタスクを直ぐリターン終了させれば、このタスクはイベント
待ち状態となります。
指定された相手のタスクが、Resume_Task関数を実行すると、この待合せが
解除され実行待ちに遷移します。そして相手タスクの終了後に次の実行タスク
として再実行されます。
この場合にも、タスクは常に最初から実行されますので、変数などの値を継続する
場合には、その変数はSTATIC変数とする必要があります。
【タスクの構成例5】
タイマやイベント待ちが解除された時の再起動の時と、最初に起動された時で
処理を変えたい時には、下図のようにGet_Trigger関数で起動条件を入手して
判定することで行います。
タスクが起動される条件は、
0 : Request_Task関数による
1 : イベント待ち解除による
2 : タイマタイムアップによる
の3種類が区別できます。
この判定によって処理の流れを変えます。
下図の例では最初起動されたあと、一定時間後に1回だけ再起動され、
実行後はタスクが終了します。