※ 2015年1月に執筆したものを転載
またまたscilab関連の話です。
といっても、話の焦点はどっちかというとRTOS側になると思います。
※RTOS
Real-time operating systemの略称です。
WindowsやLinuxに代表されるOSの一種ですが、 その中でも最軽量クラスのOSで、その名の通りリアルタイム性が売りです。
メモリ使用量も当然少ないため、 組み込み系ではかなり利用頻度の高いOSとなります。
Windows、Linuxなどの汎用OSと違いかなり機能が少なく、
・タスクの生成/制御/同期/通信
・簡易且つ高速なメモリアロケーション
ぐらいしかサポートしていないものがほとんどです。
タスク、メモリアローケーションがあるだけでも設計/実装が潤うんでかなり助かりますが。
そして、タイトルに入ってるCoSimulation。
日本語訳は「協調シミュレーション」になります。(シミュレーションが日本語になってない・・・。)
本来は、FPGA(HDL)とCPUの連携シミュレーションに特化した表現らしいのですが、
ここではもうちょい拡大解釈して、「複数のシミュレータ、またはシミュレーション要素から構成され、時間的同期をとったシミュレーション」を指すとします。
ここまで説明するともう何するかバレバレな感じですが、 RTOSシミュレータと数式シミュレータの合体技をやってみたいと思います。
ネタとしては、前回までに作成した、状態機、制御器、モータープラントを流用。
Scilab側に数式モデルのモータープラント。
RTOS側にソフトウェア要素の状態機、制御器。
のシミュレーションをさせます。
RTOS上にソフトウェア要素を実装するんで、構成としてはかなりマジっぽくはなってきました。
あとはScilabとRTOSのどちらに時間的主導権を握ってもらうかですが、 ここは当然Scilabになります。
RTOS側は生成msecオーダー、Scilabは連続時間で動作していることになっているので、 周期という概念すらもっていないことになっています。
よって、ここはScilab側でmsオーダーの周期を作ってもらって、 RTOS側に通知するのがよさそうです。
とりあえず全体像↓
タスクをI/Oタスク、状態機タスク、制御器タスクに分けてますが、特に意味は無いです。
すべて10msで周期で駆動させるつもりなので、1タスクに詰め込んでもきっとOKでしょう。
つなぎにSocketを使用してます。
共有メモリを使用した方がオーバーヘッドは少ないかもしれませんが、 これはそれぞれのシミュレータを別々のPCでできたらいいなぁってことで選定しました。
ちなみに、RTOSシミュレータはTOPPERSというITRON仕様OSを使用します。
例によってフリー且つオープンソースのブツです。
ライセンスはちょっと特殊で、「著作権明記」か「TOPPERS協会への利用の報告」のどちらかを満たしておけばOKで、商用利用を阻害しないことを意識したものとなっています。
割と多くのCPUに対応しているOSなのですが、
Windows、Linuxなどの汎用OS上で動作するシミュレータも含まれています。
今回はこのシミュレータを使用します・・・
と言いたいところなのですが、
Windows用シミュレータ・・・VC6.0用のプロジェクトで構成されているんですよね。
VS2005くらいまではプロジェクトのアップグレードで、若干の問題はあるものの使用できていたのですが、VS2008あたりを境にプロジェクトのアップグレードが失敗するようになってしまいました。
Linux用があるから、こっちにするかーと画策してましたが、 このたび運良くVS2010に対応させました。
さて、Scilab側でタイマ割込み用の通知をしてもらうのですが、
RTOS側にその口があるのかが問題になります。
結果から言うと、「ありました」
TOPPERSのフォルダ構成・・・に限らないのですが、 大概の汎用OSを含んだ複数のCPUに対応したタイプのOSは、システム依存部、CPUコア依存部、非依存部に分かれています。
今回はWindows上のシミュレータなので、 Windowsシステム依存ってことになります。
該当フォルダを漁れば割と速攻で目的のブツは発見できちゃいます。
Windowsシステムに於いてのタイマ割込み実現方法。↓
通常はOSのマルチメディアタイマのコールバックで実現しているようですが、
そのタイマコールバックで呼び出している割込み関数をScilabから通知されたタイミングで呼び出してやればOKな感じです。
試しにスレッドを一個こさせて適当な周期で呼び出したら
ちゃんとタイマ割り込み&カーネルへのタイマシグナルが発行されました。
マルチメディアタイマ内のリアルタイムスレッドから呼ばれるか、ノーマルスレッドから呼ばれるかの違いなので、動いて当然といえば当然ではあるのですが、一個一個見ていかないと不安なので。
なんとなくいけそうなので、
とりあえず、動かして見ましょう。
ScilabからのSocket関数呼び出しは毎度おなじみのCBlockを使用して呼び出します。
結果は、
ほーら、ばっちり動い・・・たけど、
なんか変だ。
妙に振動してしまっています。
はて?つなぎは間違ってないと思うし、(仮想的な)10ms周期で各タスクは動いているようなんですが・・・
つづく。
コメント