はじめに
TOPPERS/R2CAは,Arduino M0 Pro (以下,M0)上で,Arduinoライブラリ+TOPPERS/ASPカーネルベースのマルチタスクプログラミング環境を提供するパッケージです.
この記事では,マルチタスクに続き,優先度やスケジューリングについて説明します.開発環境のインストールやビルド&実行方法はこちらの記事を見て下さい.
タスク
タスク数
タスクの数の指定は,R2CA_NUM_TASKで指定します.0を指定すると追加タスク無しとなり,setup()/loop()のみが使用出来ます.setup()/loop()を実行するタスクをメインタスクと呼びます.
#define R2CA_NUM_TASK 0
指定可能な最大数は5でそれぞれタスク1,2,3,4,5と呼びます.
タスク本体
それぞれのタスクが実行する関数名は次の通りである.
タスク | 関数 |
---|---|
メインタスク | setup/loop |
タスク1 | loop1 |
タスク2 | loop2 |
タスク3 | loop3 |
タスク4 | loop4 |
タスク5 | loop5 |
タスクID
ITRON仕様ではタスクに対するAPIはタスクIDを指定して発行します.
各タスクのIDは次の通りです.
タスク | タスク名 |
---|---|
メインタスク | R2CA_MAINTASK |
タスク1 | R2CA_TASK1 |
タスク2 | R2CA_TASK2 |
タスク3 | R2CA_TASK3 |
タスク4 | R2CA_TASK4 |
タスク5 | R2CA_TASK5 |
タスク優先度
タスクの優先度を設定可能です.ディフォルトは5となっています.ITRONの優先度は1から15で,数値が小さいほど優先度は高いです.
優先度は,以下のマクロをr2ca_app.hに設定することで変更可能です.
タスク | 優先度 |
---|---|
メインタスク | R2CA_MAINTASK_PRI |
タスク1 | R2CA_TASK1_PRI |
タスク2 | R2CA_TASK2_PRI |
タスク3 | R2CA_TASK3_PRI |
タスク4 | R2CA_TASK4_PRI |
タスク5 | R2CA_TASK5_PRI |
スケジューリング
ITRONでは優先度ベースのプリエンプティブスケジューリングを行います.汎用OSのラウンドロビンとは異なり,優先度が最も高いタスクのみが実行されます.優先度の高いタスクが起動すると即座に実行されます.
また,同一優先度はFCFSでスケジューリングされます.すなわち最も起動が早いタスクのみが実行されます.R2CAにおいて,優先度を変更しなかった場合は,メインタスクのみが実行されます.
実行中のタスクが他のタスクに処理を明け渡すには,待ち状態や休止状態とすればよいです.R2CAではdelay()を実行することにより,一定時間待ち状態とし,他のタスクに処理を譲ります.
ラウンドロビン
優先度ベーススケジューリングは予測可能性は良いのですが,適当にArduinoのサンプルをマルチタスクで動かすとメインタスクしか動作しないため,使い勝手が悪いときがあります.
そのような場合は,r2ca_app.h でR2CA_RR_SCHEDULE を定義すると同一優先度間は一定周期のラウンドロビンスケジューリングになります.R2CA_RR_SCHEDULE_PRIのビット0(LSB)が優先度1に対応しており,1とした優先度をラウンドロビンスケジューリングとします.周期はR2CA_RR_SCHEDULE_CYCLEマクロでms周期で設定可能であり,設定しない場合は1m周期となります.
下記の例は全ての優先度を対象に,10ms周期でラウンドロビンスケジューリングする設定となります.
#define R2CA_RR_SCHEDULE_PRI 0xff
#define R2CA_RR_SCHEDULE_CYCLE 10
API発行
ITRON(正確にはASP)でサポートしているAPIは全て使用することが出来ます.各タスクのIDは上で示した通りです.
API | 機能 |
---|---|
slp_tsk() | タスクを待ち状態へ |
wup_tsk(taskid) | 待ち状態のタスクを起床する |
act_tsk(taskid) | タスクの起動 |
ext_tsk() | タスクの終了 |
dis_int() | 割込み禁止 |
ena_int() | 割込み許可 |
おわりに
APIの使い方等を勉強したい方は,組込みソフトウェア開発技術の基礎というテキストが無償でダウンロード可能なので,参考にして下さい.