先端ソフトウェア工学 ii. プログラミング tips c と c++ のプログラムをリ...

Post on 21-Dec-2015

230 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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 に慣れ親しみ、できればソースを読もう。

top related