はじめに
TOPPERS/R2CAは,Arduino M0 Pro (以下,M0)上で,Arduinoライブラリ+TOPPERS/ASPカーネルベースのマルチタスクプログラミング環境を提供するパッケージです.
この記事では,優先度・スケジューリングで紹介したAPIの詳細について説明します.開発環境のインストールやビルド&実行方法はこちらの記事を見て下さい.
使用可能なAPIとリファレンス
R2CAで使用可能なAPIはTOPPERS/ASPカーネルで使用可能なAPIです.API仕様はOSの仕様書にまとめられています.
事例を用いてAPIの使い方等を勉強したい方は,以下のテキストが無償でダウンロード可能なので,参考にして下さい.
ID
ITRON仕様ではタスクに対するAPIはタスクIDを指定して発行します.R2CAではすでに各タスクのIDは定まっており次の通りです.
タスク | タスク名 |
---|---|
メインタスク | R2CA_MAINTASK |
タスク1 | R2CA_TASK1 |
タスク2 | R2CA_TASK2 |
タスク3 | R2CA_TASK3 |
タスク4 | R2CA_TASK4 |
タスク5 | R2CA_TASK5 |
セマフォ等のオブジェクトは後述の静的APIで指定したマクロ名により指定します.
静的API
オブジェクトの生成は静的APIと呼ばれる記法により,r2ca_app.cfg に記載します.例えばセマフォを1個生成する場合は次のように記述します.
CRE_SEM(SEM1, {TA_NULL, 1, 1});
SEM1が生成したセマフォの名前でAPIではこの名前(実際にはマクロで数値となっている)を指定してAPIを発行します.
TA_NULLはセマフォの属性,次の1はセマフォの初期資源数,最後の1はセマフォの最大資源数です.
静的APIはビルド時にコンフィギュレータと呼ばれるツールにより処理
割込みハンドラからのAPI呼び出し
幾つかのAPIは割込みハンドラから呼び出し可能です.呼び出し可能なAPIについては,API名の頭に'i'が付いています.
APIの説明
代表的なAPIについて説明します.
割込み禁止許可
割込みを禁止・許可します.割込みを禁止した状態では他のAPIを呼び出せないので注意して下さい.
API
dis_int() : 割込みの禁止
ena_int() : 割込みの許可
ディスパッチ禁止許可
ディスパッチを禁止・許可します.割込み禁止許可と異なり割込みは禁止しません.タスク間で排他制御する場合に使用します.
API
dis_dsp() : 割込みの禁止
ena_dsp() : 割込みの許可
起床待ち
タスクを起床待ちするAPIとタスクを起床をするAPIです.タスクのみが呼び出すことが可能です.slp_tsk()を呼び出すると起床待ち状態となり,wup_tsk()により起床されるまで実行されません.実行されている状態のタスクに対してwup_tsk()を実行すると起床要求がキューイングされます.この状態でslp_tsk()を呼んでも起床待ち状態になりません.
API
slp_tsk() : 起床待ち
wup_tsk() : タスクの起床
iwup_tsk() : タスクの起床(割込みハンドラ)
セマフォ
タスク間で排他制御を実現するためのオブジェクトです.数に制限がある資源を使用する際にwai_sem()を呼び出して資源を取得します.資源がない場合は,セマフォ取得待ちになります.資源を使用した後はsig_sem()を呼び出して資源を返却します.返却時にセマフォ待ちのタスクがいれば起床させます.
セマフォの初期値と最大値はセマフォ生成時に静的APIのパラメータとして宣言します.初期値と最大値をシステムに合わせて正しく設定しないと正しく排他制御できないので注意して設定する必要があります.
API
sig_sem(SEMID) : セマフォ取得
wai_sem(SEMID) : セマフォ返却
静的API
仕様)
CRE_SEM(ID semid, { ATR sematr, uint_t isemcnt, uint_t maxsem })
例)ID : SEM1, 属性 : TA_NULL, 初期値 : 1,最大値 1
CRE_SEM(SEM1, {TA_NULL, 1, 1});
データキュー
32ビットのデータをやりとりするためのオブジェクト.いわゆるFIFOです.送信は割込みハンドラからも可能です.送信時は,バッファに空きがあればデータを格納してリターンします.空きがなければ待ち状態になります.受信時はバッファにデータがあれば取得してリターンします.バッファにデータが無ければ待ち状態となります.それぞれ反対に待ち状態のタスクがいれば起床させます.
バッファの個数は静的APIで設定します.
API
snd_dtq(DTQID, data) : データキューへの送信
ipsnd_dtq(DTQID, data) : データキューへの送信(割込みハンドラ)
rcv_dtq(DTQID, *data) : データキューからの受信
静的API
仕様)
CRE_DTQ(ID dtqid, { ATR dtqatr, uint_t dtqcnt, void *dtqmb })
例)ID : DTQ1, 属性 : TA_NULL, バッファ数 4
CRE_DTQ(DTQ1, {TA_NULL, 4, NULL});
おわりに
代表的なAPIの使い方について説明しました.次回はこれらのサンプルを作ってみたいと思います.