組み込みシステム向けRTOS


57

時間管理とリソース管理にRTOSを使用する必要があることを伝える多くの記事を見てきました。私の時間は私自身の研究を許可していないので、私はチップハッカーに助言を求めに来ます。

低リソースのマイクロコントローラー(MSP430、PIC)を使用しており、使用できるRTOSを探していました。

ポイントへ:

  1. システムのリソースコスト
  2. システムの利点
  3. システムの欠点
  4. 実装のコツ
  5. RTOSを使用すべき/すべきでない状況。

私はarduinoのようなシステムを使用していません。一緒に作業するプロジェクトでは、そのようなシステムのコストをサポートできません。


2
私はこれが下票を受け取ったものについて混乱しています。投票者からフィードバックが得られた場合、今後このような行動を避けようとします。
Kortuk

1
同上。それは....素晴らしい質問です
ジェイソンS

私は質問を受け入れましたが、これは自由であると考えられていても、多くの素晴らしい反応があり、その努力に対して少なくとも1人の作家に報酬を与えたいと思ったからです。
コルトゥク

回答:


29

私はQNX以外のRTOSの個人的な経験はあまりありません(全体的には素晴らしいですが、安くはありませんし、特定のボードベンダーとQNXのシステムに関する他の気にしない態度は本当に悪い経験でしたPICやMSP430には大きすぎる。

RTOSの恩恵を受ける場所は、次のような分野です。

  • スレッド管理/スケジューリング
  • スレッド間通信+同期
  • stdin / stdout / stderrまたはシリアルポートまたはイーサネットサポートまたはファイルシステム(シリアルポートを除くほとんどの部分でMSP430またはPICではない)を備えたシステムでのI / O

PICまたはMSP430の周辺機器の場合:シリアルポートの場合、リングバッファーと割り込みを使用します。システムごとに1回書き込み、再利用するだけです。他の周辺機器は、ベンダー固有であるため、RTOSから多くのサポートを受けるとは思わないでしょう。

マイクロ秒まで確固たるタイミングが必要な場合、RTOSはおそらく役に立たないでしょう-RTOSはタイミングを制限していますが、通常、コンテキストスイッチング遅延のためにスケジューリングにタイミングジッターがあります... PXA270で実行されているQNXはジッタは通常数十マイクロ秒、最大100〜200usなので、約100Hzよりも高速で実行する必要があるものや、約500usよりもはるかに正確なタイミングが必要なものには使用しません。そのようなものについては、おそらく独自の割り込み処理を実装する必要があります。一部のRTOSはそれでうまく動作し、他のRTOSはそれを非常に苦痛にします。あなたのタイミングとタイミングがうまく共存できないかもしれません。

タイミング/スケジューリングが複雑すぎない場合は、適切に設計されたステートマシンを使用することをお勧めします。C / C ++のPractical Statechartsを読むことを強くお勧めします。私が働いている私たちのプロジェクトのいくつかでこのアプローチを使用しており、複雑さを管理するために従来のステートマシンよりもいくつかの本当の利点があります。これがRTOSを必要とする唯一の理由です。


私は、最も経験豊富な組み込みシステムの人が大学を出ていない新興企業で働いています(つまり、自分と約2年間働いている他の人)。私は、勤務時間中に非常に多くの時間を産業慣行について自分自身に教えています。私が読んでいるように、私たちの最も低コストのシステムを除いて、RTOSは大きな改善となるでしょう。
Kortuk

PICやMSP430などの非常に複雑なシステムから決定論的なシステムを作成し、モジュールを分離しておく管理を大幅にクリーン化するのに役立つ、非常に低いリソースのRTOSシステムがあるようです。私は、現場でのデータ収集とルーティングシステムを効果的に構築した2人のチームの一員でした。RTOSを見ると、設計したものに最適であることがわかりました。
Kortuk

3つの投稿スロットを使用してすみません、あなたの答えは非常に役に立ちます。非常に低リソースのソリューションを探していますが、この情報は貴重なものです。ご協力ありがとうございます。
Kortuk

コメント数について心配する必要はありません(StackExchangeフレームワークに不足していることの1つは、ディスカッションのサポートです... Q / A形式はほとんどのものをカバーしていますが、一部はカバーしていません)...あなたが探しています。Steveが言及したFreeRTOSについては見ていないが、ローエンドのマイクロコントローラーに移植されていれば、おそらく必要なスケジューリング管理を行うことができるだろう。
ジェイソンS

スタック(50プッシュ/プルステートメントのようなもの)を通して各スレッドの状態を保存し、時限割り込みを処理できるようです。私のシステムは通常、スレッドの切り替えにポート割り込みを使用しますが、タスクは実行可能に見えます。このサイトの種類がより良い形式で議論を処理することを望みます。
Kortuk

26

FreeRTOSを試しましたか?これは無料で(T&Cの対象)、MSP430といくつかのPICの両方に移植されています。

他の一部と比較して小さいですが、これは、特にRTOSを使用したことがない場合は特に、簡単に習得することもできます。

(非フリー)商用ライセンスとIEC 61508 / SIL 3バージョンが利用可能です。


1週間以内に調査します。質問は他の回答のために公開しておきますが、あなたは大いに助かります!
Kortuk

12

8052(8ビット)システムでも動作するNuttX RTOS について知りました。たくさんのポートはありませんが、面白そうです。POSIXは、より強力なプロセッサに移行してリアルタイムLinuxまたはQNXを実行したい場合、コードの一部の移植性が若干向上するため、プラスになる可能性があります。

私は商用RTOSの経験はありませんが、何年も自家製のものを使用しています!基本的に、それぞれが「タスク」または「スレッド」を取得してそれぞれの部分で作業できるため、多くのプログラマーの間でコード開発を分割するのに役立ちます。あなたはまだ調整する必要があり、誰かがプロジェクト全体を監督して、各タスクが期限に間に合うようにする必要があります。

また、RTOSを使用する場合は、レート単調分析またはRMA を調査することをお勧めします。これにより、重要なタスクが期限に間に合うことを保証できます。

また、RTOSの有無に関係なく、リアルタイム機能を提供できるMiro SamekのQP-nanoイベント駆動型プログラミングフレームワークも検討します。これにより、設計を従来のタスクの代わりに階層状態マシンに分割します。ジェイソンSは彼の投稿でミロの本に言及しました。素晴らしい読み物!


9

いくつかのマシンで役に立つとわかったものの1つは、単純なスタックスイッチャーです。私は実際にPIC用に作成していませんが、両方/すべてのスレッドが合計31以下のスタックレベルを使用している場合、PIC18でこのアプローチがうまく機能すると期待しています。8051のメインルーチンは次のとおりです。

_taskswitch:
  xch a、SP
  xch a、_altSP
  xch a、SP
  ret

PICでは、スタックポインターの名前を忘れますが、ルーチンは次のようになります。

_taskswitch:
  movlb _altSP >> 8
  movf _altSP、w、b
  movff _STKPTR、altSP 
  movwf _STKPTR、c
  帰る

プログラムの開始時に、altSPに代替スタックのアドレスをロードするtask2()ルーチンを呼び出し(16はおそらくPIC18Fxxに適しています)、task2ループを実行します。このルーチンは決して戻ってはいけません。さもないと物事は痛みを伴う死で死にます。代わりに、プライマリタスクに制御を渡したい場合は、_taskswitchを呼び出す必要があります。プライマリタスクは、セカンダリタスクに譲りたいときはいつでも_taskswitchを呼び出す必要があります。多くの場合、次のようなかわいいルーチンがあります。

void delay_t1(unsigned short val)
{
  行う
    taskswitch();
  while((unsigned short)(millisecond_clock-val)> 0xFF00);  
}

タスクスイッチャーには、「条件待機」を行う手段がないことに注意してください。サポートするのはスピンウェイトだけです。一方、タスクスイッチは非常に高速であるため、他のタスクがタイマーの期限切れを待っている間にtaskswitch()を試行すると、他のタスクに切り替わり、タイマーをチェックし、通常のタスクスイッチャーよりも速く切り替えますタスクを切り替える必要がないと判断します。

協調型マルチタスクにはいくつかの制限がありますが、一時的に妨害された不変式をすぐに再確立できる場合、多くのロックやその他のミューテックス関連コードの必要性を回避することに注意してください。

(編集):自動変数などに関するいくつかの注意事項:

  1. タスク切り替えを使用するルーチンが両方のスレッドから呼び出される場合、通常、ルーチンの2つのコピーをコンパイルする必要があります(異なる#defineステートメントを使用して、同じソースファイルを2回含めるなど)。特定のソースファイルには、1つのスレッドのみのコードが含まれるか、スレッドごとに1回ずつ2回コンパイルされるコードが含まれるため、「#define delay(x)delay_t1(x)」などのマクロを使用できます。 #define delay(x)delay_tx(x) "使用しているスレッドに応じて。
  2. 呼び出されている関数を「見る」ことができないPICコンパイラは、そのような関数がすべてのCPUレジスタを破壊する可能性があると想定しているため、タスクスイッチルーチンにレジスタを保存する必要がありません[プリエンプティブマルチタスク]。他のCPUに対して同様のタスクスイッチャーを検討している人は、使用中のレジスタ規則を知っている必要があります。タスクを切り替える前にレジスタをプッシュし、その後ポップすることは、適切なスタックスペースが存在することを前提として、物事を処理する簡単な方法です。

協調マルチタスクでは、ロックなどの問題を完全に回避することはできませんが、実際には非常に単純化されます。たとえば、圧縮ガベージコレクターを備えたプリエンプティブRTOSでは、オブジェクトを固定できるようにする必要があります。協力的なスイッチャーを使用する場合、taskswitch()が呼び出されたときにGCオブジェクトが移動する可能性があるとコードが想定している限り、これは必要ありません。ピン留めされたオブジェクトを心配する必要のない圧縮コレクターは、それを行うコレクターよりもはるかに簡単です。


1
素晴らしい答え。私自身のRTOSへのアプローチに関するリソースに関するリンクを取得することは興味深いと思います。ここでの私の焦点は、ハードリアルタイムを保証する作業を行ったベンダーから高品質のRTOSを取得することでしたが、これは私にとっては楽しい趣味のプロジェクトかもしれません。
-Kortuk

1
クール、ちょうどSP ...切り替えなどのタスクを考えたことはありません
NickHalden

1
@JGord:8x51およびTI DSPで小さなタスクスイッチャーを実行しました。上記の8051は、正確に2つのタスク用に設計されています。DSP 1は4で使用され、もう少し複雑です。ただ、おかしなアイデアがありました。3つのタスクスイッチャーを使用するだけで4つのタスクを処理できます。最初の2つのタスクのいずれかがタスク切り替えを行うたびに、TaskSwitch1とTaskSwitch2を呼び出す必要があります。2番目の2つのタスクのいずれかがタスク切り替えを行う場合、Taskswitch1およびTaskswitch3を呼び出す必要があります。コードがstack0で始まり、各タスクスイッチャーが対応するスタック番号で設定されていると仮定します。
-supercat

@JGord:うーん...それはまったく機能しません。3ウェイのラウンドロビンが生成され、3番目のスイッチャーは無視されるようです。まあ、実験して、おそらくあなたは良い式を見つけると思います。
-supercat

7

MSP430でSalvoを使用しました。これは、プロセッサリソースに非常に軽く、実装ルールに従うことを条件に、非常に使いやすく、信頼性がありました。これは協調OSであり、タスク切り替えは、タスク関数の外部関数呼び出しレベルで実行する必要があります。この制約により、OSはタスクコンテキストを維持する膨大なスタックスペースを使用することなく、非常に小さなメモリデバイスで動作できます。

AVR32では、FreeRTOSを使用しています。繰り返しになりますが、これまでのところ非常に信頼できますが、FreeRTOSが公開するバージョンとAtmelフレームワークで提供されるバージョンとの間に設定/バージョンの不一致がいくつかあります。ただし、これには無料であるという利点があります!


5

Everyday Practical Electronicsの12月版には、PICのリアルタイムオペレーティングシステムに関するシリーズの第3部(PIC n 'Mixコラム)があり、MPLABとPICKit 2を使用したFreeRTOSのセットアップの詳細が記載されています。さまざまなRTOSのメリットを議論し、FreeRTOSに落ち着いたようです。現在の記事で開発環境をセットアップすると、バイナリデジタルクロックの設計を開始します。このトピックについては、少なくとももう1つのパートがあるようです。

EPEが米国でどの程度入手可能かはわかりませんが、そのサイトからリンクされている米国のストアがあるようで、電子コピーが入手できる可能性があります。


4

PIC用のCCSコンパイラには、シンプルなRTOSが付属しています。試したことはありませんが、このコンパイラーがあれば、簡単に実験できます。


1
私は実際にこれを初めて試しました。言葉の本当の意味でのRTOSではありません。それは決して先制的ではありません。RTOSが次に実行するユーザーを決定できるように、yieldコマンドを定期的に使用する必要があります。別のプログラムが引き継ぐ必要がある場合に備えて、意図的にそれらを常に入れなければなりません。
Kortuk

2
まだRTOSと呼ばれていると思います。完全にプリエンプティブなスケジューラーではなく、協調的なスケジューラーを持っているようです。
ジェイアトキンソン

はい、それはまだ技術的にはRTOSですが、私はそれに対してほとんど価値がありませんでした。私はそれが個人的なものであることを知っていますが、私にとって価値があるためには先制的である必要があります。それは良い答えであり、価値があるので、私はまだ+1。
コルトゥク

3

ありがとう!ほとんどの人が質問を受け取っていないようですが、それでも面白いです。
Kortuk

ユーザーにE&Rに助けを求めて招待するように、SOに関する質問に投稿しました。
-Kortuk

私たちはSOに関する質問を「得た」と思う、それは何か違うことを尋ねていたが、この質問に関連していた。認定についてのコメントについては、それは多くのことに依存します。ここでの回答を見ると、QP-nanoに関するDoxaLogosの回答が好きです。私の経験から、スレッドよりもイベント駆動型コードや、スレッドの暗黙的なコンテキスト切り替えを好むようになりました。
janm

2

あなたはあなたのアプリケーションについてあまり語っていません。RTOSを使用するかどうかは、PICで何をする必要があるかに大きく依存します。厳密な時間制限を必要とする、またはいくつかのスレッドを実行している、いくつかの異なる非同期処理を行っている場合を除き、RTOSは過剰である可能性があります。

最も重要なものに応じて、マイクロコントローラーで時間を整理する方法は多数あります。

  1. 一定のフレームレート:たとえば1000Hzで実行する必要があるサーボコントローラーを実行するPICの場合。PIDアルゴリズムの実行時間が1ミリ秒未満の場合、ミリ秒の残りを使用して、CANバスの確認、センサーの読み取りなど、他のタスクを実行できます。

  2. すべての割り込み:PICで発生するすべては、割り込みによってトリガーされます。割り込みは、イベントの重要度に応じて優先順位を付けることができます。

  3. ループに貼り付けて、できるだけ早くすべてを実行します。これにより、適切な時間制限が提供されることがあります。


他の方法も理解していますが、RTOSに拡張したいと考えています。複数のタスクを実行し、ハードリアルタイムシステムを使用しますが、ハードリアルタイムの要件なしで開始することを希望します。回答に時間を割いていただきありがとうございますが、RTOSを学び、需要の高い状況で使用できるようにしたいと考えています。
-Kortuk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.