概要
Epiphany SDKの公式サンプル「HelloWorld」に日本語で解説を付けました。
このソースコードを読めばEpiphanyプログラムの基本的な書き方が理解できます。
ホスト側プログラム本体:hello_world.c
/*
hello_world.c
Copyright (C) 2012 Adapteva, Inc.
Contributed by Yaniv Sapir <yaniv@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see the file COPYING. If not, see
<http://www.gnu.org/licenses/>.
*/
// これはHello Worldサンプルのホスト側プログラムです。
// このプログラムはEpiphanyシステムを初期化し、ランダムにeCoreを
// 選択してEpiphanyプログラムをそのコアにロード、実行します。
// その後eCoreの出力したメッセージを共有外部メモリー・バッファから
// 読み込みます。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
// Epiphanyホスト・ライブラリーをインクルード
#include <e-hal.h>
#define _BufSize (128)
// 共有メモリの先頭 0x01000000 バイトはプログラム領域
// そこから 0x01000000 バイトがヒープ領域なので、
// バッファは 0x01000000 以降に確保します。
#define _BufOffset (0x01000000)
#define _SeqLen (20)
int main(int argc, char *argv[])
{
unsigned row, col, coreid, i;
e_platform_t platform;
e_epiphany_t dev;
e_mem_t emem;
char emsg[_BufSize];
srand(1);
// HDF(Hardware Description File)ファイルを
// 読み込んでeHALシステムを初期化します。
// int e_init(char *HDF);
// (NULLを与えるとデフォルトのHDFファイルで初期化します。)
e_init(NULL);
// Epiphanyプラットフォームのフル・リセット
// int e_reset_system();
e_reset_system();
// Epiphanyプラットフォーム情報を取得
// int e_get_platform_info(e_platform_t *プラットフォーム);
e_get_platform_info(&platform);
// eCoreからホストへのメッセージの受け渡しのために
// 共有外部メモリーにバッファを確保します。
// int e_alloc(e_mem_t *共有バッファ, off_t ベースオフセット,
// size_t バッファサイズ);
e_alloc(&emem, _BufOffset, _BufSize);
for (i=0; i<_SeqLen; i++)
{
// ランダムにコアを選択
row = rand() % platform.rows;
col = rand() % platform.cols;
coreid = (row + platform.row) * 64 + col + platform.col;
fprintf(stderr, "%3d: Message from eCore 0x%03x (%2d,%2d): ",
i, coreid, row, col);
// コア単体のワークグループをOpenし、
// すでに走っているプロセスがあればリセットします。
// これ以降はそのワークグループ内におけるコア座標が
// 使用されます。
// eCoreワークグループの定義
// int e_open(e_epiphany_t *Epiphany, unsigned ワークグループ起点Y座標,
// unsigned ワークグループ起点X座標, ワークグループサイズY, ワークグループサイズX);
e_open(&dev, row, col, 1, 1);
// ワークグループのソフトリセット
// int e_reset_group(e_epiphany_t *Epiphany);
e_reset_group(&dev);
// Epiphanyプログラムを選択したコアにロードし、実行します。
// int e_load(char *SRECファイル名, &Epiphany,
// unsigned ワークグループ内コア座標Y,
// unsigned ワークグループ内コア座標X, e_bool_t ロード後実行フラグ);
e_load("e_hello_world.srec", &dev, 0, 0, E_TRUE);
// Epiphanyプログラムの終了を待ちます。
usleep(10000);
// 共有バッファからメッセージを読み込みます。
// ssize_t e_read(void *共有バッファ, unsigned ワークグループ内コア座標Y,
// unsigned ワークグループ内コア座標X, off_t 読み込み開始オフセット,
// void *読み込み先バッファ, size_t 読み込みバイト数);
e_read(&emem, 0, 0, 0x0, emsg, _BufSize);
// メッセージを表示
fprintf(stderr, "\"%s\"\n", emsg);
// ワークグループをClose
// int e_close(e_epiphany_t *Epiphany);
e_close(&dev);
}
// バッファを解放
// int e_free(e_mem_t *共有バッファ);
e_free(&emem);
// Epiphanyプラットフォームへの接続を完了
e_finalize();
return 0;
}
Epiphany側プログラム本体:e_hello_world.c
/*
e_hello_world.c
Copyright (C) 2012 Adapteva, Inc.
Contributed by Yaniv Sapir <yaniv@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see the file COPYING. If not, see
<http://www.gnu.org/licenses/>.
*/
// これはHello WorldサンプルのEpiphany側プログラムです。
// このプログラムはホストからeCoreのうちのどれかにロードされます。
// 起動後、コアIDを取得してメッセージを共有バッファに書き込みます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Epiphanyハードウェア・ユーティリティ・ライブラリーをインクルード
#include "e_lib.h"
// リンカー・スクリプト・ファイルで設定されている共有メモリ領域に
// 配列を配置するように設定
char outbuf[128] SECTION("shared_dram");
int main(void) {
e_coreid_t coreid;
// 自分のコアID(eCoreの一意の識別子)を取得します。
coreid = e_get_coreid();
// printf等のライブラリ関数はローカルメモリに入りきらないので
// リンカー・スクリプト(fast.ldf)でこれらの実体を
// 外部メモリー(DRAM)に配置するよう設定しています。
// メッセージを共有バッファに書き込みます。
sprintf(outbuf, "Hello World from core 0x%03x!", coreid);
return EXIT_SUCCESS;
}
ビルド・スクリプト:build.sh
#!/bin/bash
set -e
ESDK=${EPIPHANY_HOME}
ELIBS=${ESDK}/tools/host/lib
EINCS=${ESDK}/tools/host/include
# リンカー・スクリプト「fast.ldf」では、printf等の一部の
# ライブラリは外部のDRAM上に配置され、ユーザーの
# Epiphanyプログラム本体はローカルメモリーに配置されます。
ELDF=${ESDK}/bsps/current/fast.ldf
# ホスト側プログラムのビルド
gcc src/hello_world.c -o Debug/hello_world.elf -I ${EINCS} -L ${ELIBS} -le-hal
# Epiphany側プログラムのビルド
e-gcc -T ${ELDF} src/e_hello_world.c -o Debug/e_hello_world.elf -le-lib
# Epiphany側プログラムのバイナリをSRECファイル形式に変換します。
# このファイルがホスト側プログラムからEpiphanyに転送されます。
e-objcopy --srec-forceS3 --output-target srec Debug/e_hello_world.elf Debug/e_hello_world.srec
起動スクリプト:run.sh
#!/bin/bash
set -e
ESDK=${EPIPHANY_HOME}
ELIBS=${ESDK}/tools/host/lib:${LD_LIBRARY_PATH}
EHDF=${EPIPHANY_HDF}
cd Debug
# 現在のところ、eHALライブラリを使ったプログラムの実行には
# 管理者権限が必要です。(まだユーザー・レベル・ドライバになっていないため)
# そのためsudoで実行されます。
sudo -E LD_LIBRARY_PATH=${ELIBS} EPIPHANY_HDF=${EHDF} ./hello_world.elf
ダウンロード、ビルド、実行
Parallellaで端末を開きます。(lxterminal等)
Epiphany SDKリポジトリからファイルをダウンロードします。
wget -O epiphany-examples-master.zip https://github.com/adapteva/epiphany-examples/archive/master.zip
解凍します。
unzip epiphany-examples-master.zip
hello-world ディレクトリに移動。
cd epiphany-examples-master/apps/hello-world
ビルドします。
./build.sh
実行します。
./run.sh
端末にHello Worldと表示されます。これはEpiphanyプロセッサが書き込んだメッセージをARMホストが読み出して表示しています。
Hello World from core 0x...
...
...
...
このディレクトリには、hello-worldの他に、行列積のデモ「matmul-demo」や、2次元フーリエ変換のデモ「fft2d」等が収められています。ぜひこれらのプログラムも見てみてください。
上記の情報は米国Adapteva社が公開している情報を基にしたものです。出典元の著作物の権利は、米国Adapteva社など、その原著作権者に帰属します。