Transcript Document
先端ソフトウェア工学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
gcc
gcc
gcc
–c a.c
–c b.c
–c main.c
–o main a.o b.o main.o
リンカエラー
リンク時のシンボル衝突
ライブラリを作ってリンクする場合
gcc –c a.c
gcc –c b.c
ar cr libhoge.a a.o b.o
gcc –c main.c
gcc –o main libhoge.a
先に見つかった方が使われる
(順序を入れ替えると逆になる)
リンク時のシンボル衝突
共有ライブラリを作ってリンクする場合
gcc
gcc
gcc
gcc
–fPIC –shared –o a.so a.c
–fPIC –shared –o b.so b.c
–fPIC –shared –o main.so main.c
–o main_shared ./a.so ./b.so ./main.so
先に見つかった方が使われる
(順序を入れ替えると逆になる)
リンク時のシンボル衝突
共有ライブラリを作ってリンクする場合
gcc
gcc
gcc
gcc
–fPIC –shared –o liba.so a.c
–fPIC –shared –o libb.so b.c
–c main.c
–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);
文字列をintに変換
write(fd,&buf,4);
デバイスに書き込み
read(fd,&buf,4);
デバイスから読み込み
printf("modified value=%08x\n",buf);
表示
}
close(fd);
return 0;
デバイスのクローズ
実演
クロス開発環境の構築
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=ppclinux --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 --disableshared --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
host
組込みプログラム
build
開発環境
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/powerp
c/iso-cd/debian-508-powerpc-netinst.iso
%qemu-system-ppc -hda debian_powerpc.qcow2 -boot d
-cdrom debian-508-powerpc-netinst.iso
QEMUを使ってみる
以下からパッケージとディスクイメージをダ
ウンロード
%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
パッケージのインストール
#dpkg –i qemu-ppc_1.0rc1-2-1_i386.deb
ID:password
root: hogehoge
test: hogehoge
QEMUの起動
インストールしたディスクイメージから起動
%qemu-system-ppc -hda debian_powerpc.qcow2
host->guestのネットワークを設定する場合
-redirオプションでホストのポートとゲストのポー
トを接続
%qemu-system-ppc -hda debian_powerpc.qcow2
-redir tcp:2222:10.0.2.15:22
プロトコル:tcp
hostポート番号:2222
guest IPアドレス:10.0.2.15
guestポート番号: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に
慣れ親しみ、できればソースを読もう。