先端ソフトウェア工学 ii. プログラミング tips c と c++ のプログラムをリ...
Post on 21-Dec-2015
230 views
TRANSCRIPT
先端ソフトウェア工学 II
プログラミング TIPS
C と C++ のプログラムをリンク
C/C++ とシンボル名 gcc –c func.c g++ -c func.c
func.o を nm で比較する
C++ には関数の所属する名前空間の情報や関数の引数の型情報がシンボルに含まれる
C++ から C の関数を呼び出す
ビルドして動かす gcc –c func.c gcc –c call.cpp gcc –o hoge func.o call.o
extern “C” の影響 ありとなしを nm で比較
extern “ C” の注意点 引数の型がチェックされない
extern “C” void func(int);int main(){ func(0); return 0;}
リンクに成功してしまう
C++ であれば”リンク成功 -> 間違った型で関数は呼ばれない”と考えたいが、 extern “C” を使っている部分はそうではなく、 C 相当にまで安全性が低下する。
一般的な利用方法 以下のようなヘッダを用意する。
#ifdef __cplusplus extern “C”{#endif void func(const char *);#ifdef __cplusplus }#end if
C から C++ の関数を呼ぶ g++ -c func.cpp gcc –c call.c g++ -o call_c call.o func.o
•C++ の関数は例外を C の関数側に漏らしてはならない
•関数ポインタを扱う C の関数に注意
リンク時のシンボル衝突 同名シンボルの衝突
a.c 、 b.c に同名の関数が定義されている場合
gcc –c a.cgcc –c b.cgcc –c main.cgcc –o main a.o b.o main.o
リンカエラー
リンク時のシンボル衝突 ライブラリを作ってリンクする場合
gcc –c a.cgcc –c b.car cr libhoge.a a.o b.ogcc –c main.cgcc –o main libhoge.a
先に見つかった方が使われる
(順序を入れ替えると逆になる)
リンク時のシンボル衝突 共有ライブラリを作ってリンクする場合
gcc –fPIC –shared –o a.so a.cgcc –fPIC –shared –o b.so b.cgcc –fPIC –shared –o main.so main.cgcc –o main_shared ./a.so ./b.so ./main.so
先に見つかった方が使われる
(順序を入れ替えると逆になる)
リンク時のシンボル衝突 共有ライブラリを作ってリンクする場合
gcc –fPIC –shared –o liba.so a.cgcc –fPIC –shared –o libb.so b.cgcc –c main.cgcc –o main_shared –L. –la -lb
先に見つかった方が使われる
( -la –lb の順序に依存)
LD_PRELOAD で制御可能
weak シンボル ELF では weak 参照のほかに weak 定
義というもう 1 つの weak シンボルを追加している。 Weak 定義は、通常の定義が存在しない場合に大域シンボルを定義する。通常の定義が存在される場合は weak 定義は無視される。
weak シンボル ふつうにコンパイル
g++ main.cpp 同名の実装が他にある
g++ -c a.cpp g++ -c main.cpp g++ -o main main.o a.o
実行される関数が異なる
原因は weak シンボル( nm で確認)
weak 定義 g++ がインライン関数を weak 定義
とみなす
回避するには main.cpp の class 定義をnamespace{} で囲みリンケージリークを防ぐ
クロス開発
クロス開発 開発対象 ( ターゲット ) と開発環境 ( ホ
スト ) が異なる
RS232C or Ether
ターゲット ホスト
クロス開発の実例 SUZAKU-V
CPU: PowerPC OS: Linux 開発環境 : GNUtools
開発ツールのインストール
以下の順で dpkg -i
* binutils-powerpc-linux-gnu* gcc-4.1-powerpc-linux-gnu-base_4.1.1-21_i386.deb* cpp-4.1-powerpc-linux-gnu_4.1.1-21_i386.deb* libc6-powerpc-cross_2.3.6.ds1-13etch2_all.deb* libgcc1-powerpc-cross_4.1.1-21_all.deb* linux-kernel-headers-powerpc-cross_2.6.18-7_all.deb* libc6-dev-powerpc-cross_2.3.6.ds1-13etch2_all.deb* libssp0-powerpc-cross_4.1.1-21_i386.deb* gcc-4.1-powerpc-linux-gnu_4.1.1-21_i386.deb
http://suzaku.atmark-techno.com/filebrowser/cross-dev/powerpc/debから入手
Hello world してみる
#include <stdio.h>
int main(void){ printf("hello world\n"); return 0;}
%powerpc-linux-gnu-gcc hello.c –o hello
ターゲットホストへのアクセス
シリアルコンソールで接続 minicom 等を利用
Ether 経由でデータを転送 設定例
/sbin/ifconfig eth0 192.168.0.2 @ host /sbin/ifconfig eth0 192.168.0.1 @ target
転送 ftp で接続して put する。
7SEG LED を叩いてみる#include <stdio.h>#include <sys/types.h>#include <asm-generic/fcntl.h>#include <stdlib.h>int main(int argc, char *argv[]){ int fd;int buf; char *endptr;
fd=open("/dev/sil7segc",O_RDWR); read(fd,&buf,4); printf("initial value=%08x\n",buf);
buf=strtol(argv[1],&endptr,0); write(fd,&buf,4); read(fd,&buf,4); printf("modified value=%08x\n",buf);
close(fd); return 0;}
デバイスのオープン初期値の読み込み表示
文字列を int に変換デバイスに書き込みデバイスから読み込み
デバイスのクローズ
表示
実演
クロス開発環境の構築 OS 無
binutils GCC newlib: 組込み向け標準ライブラリ
構築時のオプション target: ツールが出力するコードが動
く環境 host: ツールを動作させる環境 build: ツールを構築する環境
OS 無、 MIPS ターゲットの場合
target mips host x86 linux build x86 linux
binutils
%mkdir binutils_build%cd binutils_build%../binutils-2.21.51/configure --target=mips --prefix=/ldisk/miya/mips-cross%make%make install
GCC
%mkdir gcc_build%cd gcc_build%export PATH=$PATH:/ldisk/miya/mips-cross/bin%../gcc-4.2.4/configure --target=mips --with-newlib --with-headers=../newlib-1.18.0/newlib/libc/include --enable-languages="c" --disable-libssp%make%make install
newlib
%mkdir newlib_build%cd newlib_build%../newlib-1.18.0/configure
--prefix=/ldisk/miya/mips-cross --target=mips%make %make install
クロス開発環境の構築 OS(Linux) 有
binutils の構築 glibc に依存しない gcc の構築 glibc の構築 glibc を利用した gcc の構築
Version の問題等で割と動かず、エラーを根気よく潰す必要あり。
PowerPC Linux をターゲットとした場合
binutils 2.15
%mkdir binutils_build%cd binutils_build%../binutils-2.15/configure --target=ppc-linux --prefix=/ldisk/miya/ppc-linux%make%make install
PowerPC Linux をターゲットとした場合
gcc 3.4.6 1 回目kernel header をあらかじめ src にコピー。(2.6.23.9)%mkdir gcc_build%cd gcc_build%../binutils-3.4.6/configure --target=ppc-linux --prefix=/ldisk/miya/ppc-linux --disable-nls --disable-multilib --disable-threads --disable-shared --enable-languages=c%make%make install
PowerPC Linux をターゲットとした場合
glibc 2.3.6
%mkdir glibc_build%cd glibc_build%../glibc-2.3.6/configure –target=ppc-linux --host=ppc-linux --with-headers=/ldisk/miya/src/linux-2.6.23.9/include --enable-add-ons%make%make install
PowerPC Linux をターゲットとした場合
gcc 3.4.6 2 回目%mkdir gcc_build2%cd gcc_build2%../binutils-3.4.6/configure --target=ppc-linux --prefix=/ldisk/miya/ppc-linux --enable-threads --enable-shared --enable-languages=c%make%make install
このようにかなり面倒
Emdebian Cross Development Environment
クロス開発環境を簡単に構築するための仕組み。これを利用すると以下のようにクロス環境が構築できる。
必要なパッケージのインストール%apt-get install dpkg-cross apt-cross fakeroot dpatch gawk flex realpath automake1.7 debhelper cdbs必要なソースの取得%apt-get source gcc-4.4 binutils% cd binutils-2.x%TARGET=$linux-architecture fakeroot debian/rules binary-cross% dpkg-cross -a $architecture -b $package% xapt -a arch package% export GCC_TARGET=arch (replace arch through arm, alpha,...)% cd gcc-4.4-x% fakeroot debian/rules control% dpkg-buildpackage -b -rfakeroot
詳細は http://www.emdebian.org参照
カナディアンクロス target 、 host 、 build がすべて別
target buildhost
開発環境組込みプログラム
QEMU を用いたクロス開発
QEMU とは? 汎用のオープンソースエミュレータ、
バーチャライザ。最近流行りのAndroid の SDK にも含まれている。 エミュレータ機能 : QEMU を動作させる
のとは k 異なるアーキテクチャをターゲットとした OS やプログラムの実行が可能。ダイナミックトランスレーションを用いているので高速。
バーチャライザ機能 :Xen や KVM(Kernel –based Virtual Machine) の環境下において、ネイティブに近い高速な仮想化を実現する。
詳細は http://qemu.org参照
QEMU エミュレータがサポートするターゲット
i386-softmmu x86_64-softmmu alpha-softmmu arm-softmmu cris-softmmu lm32-softmmu m68k-softmmu microblaze-softmmu microblazeel-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu sparc64-softmmu s390x-softmmu xtensa-softmmu xtensaeb-softmmu
QEMU の導入 (target=ppc linux)
手順 QEMU のビルド QEMU に見せるディスクイメージの作成 OS のインストール
実際のコマンド %./confiugre --target-list=ppc-softmmu;make; %qemu-img create -f qcow2
debian_powerpc.qcow2 2G %wget
http://cdimage.debian.org/cdimage/archive/5.0.8/powerpc/iso-cd/debian-508-powerpc-netinst.iso
%qemu-system-ppc -hda debian_powerpc.qcow2 -boot d -cdrom debian-508-powerpc-netinst.iso
QEMU を使ってみる 以下からパッケージとディスクイメー
ジをダウンロード
パッケージのインストール #dpkg –i qemu-ppc_1.0rc1-2-
1_i386.deb ID:password
root: hogehoge test: hogehoge
%wget http://infonet.naist.jp/~miya/lecture/2011/qemu/qemu-ppc_1.0rc1-2-1_i386.deb%wget http://infonet.naist.jp/~miya/lecture/2011/qemu/debian_powerpc.qcow2
QEMU の起動 インストールしたディスクイメージから起動
host->guest のネットワークを設定する場合 -redir オプションでホストのポートとゲスト
のポートを接続
%qemu-system-ppc -hda debian_powerpc.qcow2
%qemu-system-ppc -hda debian_powerpc.qcow2 -redir tcp:2222:10.0.2.15:22
プロトコル :tcphost ポート番号 :2222guest IP アドレス :10.0.2.15guest ポート番号 :22
host<->guest のファイル転送
ネットワーク設定 host の IP アドレス : 192.168.0.1 guest の IP アドレス : 10.0.2.15 オプション : -redir tcp:2222:10.0.2.15:22 login: @host%ssh –p 2222 test@localhost
host:/h_pass/h_file を guest:/g_pass にコピー @host: %scp –P 2222 /h_pass/h_file
localhost:/g_pass/ @guest: %scp 192.168.0.1:/h_pass/h_file /g_pass/
guest:/g_pass/g_file を host:/h_pass/ にコピー @host: %scp –P 2222 localhost:/g_pass/g_file
/h_pass/ @guest: %scp /g_pass/g_file 192.168.0.1:/h_pass/
Hello world をやってみる @host%powerpc-linux-gnu-gcc
hello.c –o hello hello を host から guest にコ
ピーする。 コンソールから login する。 (ssh でも
OK) コピーしたディレクトリに移動 ./hello
QEMU を利用したデバッグ QEMU と GDB の接続
QEMU の動作を GDB で追跡 : エミュレータそのもののデバッグ
QEMU上で動作する guest を追跡 : エミュレータ上で動作するプログラムのデバッグ
両方追跡 :上記の 2 つを同時にデバッグ
詳細は QEMU のドキュメント参照。
システムレベルの開発
SW/HW の機能分割 ディジタルシステム
で実現できる処理はTuring機械と等価。 SW: CPU上で実行
される処理。プログラミング言語で記述。
HW: 専用回路で実行される処理。ハードウェア記述言語で記述。
VerilogHDL Sample Code
module adder(a, b, c_in, c_out, s); input [3:0] a, b; input c_in; output c_out; output [3:0] s; assign {c_out, s} = a + b + c_in;
endmodule
SW/HW の機能分割 要求仕様に応じた最適な機能分担。
メインメモリ
粗粒度再構成デバイス
CPU
FPGA ASIC
マルチコア
プロセッサ
アプリケーショ
ン
タスクに分割
演算資源の割り当て
要求性能,制約条件に応じた最適なシステムを提供可能に
様々な演算資源を適材適所に利用する,ヘテ
ロジニアスなコンピューティングへ
将来は UML のような仕様記述から SW もHW も生成できるか
も?
プログラマビリティの高いシステム
Tensilica Xtensa プロセッサ TIE(Tensilica
Instrucation Extension)言語にて、プロセッサに専用命令を容易に追加可能。これに対応した gcc 等も自動生成。
プログラマビリティの高いシステム
ソフトウェア無線 GNU Radio
ドータボードによる機能拡張 TVRX BasicRX/TX
複数言語への対応 C/C++ Python
FPGA の書き換え機能
“ ソフトウェア”が意味する対象の
拡大
おわりに 組込み分野で活躍したければ SW も
HW も分かるようになりましょう。 システムレベル最適化を常に考慮しま
しょう。局所最適ではなく、大域的な最適化を。
とにかく、 C に精通していなければ話にならないので、 C をしっかり。
オープンソース、特に Linux やgnutools に慣れ親しみ、できればソースを読もう。