tcp:2222:10.0.2.15:22

先端ソフトウェア工学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に
慣れ親しみ、できればソースを読もう。