ここで、OpenRTM-aistに付属のサンプルをArmadillo上で実行してみます。 Armadillo-400シリーズはSDメモリカードスロットがついており、SDメモリに実行ファイル、ライブラリおよびrtc.conf等の設定ファイルをコピーしArmadilloに挿すことで、RTコンポーネントを実行することができます。
UNIX (Linux) では Windows とは異なり、システムのすべてのファイルやフォルダがルート('/') を頂点とする一つのツリー(木)構造を構成します。 (Widnowsでは、ドライブという概念があり、C:\, D:\, ... を頂点としたツリーが複数存在します。)
UNIXではシステムにディスク (ハードディスク、USBフラッシュメモリ、SDカードメモリ等) をつないだ場合、すでに存在するツリーのどこかにディスクを接続します。これをマウント (mount) と呼びます。
工場出荷状態のArmadillo-400シリーズでは、SDメモリカードを挿しても自動的にはマウントされないかもしれません。 ここでは、Armadillo起動後にSDメモリカードを自動的にマウントするように設定します。
ArmadilloにSDメモリカードを挿して起動します。アカウント名root、パスワードrootでログインします(デフォルト設定)。 まず、mountコマンドで何がどこにマウントされているかを確認します。
atmark-dist v1.30.0 (AtmarkTechno/Armadillo-440) Linux 2.6.26-at16 [armv5tejl arch]
armadillo440-0 login: root Password: [root@armadillo440-0 (ttymxc1) ~]# mount /dev/ram0 on / type ext2 (rw) proc on /proc type proc (rw) usbfs on /proc/bus/usb type usbfs (rw) sysfs on /sys type sysfs (rw) udev on /dev type tmpfs (rw) ramfs on /home/ftp/pub type ramfs (rw)
proc, usbfs sysfs udev ramfs はそれぞれ疑似デバイスなので、今は無視してください。 /dev/ram0 というのはRAMディスクです。Armadilloではフラッシュメモリに格納された / (ルート) から始まるディスクイメージをRAM領域に展開してRAMディスクとして / にマウントして利用しています。
もし、このリストに /dev/mmcblk0p1 から始まる行が含まれている場合 SD メモリがすでにマウントされている可能性があります。/dev/mmcblk0p1 はSDメモリカードへのアクセスをファイルに抽象化したデバイスファイルです。mmcblk0p1 は
mmcblk + 0 + p + 1 ( mmcblock型のデバイスの0番目の1番目のパーティション )
という意味です。ls -l /dev/mmcblk* でほかのデバイスを見てみると、
# ls -l /dev/mmcblk* brw-rw---- 1 root root 179, 0 Jan 1 1970 /dev/mmcblk0 brw-rw---- 1 root root 179, 1 Jan 1 1970 /dev/mmcblk0p1
/dev/mmcblk0 というデバイスもあることがわかります。これはSDメモリカード全体のデバイスファイルで、その下に第1番目のパーティションとして /dev/mmcblk0p1 が存在するといったイメージで考えてください。
ここで利用するのは、パーティション1のデバイスである /dev/mmcblk0p1 です。 以下のようにタイプしてください。
[root@armadillo440-0 (ttymxc1) ~]# mount -t vfat /dev/mmcblk0p1 /mnt [root@armadillo440-0 (ttymxc1) ~]# mount /dev/ram0 on / type ext2 (rw) proc on /proc type proc (rw) usbfs on /proc/bus/usb type usbfs (rw) sysfs on /sys type sysfs (rw) udev on /dev type tmpfs (rw) ramfs on /home/ftp/pub type ramfs (rw) /dev/mmcblk0p1 on /mnt type vfat (rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1)
SDメモリの第1パーティション /dev/mmcblk0p1 が /mnt 以下にマウントされていることがわかります。 なお、最初のコマンドで -t vfat というオプションは対象デバイスのファイルシステムを指定するためのオプションで、VFAT (Virtual File Allocation Table) の略で、Windows 95 以降で採用されたロングファイル名が利用可能なファイルシステムです。 最近のWindowsではNTFSが主流ですが、USBメモリ、SDメモリなどでは VFAT た exFATなどのファイルシステムがよく利用されています。
もし、-t vfat オプションでうまくマウントできない場合は、WidnowsにSDメモリカードを挿してVFATでフォーマットしなおしてください。
さて、SDメモリカードがマウントできることが確認できたので、この作業を自動化します。 /etc/config/rc.local というファイルは、システムが起動時に自動で呼び出してくれるシェルスクリプトです。(rc: run commands の略) vi を利用してrc.localを編集します。viの使い方はWebなどを参照してください。
[root@armadillo440-0 (ttymxc1) ~]# vi /etc/config/rc.local
このファイルの最後のほうに、以下のコマンドを追加します。
if test -b /dev/mmcblk0p1; then echo -n "Mounting SD memory" mount -t vfat /dev/mmcblk0p1 /mnt check_status fi
if test -b ~ で /dev/mmcblk0p1 というブロックデバイスファイルがあるかどうかをチェックしています。ある場合は、Mounting SD memory とコンソールに表示し、mountコマンドでSDメモリを /mnt にマウントします。
起動時に以下のように done/failed といったメッセージがコンソールに表示されましたが、
Starting lighttpd: done Creating avahi.services: done Starting avahi.daemon: done Starting Xfbdev: failed
これは、起動時の実行したコマンドが正常に終了したかを示しています。 この done/failed を表示していたのが check_status というコマンドで、直前のコマンドの実行が成功したか否かを表示します。
SDメモリを自動的にマウントするだけでなく、マウントしたSDメモリカードに入っているRTCを自動的に起動するように設定します。
マウントしたSDメモリのトップにboot.shというシェルスクリプトを置き、そこにRTCを起動する手順を記述するものとします。 rc.local には以下のようなコマンドを SDカードをマウントするコマンドの後に 記述します。
if test -f /mnt/boot.sh; then echo -n "Starting RTCs" sh /mnt/boot.sh check_status fi
Armadillo-420/440 等ではリアルタイムクロックをバックアップする電池などは搭載されていないため、起動直後のクロックは無意味時刻を示します。 そこで、NTPで正確な時刻にセットします。
SDメモリカードをマウントするコマンドの前にに以下のコマンドを入力してください。
echo -n "Adjusting clock" ntpclient -h ntp.ring.gr.jp -s check_status
これで、Armadilloがネットワークにつながっていれば、NTPで正確な時刻を取得してクロックに設定します。
さて、ここまで編集したrc.localは、そのままでArmadilloを再起動すると消えてしまいます。 上でも述べたように、Armadillo のシステムファイルはフラッシュメモリ上に圧縮され格納されており、起動時にRAM領域に展開されて利用されます。 システム上のファイルを変更しても、電源を切って再投入すれば、すべてのファイルは元に戻ります。
しかし、/etc/config ディレクトリ以下のファイルだけは、システム全体とは別の領域に格納されており、flatfsdというコマンドに-sオプションをつけて起動することにより変更を保存することができます。
[root@armadillo440-0 (ttymxc1) ~]# flatfsd -s flatfsd: saving fs to partition 0, tstamp=1 flatfsd: Wrote 5686 bytes to flash in 1 seconds [root@armadillo440-0 (ttymxc1) ~]#
これでArmadillo側の事前の準備は完了です。電源を入れなおして再起動してみてください。 再起動後ログインし、mountコマンドでSDメモリがマウントされていることを確認します
なお、flatfsdの詳細についてはArmadilloのサイトの以下の文書を参照してください。以下のようなディレクトリ構成でファイルを配置します。
sdmemory + lib: ライブラリを格納するディレクトリ + rtc: RTコンポーネントを格納するディレクトリ + rtc.conf: RTコンポーネントの設定ファイル + boot.sh: RTコンポーネント起動スクリプト
libディレクトリには、RTコンポーネントを実行するのに必要なライブラリを格納します。最低限必要なライブラリは以下のものになります。
この他、動作させたいRTコンポーネントが依存しているライブラリがあれば、それらもいっしょにlibディレクトリにいれておきます。
さて、上記のライブラリや、RTCが依存ライブラリをしているライブラリを調べるには、どのようにすれば良いのでしょうか? Linuxでの開発経験がある人は、ldd コマンドを思いつくかもしれません。 lddコマンドは実行ファイルや共有ライブラリの依存関係を表示するコマンドで以下のように使用します。
atmark@atde3:~$ ldd /usr/lib/libm.so /lib/ld-linux.so.2 (0xb7f36000) linux-gate.so.1 => (0xb7f35000) libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7da6000)
libm (sin, cos関数など含む数学ライブラリ) はlibc など幾つかのライブラリに依存していることがわかります。
しかし、あいにく対象はARM用のライブラリであり、lddは利用することはできません。 こう言った場合には、readelfコマンドを使用します。ARM用のバイナリに対して利用できる arm-linux-gnueabi-readelf コマンドは /usr/bin/arm-linux-gnueabi-readelf にあります。
$ arm-linux-gnueabi-readelf -d /usr/arm-linux-gnueabi/lib/libomniORB4.so | grep NEEDED 0x00000001 (NEEDED) Shared library: [libomnithread.so.3] 0x00000001 (NEEDED) Shared library: [libpthread.so.0] 0x00000001 (NEEDED) Shared library: [libstdc++.so.6] 0x00000001 (NEEDED) Shared library: [libm.so.6] 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x00000001 (NEEDED) Shared library: [libc.so.6]
このように、libomniORB4.soが依存しているライブラリを調べることができます。 対象とする実行ファイルやライブラリが依存しているライブラリを再帰的にに調べ上げて、libディレクトリにコピーする必要があります。
SDメモリに格納されたライブラリをを利用してRTコンポーネントを実行するには、SDメモリのlibディレクトリにライブラリサーチパスを通す必要があります。
SDメモリは /mnt ディレクトリにマウントとすると、ライブラリのパスは /mnt/lib となります。ライブラリサーチパスを通すには、環境変数 LD_LIBRARY_PATH にこのパス /mnt/lib をセットする必要があります。
export LD_LIBRARY_PATH =/mnt/lib
このほか、rtcディレクトリ以下にあるRTCの実行ファイルをすべて起動するスクリプトの例を以下に示します。
#!/bin/sh MOUNT_POINT=/mnt export LD_LIBRARY_PATH=$LIBPATH:$MOUNT_POINT/lib/ comps=`ls $MOUNT_POINT/rtc` for r in $comps; do $MOUNT_POINT/rtc/$r -f $MOUNT_POINT/rtc.conf & done
LD_LIBRARY_PATHにパスを通して、rtcディレクトリの中にあるRTコンポーネントの実行ファイルを全て起動します。
PC上で実行する場合と同様にRTコンポーネントを起動後、その名前と参照を登録するネームサーバを、corba.nameservers オプションで指定します。また、デバッグフェーズではログに関するオプションも指定した方が良いかもしれませn。
corba.nameservers: 192.168.11.10 logger.log_level: PARANOID logger.file_name: /mnt/rtc%p.log
この例では、ネームサーバのアドレスを192.168.11.10に、ログレベルをPARANOID (すべてのメッセージをログに残す) に指定し、そのログファイル名をSDメモリ上の /mnt/rtc<プロセス番号>.log にしています。
詳しくは、デベロッパーズガイドの設定ファイル (基礎編)およびrtc.conf設定項目一覧を参照してください。
以上の作業を自動化するスクリプトが、openrtm_sdmem.sh です。このスクリプトのヘルプを示します。
atmark@atde3:~$ openrtm_usbmem.sh -h Usage: openrtm_usbmem.sh -d <dir> -r <rtc> -l <libdir> This script creates a directory to be copied to USB memory for Armadillo execution environment. One or more RTCs can be specified by -r and are copied to rtc directory. Dependent libraries are automatically analyzed and copied to lib directory. boot.sh to launch RTCs and rtc.conf for RTCs are also created. -d <dir> Target directory -r <rtc> Target RTC binary -l <libdir> Library search path -h Print this help EXAMPLE $ cd my_component_dir $ ls mycomponent mycomponent.so $ openrtm_usbmem.sh -d /tmp/usbmem -r mycomponent -l . -l ../deplibdir
-dオプションでファイルをコピーするターゲットディレクトリ、-rオプションでRTコンポーネントの実行ファイル、ーlでライブラリを検索するディレクトリをそれぞれ指定し実行します。