理想のRTOSを自作する (4)

【実装】

当初、アセンブラの利用もやむなしと考えていたが、コンテキスト・スイッチングにsetjmp()/longjmp()を使ったおかげで全てをC/C++言語だけで記述することができてしまった。と言ってもSDKで定義されているCPU命令マクロなどは使っているので完全にC/C++言語だけとは言えないような気もするが...

普段はヘッダーファイルだけで記述することが多いのだが、ヘッダーファイルだけにすると双方向参照をうまく解決することができないので、今回は明確にヘッダーとコードを分け、さらにインクルードを簡単にするために複数のヘッダーファイルを一つにまとめたインクルード専用ヘッダーファイルを作成してみた。

【構成】

avros.h … 共通インクルード・ファイル
heap.h … メモリ管理クラス
task.h/task.cpp … タスク管理クラス
timer.h/timer.cpp … タイマー管理クラス
wait.h…同期管理のベース・クラス
pcint.h/pcint.cpp … GPIO管理クラス
sem.h/sem.cpp … セマフォ・クラス
mutex.h/mutex.cpp … ミューテックス・クラス
queue.h … キュー・ライブラリ
ioport.h … GPIOライブラリ
variants.h … ボード仕様の定義

【共通インクルード】

【タスク管理クラス】

タスク生成は任意のタイミングで生成が可能。また、一般的にはスケジューラの開始関数呼び出しから戻ることが出来ないが、スケジューラー開始時のコール・コンテクストをデフォルト・タスクとして割り当てることで関数呼び出しから戻ることが可能となっており、arduino等の既存プラットフォームとの親和性を高く保つことができるよう考慮している。

なお、全タスクが休止状態になるとスリープモードに入り割り込みだけを待つようになる。スリープ・モードの規定値はアイドル・モードであるが変更は可能。パワーマネジメントは仕様外ではあるものの、うまく連携できる仕組みを作れるなら超省電力化も夢ではない。かも。

【概要】

タスクを生成しスタート関数(func)を実行する。スタート関数には一個のパラメタ(arg)を渡すことができる。引数省略時、128バイトのスタック領域、最低優先度として生成される。より大きなスタック領域を必要とするコードを実行する場合はスタック領域として適切な値を指定すること。指定関数(func)から戻るとタスクは削除される。タスクが生成されるとtrue、失敗するとfalseを返す。

スケジューラーを開始する。prioはデフォルト・タスクの優先度を指定する。デフォルト・タスクとしてこの呼出しから戻ってくる。

カレント・タスクの優先度を変更し変更前の優先度を返す。優先度が変更されなかった場合は、0xFFが返される。

全タスク休止時のスリープ・モードを設定する。

カレント・タスクと同一優先度内でラウンドロビン・スケジューリングを行う。

カレント・タスクの空きスタック領域のバイト数を取得する。空きスタック領域が少なすぎるとスタック・オーバーフローとなる可能性がある。デバッグ用であり運用時の使用は推奨しない。

【ソース・コード】

【関連する投稿】
理想のRTOSを自作する (1)
理想のRTOSを自作する (2)
理想のRTOSを自作する (3)
理想のRTOSを自作する (4)
理想のRTOSを自作する (5)
理想のRTOSを自作する (6)
理想のRTOSを自作する (7)
理想のRTOSを自作する (8)
理想のRTOSを自作する (9)
理想のRTOSを自作する (10)
理想のRTOSを自作する (11)

カテゴリーrtos

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください