2015年12月30日水曜日

TOPPERSにトライ

自分は組み込み系のプログラムを作る仕事はほとんどしたことがないのですが、最近IoTが騒がれており、Raspberry Piもいじっているので小型のRTOS(リアルタイムOS)に興味がでてきました。
ただ、RTOSというのは通常特殊なメーカから販売されている高価なものしか使ってみたことがなく(しかも組み込み用途では使ったことありません)、オープンソースで手頃なものというとITRONになります。
TOPPERSというITRONの実装がかなり有名なようで、ぐぐると結構かかります。調べてみると、純粋なITRONの仕様から少し拡張されているようですが、活動が2015年現在でも活発に行われており、勉強用にLinux/Windows上でも動作できるエミュレータがついているとか。いきなりRaspberry Piにインストール、という前にちょっと勉強がてらLinux上で動かすのにトライしてみました。
(注:結論を先に述べておきますが、結局失敗しました。どうもLinux上のエミュレータの実装が、かなり古いLinux(おそらくkernel2.6系?)の時から更新されていないようで、今のUbuntu等のkernel3.x系で動かすのはかなり困難が伴うようです

1.TOPPERSのDL
TOPPERSのHP(http://www.toppers.jp/)に行ってみると、様々なバージョンがあるのにびっくりしました。各バージョンがどんな内容かひと通り読むだけで結構時間がかかりましたが、とりあえずスタンダードな以下をDLしてきました。

・TOPPERS/JSP-1.4.4.1

2.TOPPERSのビルド
以下のコマンドでLinuxエミュレータ上で動くものができるようです。(Linuxでは、sample1というプログラムが動くそうです)

$ ./configure -C linux
$ make depend
$ make

ところが当然ながら問題がでてきます。

(1)configureのperlスクリプトでエラーがでる。
configure:40lineで以下の行があります。

require "getopt.pl";

これ、perlのスクリプト起動時のオプションを拾ってくる機能拡張モジュールらしいんですが、現在では使われておらず、以下の様にするようです。

use Getopt::Std;
あと、Getoopt()→getopt()にする。

TOPPERSのMLの2012年にこの指摘があり、提案するとありましたがいまだに採用されていないようです。他の箇所にも同じような所がありましたが、修正してconfigureは通しました。

(2)make dependで、cfg/cfgがないと怒られる。
TOPレベルにcfg/というディレクトリがあるのですが、どうもここのビルドが実行されていないようです。make dependの段階でこれが必要ということは、configureの時点でアーキテクチャに応じてcfg/cfgがビルドされていることを期待しているんでしょうが、先の(1)の修正だけではまだ問題があったようです。
とりあえず手動でビルドして、cfg/cfgを作ります。
→これは、動かしたいTASKの登録をここでしておくので、先に設定をしてビルドしておくものだと判明。

(3)makeでエラー
さて、(2)までの修正でmake dependはパスしました。やっとビルドですが、以下の様なエラーがでてきました。

In file included from ../kernel/task.c:47:0:
../config/linux/cpu_context.h: In function ‘activate_context’:
../config/linux/cpu_context.h:74:35: error: ‘JB_PC’ undeclared (first use in this function)
     ((int *) &(tcb->tskctxb.env))[JB_PC] = (int) activate_r;
                                   ^
../config/linux/cpu_context.h:74:35: note: each undeclared identifier is reported only once for each function it appears in
../config/linux/cpu_context.h:75:35: error: ‘JB_SP’ undeclared (first use in this function)
     ((int *) &(tcb->tskctxb.env))[JB_SP] = (int)(((VB *) tcb->tinib->stk) +

何のことやらさっぱりですが、どうも自分の環境のライブラリには、"JB_PC", JB_SP"の定義がない、と怒られています。
そもそも、これらのdefineが何なのかぐぐってみると、cの関数で、setjmp()/longjmp()のための定義とのことでした。それらは本来以下の場所に定義されているようです。

/usr/include/setjmp.h
/usr/include/bits/setjmp.h

一つ目が2つ目をincludeしており、そこが肝心な部分なんですが、自分の環境(Ubuntu-14.04)ではそもそも2つ目のincludeが位置が違い、内容も大幅に変わっていて、JB_PC/JB_SPとかのdefineがありません。
bits/setjmp.hの定義場所が、CPUのアーキテクチャ毎のところになっていました。そもそも、このsetjmp()/longjmp()が何者なのかですが、c++等で例外処理にthrow→catchが使われていますが、cの時代にはこれが使われていたようです。つまり、ある関数を実行中(これが大事!)にエラーが発生したことを検知した場合、強制的に別のエラー処理用の関数にジャンプする関数だそうです。
かなりやばい系の関数ですが、当然その実装のためには様々なCPUのレジスタの退避とかしないと、エラー処理なんてできません。kernel2.x系の頃は、なんとかc言語だけで実装していたのを、kernel3.x系になったところでCPUアーキテクチャ別にしたようです。(性能とか、完全な動作を考えるとまともな考えですね。)
doc/linux.txtを見てみると、kernel2.2/glibc2.1の頃に作られた模様...、ちょっとこれはお手上げです。(・_・)


さてそうなるととりあえず自分ではお手上げの状態です。自分はc言語で、setjmp()/longjmp()を使ったことないので、既存のエミュレータをどう改修したらいいかわかりません。
自分のところにはまだ別の環境があるので、そちらで動かないか試してみます。


PS@20151231
自分の持っているVMPlayerの環境に、CentOS4と古いバージョンがありました。これで試してみると、

・(1)の問題は発生しません。やはりPerlの古い使い方のようです。
・makeで別の問題が発生しました。
 ../config/linux/tool_config.h:70: undefined reference to `software_term_hook'
ぐぐってみると、2007年に同じ問題にぶつかった人がMLに残していましたが、問題の箇所の関数はjsp-1.4.2のころは全部コメントアウトしてあったのが、jsp-1.4.3からコメントアウトが外されていて、エラーがでるようになったとのこと。別途、関数定義例があり、それを使ってビルド終了。

サンプルの、./jspが動くようになりました!ただコマンドをシリアルから入力することになっていますが、Linuxエミュレータ上で./jspプロセスのシリアルにどうやってつないだらいいのかわかりません。ttyで送ってみましたがダメでした。
まあ、とりあえず動かせる環境はできたんで、後はこれで勉強してみます。



0 件のコメント:

コメントを投稿