SDx 2016.3+yocto+Z-Turnを実機検証

昨日までに整ったことをおさらいすると・・・

  • SDx 2016.3
    • include Z-Turn platform
  • yocto project 2.2(morty)
    • linaro gcc 6.2.1 toolchian
    • OpenCV 3.1.0
    • gstreamer 1.0
    • libjpeg-trubo
  • Linux Kernel 4.9.0

と、SDx+Z-Turnで遊べる環境まで仕上がった。

SDxでELFファイルとbitファイルが出来上がるところまでは確認したのですがまだ、実機でのテストは行っていなんですね。

実機で気になる点は・・・

  • ELFファイルが実行できるか
    • これは問題ないはず
  • Linux Kernel 4.9.0とlibsds.aが噛み合うか
    • これが実機テストでの一番、気になるところ
  • bitファイルが動作するか
    • 回路がアプリ上からのトリガーで動作するか?

これが突破できれば、今回、構築したSDxのアプリケーション開発環境構築はミッション終了です。

検証に使用したソースコード

検証に使用したコードは次のようにしました。

玲奈姫をグレースケールで読み込んでラプラシアンしてから、輝度をラインごとに+128する簡単な変換です。

ここでの注目点は、次のようにライブラリとFPGA処理を組み合わせているがアプリケーション自体はひとつであるということです。

  • ラプラシアンはOpenCV 3.1.0でソフトウェアで処理
  • 輝度増量はハードウェアで処理
アプリケーション側のソースコード
/*
 * OpenCV フィルタサンプル - ラプラシアン
 */
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

extern int wrapper_conv_data(unsigned char* img_in, unsigned char* img_out, int width, int height);

int main( int argc, char** argv )
{
  printf("exec: OpenCV_Sample01\n");

  // Read lena-chan with Grayscale
  printf("read: lena.png\n");
  cv::Mat src = cv::imread("lena.png", 0);

  printf("exec: laplacian\n");
  cv::Mat laplacian, tmp;
  cv::Laplacian(src, tmp, CV_32F, 3);
  cv::convertScaleAbs(tmp, laplacian, 1, 0);

  unsigned char* img = (unsigned char*)&laplacian.data[0];
  unsigned char* img2 = (unsigned char*)&tmp.data[0];

  wrapper_conv_data(img, img2, src.cols, src.rows);

  // Write for laplacian not kuracian
  printf("write: lena_laplacian.png\n");
  cv::imwrite("lena_laplacian.png", laplacian);

  printf("finish: OpenCV_Sample01\n");

  return 0;
}
FPGA化する側のソースコード
/*
 * FPGA
 */

#pragma SDS data zero_copy(img_in)
#pragma SDS data zero_copy(img_out)
int conv_data(unsigned char img_in[1024], unsigned char img_out[1024], int width)
{
    for(int x = 0; x < width; x++){
        if(img_out[x] < 128){
            img_out[x] = img_in[x] + 128;
        }else{
            img_out[x] = 255;
        }
    }

    return 0;
}

/*
 * Function Wrapper
 */
int wrapper_conv_data(unsigned char* img_in, unsigned char* img_out, int width, int height)
{
    int rslt = 0;

    if(width > 256){
        rslt = -1;
        return rslt;
    }

    for(int y = 0; y < height; y++){
        rslt += conv_data(&img_in[y * width], &img_out[y * width], width);
    }

    return rslt;
}

コンパイルが完了することはすでにわかっているので、完了後に必要なファイルをSDカードにコピーする。

SDxのコンパイル後に必要なファイルは次の2つです。

  • OpenCV_Sample03.elf
  • sd_cadrd/_sds/p0.bin

気がつくと思いますが、SDxで生成されたboot.bin、devicetree.dtb、image.ubは使用しません。

これらのファイルはyocto projectで生成済みの環境を使用します。

SDカードはすでにyocto projectで次のように構築しています。

  • 第一パーティション(VFAT)
    • boot.bin(u-boot SPL)
    • zImage
    • zynq-zturn.dtb
  • 第二パーティション(ext4)
    • Linux Root File System

なので、SDxで生成したELFファイルとbitファイルをコピーしてSDカードは次のようになります。

  • 第一パーティション(VFAT)
    • boot.bin(u-boot SPL)
    • zImage
    • zynq-zturn.dtb
    • p0.bin
    • OpenCV_Sample03.elf(これは第二パーティションでも良い)
  • 第二パーティション(ext4)
    • Linux Root File System

いざ、実行!

root@zturn:~# ./OpenCV_Sample03.elf
-sh: ./OpenCV_Sample03.elf: not found

あれ?なんでnot found?