SyntaxHighlighter

2015年7月2日木曜日

Windows上に、Eclipseを用いたRaspberry PiのC言語クロスコンパイル開発環境を作る。(ついでにBoost)

参考文献(Linux版の手順)
http://www.sadaji.net/Firmware/eclipse/index.htm

本ページでは、初心者をターゲットに説明している。
多少不快な表現があるかも知れないが、流して欲しい。


Windowsでの手順を以下に示す。

1.以下のものをダウンロードする。

・Pleiades All in One 日本語ディストリビューション [必須]
C/C++ 64bit Full Edition
http://mergedoc.osdn.jp/

バージョンは4.5 Marsで確認済み。32bit環境では当然32bit版が必要。Ultimateでもよい。
日本語が嫌いであれば、Eclipse公式でも良い。

・Windows toolchain for Raspberry/PI [必須]
GCC 4.6.3である、raspberry-gcc4.6.3.exeで動作確認済み。
http://gnutoolchains.com/raspberry/

・Boost C++ Libraries [おまけ]
Version 1.58.0で確認している。
http://www.boost.org/

・TeraTerm [おまけ]
SCPでファイル転送、コンソールアクセスする。
他に転送手段がある、SSHアクセスしないでUSBなどで渡す場合はなくても良い。
http://www.forest.impress.co.jp/library/software/utf8teraterm/


2.インストール手順

2-1.TeraTerm
 適当にインストールしてください。これが出来ないなら以下読まないほうがいいです。

2-2. Eclipse - Pleiades All in One
 適当なところに解凍すればそれでインストール完了です。
 ただ、デスクトップなどに置くのは非常におすすめしません。

 ここてば、C:\Pleiades\ に解凍したと仮定します。
 C:\Pleiades\Eclipse\ に、Eclipse.exeがあればOKです。

 初回起動時は、Eclipse.exeではなく、eclipse.exe -clean.cmd」で起動します。
 キャッシュのクリーンアップが行われます。

 ワークスペースの選択は、「../workspace」のままで構いません。
 C:\Pleiades\workspace\に保存されます。
 
 「この選択をデフォルトとして使用し、今後この質問を表示しない」にチェックを付けてOK。
 しばらくして、起動が完了したら閉じましょう。

2-3 Windows toolchain for Raspberry/PI
 ダウンロードしてきたEXEファイルを起動すると、すぐにインストール直前の画面になります。
 デフォルトでは「C:\SysGCC\Raspberry」にインストールするようになっています。
 利用規約(GPLライセンス)を読み、同意できる場合は、
 そのまま、「I accept the terms of liscense agreement」にチェックを付け、
 Installボタンを押すとインストール完了です。

2-4 Boost C++ Libraries
 入れる人だけ。ここではヘッダーオンリーでBoost asioを使う解説しかしないので
 その場合のみ説明します。
 http://sourceforge.net/projects/boost/files/boost/1.58.0/
 ここからダウンロード。zipでもよいが、個人的には7zの方がオススメ。
 
 ダウンロードしたら、解凍すれば完了。ヘッダーオンリーで使用するなら、
 Bootstrapもb2も不要。

 C:\boost_1_58_0\に解凍したと仮定する。

3.プロジェクトの作り方(Hello Worldをする)
3-1. まずはじめに
 もうセットアップは終わっているので、プロジェクトを作りましょう。
 まず、Eclipse.exeを起動。

 起動したら、「ファイル(F)」→「新規(N)」→「Cプロジェクト」



3-2. 「Cプロジェクト」
 プロジェクト名は適当に。ここでは「ccHello」とする。
 ここで、プロジェクト・タイプは「実行可能」→「空のプロジェクト」。
 ツールチェーンを「Cross GCC」とすること。
 設定したら次へ。

 

3-3 「構成の選択」
特に何も変更せず次へ。

3-4 「クロスGCCコマンド」
重要です。
クロス・コンパイラー接頭部に「arm-linux-gnueabihf-
クロス・コンパイラー・パスに「C:\SysGCC\Raspberry\bin」と入力。
そして完了をクリック。



3-5 ソースファイル入れよう
 プロジェクトは生成されましたが、空っぽです。
 ので、プロジェクトccHelloを右クリック。
 「新規(N)」→「ソース・ファイル」をクリック。


「新規ソース・ファイル」というダイアログが開くので
ソース・ファイルの欄に、main.cと入力。(.cのファイル名であれば何でも良いが)
そして「完了(F)」をクリック。


3-6 Hello Worldしよう。
 ソースが打ち込めるようになるので、HelloWorldを打ちましょう。

3-7 ビルドしよう
 打ち込み終わったら、「ファイル(F)」→「すべて保管(Ctrl + Shift + S)」をクリック。

できたら、「プロジェクト(P)」→「すべでビルド(A)」をクリック。
ビルド結果は下に出ます。無事ビルドできましたかね?

ここで出来たバイナリは、ARM-Linux専用です。Windows上では実行できません。

3-8 ファイルを見に行こう
 特にビルド設定を変えていなければ、出来上がったファイルは
 「C:\pleiades\workspace\ccHello\Debug」に「ccHello」として生成されています。

 これをTeraTerm等でRaspberryPiに転送。
 chmod 777 ccHello
 などとして、実行権限を付与した後、
 ./ccHello
 と実行し、
 「Hello World\n」と表示されれば万歳です。

4-1 C++で作る場合の注意点。
  プロジェクトを上記の「Cプロジェクト」で作ってしまった場合、もれなくC++言語は
 コンパイルやビルドに失敗します。

 「新規(N)」→「C++ プロジェクト」から生成したプロジェクトでは、正常に行きます。


力尽きたのでここまで。
Boostを使う場合などの注意点は、あとで追記するかもしれません。


Boost aisoを使う場合のヒント。

ヒント1
当然インクルードパスの設定は必要です。ただちょっと罠がある。
GCCではなく、G++の方に設定する。

(.text+0x34): undefined reference to `main'
mainなんて関数ないヨとエラーを吐かれる時は、インクルードパスを直してると治ります。
というか、多分、ソースを保存してないだけだと思います。

デフォルトでは、ビルド時自動で保存はしてくれないです。

ヒント2
Boost Asioをヘッダオンリーで使う場合、「ライブラリがない」エラーを吐きます。

C:\boost/boost/system/error_code.hpp:221: undefined reference to `boost::system::generic_category()'
C:\boost/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
C:\boost/boost/system/error_code.hpp:223: undefined reference to `boost::system::system_category()'
./main.o: In function `error_code':
C:\boost/boost/system/error_code.hpp:322: undefined reference to `boost::system::system_category()'
./main.o: In function `boost::asio::error::get_system_category()':
C:\boost/boost/asio/error.hpp:230: undefined reference to `boost::system::system_category()'


ソースの先頭に以下の記述をすれば治ります。

#define BOOST_DATE_TIME_NO_LIB
#define BOOST_REGEX_NO_LIB
#define BOOST_ERROR_CODE_HEADER_ONLY
#define BOOST_SYSTEM_NO_LIB

ヒント3
それでもpthreadが無いエラーを吐くので

./main.o: In function `boost::asio::detail::posix_tss_ptr_create(unsigned int&)':
C:\boost/boost/asio/detail/impl/posix_tss_ptr.ipp:34: undefined reference to `pthread_key_create'
./main.o: In function `~posix_tss_ptr':
C:\boost/boost/asio/detail/posix_tss_ptr.hpp:48: undefined reference to `pthread_key_delete'
./main.o: In function `boost::asio::detail::posix_tss_ptr<boost::asio::detail::call_stack<boost::asio::detail::task_io_service, boost::asio::detail::task_io_service_thread_info>::context>::operator boost::asio::detail::call_stack<boost::asio::detail::task_io_service, boost::asio::detail::task_io_service_thread_info>::context*() const':
C:\boost/boost/asio/detail/posix_tss_ptr.hpp:54: undefined reference to `pthread_getspecific'
./main.o: In function `~posix_tss_ptr':
C:\boost/boost/asio/detail/posix_tss_ptr.hpp:48: undefined reference to `pthread_key_delete'
collect2: ld returned 1 exit status
make: *** [ccpHello] Error 1

ライブラリの設定にpthreadを追加してやればOKです。


以上。

2015年7月1日水曜日

仮想シリアルポートcom0comって知ってる?

仮想シリアルポートcom0comって知ってますか?

クロスケーブルで繋いだCOMポートを2つ用意したような感じのを作れるもので、
シリアル通信するアプリケーションのデバッグに非常に便利です。



が、デバイスドライバなので、いわゆる署名問題が気になるところ。
私もVistaまでは使っていたのですが、それ以降、テストモードに切り替えるのが面倒で使わなくなっていました。

最新版だと、署名されてないため、やっぱり面倒です。
しかし、あったんですね、署名済みドライバ。1つ前のバージョンです。

公式のこちらから
http://sourceforge.net/projects/com0com/files/com0com/2.2.2.0/

com0com-2.2.2.0-x64-fre-signed.zipをダウンロード。
普通にsetuoすれば、使えます。

使い方は簡単。

スタートメニューの「com0com」フォルダに「Setup Command Prompt」ができてるので起動。

>install PortName=COM10 PortName=COM11
と入力してEnter。

ドライバのインストールが走り、シリアルポートが生成されます。

listコマンドで現在あるポートのリストが出ます。

削除はremove 0とか。消えなければ、1や2などの数字を試してください。
CNCA0,CNCB0なら、remove 0
CNCA1,CNCB1なら、remove 1です。多分。

Chrono::Engineで、球体や振り子が高速回転する、妙なところでエラーを吐く、発散する場合の対処法。

Chrono::Engineで、球体や振り子が高速回転する、妙なところでエラーを吐く、発散する場合の対処法。
(glitch or bug: ball and pendulum fast spinning ,moving,or clash in Chrono::Engine.)

・ボールが突然妙な加速とともに回転しはじめませんか?
・動力のない振り子が、宇宙からエネルギーをもらいながら高速回転しませんか?
・Print Screen キーを押して連続写真が撮れるはずが、エラーで落ちませんか?
・反発係数0にするとプログラムが落ちませんか?
・Visual Studio 2010 Expressを使っていませんか?



Visual Studio 2013 Express/Community/Professionalを使いましょう。
治ります。原因不明。

近藤科学のFTDI FT232RL搭載USBアダプターをRaspberry Piで使うのに苦労した話。

近藤科学のFTDI搭載USBアダプターをRaspberry Piで使うのに苦労した話。

おそらく、他のFTDIチップ搭載のUSBアダプタ、変換器でも利用できるだろう。

ただし、内容は保証しない。USBアダプターやOS、ハードウェアが恒久的に破損する危険性を
理解した上で自己責任で行うこと。

・はじめに

 近藤科学のICSサーボをPCで制御するにはどうするか。
Dual USBアダプターHSという、アダプターが近藤科学から出ているので使う。

終わり。

しかし、それはWindowsの話である。
Linuxから使うにはどうするか。

1.シリアルポートおよびUSB-シリアルアダプタを加工する。
 
 近藤科学のページ
 シリアルサーボ制御方法(1) 回路編 (近藤科学)
 http://kondo-robot.com/faq/serial-servo-method-tech
 にて、マイコンと接続する場合の解説が乗っている。
 同様に、FT232RLなどを使って接続すれば良い。

 まっとうで手早い方法だ。

2. Dual USBアダプターHS を無理やり使う。

 Dual USBアダプターHSは、そもそもが中身はFTDI社のFT232である。
 ただ、発売元も製品も違うことになるので、独自のベンダーIDとプロダクトIDが割り当てられ
 FTDI社のチップではない独自のチップとしてPCからは認識される。

 Windowsでは、そのベンダーIDとプロダクトIDの違うドライバを入れれば済む話。
 Linuxではどうするかというと、FTDIのドライバモジュールに
 ベンダーIDとプロダクトIDを登録すれば良い。
 というのは、このページに書いてある。

 シリアルUSBアダプターをLinuxで使うには (近藤科学)
 http://kondo-robot.com/faq/usb-adapter-for-linux

 上記のページに従い、いくつかのコマンドを打てば、
 通常のシリアルポートとして使えるはずである。

それでうまく行っていたらこのページは生まれない。

何が起きたかを説明する。

・前提として

Raspberry Pi + Raspbianを用いた場合、
内臓のシリアルポートは /dev/ttyAMAn
USB経由のシリアルポートは /dev/ttyUSBn として認識される。

そのため、USB経由のシリアルポートを探すには
ls /dev/ttyUSB*
と打てば良い。

無事見つかった後、単純に動作確認するなら、
echo A > /dev/ttyUSB0
とか実行すれば、出力される。

そして、事前に、FTDI社公式のICを積んだUSB-シリアル変換アダプタ

超小型USBシリアル変換モジュール (秋月電子通商) @ FT234X
http://akizukidenshi.com/catalog/g/gM-08461/

を用いて、USBシリアルポートが認識&出力できることは確認していた。

・認識されない

同様に、
まず、近藤科学のページの通り
sudo modprobe ftdi_sio vendor=0x165C product=0007
を発行した。

Dual USBアダプターHSをさし込むが、シリアル・ポートして認識されない。

USB接続された機器を調べる
lsusb
というコマンドを使うと、社名不明で認識されていることがわかった。

しかし、ベンダーIDこそ0x165Cであるが、プロダクトIDが0008であった。
(これは、先ほどのページの最後の方に記載されている。)

「ああ、これが原因か」と思い、
sudo modprobe ftdi_sio vendor=0x165C product=0008
を発行するも、やはり認識されない。

近藤科学のページの通り、dmesgコマンドを実行すると、
どうやら、USB機器としては認識されているが、FTDIの機器として認識されていないことがわかった。

さらにログをたどると、なにやら変なメッセージが。
FTDIのドライバが
「vendorなんてオプションはない、拒否する」(意訳)
「productなんてオプションはない、拒否する」(意訳)
とエラーを吐いているのだ。

タイミング的に、sudo modprobe ftdi_sio vendor=0x165C product=0008を
打ち込んだ結果らしい。

どうも、ftdi_sio vendor=0x165C product=0008という形式のコマンドは
そもそもサポートされていないようだ。

「近藤科学のページに嘘が書かれていたのか?」
と思い検索してみると、どうもこのページが書かれたのは2009年の話。
現在は2015年。

これは怪しいぞ、と思い検索してみると、案の定英語のフォーラムで話があった。

modprobe ftdi_sio errors / Kernel &amp; Hardware / Arch Linux Forums

[SOLVED] ttyUSB not showing up, modprobe unknown parameter 'vendor' & 'product'

どうやら、FTDIのこのコマンドは、デバッグ用か何かだったらしく、
すでに使用できなくなっているとのこと。

対処法は
echo vvvv pppp > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
のように、/sys/bus/usb-serial/drivers/ftdi_sio/new_idに
ベンダーIDとプロダクトIDを書き込んでやることらしい。

もちろん、suでなければならない。

今回の近藤科学のUSBアダプターをRaspberry Piに接続するには以下のようにする。

$ sudo su
# modprobe ftdi-sio 
# echo 165C 0008 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# exit

これで再度dmesgすると、FTDIドライバの認識メッセージが表示されるだろう。
ls /etc/ttyUSB* をすればどの番号に接続されたかわかるはずだ。

近藤科学のすべてのUSBアダプターを使用するには、以下のようにすればよいだろう。

$ sudo su
# modprobe ftdi-sio 
# echo 165C 0001 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# echo 165C 0002 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# echo 165C 0006 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# echo 165C 0007 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# echo 165C 0008 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id
# exit

ちなみに、このままだと再起動等すると接続できなくなるので
/etc/rc.localなどに追記しておくと良い。

以上、参考になれば幸いである。