FC2カウンター FPGAの部屋 2019年08月
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Ultra96-V2でVivado Analyzerを接続した時にUltra96-V2のDebianが落ちる

まだブログには書いていないのだが、OV5642 にガボールフィルタとラプラシアンフィルタを付けてカメラ画像と、ガボールフィルタ画像とラプラシアンフィルタ画像の比較をする回路をUltra96-V2に実装してある。それが動かないので、Vivado Analyzer でデバックしようと思ったのだ。しかし、Vivado Analyzer で波形を見ようとして、Vivado 2018.3 のPROGRAM AND DEBUG -> Open Hardware Manager -> Open Target -> Auto Connect でVivado Analyzer を開始するとUltra96-V2 のDebian が落ちてしまった。
ツィッターでツィートしたところ、ikzwm さんが、bootargs に cpuidle.off=1 を入れるとOKと教えてくれた。


そういえば、そんなこともあったということで、自分のブログを検索すると、”Ultra96 のuEnv.txt のbootargs に cpuidle.off=1を追加した”の記事があった。

この通りに bootargs に cpuidle.off=1 を追加すると、Vivado Analyzer でデバックしてもUltra96-V2 のDebian が落ちなくなった。良かった。。。ikwzm さん、ありがとうございました。
  1. 2019年08月31日 13:22 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96用ラプラシアンフィルタIP の作成2

Ultra96用ラプラシアンフィルタIP の作成1”の続き。

前回は、Ultra96 用のエッジ検出フィルタのラプラシアンフィルタを作成するということで、ソースコードを貼った。今回は、C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL を行う。

まずは、C シミュレーションからやってみよう。
lap_filter_axis_2_190829.png

成功した。
lap_filter_axis/solution1/csim/build/ ディレクトリを見ると、C シミュレーションの生成物が見える。
lap_filter_axis_3_190830.png

元画像がこれで、
lap_filter_axis_4_190830.jpg

ラプラシアンフィルタ後の画像がこれだ。
lap_filter_axis_5_190830.jpg

エッジが出ているのが分かる。

C コードの合成を行った。
lap_filter_axis_6_190830.png

Latency もかなり良い状況だ。ガボールフィルタよりもカーネルの大きさが 3 x 3 のためリソース使用量も少ない。ガボールフィルタは 9 x 9 。

C/RTL 協調シミュレーションを行った。
lap_filter_axis_7_190830.png

Latency は 480061 クロックだった。 800 x 600 = 480000 ピクセルなので、ほとんど 1 クロック/ピクセルの性能が出ている。

C/RTL 協調シミュレーションの波形を示す。
lap_filter_axis_8_190830.png

ins と outs の TVALID と TREADY がほとんど 1 になっているので、スループットが高い。

Export RTL を行った。
lap_filter_axis_9_190830.png

CP achieved post-implementation は 4.369 ns ということで問題ない数値だと思う。
  1. 2019年08月30日 06:30 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96用ラプラシアンフィルタIP の作成1

前回は、Ultra96 用のガボールフィルタを作成したが、今回は、Ultra96 用のエッジ検出フィルタのラプラシアンフィルタを作成しよう。

ラプラシアンフィルタについては過去たくさん出てきているが、行と列の数を引数として入力できるように変更したソースコードの lap_filter_axis.cpp を貼っておく。なお、このコードでは、マイナスの値は絶対値に変換せずに 0 に丸めている。

//
// lap_filter_axis.cpp
// 2015/05/01
// 2015/06/25 : 修正、ラプラシアンフィルタの値が青だけになっていたので、RGBに拡張した
// 2019/08/29 : row, colを引数として入力できるように変更
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axis(int row, int col, hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE s_axilite port=col
#pragma HLS INTERFACE s_axilite port=row
#pragma HLS INTERFACE axis register both port=ins
#pragma HLS INTERFACE axis register both port=outs
#pragma HLS INTERFACE s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> lap;

    unsigned int line_buf[2][1920];
#pragma HLS array_partition variable=line_buf block factor=2 dim=1
#pragma HLS resource variable=line_buf core=RAM_2P

    int pix_mat[3][3];
#pragma HLS array_partition variable=pix_mat complete

    int lap_fil_val;

    Loop1 : do {    // user が 1になった時にフレームがスタートする
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
        ins >> pix;
    } while(pix.user == 0);

    Loop2 : for (int y=0; y<row; y++){
#pragma HLS LOOP_TRIPCOUNT min=48 max=1080 avg=600
        Loop3 : for (int x=0; x<col; x++){
#pragma HLS LOOP_TRIPCOUNT min=64 max=1920 avg=800
#pragma HLS PIPELINE II=1
            if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                ins >> pix; // AXI4-Stream からの入力

            Loop4 : for (int k=0; k<3; k++){
                Loop5 : for (int m=0; m<2; m++){
#pragma HLS UNROLL
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];

            int y_val = conv_rgb2y(pix.data);
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            lap_fil_val = laplacian_fil(    pix_mat[0][0], pix_mat[0][1], pix_mat[0][2],
                                        pix_mat[1][0], pix_mat[1][1], pix_mat[1][2],
                                        pix_mat[2][0], pix_mat[2][1], pix_mat[2][2]);
            lap.data = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる

            if (x<2 || y<2) // 最初の2行とその他の行の最初の2列は無効データなので0とする
                lap.data = 0;

            if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                lap.user = 1;
            else
                lap.user = 0;

            if (x == (col-1))   // 行の最後で TLAST をアサートする
                lap.last = 1;
            else
                lap.last = 0;

            outs << lap;    // AXI4-Stream へ出力
        }
    }

    return 0;
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


テストベンチの lap_filter_axis_tb.cpp を示す。

// lap_filter_axis_tb.cpp
// 2015/05/01
// 2015/08/17 : BMPファイルを読み書きするように変更した
// 2019/08/29 : row, colを引数として入力できるように変更
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <ap_axi_sdata.h>

#include "bmp_header.h"

int lap_filter_axis(int row, int col, hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs);

int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y_soft(int rgb);
int lap_filter_axis_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, int width, int height);

#define CLOCK_PERIOD 10

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > ins;
    hls::stream<ap_axis<32,1,1,1> > ins_soft;
    hls::stream<ap_axis<32,1,1,1> > outs;
    hls::stream<ap_axis<32,1,1,1> > outs_soft;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals;
    ap_axis<32,1,1,1> vals_soft;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw;
    int *rd_bmp, *hw_lapd;
    int blue, green, red;

    if ((fbmpr = fopen("test2.bmp", "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_lapd =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_lapd memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // ins に入力データを用意する
    for(int i=0; i<5; i++){ // dummy data
        pix.user = 0;
        pix.data = i;
        ins << pix;
    }

    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];

            if (j==0 && i==0)   // 最初のデータの時に TUSER を 1 にする
                pix.user = 1;
            else
                pix.user = 0;

            if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
                pix.last = 1;
            else
                pix.last = 0;

            ins << pix;
            ins_soft << pix;
        }
    }

    lap_filter_axis(bmpihr.biHeight, bmpihr.biWidth, ins, outs);
    lap_filter_axis_soft(ins_soft, outs_soft, bmpihr.biWidth, bmpihr.biHeight);

    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    cout << endl;
    cout << "outs" << endl;
    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            outs >> vals;
            outs_soft >> vals_soft;
            ap_int<32> val = vals.data;
            ap_int<32> val_soft = vals_soft.data;

            hw_lapd[(j*bmpihr.biWidth)+i] = (int)val;

            if (val != val_soft){
                printf("ERROR HW and SW results mismatch i = %ld, j = %ld, HW = %d, SW = %d\n", i, j, (int)val, (int)val_soft);
                return(1);
            }
            if (vals.last)
                //cout << "AXI-Stream is end" << endl
                ;
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    // ハードウェアのラプラシアンフィルタの結果を temp_lap.bmp へ出力する
    if ((fbmpw=fopen("temp_lap.bmp", "wb")) == NULL){
        fprintf(stderr, "Can't open temp_lap.bmp by binary write mode\n");
        exit(1);
    }
    // BMPファイルヘッダの書き込み
    fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

    // RGB データの書き込み、逆順にする
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
            green = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
            red = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

            fputc(blue, fbmpw);
            fputc(green, fbmpw);
            fputc(red, fbmpw);
        }
    }
    fclose(fbmpw);
    free(rd_bmp);
    free(hw_lapd);

    return 0;
}

int lap_filter_axis_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, int width, int height){
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> lap;
    unsigned int **line_buf;
    int pix_mat[3][3];
    int lap_fil_val;
    int i;

    // line_buf の1次元目の配列をアロケートする
    if ((line_buf =(unsigned int **)malloc(sizeof(unsigned int *) * 2)) == NULL){
        fprintf(stderr, "Can't allocate line_buf[3][]\n");
        exit(1);
    }

    // メモリをアロケートする
    for (i=0; i<2; i++){
        if ((line_buf[i]=(unsigned int *)malloc(sizeof(unsigned int) * width)) == NULL){
            fprintf(stderr, "Can't allocate line_buf[%d]\n", i);
            exit(1);
        }
    }

    do {    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (int y=0; y<height; y++){
        for (int x=0; x<width; x++){
            if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                ins >> pix; // AXI4-Stream からの入力

            for (int k=0; k<3; k++){
                for (int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];

            int y_val = conv_rgb2y_soft(pix.data);
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            lap_fil_val = laplacian_fil_soft(    pix_mat[0][0], pix_mat[0][1], pix_mat[0][2],
                                        pix_mat[1][0], pix_mat[1][1], pix_mat[1][2],
                                        pix_mat[2][0], pix_mat[2][1], pix_mat[2][2]);
            lap.data = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる

            if (x<2 || y<2) // 最初の2行とその他の行の最初の2列は無効データなので0とする
                lap.data = 0;

            if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                lap.user = 1;
            else
                lap.user = 0;

            if (x == (width-1))    // 行の最後で TLAST をアサートする
                lap.last = 1;
            else
                lap.last = 0;

            outs << lap;    // AXI4-Stream へ出力
        }
    }

    for (i=0; i<2; i++)
        free(line_buf[i]);
    free(line_buf);

    return 0;
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


bmp_header.h を示す。

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType; 
    uint32_t bfSize; 
    uint16_t bfReserved1; 
    uint16_t bfReserved2; 
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize; 
    int32_t biWidth; 
    int32_t biHeight; 
    uint16_t biPlanes; 
    uint16_t biBitCount; 
    uint32_t biCompression; 
    uint32_t biSizeImage; 
    int32_t biXPixPerMeter; 
    int32_t biYPixPerMeter; 
    uint32_t biClrUsed; 
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} BMP24FORMAT;


Vivado HLS 2018.3 の lap_filter_axis プロジェクトを作成した。
lap_filter_axis_1_190829.png
  1. 2019年08月29日 05:16 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96用ガボールフィルタIP の作成3

Ultra96用ガボールフィルタIP の作成2”の続き。

前回は、Ultra96 用ガボールフィルタのC シミュレーション、Cコードの合成を行った。今回は、C/RTL 協調シミュレーションとExport RTL を行う。

C/RTL 協調シミュレーションを行った。
Gabor_filter_lh_2_16_190828.png

800 ピクセル x 600 行の画像を 2 フレーム処理しているので、 800 x 600 x 2 = 960000 ピクセル処理しているので、ほとんど 1 クロック / ピクセルと言える。

C/RTL 協調シミュレーションの波形を示す。
Gabor_filter_lh_2_17_190828.png

outs も ins もTVALID とTREADY がほとんど 1 となっていて性能が出ているのが分かる。

Export RTL を行った。
Gabor_filter_lh_2_18_190828.png

9 x 9 のフィルタを 1 クロック/ピクセルでやっているので、リソースは結構食ってしまっている。
CP achieved post-implementation は 4.946 ns と少々心配な値であるが、このままVivado に持っていてやってみよう。
  1. 2019年08月28日 04:54 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96用ガボールフィルタIP の作成2

Ultra96用ガボールフィルタIP の作成1”の続き。

Ultra96-V2 にガボールフィルタを実装しようということで、以前、ZYBO 用に作っていたガボールフィルタIP をUltra96用に変更することにした。
前回は、ガボールフィルタをかけるフィルタ・サイズを row と col を引数に入れて設定できるように変更したソースコード、テストベンチなどを貼った。今回は、C シミュレーション、Cコードの合成を行った。

早速、C シミュレーションを行った。
Gabor_filter_lh_2_2_190825.png

固定小数点演算と浮動小数点演算の値の差が出てしまっている。ログを貼っておく。

INFO: [SIM 2] *************** CSIM start ***************
INFO: [SIM 4] CSIM will launch GCC as the compiler.
   Compiling ../../../Gabor_filter_lh_2_tb.cpp in debug mode
   Compiling ../../../Gabor_filter_lh_2.cpp in debug mode
   Generating csim.exe

outs
ERROR HW and SW results mismatch i = 532, j = 85, HW = 00a2a2a2, SW = 009f9f9f
ERROR HW and SW results mismatch i = 727, j = 91, HW = 002b2b2b, SW = 00282828
ERROR HW and SW results mismatch i = 751, j = 95, HW = 000f0f0f, SW = 000c0c0c
ERROR HW and SW results mismatch i = 531, j = 140, HW = 00040404, SW = 00010101
ERROR HW and SW results mismatch i = 213, j = 144, HW = 00797979, SW = 00767676
ERROR HW and SW results mismatch i = 550, j = 147, HW = 00050505, SW = 00020202
ERROR HW and SW results mismatch i = 550, j = 150, HW = 00121212, SW = 000f0f0f
ERROR HW and SW results mismatch i = 313, j = 164, HW = 00515151, SW = 004e4e4e
ERROR HW and SW results mismatch i = 314, j = 164, HW = 001d1d1d, SW = 001a1a1a
ERROR HW and SW results mismatch i = 314, j = 165, HW = 00d0d0d0, SW = 00cdcdcd
ERROR HW and SW results mismatch i = 315, j = 165, HW = 00a1a1a1, SW = 009e9e9e
ERROR HW and SW results mismatch i = 369, j = 176, HW = 00161616, SW = 00131313
ERROR HW and SW results mismatch i = 174, j = 196, HW = 00919191, SW = 008e8e8e
ERROR HW and SW results mismatch i = 43, j = 200, HW = 00272727, SW = 00242424
ERROR HW and SW results mismatch i = 46, j = 200, HW = 00555555, SW = 00525252
ERROR HW and SW results mismatch i = 48, j = 200, HW = 00727272, SW = 006f6f6f
ERROR HW and SW results mismatch i = 49, j = 200, HW = 00666666, SW = 00636363
ERROR HW and SW results mismatch i = 50, j = 200, HW = 00606060, SW = 005d5d5d
ERROR HW and SW results mismatch i = 51, j = 200, HW = 00686868, SW = 00656565
ERROR HW and SW results mismatch i = 55, j = 200, HW = 00727272, SW = 006f6f6f
ERROR HW and SW results mismatch i = 59, j = 200, HW = 00b7b7b7, SW = 00b4b4b4
ERROR HW and SW results mismatch i = 63, j = 200, HW = 00b5b5b5, SW = 00b2b2b2
ERROR HW and SW results mismatch i = 65, j = 200, HW = 00a7a7a7, SW = 00a4a4a4
ERROR HW and SW results mismatch i = 66, j = 200, HW = 008c8c8c, SW = 00898989
ERROR HW and SW results mismatch i = 67, j = 200, HW = 00747474, SW = 00717171
ERROR HW and SW results mismatch i = 70, j = 200, HW = 00121212, SW = 000f0f0f
ERROR HW and SW results mismatch i = 74, j = 201, HW = 00e7e7e7, SW = 00e4e4e4
Success HW and SW results match

WARNING: Hls::stream 'hls::stream<ap_axis<32, 1, 1, 1> >.2' contains leftover data, which may result in RTL simulation hanging.
WARNING: Hls::stream 'hls::stream<ap_axis<32, 1, 1, 1> >.1' contains leftover data, which may result in RTL simulation hanging.
INFO: [SIM 1] CSim done with 0 errors.
INFO: [SIM 3] *************** CSIM finish ***************


2乗誤差が 4 よりも大きい誤差になるとエラーにしているが、全部 3 違っているだけのようなので大丈夫だろうと思う。
ガボールフィルタの元の画像は、家の前の道路のBMP ファイルだ。写真を示す。
Gabor_filter_lh_2_3_190825.jpg

ハードウェアとする固定小数点演算でガボールフィルタをかけた画層を示す。まずは左白線用の画像から示す。
Gabor_filter_lh_2_4_190825.jpg

同じく、右白線用のガボールフィルタ画像を示す。
Gabor_filter_lh_2_5_190825.jpg

浮動小数点演算のガボールフィルタ画像を示す。左白線用画像だ。
Gabor_filter_lh_2_6_190825.jpg

同じく、右白線用画像を示す。
Gabor_filter_lh_2_7_190825.jpg

固定小数点演算と浮動小数点演算で似たようなガボールフィルタ画像になっていることが分かると思う。

C コードの合成を行った。220 MHz で動作するようにするために、ターゲットの周期は、4.5 ns とした。合成結果を示す。
Gabor_filter_lh_2_8_190827.png

Estimated が 4.758 ns で 4.5 ns を超過している。

Uncertainty を 1 ns にして、もう一度C コードの合成を行った。
Gabor_filter_lh_2_10_190827.png

リソース使用量は増えたが、Estimated が 4.758 ns で変化がない。どうやらクリティカル・パスが変わっていないのだろう?

Analysis の結果を見てみよう。
レポートをTiming Violation に変えると、クリティカル・パスが見えた。
Gabor_filter_lh_2_12_190827.png

Gabor_filter_lh_2_13_190827.png

row の for ループから最初のピクセルは取り込み済みだから、最初のピクセルはAXI4 Stream から取り込まないようにする if 文がクリティカル・パスのようだ。
これは仕方ないので、タイミング制約の方を変更することにした。
ターゲットの動作周波数を 5 ns とした。
Gabor_filter_lh_2_14_190827.png

これで C コードの合成を行った。
Gabor_filter_lh_2_15_190827.png

一応、タイミング制約は満たしたが、Estimated は 4.758 ns で同じだった。クリティカル・パスなので、このままだ。Uncertainty が 0.62 ns なので、Estimated + Uncertainty は 5 ns を超えてしまうのだが、良いのだろうか?この辺のコンセプトが見えない気がする。
Latency の評価をしよう。min では、64 ピクセル x 48 行なので、総ピクセル数は 3072 ピクセルだ。それを左白線検出、右白線検出するので、 x 2 となっているので、合計 6144 ピクセルとなる。Latency の min は 6149 クロックなので、
6149 クロック / 6144 ピクセル ≒ 1.00 クロック/ピクセルとなって、1 ピクセルを 1 クロックで処理できていることになる。
  1. 2019年08月27日 04:51 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96用ガボールフィルタIP の作成1

Ultra96-V2 にガボールフィルタを実装しようということで、以前、ZYBO 用に作っていたガボールフィルタIP をUltra96用に変更することにした。
以前の記事は、”Zybot による白線間の自動走行1(Gabor fillter の修正、C ソースコード)”だった。

Ultra96用に開発するに当たっては、ガボールフィルタをかけるフィルタ・サイズを row と col を引数に入れて設定できるように変更した。
まずは、Gabor_filter_lh_2.h を貼っておく。

// Gabor_filter_lh_2.h
// 2016/07/24
// 2016/07/25 : 右白線検出用のGabor Filterの重みを追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2019/08/22 : 更新
//

#ifndef __Gabor_filter_lh_H__
#define __Gabor_filter_lh_H__

#define ARRAY_SIZE  9

#define RIGHT_WEIGHT    1
#define LEFT_WEIGHT     0
#define L_R_WEIGHT      2

const int gabor_weight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用
    {
        {0,-3,-10,-16,-7,7,10,5,1},
        {-3,-15,-27,-11,32,50,29,5,-2},
        {-11,-24,-5,73,135,95,16,-17,-10},
        {-11,4,85,187,160,14,-72,-52,-14},
        {4,51,135,137,-18,-159,-136,-45,-2},
        {16,50,59,-39,-179,-185,-73,3,13},
        {10,12,-25,-104,-131,-60,15,27,11},
        {1,-7,-31,-48,-24,18,29,14,3},
        {-1,-5,-9,-4,10,16,10,2,-1}
    },
    {
        {1,5,7,1,-12,-17,-10,-3,0},
        {1,11,33,45,21,-16,-27,-15,-4},
        {-8,-5,35,107,131,69,-2,-21,-11},
        {-17,-47,-51,40,169,187,93,13,-7},
        {-8,-54,-134,-147,-18,123,130,58,11},
        {9,-6,-82,-185,-187,-65,36,44,17},
        {11,24,12,-55,-125,-112,-43,1,7},
        {3,14,30,23,-13,-41,-33,-12,-1},
        {0,2,9,17,14,1,-6,-5,-2}
    }
};
const float gabor_fweight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用(float)
    {
        {0.001282,-0.009914,-0.04062,-0.060586,-0.027574,0.026072,0.038427,0.018191,0.003056},
        {-0.012155,-0.057448,-0.104645,-0.042953,0.123263,0.197238,0.114451,0.020448,-0.007239},
        {-0.042252,-0.093065,-0.018911,0.285374,0.525746,0.372687,0.060734,-0.064748,-0.040465},
        {-0.042261,0.015673,0.332798,0.728763,0.625046,0.053591,-0.283076,-0.203293,-0.05608},
        {0.017342,0.198305,0.52554,0.535526,-0.069756,-0.622839,-0.531089,-0.177366,-0.006367},
        {0.060866,0.19708,0.231032,-0.154219,-0.699885,-0.721808,-0.286707,0.013004,0.049249},
        {0.038379,0.04877,-0.098477,-0.404993,-0.510165,-0.233566,0.057894,0.104366,0.041887},
        {0.0047,-0.0278,-0.121277,-0.187262,-0.093276,0.070512,0.113857,0.055799,0.009976},
        {-0.003798,-0.01885,-0.035607,-0.01709,0.037692,0.064268,0.038606,0.007536,-0.002133}
    },
    {
        {0.005562,0.018882,0.028293,0.004499,-0.044995,-0.064838,-0.039469,-0.009822,0.000815},
        {0.002294,0.04108,0.127023,0.175094,0.083025,-0.063755,-0.106402,-0.057798,-0.01406},
        {-0.031269,-0.021096,0.135641,0.417286,0.512467,0.269946,-0.008354,-0.082091,-0.041357},
        {-0.066348,-0.184919,-0.197802,0.15614,0.65976,0.728616,0.361674,0.052074,-0.027152},
        {-0.031146,-0.211178,-0.523777,-0.573856,-0.069756,0.480311,0.506451,0.225223,0.041031},
        {0.035552,-0.023892,-0.320104,-0.723563,-0.728735,-0.253689,0.1391,0.170625,0.067723},
        {0.04216,0.094939,0.047511,-0.216623,-0.488075,-0.437898,-0.168739,0.003336,0.027009},
        {0.012112,0.056596,0.115239,0.090332,-0.05076,-0.158403,-0.127847,-0.046375,-0.004918},
        {-0.00168,0.007437,0.036985,0.067021,0.053689,0.004977,-0.02365,-0.018248,-0.005928}
    }
};

#endif


次に、Gabor_filter_lh_2.cpp を貼っておく。

// Gabor_fiter_lh_2.cpp
// 2016/07/23 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2019/08/22 : 引数に int row, int col を追加
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include <hls_video.h>

#include "Gabor_filter_lh_2.h"

int conv_rgb2y(int rgb);

int Gabor_filter_lh_2(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, int row, int col, ap_uint<2> & RorL){
#pragma HLS INTERFACE s_axilite port=RorL
#pragma HLS INTERFACE s_axilite port=col
#pragma HLS INTERFACE s_axilite port=row
#pragma HLS INTERFACE axis register both port=ins
#pragma HLS INTERFACE axis register both port=outs
#pragma HLS INTERFACE s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    hls::LineBuffer<ARRAY_SIZE-1, 1920, int> linebuf;
    hls::Window<ARRAY_SIZE, ARRAY_SIZE, int> mbuf;

    int gray_pix, val, i, j, x, y;

    do {
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (int k=0; k<2; k++){
        for (y=0; y<row; y++){
#pragma HLS LOOP_TRIPCOUNT min=48 max=1080 avg=600
            for (x=0; x<col; x++){
#pragma HLS LOOP_TRIPCOUNT min=64 max=1920 avg=800          
#pragma HLS PIPELINE II=1
                if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                mbuf.shift_left();    // mbuf の列を1ビット左シフト
                for(i=ARRAY_SIZE-2; i>=0; --i){
                    mbuf.insert(linebuf(i,x), i+1, ARRAY_SIZE-1);
                }
                gray_pix = conv_rgb2y(pix.data);
                mbuf.insert(gray_pix, 0, ARRAY_SIZE-1);

                // LineBuffer の更新
                linebuf.shift_down(x);
                linebuf.insert_bottom(gray_pix, x);

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = LEFT_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE-1; j++){
                    for (i=0; i<ARRAY_SIZE-1; i++){
                        val += gabor_weight[ano][j][i] * mbuf(ARRAY_SIZE-1-j,i);
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                gabor.data = (val<<16)+(val<<8)+val;
                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1))
                    gabor.data = 0;

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (col-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


Gabor_filter_lh_2_tb.cpp を貼っておく。

// Gabor_filter_lh_tb.cpp
// 2016/07/24 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2019/08/22 : 引数に int row, int col を追加
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <ap_axi_sdata.h>
#include <hls_video.h>

#include "Gabor_filter_lh_2.h"
#include "bmp_header.h"

int Gabor_filter_lh_2(hls::stream<ap_axis<32,1,1,1> >& ins,
    hls::stream<ap_axis<32,1,1,1> >& outs, int row, int col, ap_uint<2> & RorL);

int conv_rgb2y_soft(int rgb);
int Gabor_filter_lh_2_soft(hls::stream<ap_axis<32,1,1,1> >& ins, 
    hls::stream<ap_axis<32,1,1,1> >& outs, int row, int col, ap_uint<2> & RorL);

#define CLOCK_PERIOD 10
#define RIGHT_OR_LEFT   L_R_WEIGHT
#define BMP_FILE_NAME   "road_1.bmp"

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > ins;
    hls::stream<ap_axis<32,1,1,1> > ins_soft;
    hls::stream<ap_axis<32,1,1,1> > outs;
    hls::stream<ap_axis<32,1,1,1> > outs_soft;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals;
    ap_axis<32,1,1,1> vals_soft;

    int m_seq = 1; // M系列の値
    int i, k;
    int xor_shift;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw, *fbmpwf;
    int *rd_bmp, *hw_gabor, *sw_gabor;
    int blue, green, red;
    ap_uint<2> r_l;
    char fhname[100];
    char fsname[100];

    if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }
    if ((sw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // ins に入力データを用意する
    for(int i=0; i<5; i++){    // dummy data
        pix.user = 0;
        pix.data = i;
        ins << pix;
    }

    // 2画面分を入力する
    for(int k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];

                if (j==0 && i==0)    // 最初のデータの時に TUSER を 1 にする
                    pix.user = 1;
                else
                    pix.user = 0;

                if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
                    pix.last = 1;
                else
                    pix.last = 0;

                ins << pix;
                ins_soft << pix;
            }
        }
    }

    r_l = (ap_uint<2>)RIGHT_OR_LEFT;
    Gabor_filter_lh_2(ins, outs, bmpihr.biHeight, bmpihr.biWidth, r_l);
    Gabor_filter_lh_2_soft(ins_soft, outs_soft, bmpihr.biHeight, bmpihr.biWidth, r_l);

    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    cout << endl;
    cout << "outs" << endl;
    for(k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                outs >> vals;
                outs_soft >> vals_soft;
                ap_int<32> val = vals.data;
                ap_int<32> val_soft = vals_soft.data;

                hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val;
                sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val_soft;

                //printf("k=%d, j=%d, i=%d\n",k,j,i);
                if ((double)pow((double)(val&0xff)-(val_soft&0xff),(double)2) > 4){ // 2乗誤差が4よりも大きい
                    printf("ERROR HW and SW results mismatch i = %ld, j = %ld, HW = %08x, SW = %08x\n", i, j, (int)val, (int)val_soft);
                    //return(1);
                }
                //if (vals.last)
                    //cout << "AXI-Stream is end" << endl;
            }
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    // ハードウェアのラプラシアンフィルタの結果を temp_gabor0.bmp, temp_gabor1.bmp へ出力する
    for(k=0; k<2; k++){
        if(k == 0){
            if ((fbmpw=fopen("temp_gabor0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpw=fopen("temp_gabor1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpw);
                fputc(green, fbmpw);
                fputc(red, fbmpw);
            }
        }
        fclose(fbmpw);
    }

    // ソフトウェアのラプラシアンフィルタの結果を temp_gabor_float0.bmp, temp_gabor_float1.bmp へ出力する
    for(k=0; k<2; k++){
        if (k == 0){
            if ((fbmpwf=fopen("temp_gabor_float0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpwf=fopen("temp_gabor_float1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpwf);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpwf);
                fputc(green, fbmpwf);
                fputc(red, fbmpwf);
            }
        }
        fclose(fbmpwf);
    }

    free(rd_bmp);
    free(hw_gabor);

    return 0;
}

int Gabor_filter_lh_2_soft(hls::stream<ap_axis<32,1,1,1> >& ins, 
    hls::stream<ap_axis<32,1,1,1> >& outs, int row, int col, ap_uint<2> & RorL){
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    hls::LineBuffer<ARRAY_SIZE-1, 1920, int> linebuf;
    hls::Window<ARRAY_SIZE, ARRAY_SIZE, int> mbuf;

    int gray_pix, val, i, j, x, y;
    float valf;

    do {    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (int k=0; k<2; k++){
        for (y=0; y<row; y++){
            for (x=0; x<col; x++){
                if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                mbuf.shift_left();    // mbuf の列を1ビット左シフト
                for(i=ARRAY_SIZE-2; i>=0; --i){
                    mbuf.insert(linebuf(i,x), i+1, ARRAY_SIZE-1);
                }
                gray_pix = conv_rgb2y_soft(pix.data);
                mbuf.insert(gray_pix, 0, ARRAY_SIZE-1);

                // LineBuffer の更新
                linebuf.shift_down(x);
                linebuf.insert_bottom(gray_pix, x);

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = LEFT_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, valf=0; j<ARRAY_SIZE-1; j++){
                    for (i=0; i<ARRAY_SIZE-1; i++){
                        valf += gabor_fweight[ano][j][i] * (float)mbuf(ARRAY_SIZE-1-j,i);
                    }
                }

                val = (int)valf;
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                gabor.data = (val<<16)+(val<<8)+val;
                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1))
                    gabor.data = 0;

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (col-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


bmp_header.h を示す。

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType; 
    uint32_t bfSize; 
    uint16_t bfReserved1; 
    uint16_t bfReserved2; 
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize; 
    int32_t biWidth; 
    int32_t biHeight; 
    uint16_t biPlanes; 
    uint16_t biBitCount; 
    uint32_t biCompression; 
    uint32_t biSizeImage; 
    int32_t biXPixPerMeter; 
    int32_t biYPixPerMeter; 
    uint32_t biClrUsed; 
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} BMP24FORMAT;


Vivado 2018.2 の Ultra96用Gabor_filter_lh_2 プロジェクトを示す。
Gabor_filter_lh_2_1_190825.png
  1. 2019年08月26日 04:21 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る5

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る4”の続き。

前回は、x と y を構造体で表現したコードをチューニングしたが、1 クロックで 1 出力まではチューニングすることができなかった。今回は、32 ビット幅のDMA トランザクションの中で、フィールドを自分で決めて x と y を配置する形態でチューニングをしてみよう。

今回の sum_of_squares.cpp を示す。今回は、 ap_int<32> を使用している。
ap_int<32> の中から x と y の ap_int<8> の 8 ビット幅を切り出して、 ap_int<8> でキャストしている。

#include <ap_int.h>

int sum_of_squares(volatile ap_int<32> *xy, volatile ap_int<32> *result){
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave
    ap_int<8> x, y;

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        ap_int<16> xyt = xy[i];

        x = (ap_int<8>)(xyt & 0xff);
        y = (ap_int<8>)((xyt & 0xff00)>>8);

        result[i] = x * x + y * y;
    }

    return(0);
}


テストベンチの sum_of_squares_tb.cpp を示す。

// sum_of_squares_tb.cpp

#include <iostream>
#include <ap_int.h>

int sum_of_squares(volatile ap_int<32> *xy, volatile ap_int<32> *result);

int main(){
    ap_int<32> xy[10];
    ap_int<32> result[10];

    for(int i=0; i<10; i++){
        xy[i] = i;
        xy[i] += (ap_int<32>)((i+1)<<8);
    }

    sum_of_squares(xy, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << i <<
                ", y[" << i << "] = " << i+1 <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


sum_of_squares_28_190821.png

C シミュレーションを行った。
sum_of_squares_29_190821.png

C コードの合成を行った。
sum_of_squares_30_190821.png

Initiation Interval の achieved が 1 クロックで良さそう。

C/RTL 協調シミュレーションを行った。
sum_of_squares_31_190821.png

C/RTL 協調シミュレーションの波形を示す。
sum_of_squares_32_190821.png

DMA Read 、 DMA Write 共にバーストできていて良い感じだし、Latency も小さい。
これが良さそうだと思う。

最後におまけで、C++ でな無く、 C で書いたサンプル・プログラムを示す。

#include <ap_cint.h>

typedef struct xy_struct{
    int8 x;
    int8 y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
        result[i] = xy[i].x * xy[i].x + xy[i].y * xy[i].y;
    }

    return(0);
}

  1. 2019年08月24日 05:00 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る4

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る3”の続き。

前回は、AXI4 インターフェースが 3 個あるのはもったいないので、1 個のAXI4 インターフェースでループで性能を向上させたい。ということで、x と y を構造体で表現したのだが、性能的には、x と y を個別に実装したときと同様の性能だった。今回は、もっと成功向上を図ろうと思う。

前回の sum_of_squares.cpp で引数の構造体を 1 回で読んできたいということで、構造体を = でコピーしようと思い、以下のコードを作成した。

#include <stdint.h>

typedef struct xy_struct{
    int8_t x;
    int8_t y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int32_t *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        xy_st xyt;
        xyt = xy[i];

        result[i] = xyt.x * xyt.x + xyt.y * xyt.y;
    }

    return(0);
}


C コードを合成したのだが、エラーになってしまった。
sum_of_squares_24_190821.png

エラー内容を示す。

ERROR: [HLS 200-70] Compilation errors found: In file included from sum_of_squares/sum_of_squares.cpp:1:
sum_of_squares/sum_of_squares.cpp:17:7: error: no viable overloaded '='
  xyt = xy[i];
  ~~~ ^ ~~~~~
sum_of_squares/sum_of_squares.cpp:3:16: note: candidate function (the implicit copy assignment operator) not viable: 1st argument ('volatile xy_st' (aka 'volatile xy_struct')) would lose volatile qualifier
typedef struct xy_struct{
               ^


構造体自体をコピーできないようだ。それではということで、volatile xy_st *xy を union にしてみたが、union は関数の引数にできないという仕様だそうだ。残念。。。

とりあえず、構造体のメンバことにコピーしてみよう。
sum_of_squares.cpp を示す。

#include <stdint.h>

typedef struct xy_struct{
    int8_t x;
    int8_t y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int32_t *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        xy_st xyt;
        xyt.x = xy[i].x; xyt.y = xy[i].y;

        result[i] = xyt.x * xyt.x + xyt.y * xyt.y;
    }

    return(0);
}


C コードの合成を行った。
sum_of_squares_25_190821.png

やはり、 for 文を実行するのに 2 クロックかかっている。

C/RTL 協調シミュレーションを行った。
sum_of_squares_26_190821.png

C/RTL 協調シミュレーションの波形を示す。
sum_of_squares_27_190821.png

やはり、Read トランザクションが 20 個あるよね。。。
構造体を使った場合はチューニングがうまく行かなかった。
  1. 2019年08月23日 04:00 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る3

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る2”の続き。

前回は、AXI4 インターフェースを独立な 3 個にすることで、DMA Read がバーストするようになって、ループの中を 1 クロックで実行できるようになった。今回は、AXI4 インターフェースが 3 個あるのはもったいないので、1 個のAXI4 インターフェースでループで性能を向上させたい。

入力ポートの x と y は 8 ビットなので、32 ビット幅のインターフェースでは、1 トランザクションで 4 個転送できる。x と y をまとめてしまえば 1 回のRead で x と y を持ってこられるんじゃないか?ということで、とりあえずは structure にしてみよう。
sum_of_squares.cpp はこうなった。

#include <stdint.h>

typedef struct xy_struct{
    int8_t x;
    int8_t y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int32_t *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        result[i] = xy[i].x * xy[i].x + xy[i].y * xy[i].y;
    }

    return(0);
}


今回は、ap_int<8> は * の演算子がオーバーロードされていないということで、 int_8t を使うことにした。
テストベンチのsum_of_squares_tb.cpp はこうなった。

// sum_of_squares_tb.cpp

#include <iostream>
#include <stdint.h>

typedef struct xy_struct{
    int8_t x;
    int8_t y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int *result);

int main(){
    xy_st xy[10];
    int result[10];

    for(int i=0; i<10; i++){
        xy[i].x = i;
        xy[i].y = i+1;
    }

    sum_of_squares(xy, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << (int)xy[i].x <<
                ", y[" << i << "] = " << (int)xy[i].y <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


sum_of_squares_17_190821.png

C シミュレーションを行った。
sum_of_squares_18_190821.png

問題ないようだ。

C コードの合成を行った。
sum_of_squares_19_190821.png

ループの中は 4 クロックで処理している。

AXI4 Lite Slave のアドレスマップを見ると、引数で x と y を実装したときと同じようだ。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of xy_x
//        bit 31~0 - xy_x[31:0] (Read/Write)
// 0x1c : reserved
// 0x20 : Data signal of xy_y
//        bit 31~0 - xy_y[31:0] (Read/Write)
// 0x24 : reserved
// 0x28 : Data signal of result
//        bit 31~0 - result[31:0] (Read/Write)
// 0x2c : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)



次に引数 xy に DATA_PACK 指示子を追加してみよう。
sum_of_squares_20_190821.png

sum_of_squares.cpp はこうなった。

#include <stdint.h>

typedef struct xy_struct{
    int8_t x;
    int8_t y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int32_t *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        result[i] = xy[i].x * xy[i].x + xy[i].y * xy[i].y;
    }

    return(0);
}


C コードの合成を行った。
sum_of_squares_21_190821.png

やはり、ループの中は 4 クロックで処理している。
AXI4 Lite Slave のアドレスマップを示す。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of xy
//        bit 31~0 - xy[31:0] (Read/Write)
// 0x1c : reserved
// 0x20 : Data signal of result
//        bit 31~0 - result[31:0] (Read/Write)
// 0x24 : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


データがパックされて、xy のオフセットアドレスのみになったのだが、ループの中は 4 クロックなのか???

C/RTL 協調シミュレーションを行った。
sum_of_squares_22_190821.png

C/RTL 協調シミュレーションの波形を示す。
sum_of_squares_23_190821.png

結局、40 回Read している。RDATA を見るとデータがパックされているのが分かるが、アクセスとしては x と y が独立の引数のときと同じということが分かった。
  1. 2019年08月22日 05:12 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る2

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る1”の続き。

前回は、x と y の平方数の和を求める C ソースコードをいろいろとチューニングしていった。しかし、入力の x と y を同じAXI4 インターフェースから取ってくるので、どうしても x と y をRead する DMA がバーストにならないという欠点があった。今回は、AXI4 インターフェースを独立な 3 個にすることで、DMA Read がバーストするようにしてみよう。

さて、AXI4 インターフェースを 3 個にするにはどうするかというと、x , y , result の 3 個の引数に独立な bundle を与えればよい。
今回の sum_of_squares.cpp を示す。

int sum_of_squares(volatile char *x, volatile char *y, volatile int *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave bundle=y
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave bundle=x
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave bundle=result

    LOOP1: for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        char xt = x[i];
        char yt = y[i];

        result[i] = xt*xt + yt*yt;
    }

    return(0);
}


今回の sum_of_squares.cpp を合成した。結果を示す。
sum_of_squares_14_190821.png

PIPELINE の Initiation Interval が 1 クロックになった。これで完璧だ。
Verilog HDL のトップのファイル sum_of_squares.v の module 定義を引用すると、 x , y , result の 3 個のAXI4 インターフェースが実装されているのが分かる。

module sum_of_squares (
        ap_clk,
        ap_rst_n,
        m_axi_x_AWVALID,
        m_axi_x_AWREADY,
        m_axi_x_AWADDR,
        m_axi_x_AWID,
        m_axi_x_AWLEN,
        m_axi_x_AWSIZE,
        m_axi_x_AWBURST,
        m_axi_x_AWLOCK,
        m_axi_x_AWCACHE,
        m_axi_x_AWPROT,
        m_axi_x_AWQOS,
        m_axi_x_AWREGION,
        m_axi_x_AWUSER,
        m_axi_x_WVALID,
        m_axi_x_WREADY,
        m_axi_x_WDATA,
        m_axi_x_WSTRB,
        m_axi_x_WLAST,
        m_axi_x_WID,
        m_axi_x_WUSER,
        m_axi_x_ARVALID,
        m_axi_x_ARREADY,
        m_axi_x_ARADDR,
        m_axi_x_ARID,
        m_axi_x_ARLEN,
        m_axi_x_ARSIZE,
        m_axi_x_ARBURST,
        m_axi_x_ARLOCK,
        m_axi_x_ARCACHE,
        m_axi_x_ARPROT,
        m_axi_x_ARQOS,
        m_axi_x_ARREGION,
        m_axi_x_ARUSER,
        m_axi_x_RVALID,
        m_axi_x_RREADY,
        m_axi_x_RDATA,
        m_axi_x_RLAST,
        m_axi_x_RID,
        m_axi_x_RUSER,
        m_axi_x_RRESP,
        m_axi_x_BVALID,
        m_axi_x_BREADY,
        m_axi_x_BRESP,
        m_axi_x_BID,
        m_axi_x_BUSER,
        m_axi_y_AWVALID,
        m_axi_y_AWREADY,
        m_axi_y_AWADDR,
        m_axi_y_AWID,
        m_axi_y_AWLEN,
        m_axi_y_AWSIZE,
        m_axi_y_AWBURST,
        m_axi_y_AWLOCK,
        m_axi_y_AWCACHE,
        m_axi_y_AWPROT,
        m_axi_y_AWQOS,
        m_axi_y_AWREGION,
        m_axi_y_AWUSER,
        m_axi_y_WVALID,
        m_axi_y_WREADY,
        m_axi_y_WDATA,
        m_axi_y_WSTRB,
        m_axi_y_WLAST,
        m_axi_y_WID,
        m_axi_y_WUSER,
        m_axi_y_ARVALID,
        m_axi_y_ARREADY,
        m_axi_y_ARADDR,
        m_axi_y_ARID,
        m_axi_y_ARLEN,
        m_axi_y_ARSIZE,
        m_axi_y_ARBURST,
        m_axi_y_ARLOCK,
        m_axi_y_ARCACHE,
        m_axi_y_ARPROT,
        m_axi_y_ARQOS,
        m_axi_y_ARREGION,
        m_axi_y_ARUSER,
        m_axi_y_RVALID,
        m_axi_y_RREADY,
        m_axi_y_RDATA,
        m_axi_y_RLAST,
        m_axi_y_RID,
        m_axi_y_RUSER,
        m_axi_y_RRESP,
        m_axi_y_BVALID,
        m_axi_y_BREADY,
        m_axi_y_BRESP,
        m_axi_y_BID,
        m_axi_y_BUSER,
        m_axi_result_AWVALID,
        m_axi_result_AWREADY,
        m_axi_result_AWADDR,
        m_axi_result_AWID,
        m_axi_result_AWLEN,
        m_axi_result_AWSIZE,
        m_axi_result_AWBURST,
        m_axi_result_AWLOCK,
        m_axi_result_AWCACHE,
        m_axi_result_AWPROT,
        m_axi_result_AWQOS,
        m_axi_result_AWREGION,
        m_axi_result_AWUSER,
        m_axi_result_WVALID,
        m_axi_result_WREADY,
        m_axi_result_WDATA,
        m_axi_result_WSTRB,
        m_axi_result_WLAST,
        m_axi_result_WID,
        m_axi_result_WUSER,
        m_axi_result_ARVALID,
        m_axi_result_ARREADY,
        m_axi_result_ARADDR,
        m_axi_result_ARID,
        m_axi_result_ARLEN,
        m_axi_result_ARSIZE,
        m_axi_result_ARBURST,
        m_axi_result_ARLOCK,
        m_axi_result_ARCACHE,
        m_axi_result_ARPROT,
        m_axi_result_ARQOS,
        m_axi_result_ARREGION,
        m_axi_result_ARUSER,
        m_axi_result_RVALID,
        m_axi_result_RREADY,
        m_axi_result_RDATA,
        m_axi_result_RLAST,
        m_axi_result_RID,
        m_axi_result_RUSER,
        m_axi_result_RRESP,
        m_axi_result_BVALID,
        m_axi_result_BREADY,
        m_axi_result_BRESP,
        m_axi_result_BID,
        m_axi_result_BUSER,
        s_axi_AXILiteS_AWVALID,
        s_axi_AXILiteS_AWREADY,
        s_axi_AXILiteS_AWADDR,
        s_axi_AXILiteS_WVALID,
        s_axi_AXILiteS_WREADY,
        s_axi_AXILiteS_WDATA,
        s_axi_AXILiteS_WSTRB,
        s_axi_AXILiteS_ARVALID,
        s_axi_AXILiteS_ARREADY,
        s_axi_AXILiteS_ARADDR,
        s_axi_AXILiteS_RVALID,
        s_axi_AXILiteS_RREADY,
        s_axi_AXILiteS_RDATA,
        s_axi_AXILiteS_RRESP,
        s_axi_AXILiteS_BVALID,
        s_axi_AXILiteS_BREADY,
        s_axi_AXILiteS_BRESP,
        interrupt
);


C/RTL 協調シミュレーションを行った。
sum_of_squares_15_190821.png

Latency は 84 クロックに減っている。

C/RTL 協調シミュレーションの波形を示す。
sum_of_squares_16_190821.png

result の DMA Write と y の DMA Read の波形だ。 y の DMA Read は ARLEN が 3 になっていてバーストで Read しているのが分かる。 x も波形がここにはないが同様にバースト Read してる。

これで、このインターフェースでのチューニングは終了だが、3 個のAXI4 インターフェースが実装されているのがもったいないと感じる。オーバースペックじゃないかな?
x と y は 8 ビットなので、バス幅 32 ビットの内の 8 ビットを 2 個使えば良いのではないか?というコンセプトで次回の検討を行おう。
  1. 2019年08月21日 05:04 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る1

Vivado HLS で 2 つの入力のAXI4 Master モジュールを作ってみよう。題材は平方数の和を求めるコードだ。

まずは、ap_int 型を使って作ってみよう。
Source は sum_of_squares.cpp とした。

#include <ap_int.h>

int sum_of_squares(volatile ap_int<8> *x, volatile ap_int<8> *y, volatile ap_int<17> *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
        result[i] = x[i]*x[i] + y[i]*y[i];
    }

    return(0);
}


Testbench は sum_of_squares_tb.cpp とした。

// sum_of_squares_tb.cpp

#include <iostream>
#include <ap_int.h>

int sum_of_squares(volatile ap_int<8> *x, volatile ap_int<8> *y, volatile ap_int<17> *result);

int main(){
    ap_int<8> x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    ap_int<8> y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    ap_int<17> result[10];

    sum_of_squares(x, y, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << (int)x[i] <<
                ", y[" << i << "] = " << (int)y[i] <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


Vivado HLS 2018.3 で sum_of_squares プロジェクトを作成した。使用するFPGA は xc7z010clg400-1 のZYBO Z7-10 を想定している。
sum_of_squares_1_190820.png

C シミュレーションをするとエラーになった。
sum_of_squares_2_190820.png

最初のエラーを貼る。

../../../sum_of_squares.cpp: 関数 ‘int sum_of_squares(volatile ap_int<8>*, volatile ap_int<8>*, volatile ap_int<17>*)’ 内:
../../../sum_of_squares.cpp:10:19: エラー: no match for ‘operator*’ (operand types are ‘volatile ap_int<8>’ and ‘volatile ap_int<8>’)
   result[i] = x[i]*x[i] + y[i]*y[i];


なんと乗算の定義が無い様だ。
なお、”高位合成ユーザーズ ガイド UG902 (v2018.3) 2018 年 12 月 20 日”の 90 ページに

値が複数回更新されるデータ信号を指定するには、volatile 修飾子を使用してください。

と書いてあるので、volatile は必要だ。

エラーを回避するにはどうするかというと、char と int に引数の方を変えてみよう。
sum_of_squares.cpp を示す。

int sum_of_squares(volatile char *x, volatile char *y, volatile int *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
        result[i] = x[i]*x[i] + y[i]*y[i];
    }

    return(0);
}


sum_of_squares_tb.cpp を示す。

// sum_of_squares_tb.cpp

#include <iostream>

int sum_of_squares(volatile char *x, volatile char *y, volatile int *result);

int main(){
    char x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    char y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int result[10];

    sum_of_squares(x, y, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << (int)x[i] <<
                ", y[" << i << "] = " << (int)y[i] <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


C シミュレーションを行った。
sum_of_squares_3_190820.png

今度は成功した。”高位合成ユーザーズ ガイド UG902 (v2018.3) 2018 年 12 月 20 日”のAXI4 Master のサンプルの引数の型が int なのはこのような理由なのだろうか?

C コードの合成を行った。結果を示す。
sum_of_squares_4_190820.png

AXI4 Lite Slave のアドレスマップを示す。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of x
//        bit 31~0 - x[31:0] (Read/Write)
// 0x1c : reserved
// 0x20 : Data signal of y
//        bit 31~0 - y[31:0] (Read/Write)
// 0x24 : reserved
// 0x28 : Data signal of result
//        bit 31~0 - result[31:0] (Read/Write)
// 0x2c : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


C/RTL 協調シミュレーションを行った。
sum_of_squares_5_190820.png

0x18 番地(x のアドレス)には 0 、0x20 番地(y のアドレス)には 0xC 、 0x28 番地(result のアドレス)には 0x18 を書いている。
C/RTL 協調シミュレーションの波形を拡大した図を示す。
sum_of_squares_6_190820.png

AXI4 Master Read は、ARLEN が 00 なので単発のアクセス、AXI4 Master Write は AWLEN が 09 なので、バースト・アクセスとなる。
x の値は 2 回 Read されている。 y の値も 2 回 Read されているようだ。

次に、sum_of_squares.cpp の for 文に PIPELINE 指示子を追加してみよう。

int sum_of_squares(volatile char *x, volatile char *y, volatile int *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    LOOP1: for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        result[i] = x[i]*x[i] + y[i]*y[i];
    }

    return(0);
}


C コードの合成結果を示す。
sum_of_squares_10_190820.png

約 1/3 程度のLatency になった。

C/RTL 協調シミュレーション結果を示す。
sum_of_squares_8_190820.png

C/RTL 協調シミュレーションの波形を拡大した図を示す。
sum_of_squares_9_190820.png

1 回の演算を行うのに、合計 40 回 Read している。 write は 10 回だ。

それじゃ、このRead のアクセス回数を 1/2 にしてみよう。
Source の sum_of_squares.cpp のコードを以下のように変更した。

int sum_of_squares(volatile char *x, volatile char *y, volatile int *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    LOOP1: for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        char xt = x[i];
        char yt = y[i];

        result[i] = xt*xt + yt*yt;
    }

    return(0);
}


C コードの合成結果を示す。
sum_of_squares_11_190820.png

Initiation Interval が 4 クロックから 2 クロックになった。

C/RTL 協調シミュレーションの結果を示す。
sum_of_squares_12_190820.png

C/RTL 協調シミュレーションの波形を示す。
sum_of_squares_13_190820.png

Read が 20 回になった。
  1. 2019年08月20日 05:27 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 でカメラ画像をDisplayPort に出力する3(完成)

Ultra96-V2 でカメラ画像をDisplayPort に出力する2(Ultra96-V2 の環境整備)”の続き。

前回は、bin ファイルを作成し、Ultra96-V2 のDebian を起動して、環境の整備を行った。しかし、fclkcfg でエラーが出てしまい、目的の周波数に pl_clk0 を設定することができなかった。pl_clk0 は 100 MHz に設定されたので、XGA 解像度でカメラ画像をDisplayPort に表示することはできたが、HD 解像度で表示することはできなかった。今回は、ikwzm さんがfclkcfg のバグを修正してくれたので、HD 解像度でのDisplayPort 出力を試してみよう。

ikzwm さんの以下のツィートでfclkcfg を修正していただいたのがわかった。ありがとうございました。

ZynqMP-FPGA-Linux v2019.1.2 を緊急リリースしていただいた。

Ubuntu 18.04 のホストパソコンの方で、ZynqMP-FPGA-Linux にgit pull しようとしたが、うまくアップデートできなかった。
よって、一度削除してからもう一度ダウンロードすることにした。
rm -rf ZynqMP-FPGA-Linux
git clone -b v2019.1.0 git://github.com/ikwzm/ZynqMP-FPGA-Linux
cd ZynqMP-FPGA-Linux
git lfs pull


これだけだと v2019.1.2 になってなかったので、次のコマンドを入力した。
git pull git://github.com/ikwzm/ZynqMP-FPGA-Linux v2019.1.2
cam_dp_V2_24_190819.png

これで変更されたのは、image-4.19.0-xlnx-v2019.1-zynqmp_fpga だけだったので、これだけをMicro SD カードのboot パーティションの同じ名前のファイルと入れ替えた。
cam_dp_V2_23_190819.png

Micro SD カードをUltra96-V2 に入れて、電源ON し、Debian をブートした。
cd example/cam_dp_V2/
./lddtorvary.sh
./cam_dp_ov5642 -r 2
./disp_pattern.sh


すると、DisplayPort にHD 解像度のカメラ画像が表示された。
cam_dp_V2_25_190819.png

cam_dp_V2_26_190819.jpg

./lddtorvary.sh を起動した時のメッセージを示す。
cam_dp_V2_27_190819.png

pl_clk0 は 214285713 Hz だそうだ。うまく設定されているようだ。
なお、pl_clk1 は rpll になっているが、DTS ファイルの<&zynqmp_clk 0x48 &zynqmp_clk 1>の最後の 1 が rpll を示すようだ。ここが 0 だと iopll になる。

cam_dp_ov5642.cpp を貼っておく。

// cam_dp_ov5642.cpp (for Ultra96-V2)
// 2018/12/14 by marsee
//
// This software converts the left and right of the camera image to BMP file.
// -b : bmp file name
// -n : Start File Number
// -h : help
//
// 2018/12/20 : completed.
// I am using the SVGA driver register setting of https://github.com/virajkanwade/rk3188_android_kernel/blob/master/drivers/media/video/ov5642.c
// 2018/12/22 : fixed
// 2018/12/30 : ov5642_inf_axis[0] fixed
// 2019/02/06 : for DisplayPort
// 2019/08/18 : Changed to /dev/uio4 ~ uio9 for Ultra96-V2. by marsee

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

#define PIXEL_NUM_OF_BYTES    4
#define NUMBER_OF_WRITE_FRAMES  3

#define SVGA_HORIZONTAL_PIXELS  800
#define SVGA_VERTICAL_LINES     600
#define SVGA_ALL_DISP_ADDRESS   (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define SVGA_3_PICTURES         (SVGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

#define XGA_HORIZONTAL_PIXELS  1024
#define XGA_VERTICAL_LINES     768
#define XGA_ALL_DISP_ADDRESS   (XGA_HORIZONTAL_PIXELS * XGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define XGA_3_PICTURES         (XGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

#define HD_HORIZONTAL_PIXELS  1920
#define HD_VERTICAL_LINES     1080
#define HD_ALL_DISP_ADDRESS   (HD_HORIZONTAL_PIXELS * HD_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define HD_3_PICTURES         (HD_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

int WriteBMPfile(char *bmp_file, volatile unsigned int *frame_buffer, int active_frame, int resolution);

void cam_i2c_init(volatile unsigned *ov5642_axi_iic) {
    ov5642_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
    ov5642_axi_iic[64] = 0x1; // enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
    // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile unsigned *ov5642_axi_iic, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
    ov5642_axi_iic[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    ov5642_axi_iic[66] = (write_addr >> 8) & 0xff;  // address upper byte
    ov5642_axi_iic[66] = write_addr & 0xff;           // address lower byte
    ov5642_axi_iic[66] = 0x200 | (write_data & 0xff);      // data
    cam_i2x_write_sync();
}

int cam_reg_set(volatile unsigned *axi_iic, unsigned int device_addr);

int main(int argc, char *argv[]){
    int opt;
    int c, help_flag=0;
    char bmp_fn[256] = "bmp_file";
    char  attr[1024];
    unsigned long  phys_addr;
    int file_no = -1;
    int fd4, fd5, fd6, fd7, fd8, fd9, fd10, fd11;
    volatile unsigned int *ov5642_inf_axis, *axi_iic, *disp_dmar_axis, *vflip_dma_write;
    volatile unsigned int *axi_gpio_0, *axi_gpio_1;
    volatile unsigned int *frame_buffer;
    int active_frame;
    int resolution;
    int all_disp_addr;
    
    resolution = 1; // XGA
    while ((opt=getopt(argc, argv, "b:n:h:r:")) != -1){
        switch (opt){
            case 'b':
                strcpy(bmp_fn, optarg);
                break;
            case 'n':
                file_no = atoi(optarg);
                printf("file_no = %d\n", file_no+1);
                break;
            case 'r':
                resolution = atoi(optarg);
                break;
            case 'h':
                help_flag = 1;
                break;
        }
    }
    if(resolution == 0){
        printf("SVGA\n");
    } else if(resolution == 1){
        printf("XGA\n");
    } else {
        printf("HD\n");
    }

    if (help_flag == 1){ // help
        printf("Usage : cam_capture [-b <bmp file name>] [-n <Start File Number>] [-h]\n");
        printf("         -r [0|1|2](0:SVGA, 1:XGA, 2:HD)\n");
        exit(0);
    }
       
    // all_disp_addr
    switch(resolution){
        case 0 :
            all_disp_addr = SVGA_ALL_DISP_ADDRESS;
            break;
        case 1 :
            all_disp_addr = XGA_ALL_DISP_ADDRESS;
            break;
        default : // 2
            all_disp_addr = HD_ALL_DISP_ADDRESS;
            break;
    }
    
    // ov5642_inf_axis-uio IP
    fd4 = open("/dev/uio4", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd4 < 1){
        fprintf(stderr, "/dev/uio4 (ov5642_inf_axis) open error\n");
        exit(-1);
    }
    ov5642_inf_axis = (volatile unsigned *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
    if (!ov5642_inf_axis){
        fprintf(stderr, "ov5642_inf_axis mmap error\n");
        exit(-1);
    }
    
    // axi_iic-uio IP
    fd5 = open("/dev/uio5", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd5 < 1){
        fprintf(stderr, "/dev/uio5 (axi_iic) open error\n");
        exit(-1);
    }
    axi_iic = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd5, 0);
    if (!axi_iic){
        fprintf(stderr, "axi_iic mmap error\n");
        exit(-1);
    }

    // disp_dmar_axis-uio IP
    fd6 = open("/dev/uio6", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd6 < 1){
        fprintf(stderr, "/dev/uio6 (disp_dmar_axis) open error\n");
        exit(-1);
    }
    disp_dmar_axis = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
    if (!disp_dmar_axis){
        fprintf(stderr, "disp_dmar_axis mmap error\n");
        exit(-1);
    }

    // vflip_dma_write-uio IP
    fd7 = open("/dev/uio7", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd7 < 1){
        fprintf(stderr, "/dev/uio7 (vflip_dma_write) open error\n");
        exit(-1);
    }
    vflip_dma_write = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
    if (!vflip_dma_write){
        fprintf(stderr, "vflip_dma_write mmap error\n");
        exit(-1);
    }

    // axi_gpio_0-uio IP (init_done output)
    fd8 = open("/dev/uio8", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd8 < 1){
        fprintf(stderr, "/dev/uio8 (axi_gpio_0) open error\n");
        exit(-1);
    }
    axi_gpio_0 = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd8, 0);
    if (!axi_gpio_0){
        fprintf(stderr, "axi_gpio_0 mmap error\n");
        exit(-1);
    }

    // axi_gpio_1-uio IP (active_frame input)
    fd9 = open("/dev/uio9", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd9 < 1){
        fprintf(stderr, "/dev/uio9 (axi_gpio_1) open error\n");
        exit(-1);
    }
    axi_gpio_1 = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
    if (!axi_gpio_1){
        fprintf(stderr, "axi_gpio_1 mmap error\n");
        exit(-1);
    }
    
    
    // udmabuf4
    fd10 = open("/dev/udmabuf4", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled. 
    if (fd10 == -1){
        fprintf(stderr, "/dev/udmabuf4 open error\n");
        exit(-1);
    }
    frame_buffer = (volatile unsigned int *)mmap(NULL, all_disp_addr*NUMBER_OF_WRITE_FRAMES, PROT_READ|PROT_WRITE, MAP_SHARED, fd10, 0);
    if (!frame_buffer){
        fprintf(stderr, "frame_buffer4 mmap error\n");
        exit(-1);
    }
    
    // phys_addr of udmabuf4
    fd11 = open("/sys/class/udmabuf/udmabuf4/phys_addr", O_RDONLY);
    if (fd11 == -1){
        fprintf(stderr, "/sys/class/udmabuf/udmabuf4/phys_addr open error\n");
        exit(-1);
    }
    read(fd11, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd11);
    printf("phys_addr = %x\n", (int)phys_addr);
    
    // vflip_dma_write start
    vflip_dma_write[6] = phys_addr; // fb0
    vflip_dma_write[8] = phys_addr+all_disp_addr; // fb1
    vflip_dma_write[10] = phys_addr+2*all_disp_addr; // fb2
    vflip_dma_write[12] = resolution;
    vflip_dma_write[0] = 0x1; // start
    vflip_dma_write[0] = 0x80; // EnableAutoRestart
       
    // CMOS Camera initialize, ov5642
    cam_i2c_init(axi_iic);
    
    cam_reg_set(axi_iic, 0x78); // OV5642 register set

    ov5642_inf_axis[0] = phys_addr; // ov5642 AXI4-Stream Start
    ov5642_inf_axis[1] = 0;
 
     // disp_dmar_axis start
    disp_dmar_axis[4] = phys_addr; // fb0
    disp_dmar_axis[6] = phys_addr+all_disp_addr; // fb1
    disp_dmar_axis[8] = phys_addr+2*all_disp_addr; // fb2
    disp_dmar_axis[10] = resolution;
    axi_gpio_0[0] = 1; // disp_dmar_axis start(init_done = 1)
    
    char bmp_file[256];

    // All 0 set
    int all_disp_frame_index = all_disp_addr/PIXEL_NUM_OF_BYTES*NUMBER_OF_WRITE_FRAMES;
    for (int i=0; i<all_disp_frame_index; i++){
        frame_buffer[i] = 0x0;
    }
    
    // w - writed the left and right eye's bmp files.  q - exit.
    c = getc(stdin);
    while(c != 'q'){
        switch ((char)c) {
            case 'w' : // w - writed a bmp files.
                // writed the frame buffer
                file_no++;
                sprintf(bmp_file, "%s%d.bmp", bmp_fn, file_no);
                active_frame = (int)(axi_gpio_1[0] & 0x3); // Data signal of active_frame_V
                WriteBMPfile(bmp_file, frame_buffer, active_frame, resolution);
                
                printf("file No. = %d\n", file_no);

                break;
            case 'e' : // e - writed a same bmp files.
                // writed the frame buffer
                if (file_no == -1)
                    file_no = 0;
                
                sprintf(bmp_file, "%s%d.bmp", bmp_fn, file_no);
                active_frame = (int)(axi_gpio_1[0] & 0x3); // Data signal of active_frame_V
                WriteBMPfile(bmp_file, frame_buffer, active_frame, resolution);
                
                printf("file No. = %d\n", file_no);

                break;
        }
        c = getc(stdin);
    }
    
    munmap((void *)ov5642_inf_axis, 0x1000);
    munmap((void *)axi_iic, 0x1000);
    munmap((void *)disp_dmar_axis, 0x10000);
    munmap((void *)vflip_dma_write, 0x10000);
    munmap((void *)axi_gpio_0, 0x1000);
    munmap((void *)axi_gpio_1, 0x1000);
    munmap((void *)frame_buffer, all_disp_addr*3);
    
    close(fd4);
    close(fd5);
    close(fd6);
    close(fd7);
    close(fd8);
    close(fd9);
    close(fd10);
    
    return(0);
}

int WriteBMPfile(char *bmp_file, volatile unsigned int *frame_buffer, int active_frame, int resolution){
    int read_frame;
    int img_width, img_height;
    
    if (active_frame == 0)
        read_frame = 2;
    else if (active_frame == 1)
        read_frame = 0;
    else // active_frame == 2
        read_frame = 1;
        
    switch(resolution){
        case 0 :
            img_width = SVGA_HORIZONTAL_PIXELS;
            img_height = SVGA_VERTICAL_LINES;
            break;
        case 1 :
            img_width = XGA_HORIZONTAL_PIXELS;
            img_height = XGA_VERTICAL_LINES;
            break;
        default : // case 2 :
            img_width = HD_HORIZONTAL_PIXELS;
            img_height = HD_VERTICAL_LINES;
            break;
    }
    
    int offset_addr = read_frame * img_width * img_height;
    
    cv::Mat img(img_height, img_width, CV_8UC3);

    cv::Mat_<cv::Vec3b> dst_vec3b = cv::Mat_<cv::Vec3b>(img);
    for(int y=0; y<img.rows; y++){
        for(int x=0; x<img.cols; x++){
            cv::Vec3b pixel;
            int rgb = frame_buffer[offset_addr+y*img.cols+x];
            pixel[0] = (rgb & 0xff); // blue
            pixel[1] = (rgb & 0xff00) >> 8; // green
            pixel[2] = (rgb & 0xff0000) >> 16; // red
            dst_vec3b(y,x) = pixel;
        }
    }
    
    cv::imwrite(bmp_file, img);
    
    return(0);
}

int cam_reg_set(volatile unsigned *axi_iic, unsigned int device_addr){
    cam_i2c_write(axi_iic, device_addr, 0x3103, 0x93);
    cam_i2c_write(axi_iic, device_addr, 0x3008, 0x82);
    cam_i2c_write(axi_iic, device_addr, 0x3017, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x3018, 0xfc);
    cam_i2c_write(axi_iic, device_addr, 0x3810, 0xc2);
    cam_i2c_write(axi_iic, device_addr, 0x3615, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x3000, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3001, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3002, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3003, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3000, 0xf8);
    cam_i2c_write(axi_iic, device_addr, 0x3001, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x3002, 0x5c);
    cam_i2c_write(axi_iic, device_addr, 0x3003, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3004, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3005, 0xb7);
    cam_i2c_write(axi_iic, device_addr, 0x3006, 0x43);
    cam_i2c_write(axi_iic, device_addr, 0x3007, 0x37);
    cam_i2c_write(axi_iic, device_addr, 0x3011, 0x08); // 0x08 - 15fps, 0x10 - 30fps
    cam_i2c_write(axi_iic, device_addr, 0x3010, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x460c, 0x22);
    cam_i2c_write(axi_iic, device_addr, 0x3815, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x370d, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x370c, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3602, 0xfc);
    cam_i2c_write(axi_iic, device_addr, 0x3612, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x3634, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3613, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3605, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x3622, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3604, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x3603, 0xa7);
    cam_i2c_write(axi_iic, device_addr, 0x3603, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x4000, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x401d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3600, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x3605, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3606, 0x3f);
    cam_i2c_write(axi_iic, device_addr, 0x3c01, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0x4f);
    cam_i2c_write(axi_iic, device_addr, 0x5020, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x79);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x22);
    cam_i2c_write(axi_iic, device_addr, 0x5197, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x5500, 0x0a);
    cam_i2c_write(axi_iic, device_addr, 0x5504, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5505, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5080, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x300e, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x4610, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x471d, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x4708, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x3710, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3632, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x3702, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x37);
    cam_i2c_write(axi_iic, device_addr, 0x3631, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x3808, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3809, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380a, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x380b, 0xe0);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x501f, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0x4f);
    cam_i2c_write(axi_iic, device_addr, 0x4300, 0x61); // RGB565
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x73);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3824, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x380c, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x380d, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xe8);
    cam_i2c_write(axi_iic, device_addr, 0x3a0d, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3a0e, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x3818, 0xc1);
    cam_i2c_write(axi_iic, device_addr, 0x3705, 0xdb);
    cam_i2c_write(axi_iic, device_addr, 0x370a, 0x81);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0xc7);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x3803, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3827, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3810, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3804, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x3805, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3806, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x3807, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3a00, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x3a1a, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3a13, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a18, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a19, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x3a08, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x3a09, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0a, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x3a0b, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3004, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x350c, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x350d, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x3500, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x350a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3a0f, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a10, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a1b, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a1e, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a11, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3a1f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3030, 0x0b);
    cam_i2c_write(axi_iic, device_addr, 0x3a02, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a03, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x3a04, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a14, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a15, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x3a16, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a00, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x3a08, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x3a09, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x3a0a, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3a0b, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0d, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3a0e, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x57);
    cam_i2c_write(axi_iic, device_addr, 0x3703, 0x98);
    cam_i2c_write(axi_iic, device_addr, 0x3704, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x589b, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x589a, 0xc5);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5380, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5381, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5382, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5383, 0x4e);
    cam_i2c_write(axi_iic, device_addr, 0x5384, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5385, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x5386, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5387, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5388, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5389, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x538a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538b, 0x31);
    cam_i2c_write(axi_iic, device_addr, 0x538c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538d, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538f, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x5390, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5391, 0xab);
    cam_i2c_write(axi_iic, device_addr, 0x5392, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5393, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x5394, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5480, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5481, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x5482, 0x36);
    cam_i2c_write(axi_iic, device_addr, 0x5483, 0x57);
    cam_i2c_write(axi_iic, device_addr, 0x5484, 0x65);
    cam_i2c_write(axi_iic, device_addr, 0x5485, 0x71);
    cam_i2c_write(axi_iic, device_addr, 0x5486, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x5487, 0x87);
    cam_i2c_write(axi_iic, device_addr, 0x5488, 0x91);
    cam_i2c_write(axi_iic, device_addr, 0x5489, 0x9a);
    cam_i2c_write(axi_iic, device_addr, 0x548a, 0xaa);
    cam_i2c_write(axi_iic, device_addr, 0x548b, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x548c, 0xcd);
    cam_i2c_write(axi_iic, device_addr, 0x548d, 0xdd);
    cam_i2c_write(axi_iic, device_addr, 0x548e, 0xea);
    cam_i2c_write(axi_iic, device_addr, 0x548f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5490, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5491, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5492, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5493, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5494, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5495, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x5496, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5497, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x5498, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5499, 0x86);
    cam_i2c_write(axi_iic, device_addr, 0x549a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549b, 0x5b);
    cam_i2c_write(axi_iic, device_addr, 0x549c, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549d, 0x3b);
    cam_i2c_write(axi_iic, device_addr, 0x549e, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549f, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x54a0, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x54a1, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x54a2, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a3, 0xed);
    cam_i2c_write(axi_iic, device_addr, 0x54a4, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a5, 0xc5);
    cam_i2c_write(axi_iic, device_addr, 0x54a6, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a7, 0xa5);
    cam_i2c_write(axi_iic, device_addr, 0x54a8, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a9, 0x6c);
    cam_i2c_write(axi_iic, device_addr, 0x54aa, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ab, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x54ac, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ad, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x54ae, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x54af, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x3406, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5192, 0x04); // 0x04
    cam_i2c_write(axi_iic, device_addr, 0x5191, 0xf8); // 0xf8
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x5194, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5195, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x518d, 0x3d);
    cam_i2c_write(axi_iic, device_addr, 0x518f, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x518e, 0x3d);
    cam_i2c_write(axi_iic, device_addr, 0x5190, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x518b, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x518c, 0xbd);
    cam_i2c_write(axi_iic, device_addr, 0x5187, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5188, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5189, 0x6e);
    cam_i2c_write(axi_iic, device_addr, 0x518a, 0x68);
    cam_i2c_write(axi_iic, device_addr, 0x5186, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5183, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x24);
    cam_i2c_write(axi_iic, device_addr, 0x5025, 0x82);
    cam_i2c_write(axi_iic, device_addr, 0x5583, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5584, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5580, 0x02); // 0x02
    cam_i2c_write(axi_iic, device_addr, 0x3633, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3702, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3703, 0xb2);
    cam_i2c_write(axi_iic, device_addr, 0x3704, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x370b, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x370d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x52);
    cam_i2c_write(axi_iic, device_addr, 0x3c00, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0xFF);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5500, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5502, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5503, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5504, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5505, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5025, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5380, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5381, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5382, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5383, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5384, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5385, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5386, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5387, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5388, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5389, 0xE1);
    cam_i2c_write(axi_iic, device_addr, 0x538A, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538B, 0x2B);
    cam_i2c_write(axi_iic, device_addr, 0x538C, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538D, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538E, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538F, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5390, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5391, 0xB3);
    cam_i2c_write(axi_iic, device_addr, 0x5392, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5393, 0xA6);
    cam_i2c_write(axi_iic, device_addr, 0x5394, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5480, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5481, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5482, 0x2a);
    cam_i2c_write(axi_iic, device_addr, 0x5483, 0x49);
    cam_i2c_write(axi_iic, device_addr, 0x5484, 0x56);
    cam_i2c_write(axi_iic, device_addr, 0x5485, 0x62);
    cam_i2c_write(axi_iic, device_addr, 0x5486, 0x6c);
    cam_i2c_write(axi_iic, device_addr, 0x5487, 0x76);
    cam_i2c_write(axi_iic, device_addr, 0x5488, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5489, 0x88);
    cam_i2c_write(axi_iic, device_addr, 0x548a, 0x96);
    cam_i2c_write(axi_iic, device_addr, 0x548b, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x548c, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x548d, 0xcc);
    cam_i2c_write(axi_iic, device_addr, 0x548e, 0xe0);
    cam_i2c_write(axi_iic, device_addr, 0x548f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5490, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5491, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5492, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5493, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5494, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5495, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x5496, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5497, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x5498, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5499, 0x26);
    cam_i2c_write(axi_iic, device_addr, 0x549a, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x549b, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x549c, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x549d, 0xee);
    cam_i2c_write(axi_iic, device_addr, 0x549e, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x549f, 0xd8);
    cam_i2c_write(axi_iic, device_addr, 0x54a0, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a1, 0xc7);
    cam_i2c_write(axi_iic, device_addr, 0x54a2, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a3, 0xb3);
    cam_i2c_write(axi_iic, device_addr, 0x54a4, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a5, 0x90);
    cam_i2c_write(axi_iic, device_addr, 0x54a6, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a7, 0x62);
    cam_i2c_write(axi_iic, device_addr, 0x54a8, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a9, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x54aa, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ab, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x54ac, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ad, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x54ae, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x54af, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x54b0, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b1, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x54b2, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b3, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x54b4, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x54b5, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x54b6, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b7, 0xdf);
    cam_i2c_write(axi_iic, device_addr, 0x5583, 0x5d);
    cam_i2c_write(axi_iic, device_addr, 0x5584, 0x5d);
    cam_i2c_write(axi_iic, device_addr, 0x5580, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5587, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5588, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x558a, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x5589, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0xcf);
    cam_i2c_write(axi_iic, device_addr, 0x5800, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x5801, 0x31);
    cam_i2c_write(axi_iic, device_addr, 0x5802, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x5803, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x5804, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5805, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5806, 0x29);
    cam_i2c_write(axi_iic, device_addr, 0x5807, 0x38);
    cam_i2c_write(axi_iic, device_addr, 0x5808, 0x26);
    cam_i2c_write(axi_iic, device_addr, 0x5809, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x580a, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x580b, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x580c, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x580d, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x580e, 0x13);
    cam_i2c_write(axi_iic, device_addr, 0x580f, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5810, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x5811, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5812, 0x8);
    cam_i2c_write(axi_iic, device_addr, 0x5813, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5814, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x5815, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5816, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x5817, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5818, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5819, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x581a, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x581b, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x581c, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x581d, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x581e, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x581f, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x5820, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x5821, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x5822, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x5823, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5824, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5825, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x5826, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x5827, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5828, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5829, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x582a, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x582b, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x582c, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x582d, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x582e, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x582f, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5830, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x5831, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5832, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5833, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5834, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5835, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5836, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x5837, 0x1d);
    cam_i2c_write(axi_iic, device_addr, 0x5838, 0x6e);
    cam_i2c_write(axi_iic, device_addr, 0x5839, 0x39);
    cam_i2c_write(axi_iic, device_addr, 0x583a, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x583b, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x583c, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x583d, 0x23);
    cam_i2c_write(axi_iic, device_addr, 0x583e, 0x2f);
    cam_i2c_write(axi_iic, device_addr, 0x583f, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x5840, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5841, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5842, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5843, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5844, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5845, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5846, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5847, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5848, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5849, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584a, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584b, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x584c, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584d, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584e, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x584f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5850, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5851, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5852, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5853, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5854, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5855, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5856, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5857, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5858, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5859, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x585a, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585b, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585c, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585d, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x585e, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x585f, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5860, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5861, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x5862, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5863, 0x7);
    cam_i2c_write(axi_iic, device_addr, 0x5864, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5865, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5866, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5867, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5868, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x5869, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x586a, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x586b, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x586c, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x586d, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x586e, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x586f, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5870, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5871, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x5872, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5873, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5874, 0x13);
    cam_i2c_write(axi_iic, device_addr, 0x5875, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5876, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5877, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5878, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5879, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x587a, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x587b, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x587c, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x587d, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x587e, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x587f, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5880, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x5881, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5882, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5883, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5884, 0x1d);
    cam_i2c_write(axi_iic, device_addr, 0x5885, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5886, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5887, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5680, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5681, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5684, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5685, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5180, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x52);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5183, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x24);
    cam_i2c_write(axi_iic, device_addr, 0x5186, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5187, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5188, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5189, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x518a, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x518b, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x518c, 0x9c);
    cam_i2c_write(axi_iic, device_addr, 0x518d, 0x36);
    cam_i2c_write(axi_iic, device_addr, 0x518e, 0x34);
    cam_i2c_write(axi_iic, device_addr, 0x518f, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x5190, 0x4c);
    cam_i2c_write(axi_iic, device_addr, 0x5191, 0xf8);
    cam_i2c_write(axi_iic, device_addr, 0x5192, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x5194, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5195, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5196, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5197, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5198, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5199, 0x2f);
    cam_i2c_write(axi_iic, device_addr, 0x519a, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x519b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x519c, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x519d, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x519e, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0f, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a10, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a1b, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a1e, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a11, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3a1f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3800, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x3802, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x3803, 0x8);
    cam_i2c_write(axi_iic, device_addr, 0x3804, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x3805, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x3806, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x3807, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3808, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x3809, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x380a, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x380b, 0x58);
    cam_i2c_write(axi_iic, device_addr, 0x380c, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x380d, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xe8);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5680, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5681, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5684, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5685, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3815, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3818, 0x81); // No Mirror
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0xa7);
    
    cam_i2c_write(axi_iic, device_addr, 0x4740, 0x21);
    
    cam_i2c_write(axi_iic, device_addr, 0x501e, 0x2a);
    cam_i2c_write(axi_iic, device_addr, 0x5002, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x501f, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x4300, 0x61);
    
    return(0);
}

  1. 2019年08月19日 21:20 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 でカメラ画像をDisplayPort に出力する2(Ultra96-V2 の環境整備)

Ultra96-V2 でカメラ画像をDisplayPort に出力する1(ブロックデザイン)”の続き。

前回は、Ultra96-V2 でPMOD 拡張ボードに搭載したOV5642 カメラの画像をUltra96-V2 のDisplayPort から出力したいということで、Ultra96-V1 のブロックデザインの内のZynq UltraScale+ MPSoC のDDR の設定をUltra96-V2 用に変更して、論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。今回は、bin ファイルを作成し、Ultra96-V2 のDebian を起動して、環境の整備を行う。

最初に、Vivado 2018.2 でビットストリームが生成できたので、ハードウェアをエクスポートして、SDK を立ち上げた。 cam_dp_183.sdk ディレクトリに新たに cam_dp_wrapper_hw_platform_1 が生成された。
cam_dp_V2_7_190818.png

カメラ画像をDisplayPortに出力する7(binファイルの生成)”の cam_dp_wrapper.bif と bootgen.sh を作成した。bootgen.sh に実行権限を与えて、実行した。
chmod +x bootgen.sh
./bootgen.sh


cam_dp_wrapper.bin が生成された。これをUltra96-V2 の /home/fpga/examples/cam_dp_V2/ ディレクトリにSFTP でアップロードした。
cam_dp_V2_9_190818.png

次に、Ultra96-V2 の /home/fpga/examples/cam_dp_V2/ ディレクトリに入った。
fpga-load.dts を作った。これからのファイルは、”カメラ画像をDisplayPortに出力する8(Ultra96 での準備)”のコードをコピーして作っている。ただし、fclk01-zynqmp.dts は修正してある。
cam_dp_V2_10_190818.png

fclk01-zynqmp.dts を示す。このファイルは、、”カメラ画像をDisplayPortに出力する8(Ultra96 での準備)”のコードを修正してある。(注)画像の pl_clk0 は 200 MHz ですが、コードの方の 220 MHz に修正済みです。
cam_dp_V2_11_190818.png

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba_pl@0";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&zynqmp_clk 0x47 &zynqmp_clk 0>;
                insert-rate   = "220000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
            
            fclk1 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&zynqmp_clk 0x48 &zynqmp_clk 1>;
                insert-rate   = "24000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};



cam_dp.dts を示す。
cam_dp_V2_12_190818.png

dtc_script.sh を示す。
cam_dp_V2_13_190818.png

lddtovary.sh を示す。
cam_dp_V2_14_190818.png

rmdtovary.sh を示す。
cam_dp_V2_15_190818.png

.sh のファイルに実行権限を与えた。
chmod +x *.sh
cam_dp_V2_16_190818.png

./dtc_script.sh
でDTS ファイルをコンパイルして、DTB ファイルを出力した。
cam_dp_V2_17_190818.png

./lddtovary.sh
を実行してデバイスツリーをロードした。ログを示す。
cam_dp_V2_18_190818.png

fclkcfg でエラーが出ている。

zynqmp_clk_divider_set_rate() set divider failed for pl0_ref_div1, ret = -22


これのせいか? 220 MHz のはずの pl_clk0 が 99999999 Hz になってしまっている。

/sys/class/uio は uio0 〜 uio 9 まであった。この内の uio4 〜 uio9 までが cam_dp.dtb でデバイスツリーに追加した uio だ。
cam_dp_V2_19_190818.png

udmabuf4 もデバイスツリーに追加されていた。
cam_dp_V2_20_190818.png
  1. 2019年08月18日 15:47 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 でカメラ画像をDisplayPort に出力する1(ブロックデザイン)

Ultra96-V2 のDisplayPort にテストパターンを表示する4(テストパターンを表示できた)”でUltra96-V2 でDisplayPort にテストパターンを表示することができた。今回は、Ultra96-V2 でカメラ画像をDisplayPort に出力してみようと思う。

カメラ画像をDisplayPortに出力する7(ブロックデザインの変更)”の cam_dp_183 の Vivado 2018.3 プロジェクトがあるので、ディレクトリごと Ultra96V2 ディレクトリにコピーして、ディレクトリの名前を cam_dp_V2_183 に変更した。
cam_dp_V2_1_190817.png

Vivado 2018.3 で ~/HDL/Ultra96/Ultra96V2/cam_dp_V2_183/ ディレクトリの cam_dp_183 プロジェクトを開いた。
cam_dp_V2_2_190817.png

今回は、ひでみさんの「FPGAの内容が薄い本2」に書かれているが、Ultra96V1 とUltra96V2 の設定の違いを使用して、Ultra96V1 用のプロジェクトをUltra96-V2 用に変換してみよう。

ブロックデザインのZYNQ UltraScale+ IP をダブルクリックして、設定を開き、Page Navigator から DDR Configuration を開く。
cam_dp_V2_3_190817.png

DDR Configuration 画面で、
DRAM Device Capacity (per 32-bit channel) を 16384 MBits
Row Address Count (Bits) を 16
Dual Rank のチェックボックスをのチェックを無し
に変更した。
cam_dp_V2_4_190817.png

Address Editor を示す。
cam_dp_V2_6_190817.png

変更後に論理合成、インプリメンテーション、ビットストリームの生成を行った。
うまく行ったようだ。結果を示す。
cam_dp_V2_5_190817.png
  1. 2019年08月17日 05:32 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

sudo: unable to resolve host の表示を止める

現在、Ultra96-V2 の ikwzm さんのDebian を使用して、 sudo コマンドを使用すると”sudo: unable to resolve host debian-fpga: Name or service not known”が表示されてしまう。
DisplayPort_test_V2_46_190816.png

ある方に解決方法を教えていただいたのだが、忘れてしまったため、Web を検索してやってみた。忘れないようにブログに書いておく。
sudo: unable to resolve host が表示されたら”を参照させていただきながらやっていく。

まずは、/etc/hosts を確認する。

127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters


/etc/hosts にホスト名を追加する。
sudo sh -c 'echo 127.0.1.1 $(hostname) >> /etc/hosts'

もう一度、/etc/hosts を見ると、ホスト名が追加されていた。

127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

127.0.1.1 debian-fpga


これで、sudo コマンドを実行しても”sudo: unable to resolve host debian-fpga: Name or service not known”が表示されなくなった。感謝。。。
DisplayPort_test_V2_47_190816.png
  1. 2019年08月16日 04:47 |
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 のDisplayPort にテストパターンを表示する4(テストパターンを表示できた)

Ultra96-V2 のDisplayPort にテストパターンを表示する3(各種スクリプト・ファイルやDTS ファイルの用意)”の続き。

前回は、各種スクリプト・ファイルやDTS ファイルを用意し、DTS ファイルをコンパイルしてDTB ファイルに変換した。今回は、つまずきはあったが、テストパターンをDisplayPort に出力することができた。

最初に、pattarn_gen_axis.c を gcc でコンパイルした。
gcc -o pattern_gen_axis pattern_gen_axis.c
次に、displayport_test_xga1_sync.bin を /lib/firmware/ ディレクトリにコピーした。
sudo cp displayport_test_xga1_sync.bin /lib/firmware/
DisplayPort_test_V2_35_190815.png

./lddtovray.sh
を実行したところエラーが発生した。
lddtovray.sh のコマンドを1個ずつ実行していったところ、fclkcfg でエラーが出ているのが分かった。
fclkcfg の DTS ファイルを下に示す。
DisplayPort_test_V2_27_190814.png

だが、ikwzm さんの”ZynqMP 向け Debian/Linux(v2019.1版) でFPGA クロックの周波数の変更に失敗する件”を見ると、fclkcfg の DTS ファイルの書き方が違っている。ikwzm さんがツィッターで教えていただいたのだが、

大元のデバイスツリーのクロックコントローラーのラベル(シンボル)が v2018.2 では &clk だったのが v2019.1 から &zynqmp_clk に変更されちゃいました。

だそうだ。
という訳で、fclk0-zynqmp.dts を書き換えた。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba_pl@0";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&zynqmp_clk 0x47 &zynqmp_clk 0>;
                insert-rate   = "100000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


DisplayPort_test_V2_37_190815.png

./dtc_script.sh
コンパイルしてから、fclkcfg のデバイスツリーをロードしたところ、問題なくロードできた。
下の図に示す。ピンクで囲ったところが、fclkcfg のエラー部分だ。
DisplayPort_test_V2_36_190815.png

DisplayPort_test_V2_38_190815.png

/sys/class/fclk0/ ディレクトリが生成されている。
DisplayPort_test_V2_39_190815.png

uio のデバイスツリーのロードを行った。
sudo mkdir /config/device-tree/overlays/pattern_gen_axis
sudo cp pattern_gen_axis.dtb /config/device-tree/overlays/pattern_gen_axis/dtbo


同様に、/sys/classe/ を見ると、uio0 〜 uio4 があったが、その内の uio4 の name が pattern_gen_axis-uio だった。
DisplayPort_test_V2_40_190815.png

ということは、pattern_gen_axis の uio 番号が違っているので、pattern_gen_axis.c を変更した。
DisplayPort_test_V2_41_190815.png

// pattern_gen_axis.c
// 2019/01/18 by marsee
// 2019/08/15 : Changed to /dev/uio4 for Ultra96-V2. by marsee
//

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main(){
    int fd4;
    volatile unsigned *pga;
    int i;

    // uio initialize (uio1)
    fd4 = open("/dev/uio4", O_RDWR|O_SYNC); // pattern_gen_axis IP
    if (fd4 < 1){
        fprintf(stderr, "/dev/uio4 (pattern_gen_axis) open error\n");
        exit(1);
    }
    pga = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
    if (!pga){
        fprintf(stderr, "pattern_gen_axis mmap error\n");
        exit(1);
    }

    pga[4] = 768; // v_size
    pga[6] = 1024; // h_size
    pga[8] = 0x1; // init_done = 1
    
    printf("sizeof volatile unsigned = %d\n", sizeof(volatile unsigned));
    
    printf("v_size = %d, h_size = %d, init_done = %d\n", pga[4], pga[6], pga[8]);
    
    munmap((void *)pga, 0x10000);
    close(fd4);
    
    return(0);
}


もう一度、gcc でコンパイルした。
gcc -o pattern_gen_axis pattern_gen_axis.c
pattern_gen_axis を sudo で実行した。
sudo ./pattern_gen_axis
DisplayPort の設定を行った。
./disp_pattern.sh
DisplayPort_test_V2_42_190815.png

しかし、memwrite が無かった。
Ultra96のDisplayPortを使用するためのテスト3(実機テスト)”から memwrite.c にコードを持ってきた。
DisplayPort_test_V2_43_190815.png

gcc -o memwrite memwrite.c
でコンパイルし、実行したところ、DisplayPort にテストパターンが表示された。良かった。。。
DisplayPort_test_V2_44_190815.png

DisplayPort_test_V2_45_190816.jpg
  1. 2019年08月16日 04:29 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 のDisplayPort にテストパターンを表示する3(各種スクリプト・ファイルやDTS ファイルの用意)

Ultra96-V2 のDisplayPort にテストパターンを表示する2(binファイルの作成)”の続き。

前回は、Ultra96-V2 のボード・ファイルを使用して、Ultra96-V2 のDisplayPort にテストパターンを表示するためのブロックデザインを論理合成、インプリメンテーション、ビットストリームの生成を行って、bin ファイルを作成した。今回は、各種スクリプト・ファイルやDTS ファイルを用意し、DTS ファイルをコンパイルしてDTB ファイルに変換した。

最初に、Ultra96-V2 の/home/fpga/ ディレクトリに examples/displayport_test_xga1_sync_V2/ ディレクトリを作成した。
DisplayPort_test_V2_21_190814.png

displayport_test_xga1_sync.bin をUltra96-V2 の/home/fpga/examples/displayport_test_xga1_sync_V2/ ディレクトリにSFTP でコピーした。
DisplayPort_test_V2_22_190814.png

Ultra96のDisplayPortを使用するためのプロジェクトを作成する2(表示失敗)”を参考にして、各種スクリプトとDTS ファイルを準備する。なお、”Ultra96のDisplayPortを使用するためのプロジェクトを作成する2(表示失敗)”に書かれている各種スクリプトとDTS ファイルのコードはここに書かないので、参照先を参考にして欲しい。

lddtovray.sh と rmdtovray.sh を用意した。
DisplayPort_test_V2_23_190814.png

DisplayPort_test_V2_24_190814.png

fpga-load.dts 、fclk0-zynqmp.dts 、pattern_gen_axis.dts を用意した。
DisplayPort_test_V2_25_190814.png

DisplayPort_test_V2_27_190814.png

DisplayPort_test_V2_28_190814.png

pattern_gen_axis.c を用意した。
DisplayPort_test_V2_29_190814.png

disp_pattern.sh を用意した。
DisplayPort_test_V2_30_190814.png

DTS をコンパイルするための dtc_script.sh を用意した。
DisplayPort_test_V2_31_190814.png

#!/bin/bash

dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
dtc -I dts -O dtb -o pattern_gen_axis.dtb pattern_gen_axis.dts



現在の /examples/displayport_test_xga1_sync_V2/ ディレクトリの内容を示す。
DisplayPort_test_V2_32_190814.png

DTS ファイルをコンパイルするために device-tree-compiler をインストールする。
sudo apt-get install device-tree-compiler
DisplayPort_test_V2_33_190814.png

./dtc_script.sh
コマンドで、 DTS ファイルをコンパイルして、DTB ファイルが出力された。
DisplayPort_test_V2_34_190814.png
  1. 2019年08月14日 14:02 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 のDisplayPort にテストパターンを表示する2(binファイルの作成)

Ultra96-V2 のDisplayPort にテストパターンを表示する1(プロジェクトの作成)”の続き。

前回は、Ultra96-V2 のボード・ファイルを使用して、Ultra96-V2 のDisplayPort にテストパターンを表示するためのブロックデザインを作成した。今回は、それを論理合成、インプリメンテーション、ビットストリームの生成を行って、bin ファイルを作成する。

ブロックデザインが完成したので、HDL wrapper file を作成し、displayport_test.xdc の制約ファイルを”Ultra96のDisplayPortを使用するためのプロジェクトを作成する1(DisplayPort_test_XGA1_sync)”のプロジェクトからコピーした。
DisplayPort_test_V2_15_190812.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。Project Summary を示す。
DisplayPort_test_V2_16_190813.png

成功したので、ハードウェアをエクスポートして、SDK を起動した。
DisplayPort_test_V2_17_190813.png

これで、 .sdk ディレクトリが生成された。
displayport_test_wrapper_hw_platform_0 ディレクトリから displayport_test_wrapper.bit をDisplayPort_test_XGA1_sync_V2.sdk ディレクトリにコピーした。
Ultra96のDisplayPortを使用するためのプロジェクトを作成する1(DisplayPort_test_XGA1_sync)”のプロジェクトからdisplayport_test_wrapper.bif と bootgen.sh をコピーした。
DisplayPort_test_V2_18_190813.png

./bootgen.sh
を実行すると、displayport_test_xga1_sync.bin が生成された。
DisplayPort_test_V2_19_190813.png

DisplayPort_test_V2_20_190813.png
  1. 2019年08月13日 09:44 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 のDisplayPort にテストパターンを表示する1(プロジェクトの作成)

Ultra96-V2 のDisplayPort にテストパターンを表示してみようということで、”Ultra96のDisplayPortを使用するためのプロジェクトを作成する1(DisplayPort_test_XGA1_sync)”を参照して Vivado 2018.3 の DisplayPort_test_XGA1_sync_V2 プロジェクトを作成した。

Vivado 2018.3 を立ち上げて DisplayPort_test_XGA1_sync_V2 プロジェクトを作成した。途中のダイアログの設定を示す。
まずは、プロジェクトのロケーションとプロジェクト名を示す。
DisplayPort_test_V2_1_190812.png

Ultra96V2 のボード・ファイルを適用する。
DisplayPort_test_V2_2_190812.png

サーマリ。
DisplayPort_test_V2_3_190812.png

DisplayPort_test_XGA1_sync_V2 プロジェクトが作成された。
DisplayPort_test_V2_4_190812.png

Ultra96のDisplayPortを使用するためのプロジェクトを作成する1(DisplayPort_test_XGA1_sync)”のプロジェクトから axi2video_out_IP と pattern_gen_axis_IP をコピーした。
DisplayPort_test_V2_5_190812.png

Zynq UltraScale+ MPSoC をAdd IP した。
DisplayPort_test_V2_6_190812.png

Run Block Automation をクリックした。
表示されたダイアログをデフォルトのまま、OK ボタンをクリックした。PS に設定が入力される。
DisplayPort_test_V2_7_190812.png

Ultra96V2 の設定が反映された。
DisplayPort_test_V2_8_190812.png

Zynq UltraScale+ MPSoC をダブルクリックして設定を行う。
PS-PL Configuration で Live Video を 1 にして、AXI_HPM1FPD のチェックを外した。
DisplayPort_test_V2_9_190812.png

次にDDR Configuration だが、”Ultra96のDisplayPortを使用するためのプロジェクトを作成する1(DisplayPort_test_XGA1_sync)”のDDR Configuration を示す。つまり、Ultra96V1 のDDR の設定だ。
DisplayPort_test_V2_10_190812.png

次に、新しいUltra96V2 にDDR Configuration の設定を示す。ひでみさんの「FPGAの内容が薄い本2」に書かれているが、Ultra96V1 とUltra96V2 の設定の違いを示す。

項目                    Ultra96V1   Ultra96V2
DRAM Device Capacity(per 32-bit channel)  8192 MBits 16384 MBits
Row Address Count(Bits)           15      16
Dual Rank                  チェック  チェック無し


DisplayPort_test_V2_11_190812.png

Clock Configuration では、PL0 を 220 MHz に設定した。
DisplayPort_test_V2_12_190812.png

Zynq UltraScale+ MPSoC はこうなった。
DisplayPort_test_V2_13_190812.png

axi2video_out_IP と pattern_gen_axis_IP をAdd IP して配線した。
DisplayPort_test_V2_14_190812.png

これでブロックデザイン完成。
Address Editor を示す。
DisplayPort_test_V2_26_190814.png
  1. 2019年08月12日 10:18 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96 のDebianにインストールしたOpenCVのC++サンプルデザインをコンパイル

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール4(OpenCV 4.1.0 のインストール)”の続き。

OpenCV 4.1.0 のC++ のサンプルデザインをコンパイルしてみようとしたが、結局うまく行かなかった。よって、以前、”Ultra96 のDebianにインストールしたOpenCV-3.4.3のC++サンプルデザインをコンパイル”でやったように、OpenCV 3.4.3 をインストールして、OpenCV 3.4.3 のC++ のサンプルデザインをコンパイルした。

、”Ultra96 のDebianにインストールしたOpenCV-3.4.3のC++サンプルデザインをコンパイル”を参考にして、ホーム・ディレクトリの直下に bin ディレクトリを作成した。
Ultra96V2_80_190810.png

bin ディレクトリの下に、g++_opencv ファイルを作成した。
Ultra96V2_81_190810.png

#!/bin/sh

if [ $# -eq 1 ] ; then
    g++ -ggdb `pkg-config --cflags opencv` -o `basename $1 .cpp` $1 `pkg-config --libs opencv`;
else
    echo "g++_opencv < C++ file name >"
fi


Ultra96V2_82_190810.png

g++_opencv ファイルのプロバティを Allow executing file as program に変更した。
Ultra96V2_83_190810.png

.bashrc に export PATH=$PATH:~/bin を追加した。
Ultra96V2_84_190810.png

opencv-4.1.0/samples/cpp に行って、
g++_opencv facedetect.cpp
を実行した。
Ultra96V2_85_190810.png

そうするとエラーが発生した。
Ultra96V2_86_190810.png

いろいろと検索してみて、試したのだが、どうしてもコンパイルできなかった。
仕方ないので、以前インストールした、OpenCV 3.4.3 をインストールした。インストール方法は、OpenCV 4.1.0 と同じだ。ただ、3.4.3.zip をダウンロードするところが違うだけだ。
Ultra96V2_91_190811.png

今度は、opencv-3.4.3/samples/cpp/ ディレクトリに行って、
g++_opencv facedetect.cpp
を行うと、成功した。
./facedetect ../data/lena.jpg
Ultra96V2_89_190811.png

Ultra96V2_90_190811.png

ちなみに 、OpenCV 3.4.3 をインストールした状態で、いろいろとOpenCV 4.1.0 の facedetect サンプル・デザインのコンパイルを試してみた。
OpenCV4.0をソースコードからインストールする”を参考に
g++ facedetect.cpp -o facedetect -I/usr/local/include/opencv4/ -L/usr/local/lib64/ -lopencv_core
をやってみたがエラーだった。エラー内容を示す。

fpga@debian-fpga:~/opencv-4.1.0/samples/cpp$ g++ facedetect.cpp -o facedetect -I/usr/local/include/opencv4/ -L/usr/local/lib64/ -lopencv_core
/usr/bin/ld: /tmp/ccZJ8MHe.o: in function `main':
facedetect.cpp:(.text+0xc8): undefined reference to `cv::VideoCapture::VideoCapture()'
/usr/bin/ld: facedetect.cpp:(.text+0xe8): undefined reference to `cv::CascadeClassifier::CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0xf0): undefined reference to `cv::CascadeClassifier::CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0x12c): undefined reference to `cv::CommandLineParser::CommandLineParser(int, char const* const*, std::__cxx11::basic_string, std::allocator > const&)'
/usr/bin/ld: facedetect.cpp:(.text+0x16c): undefined reference to `cv::CommandLineParser::has(std::__cxx11::basic_string, std::allocator > const&) const'
/usr/bin/ld: facedetect.cpp:(.text+0x2f4): undefined reference to `cv::CommandLineParser::has(std::__cxx11::basic_string, std::allocator > const&) const'
/usr/bin/ld: facedetect.cpp:(.text+0x3bc): undefined reference to `cv::CascadeClassifier::load(std::__cxx11::basic_string, std::allocator > const&)'
/usr/bin/ld: facedetect.cpp:(.text+0x41c): undefined reference to `cv::samples::findFile(std::__cxx11::basic_string, std::allocator > const&, bool, bool)'
/usr/bin/ld: facedetect.cpp:(.text+0x428): undefined reference to `cv::CascadeClassifier::load(std::__cxx11::basic_string, std::allocator > const&)'
/usr/bin/ld: facedetect.cpp:(.text+0x510): undefined reference to `cv::VideoCapture::open(int, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x5b4): undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x608): undefined reference to `cv::VideoCapture::open(std::__cxx11::basic_string, std::allocator > const&, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x6a4): undefined reference to `cv::samples::findFile(std::__cxx11::basic_string, std::allocator > const&, bool, bool)'
/usr/bin/ld: facedetect.cpp:(.text+0x6b8): undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x730): undefined reference to `cv::VideoCapture::isOpened() const'
/usr/bin/ld: facedetect.cpp:(.text+0x768): undefined reference to `cv::VideoCapture::operator>>(cv::Mat&)'
/usr/bin/ld: facedetect.cpp:(.text+0x76c): undefined reference to `cv::VideoCapture::operator>>(cv::Mat&)'
/usr/bin/ld: facedetect.cpp:(.text+0x7bc): undefined reference to `cv::waitKey(int)'
/usr/bin/ld: facedetect.cpp:(.text+0x88c): undefined reference to `cv::waitKey(int)'
/usr/bin/ld: facedetect.cpp:(.text+0x9b8): undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'
/usr/bin/ld: facedetect.cpp:(.text+0xa18): undefined reference to `cv::waitKey(int)'
/usr/bin/ld: facedetect.cpp:(.text+0xaa8): undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0xab0): undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0xad0): undefined reference to `cv::VideoCapture::~VideoCapture()'
/usr/bin/ld: facedetect.cpp:(.text+0xc9c): undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0xcac): undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'
/usr/bin/ld: facedetect.cpp:(.text+0xcd4): undefined reference to `cv::VideoCapture::~VideoCapture()'
/usr/bin/ld: /tmp/ccZJ8MHe.o: in function `detectAndDraw(cv::Mat&, cv::CascadeClassifier&, cv::CascadeClassifier&, double, bool)':
facedetect.cpp:(.text+0xf00): undefined reference to `cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)'
/usr/bin/ld: facedetect.cpp:(.text+0xf5c): undefined reference to `cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_, double, double, int)'
/usr/bin/ld: facedetect.cpp:(.text+0xf90): undefined reference to `cv::equalizeHist(cv::_InputArray const&, cv::_OutputArray const&)'
/usr/bin/ld: facedetect.cpp:(.text+0x1008): undefined reference to `cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::vector, std::allocator > >&, double, int, int, cv::Size_, cv::Size_)'
/usr/bin/ld: facedetect.cpp:(.text+0x10b0): undefined reference to `cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::vector, std::allocator > >&, double, int, int, cv::Size_, cv::Size_)'
/usr/bin/ld: facedetect.cpp:(.text+0x1318): undefined reference to `cv::circle(cv::_InputOutputArray const&, cv::Point_, int, cv::Scalar_ const&, int, int, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x13e8): undefined reference to `cv::rectangle(cv::_InputOutputArray const&, cv::Point_, cv::Point_, cv::Scalar_ const&, int, int, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x13f8): undefined reference to `cv::CascadeClassifier::empty() const'
/usr/bin/ld: facedetect.cpp:(.text+0x1490): undefined reference to `cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::vector, std::allocator > >&, double, int, int, cv::Size_, cv::Size_)'
/usr/bin/ld: facedetect.cpp:(.text+0x15a4): undefined reference to `cv::circle(cv::_InputOutputArray const&, cv::Point_, int, cv::Scalar_ const&, int, int, int)'
/usr/bin/ld: facedetect.cpp:(.text+0x1634): undefined reference to `cv::imshow(std::__cxx11::basic_string, std::allocator > const&, cv::_InputArray const&)'
/usr/bin/ld: /tmp/ccZJ8MHe.o: in function `cv::samples::findFileOrKeep(std::__cxx11::basic_string, std::allocator > const&, bool)':
facedetect.cpp:(.text._ZN2cv7samples14findFileOrKeepERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb[_ZN2cv7samples14findFileOrKeepERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb]+0x2c): undefined reference to `cv::samples::findFile(std::__cxx11::basic_string, std::allocator > const&, bool, bool)'
/usr/bin/ld: /tmp/ccZJ8MHe.o: in function `std::__cxx11::basic_string, std::allocator > cv::CommandLineParser::get, std::allocator > >(std::__cxx11::basic_string, std::allocator > const&, bool) const':
facedetect.cpp:(.text._ZNK2cv17CommandLineParser3getINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEET_RKS7_b[_ZNK2cv17CommandLineParser3getINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEET_RKS7_b]+0x38): undefined reference to `cv::CommandLineParser::getByName(std::__cxx11::basic_string, std::allocator > const&, bool, cv::Param, void*) const'
/usr/bin/ld: /tmp/ccZJ8MHe.o: in function `double cv::CommandLineParser::get(std::__cxx11::basic_string, std::allocator > const&, bool) const':
facedetect.cpp:(.text._ZNK2cv17CommandLineParser3getIdEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb[_ZNK2cv17CommandLineParser3getIdEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb]+0x30): undefined reference to `cv::CommandLineParser::getByName(std::__cxx11::basic_string, std::allocator > const&, bool, cv::Param, void*) const'
collect2: error: ld returned 1 exit status


OpenCV4.0 簡易マニュアル パターン認識演習”を参考に
g++ -std=c++11 `pkg-config opencv4 --cflags --libs` facedetect.cpp -o facedetect
をやってみたが、エラーだった。エラー内容を示す。

fpga@debian-fpga:~/opencv-4.1.0/samples/cpp$ g++ -std=c++11 `pkg-config opencv4 --cflags --libs` facedetect.cpp -o facedetect
Package opencv4 was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv4.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv4' found
facedetect.cpp: In function 'int main(int, const char**)':
facedetect.cpp:65:29: error: 'samples' has not been declared
     if (!nestedCascade.load(samples::findFileOrKeep(nestedCascadeName)))
                             ^~~~~~~
facedetect.cpp:67:23: error: 'samples' has not been declared
     if (!cascade.load(samples::findFile(cascadeName)))
                       ^~~~~~~
facedetect.cpp:84:24: error: 'samples' has not been declared
         image = imread(samples::findFileOrKeep(inputName), IMREAD_COLOR);
                        ^~~~~~~
facedetect.cpp:87:31: error: 'samples' has not been declared
             if (!capture.open(samples::findFileOrKeep(inputName)))
                               ^~~~~~~
facedetect.cpp:96:24: error: 'samples' has not been declared
         image = imread(samples::findFile("lena.jpg"), IMREAD_COLOR);
                        ^~~~~~~

  1. 2019年08月11日 14:40 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール4(OpenCV 4.1.0 のインストール)

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール3(GUIアプリのインストール)”の続き。

前回は、nautilus, geany などのGUI アプリをインストールして、起動させることができた。今回は、Ultra96-V2 のDebian に OpenCV 4.1.0 をインストールしてみよう。

まずは、wget と unzip をインストールする。
sudo apt install wget unzip
Ultra96V2_59_190808.png

OpenCV 4.1.0 を opencv.zip としてダウンロードした。
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.1.0.zip
Ultra96V2_60_190808.png

opencv.zip を解凍した。
unzip opencv.zip
Ultra96V2_61_190808.png

次は、OpenCV をインストールする時にインストールしといたほうが良さそうなパッケージをインストールする。
sudo apt install python3-tk libgtk2.0-dev pkg-config
Ultra96V2_62_190808.png

V4L をインストールする。
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
Ultra96V2_63_190808.png

sudo apt-get install libcanberra-gtk-module
Ultra96V2_64_190808.png

opencv-4.1.0 ディレクトリに入って、 build ディレクトリを作成した。build ディレクトリに入った。
cd opencv-4.1.0
mkdir build
cd build

Ultra96V2_65_190808.png

cmake をインストールした。
sudo apt install cmake
Ultra96V2_66_190808.png

cmake を行った。
cmake -DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DINSTALL_PYTHON_EXAMPLES=ON \
-DINSTALL_C_EXAMPLES=ON \
-DPYTHON_EXECUTABLE=/usr/bin/python3 \
-DBUILD_EXAMPLES=ON \
-DWITH_GTK=ON \
-DWITH_FFMPEG=ON ..

Ultra96V2_67_190808.png

Ultra96V2_68_190808.png

-- General configuration for OpenCV 4.1.0 =====================================
--   Version control:               unknown
-- 
--   Platform:
--     Timestamp:                   2019-08-08T12:26:15Z
--     Host:                        Linux 4.19.0-xlnx-v2019.1-zynqmp-fpga aarch64
--     CMake:                       3.13.4
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
-- 
--   CPU/HW features:
--     Baseline:                    NEON FP16
--       required:                  NEON
--       disabled:                  VFPV3
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ Compiler:                /usr/bin/c++  (ver 8.3.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      -Wl,--gc-sections  
--     Linker flags (Debug):        -Wl,--gc-sections  
--     ccache:                      NO
--     Precompiled headers:         YES
--     Extra dependencies:          dl m pthread rt
--     3rdparty dependencies:
-- 
--   OpenCV modules:
--     To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo python2 python3 stitching ts video videoio
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 java js
--     Applications:                tests perf_tests examples apps
--     Documentation:               NO
--     Non-free algorithms:         NO
-- 
--   GUI: 
--     GTK+:                        YES (ver 2.24.32)
--       GThread :                  YES (ver 2.58.3)
--       GtkGlExt:                  NO
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
--     JPEG:                        libjpeg-turbo (ver 2.0.2-62)
--     WEBP:                        build (ver encoder: 0x020e)
--     PNG:                         /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.6.36)
--     TIFF:                        build (ver 42 - 4.0.10)
--     JPEG 2000:                   build (ver 1.900.1)
--     OpenEXR:                     build (ver 1.7.1)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--     PFM:                         YES
-- 
--   Video I/O:
--     DC1394:                      NO
--     FFMPEG:                      YES
--       avcodec:                   YES (58.35.100)
--       avformat:                  YES (58.20.100)
--       avutil:                    YES (56.22.100)
--       swscale:                   YES (5.3.100)
--       avresample:                NO
--     GStreamer:                   NO
--     v4l/v4l2:                    YES (linux/videodev2.h)
-- 
--   Parallel framework:            pthreads
-- 
--   Trace:                         YES (built-in)
-- 
--   Other third-party libraries:
--     Lapack:                      NO
--     Eigen:                       NO
--     Custom HAL:                  YES (carotene (ver 0.0.1))
--     Protobuf:                    build (3.5.1)
-- 
--   OpenCL:                        YES (no extra features)
--     Include path:                /home/fpga/opencv-4.1.0/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
-- 
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.16)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.16)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python2.7/dist-packages/cv2/python-2.7
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.7.3)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.7m.so (ver 3.7.3)
--     numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python3.7/dist-packages/cv2/python-3.7
-- 
--   Python (for build):            /usr/bin/python2.7
-- 
--   Java:                          
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
-- 
--   Install to:                    /usr/local
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/fpga/opencv-4.1.0/build


make した。make -j4 で 4 CPU で make した時にメモリのエラーが出たので、make -j2 でやったが make -j2 でも途中でメモリのエラーが出たので、もう一度 make -j2 を入力した。

virtual memory exhausted: Cannot allocate memory
make[2]: *** [modules/python2/CMakeFiles/opencv_python2.dir/build.make:63: modules/python2/CMakeFiles/opencv_python2.dir/__/src2/cv2.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:7148: modules/python2/CMakeFiles/opencv_python2.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....


make -j2
Ultra96V2_69_190808.png

Ultra96V2_70_190808.png

sudo make install
Ultra96V2_71_190808.png

sudo ldconfig
Ultra96V2_72_190808.png

1 つ上のディレクトリに上がって、 samples/python ディレクトリに入った。
cd ../samples/python/
Ultra96V2_73_190808.png

デモ・ソフトウェアを起動した。
python3 demo.py
Ultra96V2_74_190808.png

facedetect.py を Run した。
Ultra96V2_75_190808.png

Ultra96V2_76_190808.jpg

うまく行った。

asift.py を Run した。
Ultra96V2_77_190808.png

Ultra96V2_78_190808.jpg

これもうまく行った。

画像を見るのに、 viewnior をインストールした。
sudo apt install viewnior
Ultra96V2_79_190809.png
  1. 2019年08月10日 03:53 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール3(GUIアプリのインストール)

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール2(無線LANへの接続とデバイス・ドライバのインストール)”の続き。

前回は、Ultra96-V2 のDebian を無線LANに接続し、デバイス・ドライバのパッケージをインストールした。今回は、nautilus, geany などのGUI アプリをインストールして、起動してみよう。

最初に現在の環境をアップデートする。
sudo apt update
Ultra96V2_52_190808.png

sudo apt upgrade
Ultra96V2_53_190808.png

X11関連のパッケージをインストールする。
sudo apt install xbase-clients xterm x11-apps
Ultra96V2_54_190808.png

現在は、LANG が設定されていないので、使用されないが、日本語フォントをインストールする。
sudo apt install fonts-vlgothic fonts-horai-umefont fonts-umeplus
Ultra96V2_55_190808.png

GUI アプリ(nautilus と geany)をインストールする。
sudo apt install nautilus geany
Ultra96V2_56_190808.png

そのままコマンドを入力しても GUI が起動しなかったので、リブートした。
sudo reboot

再起動してからnautilus と geany を起動したところ、問題なく起動した。
Ultra96V2_57_190808.png

Ultra96V2_58_190808.png

なお、ホストパソコンには、Ubuntu 18.04 をインストールしてあって、Ultra96-V2 に
ssh IPアドレス -X -l fpga
で接続している。
  1. 2019年08月09日 04:37 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール2(無線LANへの接続とデバイス・ドライバのインストール)

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール1”の続き。

前回は、MicroSD カードにファイルをコピーして、Ultra96-V2 で Debian を起動した。今回は、そのDebian を無線LANに接続し、デバイス・ドライバのパッケージをインストールしてみよう。

なお、”UltraZed/Ultra96/Ultra96-V2 向け Debian GNU/Linux (v2019.1版) ブートイメージの提供”を引用させて頂いている。

wpa_passphrase 自分のSSID パスワード
を入れて、暗号化したアクセスキーを作成する。
Ultra96V2_42_190806.png

/etc/network/interfaces.d/ ディレクトリに行って、wlan0 を作成する。
cd /etc/network/interfaces.d/
sudo vi wlan0

Ultra96V2_43_190806.png

auto  wlan0
iface wlan0 inet dhcp
    wpa-ssid 自分のSSID
    wpa-psk 暗号化したアクセスキー


を入力した。
Ultra96V2_44_190806.png

リブートして、
sudo reboot
再起動してから
ip addr show
をすると、wlan0 にIP アドレスが割り振られていた。
Ultra96V2_45_190806.png

ssh IPアドレス -X -l fpga
で、SSH でUltra96-V2 のDebian にログインしようとしたが、RSA key の関係でログインできなかった。
Ultra96V2_46_190806.png

画面に書いてあるとおりに、
ssh-keygen -f "/home/masaaki/.ssh/known_hosts" -R "IPアドレス"
を実行してから、もう一度、
ssh IPアドレス -X -l fpga
を実行した。
Ultra96V2_47_190806.png

無線LANがつながって、SSH 接続できるようになったので、次は、デバイス・ドライバのパッケージをインストールする。

まずは、debian ディレクトリに入った。
cd debain

Linux Image Package のインストール
sudo dpkg -i linux-image-4.19.0-xlnx-v2019.1-zynqmp-fpga_4.19.0-xlnx-v2019.1-zynqmp-fpga-2_arm64.deb
Ultra96V2_48_190808.png

Linux Header Package のインストール
sudo dpkg -i linux-headers-4.19.0-xlnx-v2019.1-zynqmp-fpga_4.19.0-xlnx-v2019.1-zynqmp-fpga-2_arm64.deb
Ultra96V2_49_190808.png

fclkcfg デバイスドライバ&サービスのインストール
sudo dpkg -i fclkcfg-4.19.0-xlnx-v2019.1-zynqmp-fpga_1.1.0-1_arm64.deb
Ultra96V2_50_190808.png

udmabuf デバイスドライバ&サービスのインストール
sudo dpkg -i udmabuf-4.19.0-xlnx-v2019.1-zynqmp-fpga_1.4.2-0_arm64.deb
Ultra96V2_51_190808.png

最後に無線LAN有効時の起動ログを貼っておく

PMUFW:  v1.1


U-Boot 2019.01 (Jul 21 2019 - 00:29:10 +0900)

Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
DRAM:  2 GiB
EL Level:   EL2
Chip ID:    zu3eg
MMC:   mmc@ff160000: 0, mmc@ff170000: 1
In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Bootmode: SD_MODE
Reset reason:   SOFT 
Net:   No ethernet found.
626 bytes read in 9 ms (67.4 KiB/s)
Loaded environment from uEnv.txt
Importing environment from SD ...










  *** U-Boot Boot Menu ***

     Boot Default
     U-Boot console


  Press UP/DOWN to move, ENTER to select
























switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Card did not respond to voltage select!
starting USB...
USB0:   Register 2000440 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 4 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device

Device 1: unknown device
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm-zynqmp
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
No ethernet found.
No ethernet found.
!!!
!!! Booting cmd is deprecated (will be removed in 2020).
!!! Please move to distro bootcmd.
!!!
switch to partitions #0, OK
mmc0 is current device
Device: mmc@ff160000
Manufacturer ID: 58
OEM: 4444
Name: DDINC 
Bus Speed: 15000000
Mode : SD High Speed (50MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.9 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
Running uenvcmd ...
16110080 bytes read in 2540 ms (6 MiB/s)
41407 bytes read in 21 ms (1.9 MiB/s)
## Flattened Device Tree blob at 04000000
   Booting using the fdt blob at 0x4000000
   Loading Device Tree to 000000000fff2000, end 000000000ffff1be ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 4.19.0-xlnx-v2019.1-zynqmp-fpga (ichiro@Jabberwock) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04)) #3 SMP Thu Jul 25 06:32:25 DST 2019
[    0.000000] Machine model: Avnet Ultra96-V2 Rev1
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x0000000070000000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] random: get_random_bytes called from start_kernel+0xa8/0x414 with crng_init=0
[    0.000000] percpu: Embedded 22 pages/cpu @(____ptrval____) s52504 r8192 d29416 u90112
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Speculative Store Bypass Disable mitigation not required
[    0.000000] CPU features: detected: Kernel page table isolation (KPTI)
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 517120
[    0.000000] Kernel command line: console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio
[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Memory: 1786316K/2097152K available (11004K kernel code, 628K rwdata, 3252K rodata, 832K init, 315K bss, 48692K reserved, 262144K cma-reserved)
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] arch_timer: cp15 timer(s) running at 100.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns
[    0.000003] sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
[    0.000274] Console: colour dummy device 80x25
[    0.000303] Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=400000)
[    0.000312] pid_max: default: 32768 minimum: 301
[    0.000441] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000456] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.001399] ASID allocator initialised with 32768 entries
[    0.001457] rcu: Hierarchical SRCU implementation.
[    0.001779] EFI services will not be available.
[    0.001923] smp: Bringing up secondary CPUs ...
[    0.002252] Detected VIPT I-cache on CPU1
[    0.002292] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.002645] Detected VIPT I-cache on CPU2
[    0.002665] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.002979] Detected VIPT I-cache on CPU3
[    0.002999] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.003044] smp: Brought up 1 node, 4 CPUs
[    0.003060] SMP: Total of 4 processors activated.
[    0.003066] CPU features: detected: 32-bit EL0 Support
[    0.005325] CPU: All CPU(s) started at EL2
[    0.005340] alternatives: patching kernel code
[    0.006667] devtmpfs: initialized
[    0.011694] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.011715] futex hash table entries: 1024 (order: 4, 65536 bytes)
[    0.018156] xor: measuring software checksum speed
[    0.057420]    8regs     :  2303.000 MB/sec
[    0.097451]    8regs_prefetch:  2053.000 MB/sec
[    0.137481]    32regs    :  2831.000 MB/sec
[    0.177511]    32regs_prefetch:  2456.000 MB/sec
[    0.177515] xor: using function: 32regs (2831.000 MB/sec)
[    0.177529] pinctrl core: initialized pinctrl subsystem
[    0.178431] NET: Registered protocol family 16
[    0.178803] audit: initializing netlink subsys (disabled)
[    0.178893] audit: type=2000 audit(0.176:1): state=initialized audit_enabled=0 res=1
[    0.179470] cpuidle: using governor menu
[    0.179617] vdso: 2 pages (1 code @ (____ptrval____), 1 data @ (____ptrval____))
[    0.179625] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.180544] DMA: preallocated 256 KiB pool for atomic allocations
[    0.194151] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.261790] raid6: int64x1  gen()   448 MB/s
[    0.329789] raid6: int64x1  xor()   439 MB/s
[    0.397872] raid6: int64x2  gen()   682 MB/s
[    0.465889] raid6: int64x2  xor()   601 MB/s
[    0.533917] raid6: int64x4  gen()  1039 MB/s
[    0.601966] raid6: int64x4  xor()   761 MB/s
[    0.670005] raid6: int64x8  gen()   982 MB/s
[    0.738059] raid6: int64x8  xor()   749 MB/s
[    0.806103] raid6: neonx1   gen()   728 MB/s
[    0.874171] raid6: neonx1   xor()   848 MB/s
[    0.942226] raid6: neonx2   gen()  1165 MB/s
[    1.010266] raid6: neonx2   xor()  1197 MB/s
[    1.078326] raid6: neonx4   gen()  1503 MB/s
[    1.146386] raid6: neonx4   xor()  1432 MB/s
[    1.214438] raid6: neonx8   gen()  1663 MB/s
[    1.282492] raid6: neonx8   xor()  1529 MB/s
[    1.282497] raid6: using algorithm neonx8 gen() 1663 MB/s
[    1.282501] raid6: .... xor() 1529 MB/s, rmw enabled
[    1.282506] raid6: using neon recovery algorithm
[    1.283540] SCSI subsystem initialized
[    1.283786] usbcore: registered new interface driver usbfs
[    1.283827] usbcore: registered new interface driver hub
[    1.283876] usbcore: registered new device driver usb
[    1.283952] media: Linux media interface: v0.10
[    1.283981] videodev: Linux video capture interface: v2.00
[    1.284013] pps_core: LinuxPPS API ver. 1 registered
[    1.284017] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.284035] PTP clock support registered
[    1.284066] EDAC MC: Ver: 3.0.0
[    1.284663] zynqmp-ipi-mbox mailbox@ff990400: Probed ZynqMP IPI Mailbox driver.
[    1.284895] FPGA manager framework
[    1.285065] Advanced Linux Sound Architecture Driver Initialized.
[    1.285442] Bluetooth: Core ver 2.22
[    1.285469] NET: Registered protocol family 31
[    1.285473] Bluetooth: HCI device and connection manager initialized
[    1.285485] Bluetooth: HCI socket layer initialized
[    1.285492] Bluetooth: L2CAP socket layer initialized
[    1.285511] Bluetooth: SCO socket layer initialized
[    1.285933] clocksource: Switched to clocksource arch_sys_counter
[    1.286033] VFS: Disk quotas dquot_6.6.0
[    1.286087] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.291478] NET: Registered protocol family 2
[    1.291915] tcp_listen_portaddr_hash hash table entries: 1024 (order: 2, 16384 bytes)
[    1.291942] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[    1.292049] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[    1.292380] TCP: Hash tables configured (established 16384 bind 16384)
[    1.292475] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[    1.292517] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[    1.292658] NET: Registered protocol family 1
[    1.292917] RPC: Registered named UNIX socket transport module.
[    1.292922] RPC: Registered udp transport module.
[    1.292926] RPC: Registered tcp transport module.
[    1.292930] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.293777] hw perfevents: no interrupt-affinity property for /pmu, guessing.
[    1.294337] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    1.295293] Initialise system trusted keyrings
[    1.295394] workingset: timestamp_bits=62 max_order=19 bucket_order=0
[    1.296195] NFS: Registering the id_resolver key type
[    1.296208] Key type id_resolver registered
[    1.296213] Key type id_legacy registered
[    1.296224] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    1.296242] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    2.372694] NET: Registered protocol family 38
[    2.429188] Key type asymmetric registered
[    2.429195] Asymmetric key parser 'x509' registered
[    2.429250] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[    2.429258] io scheduler noop registered
[    2.429263] io scheduler deadline registered
[    2.429311] io scheduler cfq registered (default)
[    2.429316] io scheduler mq-deadline registered
[    2.429321] io scheduler kyber registered
[    2.460296] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    2.463380] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    2.468877] brd: module loaded
[    2.474237] loop: module loaded
[    2.475059] mtdoops: mtd device (mtddev=name/number) must be supplied
[    2.476508] libphy: Fixed MDIO Bus: probed
[    2.477972] tun: Universal TUN/TAP device driver, 1.6
[    2.478177] CAN device driver interface
[    2.479040] usbcore: registered new interface driver asix
[    2.479091] usbcore: registered new interface driver ax88179_178a
[    2.479121] usbcore: registered new interface driver cdc_ether
[    2.479156] usbcore: registered new interface driver net1080
[    2.479188] usbcore: registered new interface driver cdc_subset
[    2.479218] usbcore: registered new interface driver zaurus
[    2.479261] usbcore: registered new interface driver cdc_ncm
[    2.480423] usbcore: registered new interface driver uas
[    2.480470] usbcore: registered new interface driver usb-storage
[    2.481112] rtc_zynqmp ffa60000.rtc: rtc core: registered ffa60000.rtc as rtc0
[    2.481178] i2c /dev entries driver
[    2.482594] usbcore: registered new interface driver uvcvideo
[    2.482599] USB Video Class driver (1.1.1)
[    2.483190] Bluetooth: HCI UART driver ver 2.3
[    2.483201] Bluetooth: HCI UART protocol H4 registered
[    2.483206] Bluetooth: HCI UART protocol BCSP registered
[    2.483235] Bluetooth: HCI UART protocol LL registered
[    2.483240] Bluetooth: HCI UART protocol ATH3K registered
[    2.483266] Bluetooth: HCI UART protocol Three-wire (H5) registered
[    2.483312] Bluetooth: HCI UART protocol Intel registered
[    2.483336] Bluetooth: HCI UART protocol QCA registered
[    2.483377] usbcore: registered new interface driver bcm203x
[    2.483414] usbcore: registered new interface driver bpa10x
[    2.483456] usbcore: registered new interface driver bfusb
[    2.483493] usbcore: registered new interface driver btusb
[    2.483498] Bluetooth: Generic Bluetooth SDIO driver ver 0.1
[    2.483558] usbcore: registered new interface driver ath3k
[    2.483675] EDAC MC: ECC not enabled
[    2.483890] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[    2.484719] sdhci: Secure Digital Host Controller Interface driver
[    2.484723] sdhci: Copyright(c) Pierre Ossman
[    2.484727] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.485095] ledtrig-cpu: registered to indicate activity on CPUs
[    2.485148] zynqmp_firmware_probe Platform Management API v1.1
[    2.485155] zynqmp_firmware_probe Trustzone version v1.0
[    2.488304] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: zynqmp pinctrl initialized
[    2.510144] zynqmp_clk_mux_get_parent() getparent failed for clock: lpd_wdt, ret = -22
[    2.510686] alg: No test for xilinx-zynqmp-aes (zynqmp-aes)
[    2.510704] zynqmp_aes zynqmp_aes: AES Successfully Registered
[    2.510704] 
[    2.510892] alg: No test for xilinx-keccak-384 (zynqmp-keccak-384)
[    2.511055] alg: No test for xilinx-zynqmp-rsa (zynqmp-rsa)
[    2.511301] usbcore: registered new interface driver usbhid
[    2.511306] usbhid: USB HID core driver
[    2.513320] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[    2.513719] usbcore: registered new interface driver snd-usb-audio
[    2.514646] pktgen: Packet Generator for packet performance testing. Version: 2.75
[    2.515113] Initializing XFRM netlink socket
[    2.515214] NET: Registered protocol family 10
[    2.515676] Segment Routing with IPv6
[    2.515783] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    2.516194] NET: Registered protocol family 17
[    2.516207] NET: Registered protocol family 15
[    2.516226] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    2.516280] can: controller area network core (rev 20170425 abi 9)
[    2.516319] NET: Registered protocol family 29
[    2.516325] can: raw protocol (rev 20170425)
[    2.516331] can: broadcast manager protocol (rev 20170425 t)
[    2.516338] can: netlink gateway (rev 20170425) max_hops=1
[    2.516744] Bluetooth: RFCOMM TTY layer initialized
[    2.516761] Bluetooth: RFCOMM socket layer initialized
[    2.516785] Bluetooth: RFCOMM ver 1.11
[    2.516794] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    2.516798] Bluetooth: BNEP filters: protocol multicast
[    2.516805] Bluetooth: BNEP socket layer initialized
[    2.516810] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    2.516817] Bluetooth: HIDP socket layer initialized
[    2.516946] 9pnet: Installing 9P2000 support
[    2.516975] Key type dns_resolver registered
[    2.517466] registered taskstats version 1
[    2.517471] Loading compiled-in X.509 certificates
[    2.517855] Btrfs loaded, crc32c=crc32c-generic
[    2.525892] ff000000.serial: ttyPS1 at MMIO 0xff000000 (irq = 24, base_baud = 6249999) is a xuartps
[    2.526695] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 25, base_baud = 6249999) is a xuartps
[    3.757515] console [ttyPS0] enabled
[    3.761996] of-fpga-region fpga-full: FPGA Region probed
[    3.768331] xilinx-dpdma fd4c0000.dma: Xilinx DPDMA engine is probed
[    3.775088] xilinx-psgtr fd400000.zynqmp_phy: Lane:1 type:8 protocol:4 pll_locked:yes
[    3.785334] xilinx-dp-snd-codec fd4a0000.zynqmp-display:zynqmp_dp_snd_codec0: Xilinx DisplayPort Sound Codec probed
[    3.796033] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm0: Xilinx DisplayPort Sound PCM probed
[    3.804069] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm1: Xilinx DisplayPort Sound PCM probed
[    3.812967] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.825473] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.838246] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: Xilinx DisplayPort Sound Card probed
[    3.848459] OF: graph: no port node found in /amba/zynqmp-display@fd4a0000
[    3.855524] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    3.862131] [drm] No driver support for vblank timestamp query.
[    3.868126] xlnx-drm xlnx-drm.0: bound fd4a0000.zynqmp-display (ops 0xffffff8008bfca20)
[    4.047473] Console: switching to colour frame buffer device 240x67
[    4.070372] zynqmp-display fd4a0000.zynqmp-display: fb0:  frame buffer device
[    4.077787] [drm] Initialized xlnx 1.0.0 20130509 for fd4a0000.zynqmp-display on minor 0
[    4.085903] zynqmp-display fd4a0000.zynqmp-display: ZynqMP DisplayPort Subsystem driver probed
[    4.096835] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[    4.103385] xilinx-axipmon fd0b0000.perf-monitor: Probed Xilinx APM
[    4.109877] xilinx-axipmon fd490000.perf-monitor: Probed Xilinx APM
[    4.116369] xilinx-axipmon ffa10000.perf-monitor: Probed Xilinx APM
[    4.124487] dwc3 fe200000.dwc3: Failed to get clk 'ref': -2
[    4.130542] xilinx-psgtr fd400000.zynqmp_phy: Lane:2 type:0 protocol:3 pll_locked:yes
[    4.144082] dwc3 fe300000.dwc3: Failed to get clk 'ref': -2
[    4.150066] xilinx-psgtr fd400000.zynqmp_phy: Lane:3 type:1 protocol:3 pll_locked:yes
[    4.160227] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    4.165722] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
[    4.174243] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x0000000202010010
[    4.183671] xhci-hcd xhci-hcd.0.auto: irq 33, io mem 0xfe300000
[    4.189841] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 4.19
[    4.198106] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.205322] usb usb1: Product: xHCI Host Controller
[    4.210195] usb usb1: Manufacturer: Linux 4.19.0-xlnx-v2019.1-zynqmp-fpga xhci-hcd
[    4.217762] usb usb1: SerialNumber: xhci-hcd.0.auto
[    4.222985] hub 1-0:1.0: USB hub found
[    4.226751] hub 1-0:1.0: 1 port detected
[    4.230886] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    4.236369] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
[    4.244026] xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0  SuperSpeed
[    4.250676] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[    4.258843] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 4.19
[    4.267101] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.274318] usb usb2: Product: xHCI Host Controller
[    4.279189] usb usb2: Manufacturer: Linux 4.19.0-xlnx-v2019.1-zynqmp-fpga xhci-hcd
[    4.286748] usb usb2: SerialNumber: xhci-hcd.0.auto
[    4.291883] hub 2-0:1.0: USB hub found
[    4.295651] hub 2-0:1.0: 1 port detected
[    4.301376] i2c i2c-0: Added multiplexed i2c bus 2
[    4.306314] i2c i2c-0: Added multiplexed i2c bus 3
[    4.311237] i2c i2c-0: Added multiplexed i2c bus 4
[    4.316152] i2c i2c-0: Added multiplexed i2c bus 5
[    4.321653] tps65086 6-005e: Failed to read revision register
[    4.327494] i2c i2c-0: Added multiplexed i2c bus 6
[    4.332897] ina2xx 7-0040: error configuring the device: -6
[    4.338505] i2c i2c-0: Added multiplexed i2c bus 7
[    4.343443] i2c i2c-0: Added multiplexed i2c bus 8
[    4.348378] i2c i2c-0: Added multiplexed i2c bus 9
[    4.353167] pca954x 0-0075: registered 8 multiplexed busses for I2C switch pca9548
[    4.360760] cdns-i2c ff030000.i2c: 100 kHz mmio ff030000 irq 14
[    4.367603] cdns-wdt fd4d0000.watchdog: Xilinx Watchdog Timer at (____ptrval____) with timeout 60s
[    4.409203] mmc0: SDHCI controller on ff160000.mmc [ff160000.mmc] using ADMA 64-bit
[    4.453935] mmc1: SDHCI controller on ff170000.mmc [ff170000.mmc] using ADMA 64-bit
[    4.465518] mmc0: new high speed SDHC card at address 5048
[    4.471747] mmcblk0: mmc0:5048 DDINC 14.9 GiB 
[    4.480214] input: gpio-keys as /devices/platform/gpio-keys/input/input0
[    4.487308] rtc_zynqmp ffa60000.rtc: setting system clock to 1970-01-01 00:14:15 UTC (855)
[    4.495571] of_cfs_init
[    4.498038] of_cfs_init: OK
[    4.500980] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    4.510338]  mmcblk0: p1 p2
[    4.525838] random: fast init done
[    4.529613] mmc1: new high speed SDIO card at address 0001
[    4.536926] wifi_pm : 0
[    4.539376] wifi_pm : 1
[    4.541943] wilc_sdio mmc1:0001:1: Driver Initializing success
[    4.640217] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    4.646758] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci-hcd
[    4.646897] zynqmp_pll_disable() clock disable failed for dpll_int, ret = -13
[    4.661656] ALSA device list:
[    4.664615]   #0: DisplayPort monitor
[    4.668840] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    4.677477] cfg80211: failed to load regulatory.db
[    4.682583] usb 2-1: New USB device found, idVendor=0424, idProduct=5744, bcdDevice= 2.05
[    4.690768] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=0
[    4.697893] usb 2-1: Product: USB5744
[    4.700075] EXT4-fs (mmcblk0p2): mounting ext3 file system using the ext4 subsystem
[    4.701548] usb 2-1: Manufacturer: Microchip Tech
[    4.721450] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    4.729569] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    4.743064] devtmpfs: mounted
[    4.746326] Freeing unused kernel memory: 832K
[    4.746840] hub 2-1:1.0: USB hub found
[    4.754581] hub 2-1:1.0: 3 ports detected
[    4.770021] Run /sbin/init as init process
[    4.813953] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[    4.970763] usb 1-1: New USB device found, idVendor=0424, idProduct=2744, bcdDevice= 2.05
[    4.978942] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    4.986071] usb 1-1: Product: USB2744
[    4.989726] usb 1-1: Manufacturer: Microchip Tech
[    5.051002] hub 1-1:1.0: USB hub found
[    5.054884] hub 1-1:1.0: 4 ports detected
[    5.401962] usb 1-1.4: new high-speed USB device number 3 using xhci-hcd
[    5.489896] systemd[1]: System time before build time, advancing clock.
[    5.506672] usb 1-1.4: New USB device found, idVendor=0424, idProduct=2740, bcdDevice= 2.00
[    5.515026] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    5.522327] usb 1-1.4: Product: Hub Controller
[    5.526767] usb 1-1.4: Manufacturer: Microchip Tech
[    5.532771] systemd[1]: systemd 241 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid)
[    5.554542] systemd[1]: Detected architecture arm64.

Welcome to Debian GNU/Linux 10 (buster)!

[    5.574696] systemd[1]: Set hostname to <debian-fpga>.
[    5.580550] Interface is neither WLAN0 nor P2P0
[    5.807264] systemd[1]: File /lib/systemd/system/systemd-journald.service:12 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.
[    5.824361] systemd[1]: Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)
[    5.983265] systemd[1]: /lib/systemd/system/smbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/smbd.pid → /run/samba/smbd.pid; please update the unit file accordingly.
[    6.007004] systemd[1]: /lib/systemd/system/nmbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/nmbd.pid → /run/samba/nmbd.pid; please update the unit file accordingly.
[    6.057264] random: systemd: uninitialized urandom read (16 bytes read)
[    6.069149] random: systemd: uninitialized urandom read (16 bytes read)
[    6.076067] systemd[1]: Listening on udev Kernel Socket.
[  OK  ] Listening on udev Kernel Socket.
[    6.098046] random: systemd: uninitialized urandom read (16 bytes read)
[    6.105124] systemd[1]: Created slice User and Session Slice.
[  OK  ] Created slice User and Session Slice.
[    6.126177] systemd[1]: Listening on initctl Compatibility Named Pipe.
[  OK  ] Listening on initctl Compatibility Named Pipe.
[  OK  ] Reached target Slices.
[  OK  ] Listening on Journal Audit Socket.
[  OK  ] Started Dispatch Password …ts to Console Directory Watch.
[  OK  ] Created slice system-serial\x2dgetty.slice.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Listening on Journal Socket.
         Starting Nameserver information manager...
         Mounting POSIX Message Queue File System...
         Starting Remount Root and Kernel File Systems...
[  OK  ] Listening on Syslog Socket.
[  OK  ] Started Forward Password R…uests to Wall Directory Watch.
[  OK  ] Reached target Paths.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Listening on udev Control Socket.
         Starting udev Coldplug all Devices...
         Starting Load Kernel Modules...
         Mounting Huge Pages File System...
[  OK  ] Reached target Remote File Systems.
[  OK  ] Reached target System Time Synchronized.
[  OK  ] Listening on Journal Socket (/dev/log).
         Starting Journal Service...
         Mounting Kernel Debug File System...
[  OK  ] Reached target Swap.
[  OK  ] Mounted POSIX Message Queue File System.
[  OK  ] Started Remount Root and Kernel File Systems.
[  OK  ] Started Load Kernel Modules.
[  OK  ] Started Journal Service.
[  OK  ] Mounted Huge Pages File System.
[  OK  ] Mounted Kernel Debug File System.
[  OK  ] Started Nameserver information manager.
         Mounting Kernel Configuration File System...
         Starting Apply Kernel Variables...
         Starting Flush Journal to Persistent Storage...
         Starting Load/Save Random Seed...
         Starting Create System Users...
[  OK  ] Mounted Kernel Configuration File System.
[  OK  ] Started Apply Kernel Variables.
[    6.809227] systemd-journald[2028]: Received request to flush runtime journal from PID 1
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Flush Journal to Persistent Storage.
[  OK  ] Started Create System Users.
[  OK  ] Started udev Coldplug all Devices.
         Starting Helper to synchronize boot up for ifupdown...
         Starting Create Static Device Nodes in /dev...
[  OK  ] Started Create Static Device Nodes in /dev.
         Starting udev Kernel Device Manager...
[  OK  ] Reached target Local File Systems (Pre).
         Mounting /config...
[  OK  ] Mounted /config.
[  OK  ] Started udev Kernel Device Manager.
[  OK  ] Reached target Sound Card.
[  OK  ] Found device /dev/ttyPS0.
[  OK  ] Started Helper to synchronize boot up for ifupdown.
[  OK  ] Found device /dev/mmcblk0p1.
         Mounting /mnt/boot...
[  OK  ] Listening on Load/Save RF …itch Status /dev/rfkill Watch.
         Starting Load/Save RF Kill Switch Status...
[  OK  ] Started Load/Save RF Kill Switch Status.
[  OK  ] Mounted /mnt/boot.
[  OK  ] Reached target Local File Systems.
         Starting Create Volatile Files and Directories...
         Starting Raise network interfaces...
[  OK  ] Started Create Volatile Files and Directories.
[  OK  ] Started Entropy daemon using the HAVEGE algorithm.
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Started Update UTMP about System Boot/Shutdown.
[  OK  ] Reached target System Initialization.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Started Daily rotation of log files.
[  OK  ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Reached target Basic System.
         Starting Login Service...
[  OK  ] Started Regular background program processing daemon.
[  OK  ] Started D-Bus System Message Bus.
         Starting WPA supplicant...
[  OK  ] Started Daily apt download activities.
[  OK  ] Started Daily apt upgrade and clean activities.
[  OK  ] Reached target Timers.
         Starting System Logging Service...
         Starting Avahi mDNS/DNS-SD Stack...
[   10.549882] random: crng init done
[   10.553300] random: 7 urandom warning(s) missed due to ratelimiting
[   13.092773] WILC POWER UP
[   13.095425] wilc_sdio mmc1:0001:1: SDIO speed: 50000000
[   13.102051] wilc_sdio mmc1:0001:1: chipid 003000d0
[  OK  ] Started System Logging Service.
[  OK  ] Started Login Service.
[  OK  ] Started WPA supplicant.
[  OK  ] Started Avahi mDNS/DNS-SD Stack.
[   15.652365] NOHZ: local_softirq_pending 08
[  OK  ] Started Raise network interfaces.
[  OK  ] Reached target Network.
         Starting Network Time Service...
         Starting Permit User Sessions...
         Starting OpenBSD Secure Shell server...
[  OK  ] Reached target Network is Online.
         Starting Samba NMB Daemon...
[  OK  ] Started Permit User Sessions.
[  OK  ] Started Network Time Service.
[  OK  ] Started Getty on tty1.
[  OK  ] Started Serial Getty on ttyPS0.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started OpenBSD Secure Shell server.
[  OK  ] Started Samba NMB Daemon.
         Starting Samba SMB Daemon...
[  OK  ] Started Samba SMB Daemon.
[  OK  ] Reached target Multi-User System.
[  OK  ] Reached target Graphical Interface.
         Starting Update UTMP about System Runlevel Changes...
[  OK  ] Started Update UTMP about System Runlevel Changes.

Debian GNU/Linux 10 debian-fpga ttyPS0

debian-fpga login: fpga
fpPassword: 
Last login: Thu Feb 14 19:12:22 JST 2019 on ttyPS0
Linux debian-fpga 4.19.0-xlnx-v2019.1-zynqmp-fpga #3 SMP Thu Jul 25 06:32:25 DST 2019 aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
fpga@debian-fpga:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether f8:f0:05:c4:17:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.35/24 brd 192.168.3.255 scope global dynamic wlan0
       valid_lft 86379sec preferred_lft 86379sec
    inet6 2400:2411:c841:f700:faf0:5ff:fec4:173c/64 scope global dynamic mngtmpaddr 
       valid_lft 86366sec preferred_lft 14366sec
    inet6 fe80::faf0:5ff:fec4:173c/64 scope link 
       valid_lft forever preferred_lft forever
4: p2p0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
fpga@debian-fpga:~$ 

  1. 2019年08月08日 04:41 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール1

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストールすることにした。

まずは、MicroSD カードの用意から始めよう。Ultra96-V2 Factory Image が書いてあったMicroSD カードを使用する。
参考にするFPGAの部屋のブログの記事は、””FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる2(Micro SDカードの準備)”だ。

lsblk で MicroSD カードがマウントされているドライブを調査する。
Ultra96V2_27_190806.png

MicroSD カードは sdd1, sdd2 にマウントされているようだ。
2 つのドライブのマウントを外そう。
sudo umount /dev/sdd1
sudo umount /dev/sdd2

Ultra96V2_28_190806.png

MicroSD カードをフォーマットする。
sudo fdisk /dev/sdd
Ultra96V2_29_190806.png

sdd1, sdd2 が見えるので、d コマンドで 2 つとも削除した。
Ultra96V2_30_190806.png

ここから、100 MB のFAT32 フォーマットの第1パーティション と残りの容量のLinux の第2パーティションを生成した。やり方は、””FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる2(Micro SDカードの準備)”を参照のこと。
そして、 w コマンドで書き込んだ。
Ultra96V2_31_190806.png

sudo mkfs.msdos -n U96V2_BOOT /dev/sdd1
sudo mkfs.ext3 -L ROOT_FS /dev/sdd2

Ultra96V2_32_190806.png

UltraZed/Ultra96/Ultra96-V2 向け Debian GNU/Linux (v2019.1版) ブートイメージの提供”を参考に git clone してファイルをダウンロードしよう。
git clone -b v2019.1.0 git://github.com/ikwzm/ZynqMP-FPGA-Linux
cd ZynqMP-FPGA-Linux
git lfs pull

Ultra96V2_33_190806.png

ZynqMP-FPGA-Linux ディレクトリに入って、target/Ultra96-V2/boot/ ディレクトリのすべてのファイルをMicroSD カードの第1パーティションに書き込む。
cp target/Ultra96-V2/boot/* /media/masaaki/U96V2_BOOT/
Ultra96V2_34_190806.png

コピーしたファイルを示す。
Ultra96V2_35_190806.png

Root File System をMicroSD カードの第2パーティションにコピーする。
sudo tar xfz debian10-rootfs-vanilla.tgz -C /media/masaaki/ROOT_FS/
Ultra96V2_36_190806.png

コピーしたファイルを示す。
Ultra96V2_37_190806.png

Root File System の下の /home/fpga の下に、 debian ディレクトリを作成して、Debian パッケージをコピーした。
mkdir /media/masaaki/ROOT_FS/home/fpga/debian/
cp linux-image-4.19.0-xlnx-v2019.1-zynqmp-fpga_4.19.0-xlnx-v2019.1-zynqmp-fpga-2_arm64.deb /media/masaaki/ROOT_FS/home/fpga/debian/
cp linux-headers-4.19.0-xlnx-v2019.1-zynqmp-fpga_4.19.0-xlnx-v2019.1-zynqmp-fpga-2_arm64.deb /media/masaaki/ROOT_FS/home/fpga/debian/
cp fclkcfg-4.19.0-xlnx-v2019.1-zynqmp-fpga_1.1.0-1_arm64.deb /media/masaaki/ROOT_FS/home/fpga/debian/
cp udmabuf-4.19.0-xlnx-v2019.1-zynqmp-fpga_1.4.2-0_arm64.deb /media/masaaki/ROOT_FS/home/fpga/debian/

Ultra96V2_38_190806.png

debian ディレクトリにコピーしたファイルを示す。
Ultra96V2_39_190806.png

MicroSD カードの第2パーティションの/mnt/boot を作成し、同じく、/etc/fstab に設定を追加して、ブートパーティションを見えるように fstab を設定する。設定を試行錯誤してしまったが、su にならないと書き換え出来なかった。
sudo mkdir /media/masaaki/ROOT_FS/mnt/boot
sudo su

cat <<EOT >> /media/masaaki/ROOT_FS/etc/fstab
/dev/mmcblk0p1  /mnt/boot   auto    defaults    0   0
EOT

exit

Ultra96V2_40_190806.png

これでとりあえずの設定は終了した。MicroSD カードを取り出して、Ultra96-V2 に挿入して、電源ON した。
すると無事にDebian を起動することができた。
Ultra96V2_41_190806.png

起動メッセージを貼っておく。

PMUFW:  v1.1


U-Boot 2019.01 (Jul 21 2019 - 00:29:10 +0900)

Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
DRAM:  2 GiB
EL Level:   EL2
Chip ID:    zu3eg
MMC:   mmc@ff160000: 0, mmc@ff170000: 1
In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Bootmode: SD_MODE
Reset reason:   EXTERNAL 
Net:   No ethernet found.
626 bytes read in 9 ms (67.4 KiB/s)
Loaded environment from uEnv.txt
Importing environment from SD ...


  *** U-Boot Boot Menu ***

     Boot Default
     U-Boot console


  Press UP/DOWN to move, ENTER to select
























switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Card did not respond to voltage select!
starting USB...
USB0:   Register 2000440 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 4 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device

Device 1: unknown device
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm-zynqmp
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
No ethernet found.
No ethernet found.
!!!
!!! Booting cmd is deprecated (will be removed in 2020).
!!! Please move to distro bootcmd.
!!!
switch to partitions #0, OK
mmc0 is current device
Device: mmc@ff160000
Manufacturer ID: 58
OEM: 4444
Name: DDINC 
Bus Speed: 15000000
Mode : SD High Speed (50MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.9 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
Running uenvcmd ...
16110080 bytes read in 2540 ms (6 MiB/s)
41407 bytes read in 21 ms (1.9 MiB/s)
## Flattened Device Tree blob at 04000000
   Booting using the fdt blob at 0x4000000
   Loading Device Tree to 000000000fff2000, end 000000000ffff1be ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 4.19.0-xlnx-v2019.1-zynqmp-fpga (ichiro@Jabberwock) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04)) #3 SMP Thu Jul 25 06:32:25 DST 2019
[    0.000000] Machine model: Avnet Ultra96-V2 Rev1
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x0000000070000000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] random: get_random_bytes called from start_kernel+0xa8/0x414 with crng_init=0
[    0.000000] percpu: Embedded 22 pages/cpu @(____ptrval____) s52504 r8192 d29416 u90112
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Speculative Store Bypass Disable mitigation not required
[    0.000000] CPU features: detected: Kernel page table isolation (KPTI)
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 517120
[    0.000000] Kernel command line: console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio
[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Memory: 1786316K/2097152K available (11004K kernel code, 628K rwdata, 3252K rodata, 832K init, 315K bss, 48692K reserved, 262144K cma-reserved)
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] arch_timer: cp15 timer(s) running at 100.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns
[    0.000004] sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
[    0.000272] Console: colour dummy device 80x25
[    0.000300] Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=400000)
[    0.000309] pid_max: default: 32768 minimum: 301
[    0.000440] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000454] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.001392] ASID allocator initialised with 32768 entries
[    0.001451] rcu: Hierarchical SRCU implementation.
[    0.001774] EFI services will not be available.
[    0.001913] smp: Bringing up secondary CPUs ...
[    0.002239] Detected VIPT I-cache on CPU1
[    0.002279] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.002636] Detected VIPT I-cache on CPU2
[    0.002658] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.002975] Detected VIPT I-cache on CPU3
[    0.002995] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.003040] smp: Brought up 1 node, 4 CPUs
[    0.003055] SMP: Total of 4 processors activated.
[    0.003062] CPU features: detected: 32-bit EL0 Support
[    0.005325] CPU: All CPU(s) started at EL2
[    0.005340] alternatives: patching kernel code
[    0.006669] devtmpfs: initialized
[    0.011683] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.011699] futex hash table entries: 1024 (order: 4, 65536 bytes)
[    0.018143] xor: measuring software checksum speed
[    0.057412]    8regs     :  2303.000 MB/sec
[    0.097443]    8regs_prefetch:  2053.000 MB/sec
[    0.137472]    32regs    :  2831.000 MB/sec
[    0.177502]    32regs_prefetch:  2456.000 MB/sec
[    0.177507] xor: using function: 32regs (2831.000 MB/sec)
[    0.177522] pinctrl core: initialized pinctrl subsystem
[    0.178421] NET: Registered protocol family 16
[    0.178792] audit: initializing netlink subsys (disabled)
[    0.178881] audit: type=2000 audit(0.176:1): state=initialized audit_enabled=0 res=1
[    0.179402] cpuidle: using governor menu
[    0.179553] vdso: 2 pages (1 code @ (____ptrval____), 1 data @ (____ptrval____))
[    0.179560] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.180498] DMA: preallocated 256 KiB pool for atomic allocations
[    0.193774] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.261729] raid6: int64x1  gen()   448 MB/s
[    0.329749] raid6: int64x1  xor()   438 MB/s
[    0.397834] raid6: int64x2  gen()   682 MB/s
[    0.465826] raid6: int64x2  xor()   601 MB/s
[    0.533877] raid6: int64x4  gen()  1039 MB/s
[    0.601933] raid6: int64x4  xor()   761 MB/s
[    0.669968] raid6: int64x8  gen()   982 MB/s
[    0.738019] raid6: int64x8  xor()   749 MB/s
[    0.806064] raid6: neonx1   gen()   728 MB/s
[    0.874120] raid6: neonx1   xor()   848 MB/s
[    0.942182] raid6: neonx2   gen()  1165 MB/s
[    1.010217] raid6: neonx2   xor()  1197 MB/s
[    1.078304] raid6: neonx4   gen()  1504 MB/s
[    1.146340] raid6: neonx4   xor()  1432 MB/s
[    1.214391] raid6: neonx8   gen()  1663 MB/s
[    1.282441] raid6: neonx8   xor()  1529 MB/s
[    1.282445] raid6: using algorithm neonx8 gen() 1663 MB/s
[    1.282449] raid6: .... xor() 1529 MB/s, rmw enabled
[    1.282454] raid6: using neon recovery algorithm
[    1.283480] SCSI subsystem initialized
[    1.283731] usbcore: registered new interface driver usbfs
[    1.283775] usbcore: registered new interface driver hub
[    1.283819] usbcore: registered new device driver usb
[    1.283896] media: Linux media interface: v0.10
[    1.283926] videodev: Linux video capture interface: v2.00
[    1.283961] pps_core: LinuxPPS API ver. 1 registered
[    1.283966] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.283984] PTP clock support registered
[    1.284016] EDAC MC: Ver: 3.0.0
[    1.284579] zynqmp-ipi-mbox mailbox@ff990400: Probed ZynqMP IPI Mailbox driver.
[    1.284797] FPGA manager framework
[    1.284967] Advanced Linux Sound Architecture Driver Initialized.
[    1.285345] Bluetooth: Core ver 2.22
[    1.285373] NET: Registered protocol family 31
[    1.285377] Bluetooth: HCI device and connection manager initialized
[    1.285387] Bluetooth: HCI socket layer initialized
[    1.285394] Bluetooth: L2CAP socket layer initialized
[    1.285415] Bluetooth: SCO socket layer initialized
[    1.285838] clocksource: Switched to clocksource arch_sys_counter
[    1.285936] VFS: Disk quotas dquot_6.6.0
[    1.285987] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.291430] NET: Registered protocol family 2
[    1.291867] tcp_listen_portaddr_hash hash table entries: 1024 (order: 2, 16384 bytes)
[    1.291895] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[    1.292003] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[    1.292344] TCP: Hash tables configured (established 16384 bind 16384)
[    1.292441] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[    1.292482] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[    1.292619] NET: Registered protocol family 1
[    1.292928] RPC: Registered named UNIX socket transport module.
[    1.292933] RPC: Registered udp transport module.
[    1.292937] RPC: Registered tcp transport module.
[    1.292941] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.293798] hw perfevents: no interrupt-affinity property for /pmu, guessing.
[    1.294054] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    1.295014] Initialise system trusted keyrings
[    1.295106] workingset: timestamp_bits=62 max_order=19 bucket_order=0
[    1.295901] NFS: Registering the id_resolver key type
[    1.295915] Key type id_resolver registered
[    1.295919] Key type id_legacy registered
[    1.295930] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    1.295949] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    2.371860] NET: Registered protocol family 38
[    2.429799] Key type asymmetric registered
[    2.429806] Asymmetric key parser 'x509' registered
[    2.429872] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[    2.429880] io scheduler noop registered
[    2.429885] io scheduler deadline registered
[    2.429934] io scheduler cfq registered (default)
[    2.429939] io scheduler mq-deadline registered
[    2.429944] io scheduler kyber registered
[    2.477305] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    2.480436] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    2.485859] brd: module loaded
[    2.491035] loop: module loaded
[    2.491858] mtdoops: mtd device (mtddev=name/number) must be supplied
[    2.493369] libphy: Fixed MDIO Bus: probed
[    2.495001] tun: Universal TUN/TAP device driver, 1.6
[    2.495504] CAN device driver interface
[    2.496283] usbcore: registered new interface driver asix
[    2.496314] usbcore: registered new interface driver ax88179_178a
[    2.496342] usbcore: registered new interface driver cdc_ether
[    2.496370] usbcore: registered new interface driver net1080
[    2.496396] usbcore: registered new interface driver cdc_subset
[    2.496422] usbcore: registered new interface driver zaurus
[    2.496459] usbcore: registered new interface driver cdc_ncm
[    2.497154] usbcore: registered new interface driver uas
[    2.497193] usbcore: registered new interface driver usb-storage
[    2.498531] rtc_zynqmp ffa60000.rtc: rtc core: registered ffa60000.rtc as rtc0
[    2.498620] i2c /dev entries driver
[    2.499993] usbcore: registered new interface driver uvcvideo
[    2.499998] USB Video Class driver (1.1.1)
[    2.500784] Bluetooth: HCI UART driver ver 2.3
[    2.500792] Bluetooth: HCI UART protocol H4 registered
[    2.500797] Bluetooth: HCI UART protocol BCSP registered
[    2.500827] Bluetooth: HCI UART protocol LL registered
[    2.500831] Bluetooth: HCI UART protocol ATH3K registered
[    2.500858] Bluetooth: HCI UART protocol Three-wire (H5) registered
[    2.500899] Bluetooth: HCI UART protocol Intel registered
[    2.500921] Bluetooth: HCI UART protocol QCA registered
[    2.500959] usbcore: registered new interface driver bcm203x
[    2.500995] usbcore: registered new interface driver bpa10x
[    2.501033] usbcore: registered new interface driver bfusb
[    2.501068] usbcore: registered new interface driver btusb
[    2.501074] Bluetooth: Generic Bluetooth SDIO driver ver 0.1
[    2.501137] usbcore: registered new interface driver ath3k
[    2.501351] EDAC MC: ECC not enabled
[    2.501505] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[    2.502369] sdhci: Secure Digital Host Controller Interface driver
[    2.502373] sdhci: Copyright(c) Pierre Ossman
[    2.502377] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.502721] ledtrig-cpu: registered to indicate activity on CPUs
[    2.502775] zynqmp_firmware_probe Platform Management API v1.1
[    2.502782] zynqmp_firmware_probe Trustzone version v1.0
[    2.505844] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: zynqmp pinctrl initialized
[    2.527945] zynqmp_clk_mux_get_parent() getparent failed for clock: lpd_wdt, ret = -22
[    2.528453] alg: No test for xilinx-zynqmp-aes (zynqmp-aes)
[    2.528471] zynqmp_aes zynqmp_aes: AES Successfully Registered
[    2.528471] 
[    2.528637] alg: No test for xilinx-keccak-384 (zynqmp-keccak-384)
[    2.528798] alg: No test for xilinx-zynqmp-rsa (zynqmp-rsa)
[    2.529043] usbcore: registered new interface driver usbhid
[    2.529049] usbhid: USB HID core driver
[    2.531234] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[    2.531644] usbcore: registered new interface driver snd-usb-audio
[    2.532529] pktgen: Packet Generator for packet performance testing. Version: 2.75
[    2.533016] Initializing XFRM netlink socket
[    2.533116] NET: Registered protocol family 10
[    2.533573] Segment Routing with IPv6
[    2.533680] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    2.534131] NET: Registered protocol family 17
[    2.534145] NET: Registered protocol family 15
[    2.534166] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    2.534223] can: controller area network core (rev 20170425 abi 9)
[    2.534265] NET: Registered protocol family 29
[    2.534272] can: raw protocol (rev 20170425)
[    2.534277] can: broadcast manager protocol (rev 20170425 t)
[    2.534285] can: netlink gateway (rev 20170425) max_hops=1
[    2.535627] Bluetooth: RFCOMM TTY layer initialized
[    2.535639] Bluetooth: RFCOMM socket layer initialized
[    2.535674] Bluetooth: RFCOMM ver 1.11
[    2.535684] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    2.535688] Bluetooth: BNEP filters: protocol multicast
[    2.535696] Bluetooth: BNEP socket layer initialized
[    2.535701] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    2.535709] Bluetooth: HIDP socket layer initialized
[    2.535872] 9pnet: Installing 9P2000 support
[    2.535905] Key type dns_resolver registered
[    2.536404] registered taskstats version 1
[    2.536408] Loading compiled-in X.509 certificates
[    2.536812] Btrfs loaded, crc32c=crc32c-generic
[    2.544749] ff000000.serial: ttyPS1 at MMIO 0xff000000 (irq = 24, base_baud = 6249999) is a xuartps
[    2.545517] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 25, base_baud = 6249999) is a xuartps
[    3.776160] console [ttyPS0] enabled
[    3.780470] of-fpga-region fpga-full: FPGA Region probed
[    3.786808] xilinx-dpdma fd4c0000.dma: Xilinx DPDMA engine is probed
[    3.793561] xilinx-psgtr fd400000.zynqmp_phy: Lane:1 type:8 protocol:4 pll_locked:yes
[    3.803813] xilinx-dp-snd-codec fd4a0000.zynqmp-display:zynqmp_dp_snd_codec0: Xilinx DisplayPort Sound Codec probed
[    3.814512] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm0: Xilinx DisplayPort Sound PCM probed
[    3.822552] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm1: Xilinx DisplayPort Sound PCM probed
[    3.831320] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.843814] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.856574] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: Xilinx DisplayPort Sound Card probed
[    3.866790] OF: graph: no port node found in /amba/zynqmp-display@fd4a0000
[    3.873850] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    3.880455] [drm] No driver support for vblank timestamp query.
[    3.886454] xlnx-drm xlnx-drm.0: bound fd4a0000.zynqmp-display (ops 0xffffff8008bfca20)
[    4.065839] Console: switching to colour frame buffer device 240x67
[    4.088730] zynqmp-display fd4a0000.zynqmp-display: fb0:  frame buffer device
[    4.096147] [drm] Initialized xlnx 1.0.0 20130509 for fd4a0000.zynqmp-display on minor 0
[    4.104262] zynqmp-display fd4a0000.zynqmp-display: ZynqMP DisplayPort Subsystem driver probed
[    4.115180] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[    4.121720] xilinx-axipmon fd0b0000.perf-monitor: Probed Xilinx APM
[    4.128214] xilinx-axipmon fd490000.perf-monitor: Probed Xilinx APM
[    4.134711] xilinx-axipmon ffa10000.perf-monitor: Probed Xilinx APM
[    4.142822] dwc3 fe200000.dwc3: Failed to get clk 'ref': -2
[    4.148889] xilinx-psgtr fd400000.zynqmp_phy: Lane:2 type:0 protocol:3 pll_locked:yes
[    4.162384] dwc3 fe300000.dwc3: Failed to get clk 'ref': -2
[    4.168347] xilinx-psgtr fd400000.zynqmp_phy: Lane:3 type:1 protocol:3 pll_locked:yes
[    4.178503] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    4.183994] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
[    4.192500] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x0000000202010010
[    4.201928] xhci-hcd xhci-hcd.0.auto: irq 33, io mem 0xfe300000
[    4.208098] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 4.19
[    4.216359] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.223582] usb usb1: Product: xHCI Host Controller
[    4.228457] usb usb1: Manufacturer: Linux 4.19.0-xlnx-v2019.1-zynqmp-fpga xhci-hcd
[    4.236016] usb usb1: SerialNumber: xhci-hcd.0.auto
[    4.241246] hub 1-0:1.0: USB hub found
[    4.245015] hub 1-0:1.0: 1 port detected
[    4.249149] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    4.254635] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
[    4.262291] xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0  SuperSpeed
[    4.268944] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[    4.277115] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 4.19
[    4.285372] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.292582] usb usb2: Product: xHCI Host Controller
[    4.297453] usb usb2: Manufacturer: Linux 4.19.0-xlnx-v2019.1-zynqmp-fpga xhci-hcd
[    4.305013] usb usb2: SerialNumber: xhci-hcd.0.auto
[    4.310143] hub 2-0:1.0: USB hub found
[    4.313907] hub 2-0:1.0: 1 port detected
[    4.319607] i2c i2c-0: Added multiplexed i2c bus 2
[    4.324540] i2c i2c-0: Added multiplexed i2c bus 3
[    4.329470] i2c i2c-0: Added multiplexed i2c bus 4
[    4.334393] i2c i2c-0: Added multiplexed i2c bus 5
[    4.339898] tps65086 6-005e: Failed to read revision register
[    4.345739] i2c i2c-0: Added multiplexed i2c bus 6
[    4.351148] ina2xx 7-0040: error configuring the device: -6
[    4.356752] i2c i2c-0: Added multiplexed i2c bus 7
[    4.361688] i2c i2c-0: Added multiplexed i2c bus 8
[    4.366620] i2c i2c-0: Added multiplexed i2c bus 9
[    4.371414] pca954x 0-0075: registered 8 multiplexed busses for I2C switch pca9548
[    4.379010] cdns-i2c ff030000.i2c: 100 kHz mmio ff030000 irq 14
[    4.385836] cdns-wdt fd4d0000.watchdog: Xilinx Watchdog Timer at (____ptrval____) with timeout 60s
[    4.425841] mmc0: SDHCI controller on ff160000.mmc [ff160000.mmc] using ADMA 64-bit
[    4.469839] mmc1: SDHCI controller on ff170000.mmc [ff170000.mmc] using ADMA 64-bit
[    4.484696] mmc0: new high speed SDHC card at address 5048
[    4.490924] mmcblk0: mmc0:5048 DDINC 14.9 GiB 
[    4.498629] input: gpio-keys as /devices/platform/gpio-keys/input/input0
[    4.505684] rtc_zynqmp ffa60000.rtc: setting system clock to 1970-01-01 00:00:08 UTC (8)
[    4.513777] of_cfs_init
[    4.516245] of_cfs_init: OK
[    4.519203] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    4.528402]  mmcblk0: p1 p2
[    4.543724] random: fast init done
[    4.547515] mmc1: new high speed SDIO card at address 0001
[    4.554639] wifi_pm : 0
[    4.557072] wifi_pm : 1
[    4.559643] wilc_sdio mmc1:0001:1: Driver Initializing success
[    4.585848] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[    4.658472] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    4.665162] zynqmp_pll_disable() clock disable failed for dpll_int, ret = -13
[    4.673021] ALSA device list:
[    4.675979]   #0: DisplayPort monitor
[    4.680186] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    4.688799] cfg80211: failed to load regulatory.db
[    4.696239] EXT4-fs (mmcblk0p2): mounting ext3 file system using the ext4 subsystem
[    4.738720] usb 1-1: New USB device found, idVendor=0424, idProduct=2744, bcdDevice= 2.05
[    4.746900] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    4.754034] usb 1-1: Product: USB2744
[    4.757686] usb 1-1: Manufacturer: Microchip Tech
[    4.813188] hub 1-1:1.0: USB hub found
[    4.816971] hub 1-1:1.0: 4 ports detected
[    4.876964] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci-hcd
[    4.902635] usb 2-1: New USB device found, idVendor=0424, idProduct=5744, bcdDevice= 2.05
[    4.910812] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=0
[    4.917942] usb 2-1: Product: USB5744
[    4.921590] usb 2-1: Manufacturer: Microchip Tech
[    4.957037] hub 2-1:1.0: USB hub found
[    4.960816] hub 2-1:1.0: 3 ports detected
[    5.169839] usb 1-1.4: new high-speed USB device number 3 using xhci-hcd
[    5.274850] usb 1-1.4: New USB device found, idVendor=0424, idProduct=2740, bcdDevice= 2.00
[    5.283203] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    5.290507] usb 1-1.4: Product: Hub Controller
[    5.294941] usb 1-1.4: Manufacturer: Microchip Tech
[    5.351175] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    5.359306] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    5.373192] devtmpfs: mounted
[    5.376457] Freeing unused kernel memory: 832K
[    5.380952] Run /sbin/init as init process
[    6.110280] systemd[1]: System time before build time, advancing clock.
[    6.148085] systemd[1]: systemd 241 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid)
[    6.169753] systemd[1]: Detected architecture arm64.

Welcome to Debian GNU/Linux 10 (buster)!

[    6.190648] systemd[1]: Set hostname to <debian-fpga>.
[    6.196536] Interface is neither WLAN0 nor P2P0
[    6.416824] systemd[1]: File /lib/systemd/system/systemd-journald.service:12 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.
[    6.433898] systemd[1]: Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)
[    6.586782] systemd[1]: /lib/systemd/system/smbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/smbd.pid → /run/samba/smbd.pid; please update the unit file accordingly.
[    6.610504] systemd[1]: /lib/systemd/system/nmbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/nmbd.pid → /run/samba/nmbd.pid; please update the unit file accordingly.
[    6.659329] random: systemd: uninitialized urandom read (16 bytes read)
[    6.671241] random: systemd: uninitialized urandom read (16 bytes read)
[    6.678258] systemd[1]: Listening on Journal Socket (/dev/log).
[  OK  ] Listening on Journal Socket (/dev/log).
[    6.701927] random: systemd: uninitialized urandom read (16 bytes read)
[    6.708564] systemd[1]: Reached target Swap.
[  OK  ] Reached target Swap.
[    6.721899] systemd[1]: Reached target Remote File Systems.
[  OK  ] Reached target Remote File Systems.
[  OK  ] Listening on initctl Compatibility Named Pipe.
[  OK  ] Created slice system-serial\x2dgetty.slice.
[  OK  ] Reached target System Time Synchronized.
[  OK  ] Listening on Journal Audit Socket.
[  OK  ] Listening on Syslog Socket.
[  OK  ] Started Dispatch Password …ts to Console Directory Watch.
[  OK  ] Listening on Journal Socket.
         Starting Journal Service...
         Starting Nameserver information manager...
[  OK  ] Started Forward Password R…uests to Wall Directory Watch.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target Paths.
[  OK  ] Created slice User and Session Slice.
[  OK  ] Reached target Slices.
[  OK  ] Listening on udev Kernel Socket.
         Starting Remount Root and Kernel File Systems...
         Mounting Kernel Debug File System...
         Starting Load Kernel Modules...
         Mounting Huge Pages File System...
[  OK  ] Created slice system-getty.slice.
[  OK  ] Listening on udev Control Socket.
         Starting udev Coldplug all Devices...
         Mounting POSIX Message Queue File System...
[  OK  ] Started Journal Service.
[  OK  ] Started Remount Root and Kernel File Systems.
[  OK  ] Mounted Kernel Debug File System.
[  OK  ] Started Load Kernel Modules.
[  OK  ] Mounted Huge Pages File System.
[  OK  ] Mounted POSIX Message Queue File System.
[  OK  ] Started Nameserver information manager.
         Mounting Kernel Configuration File System...
         Starting Apply Kernel Variables...
         Starting Load/Save Random Seed...
         Starting Create System Users...
         Starting Flush Journal to Persistent Storage...
[  OK  ] Mounted Kernel Configuration File System.
[  OK  ] Started Apply Kernel Variables.
[    7.381021] systemd-journald[1770]: Received request to flush runtime journal from PID 1
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Flush Journal to Persistent Storage.
[  OK  ] Started udev Coldplug all Devices.
         Starting Helper to synchronize boot up for ifupdown...
[  OK  ] Started Helper to synchronize boot up for ifupdown.
[  OK  ] Started Create System Users.
         Starting Create Static Device Nodes in /dev...
[  OK  ] Started Create Static Device Nodes in /dev.
[  OK  ] Reached target Local File Systems (Pre).
         Mounting /config...
         Starting udev Kernel Device Manager...
[  OK  ] Mounted /config.
[  OK  ] Started udev Kernel Device Manager.
[  OK  ] Found device /dev/ttyPS0.
[  OK  ] Reached target Sound Card.
[  OK  ] Found device /dev/mmcblk0p1.
         Mounting /mnt/boot...
[  OK  ] Listening on Load/Save RF …itch Status /dev/rfkill Watch.
         Starting Load/Save RF Kill Switch Status...
[  OK  ] Started Load/Save RF Kill Switch Status.
[  OK  ] Mounted /mnt/boot.
[  OK  ] Reached target Local File Systems.
         Starting Raise network interfaces...
         Starting Create Volatile Files and Directories...
[  OK  ] Started Create Volatile Files and Directories.
[  OK  ] Started Entropy daemon using the HAVEGE algorithm.
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Started Update UTMP about System Boot/Shutdown.
[  OK  ] Started Raise network interfaces.
[  OK  ] Reached target System Initialization.
[  OK  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Started Daily rotation of log files.
[  OK  ] Started Daily apt download activities.
[  OK  ] Started Daily apt upgrade and clean activities.
[  OK  ] Reached target Timers.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Reached target Basic System.
[  OK  ] Started Regular background program processing daemon.
         Starting Login Service...
         Starting System Logging Service...
         Starting Avahi mDNS/DNS-SD Stack...
[  OK  ] Started D-Bus System Message Bus.
         Starting WPA supplicant...
[  OK  ] Started System Logging Service.
[  OK  ] Started Login Service.
[  OK  ] Started Avahi mDNS/DNS-SD Stack.
[  OK  ] Started WPA supplicant.
[  OK  ] Reached target Network.
         Starting Permit User Sessions...
         Starting Network Time Service...
         Starting OpenBSD Secure Shell server...
[  OK  ] Reached target Network is Online.
         Starting Samba NMB Daemon...
[  OK  ] Started Permit User Sessions.
[  OK  ] Started Serial Getty on ttyPS0.
[  OK  ] Started Getty on tty1.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started Network Time Service.
[   12.285443] random: crng init done
[   12.288871] random: 7 urandom warning(s) missed due to ratelimiting
[  OK  ] Started OpenBSD Secure Shell server.

Debian GNU/Linux 10 debian-fpga ttyPS0

debian-fpga login: 

  1. 2019年08月07日 04:39 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 Factory Image を試してみた2(Ultra96-V2 を無線LANでネットワークに接続した)

Ultra96-V2 Factory Image を試してみた”の続き。

前回は、Ultra96-V2 Factory Image をMicroSD に書いて、Linux をブートした。今回は、Ultra96-V2 Factory Image のLinux を無線LAN でネットワークに接続できた。

root のホーム・ディレクトリに wpa_supplicant.conf あったので、開いてみた。
Ultra96V2_16_190806.png

Ultra96V2_17_190806.png

ssid と psk を書けば行けそうだ。
家のネットワーク・ルーターの ssid と psk を書いた。
Ultra96V2_18_190806.png

セーブした。
root のホーム・ディレクトリを見ると、wifi.sh がある。これを見てみよう。
Ultra96V2_19_190806.png

コードを引用する。

#Add the wi-fi driver module to the kernel:
cp -rf /home/root/wpa_supplicant.conf /etc/.

# Load ATWILC3000 driver
#modprobe wilc
modprobe wilc-sdio

# bring up interface
ifconfig wlan0 up

#Run wpa_supplicant for secure networking:
wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf -B

#To add DHCP:
udhcpc -i wlan0

#To run iperf3:  (2.0.5 without the "b")
#server mode:
#comment this to simplify production testing:
#iperf3 -s


./wifi.sh
で起動した。
Ultra96V2_20_190806.png

ifconfig
すると、wlan0 が見えて、IP アドレスが取得できている。192.168.3.35 だった。
Ultra96V2_21_190806.png

192.168.3.35 に ssh ログインしてみたら、問題なく入れた。
ssh 192.168.3.35 -X -l root
Ultra96V2_22_190806.png

Chrome ブラウザで 192.168.3.35 を見ると、Web ページが見えた。
Ultra96V2_23_190806.png

dnf -> dnf Package Update と進んだ。
すべての項目にチェックを入れて、Update ボタンをクリックした。
Ultra96V2_24_190806.png

数分で Updated selected packages が出たが早すぎると思う。
Ultra96V2_25_190806.png

dnf ページの指示通りに tree コマンドをインストールしてみたが、コマンドが not found になってしまう。やはりインストールできていないのかな?
dnf repoquery dnf install -y tree
Ultra96V2_26_190806.png

dnf が動いていれば使っても良いのだが、やはり、ikwzm さんのブート・イメージを使ったほうが良いかな?
  1. 2019年08月06日 04:42 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 Factory Image を試してみた

Ultra96-V2 で Ultra96-V2 Factory Image を試してみよう。

ひでみさんの”FPGAの内容が薄い本2”にも書いてあったが、Ultra96-V2 に入っていたMicro SD カードには何も書かれていなくて空だった。そこで、SD カードのイメージをダウンロードして書き込もう。

Ultra96-V2 の Reference Designs ページで、ログインしてから”Ultra96 Factory Image”をダウンロードした。
ダウンロードしたZIP ファイルの中には、Ultra96v2_Factory_Image_Write_190611.pdf が入っていて、Ultra96-V2 のSD カード・イメージをダウンロードするURL や、イメージのSD カードへの書き方も載っていた。それに沿ってやっていこう。

マニュアルは etcher でイメージを書くということだった。 etcher はちょうど”Donkey Car のMicroSD カードを作成した”で使ったので、インストール済みだ。

SD カード・イメージをダウンロードするURL からダウンロードすると ultra96v2_oob_2018_3_190530.zip がダウンロードできた。
Ultra96V2_4_190805.png

ultra96v2_oob_2018_3_190530.zip を開くと中にイメージとPDF ファイルがあった。
Ultra96V2_5_190805.png

PDF ファイルは、zedboard.org からダウンロードしたPDF はUltra96v2_Factory_Image_Write_190611.pdf と同じだったので、イメージのultra96v2_oob_2018_3_190530.img を解凍した。
Ultra96V2_6_190805.png

イメージを etcher でMicro SD カードに書き込む。
Micro SD カードをリーダー・ライタに入れて、パソコンのUSB ポートに差し込んでマウントした。
etcher を起動して、ultra96v2_oob_2018_3_190530.img を指定した。
Ultra96V2_7_190805.png

イメージを書き込むデバイスを MicroSD カードに指定した。
Ultra96V2_8_190805.png

ここでFlash! をクリックして書き込みを開始した。
Ultra96V2_9_190805.png

MicroSD カードへのイメージの書き込みが始まった。
Ultra96V2_10_190805.png

イメージの書き込みが終了した。
Ultra96V2_11_190805.png

MicroSD カードの boot パーティションを示す。
Ultra96V2_12_190805.png

root パーティションを示す。
Ultra96V2_13_190805.png

Ultra96-V2 のMODE SW のSW3 の 1 をOFF , 2 を ON にして、書き込んだMicroSD カードをUltra96-V2 のカードスロットに入れて電源ONしたところ、PetaLinux がブートした。
Ultra96V2_14_190805.png

リターン・キーを押したところ、ログインプロンプトがでて、
root
root

でログインできた。
Ultra96V2_15_190805.png

なお、Mini DisplayPort には、”Ultra96のGetting Startedをやってみた”と同様の画面が表示されていた。

起動ログを貼っておく。

Xilinx Zynq MP First Stage Boot Loader 
Release 2018.3   May 30 2019  -  17:46:11
PMUFW:  v1.1


U-Boot 2018.01 (May 30 2019 - 17:43:24 +0000)

Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
I2C:   ready
DRAM:  2 GiB
EL Level:   EL2
Chip ID:    zu3eg
Watchdog: Started
MMC:   mmc@ff160000: 0 (SD), mmc@ff170000: 1
*** Warning - bad CRC, using default environment

In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
Bootmode: SD_MODE
Net:   Net Initialization Skipped
No ethernet found.
U-BOOT for ultra96v2-oob-2018-3

Hit any key to stop autoboot:  0 
Device: mmc@ff160000
Manufacturer ID: 58
OEM: 4444
Name: DDINC 
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.9 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
reading image.ub
7079832 bytes read in 516 ms (13.1 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
   Using 'conf@system-top.dtb' configuration
   Trying 'kernel@1' kernel subimage
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x100000f8
     Data Size:    7036769 Bytes = 6.7 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x00080000
     Entry Point:  0x00080000
     Hash algo:    sha1
     Hash value:   39d15db15c249d803c63339561eb96f2fbd184d5
   Verifying Hash Integrity ... sha1+ OK
## Loading fdt from FIT Image at 10000000 ...
   Using 'conf@system-top.dtb' configuration
   Trying 'fdt@system-top.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x106b6160
     Data Size:    41155 Bytes = 40.2 KiB
     Architecture: AArch64
     Hash algo:    sha1
     Hash value:   12cd1f17844d71ed9a1fbe1d74e4575aa76c38e9
   Verifying Hash Integrity ... sha1+ OK
   Booting using the fdt blob at 0x106b6160
   Uncompressing Kernel Image ... OK
   Loading Device Tree to 0000000007ff2000, end 0000000007fff0c2 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.0 (oe-user@oe-host) (gcc version 7.3.0 (GCC)) #1 SMP Thu May 30 17:57:52 UTC 2019
[    0.000000] Boot CPU: AArch64 Processor [410fd034]
[    0.000000] Machine model: Avnet Ultra96 Rev1
[    0.000000] earlycon: cdns0 at MMIO 0x00000000ff010000 (options '115200n8')
[    0.000000] bootconsole [cdns0] enabled
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x000000006fc00000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] random: fast init done
[    0.000000] percpu: Embedded 21 pages/cpu @ffffffc07fe69000 s45080 r8192 d32744 u86016
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 512771
[    0.000000] Kernel command line: earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Memory: 1768328K/2079744K available (10044K kernel code, 656K rwdata, 3220K rodata, 512K init, 2354K bss, 49272K reserved, 262144K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     modules : 0xffffff8000000000 - 0xffffff8008000000   (   128 MB)
[    0.000000]     vmalloc : 0xffffff8008000000 - 0xffffffbebfff0000   (   250 GB)
[    0.000000]       .text : 0xffffff8008080000 - 0xffffff8008a50000   ( 10048 KB)
[    0.000000]     .rodata : 0xffffff8008a50000 - 0xffffff8008d80000   (  3264 KB)
[    0.000000]       .init : 0xffffff8008d80000 - 0xffffff8008e00000   (   512 KB)
[    0.000000]       .data : 0xffffff8008e00000 - 0xffffff8008ea4200   (   657 KB)
[    0.000000]        .bss : 0xffffff8008ea4200 - 0xffffff80090f0d30   (  2355 KB)
[    0.000000]     fixed   : 0xffffffbefe7fd000 - 0xffffffbefec00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffffffbefee00000 - 0xffffffbeffe00000   (    16 MB)
[    0.000000]     vmemmap : 0xffffffbf00000000 - 0xffffffc000000000   (     4 GB maximum)
[    0.000000]               0xffffffbf00000000 - 0xffffffbf01bfc800   (    27 MB actual)
[    0.000000]     memory  : 0xffffffc000000000 - 0xffffffc07ff00000   (  2047 MB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000]  RCU event tracing is enabled.
[    0.000000]  RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] arch_timer: cp15 timer(s) running at 100.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns
[    0.000003] sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
[    0.008426] Console: colour dummy device 80x25
[    0.012479] Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=400000)
[    0.022839] pid_max: default: 32768 minimum: 301
[    0.027537] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.034095] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.041949] ASID allocator initialised with 65536 entries
[    0.046590] Hierarchical SRCU implementation.
[    0.051201] EFI services will not be available.
[    0.055387] zynqmp_plat_init Platform Management API v1.1
[    0.060728] zynqmp_plat_init Trustzone version v1.0
[    0.065676] smp: Bringing up secondary CPUs ...
[    0.070345] Detected VIPT I-cache on CPU1
[    0.070384] CPU1: Booted secondary processor [410fd034]
[    0.070682] Detected VIPT I-cache on CPU2
[    0.070701] CPU2: Booted secondary processor [410fd034]
[    0.070976] Detected VIPT I-cache on CPU3
[    0.070995] CPU3: Booted secondary processor [410fd034]
[    0.071037] smp: Brought up 1 node, 4 CPUs
[    0.101640] SMP: Total of 4 processors activated.
[    0.106314] CPU features: detected feature: 32-bit EL0 Support
[    0.112112] CPU: All CPU(s) started at EL2
[    0.116185] alternatives: patching kernel code
[    0.121331] devtmpfs: initialized
[    0.128716] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.133570] futex hash table entries: 1024 (order: 5, 131072 bytes)
[    0.146190] xor: measuring software checksum speed
[    0.183898]    8regs     :  2303.000 MB/sec
[    0.223928]    8regs_prefetch:  2053.000 MB/sec
[    0.263959]    32regs    :  2830.000 MB/sec
[    0.303992]    32regs_prefetch:  2379.000 MB/sec
[    0.304023] xor: using function: 32regs (2830.000 MB/sec)
[    0.308435] pinctrl core: initialized pinctrl subsystem
[    0.314209] NET: Registered protocol family 16
[    0.318718] cpuidle: using governor menu
[    0.322408] vdso: 2 pages (1 code @ ffffff8008a56000, 1 data @ ffffff8008e04000)
[    0.329188] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.336529] DMA: preallocated 256 KiB pool for atomic allocations
[    0.363415] reset_zynqmp reset-controller: Xilinx zynqmp reset driver probed
[    0.365397] ARM CCI_400_r1 PMU driver probed
[    0.370052] zynqmp-pinctrl ff180000.pinctrl: zynqmp pinctrl initialized
[    0.386078] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.453783] raid6: int64x1  gen()   401 MB/s
[    0.521766] raid6: int64x1  xor()   446 MB/s
[    0.589834] raid6: int64x2  gen()   687 MB/s
[    0.657901] raid6: int64x2  xor()   603 MB/s
[    0.725979] raid6: int64x4  gen()  1042 MB/s
[    0.793989] raid6: int64x4  xor()   742 MB/s
[    0.862083] raid6: int64x8  gen()   980 MB/s
[    0.930105] raid6: int64x8  xor()   745 MB/s
[    0.998217] raid6: neonx1   gen()   726 MB/s
[    1.066226] raid6: neonx1   xor()   851 MB/s
[    1.134318] raid6: neonx2   gen()  1169 MB/s
[    1.202331] raid6: neonx2   xor()  1207 MB/s
[    1.270397] raid6: neonx4   gen()  1506 MB/s
[    1.338446] raid6: neonx4   xor()  1441 MB/s
[    1.406528] raid6: neonx8   gen()  1653 MB/s
[    1.474578] raid6: neonx8   xor()  1535 MB/s
[    1.474607] raid6: using algorithm neonx8 gen() 1653 MB/s
[    1.478572] raid6: .... xor() 1535 MB/s, rmw enabled
[    1.483503] raid6: using neon recovery algorithm
[    1.488818] XGpio: /amba_pl@0/gpio@a0020000: registered, base is 511
[    1.494527] PLL: shutdown
[    1.497005] zynqmp_pll_disable() clock disable failed for iopll_int, ret = -13
[    1.504322] XGpio: /amba_pl@0/gpio@a0020000: dual channel registered, base is 510
[    1.512054] XGpio: /amba_pl@0/gpio@a0021000: registered, base is 509
[    1.519089] SCSI subsystem initialized
[    1.521855] usbcore: registered new interface driver usbfs
[    1.527139] usbcore: registered new interface driver hub
[    1.532418] usbcore: registered new device driver usb
[    1.537459] media: Linux media interface: v0.10
[    1.541915] Linux video capture interface: v2.00
[    1.546514] pps_core: LinuxPPS API ver. 1 registered
[    1.551406] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.560499] PTP clock support registered
[    1.564400] EDAC MC: Ver: 3.0.0
[    1.567658] PLL: shutdown
[    1.570470] zynqmp-ipi ff9905c0.mailbox: Probed ZynqMP IPI Mailbox driver.
[    1.577127] FPGA manager framework
[    1.580411] fpga-region fpga-full: FPGA Region probed
[    1.585427] Advanced Linux Sound Architecture Driver Initialized.
[    1.591683] Bluetooth: Core ver 2.22
[    1.594930] NET: Registered protocol family 31
[    1.599329] Bluetooth: HCI device and connection manager initialized
[    1.605646] Bluetooth: HCI socket layer initialized
[    1.610488] Bluetooth: L2CAP socket layer initialized
[    1.615524] Bluetooth: SCO socket layer initialized
[    1.620992] clocksource: Switched to clocksource arch_sys_counter
[    1.626505] VFS: Disk quotas dquot_6.6.0
[    1.630346] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.641503] NET: Registered protocol family 2
[    1.641902] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[    1.648739] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[    1.655563] TCP: Hash tables configured (established 16384 bind 16384)
[    1.661795] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[    1.667699] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[    1.674210] NET: Registered protocol family 1
[    1.678624] RPC: Registered named UNIX socket transport module.
[    1.684276] RPC: Registered udp transport module.
[    1.688941] RPC: Registered tcp transport module.
[    1.693612] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.700616] hw perfevents: no interrupt-affinity property for /pmu, guessing.
[    1.707463] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    1.715655] audit: initializing netlink subsys (disabled)
[    1.720242] audit: type=2000 audit(1.624:1): state=initialized audit_enabled=0 res=1
[    1.720586] workingset: timestamp_bits=62 max_order=19 bucket_order=0
[    1.734942] NFS: Registering the id_resolver key type
[    1.739311] Key type id_resolver registered
[    1.743437] Key type id_legacy registered
[    1.747421] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    1.754090] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    1.783606] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[    1.785373] io scheduler noop registered
[    1.789248] io scheduler deadline registered
[    1.793497] io scheduler cfq registered (default)
[    1.798156] io scheduler mq-deadline registered
[    1.802653] io scheduler kyber registered
[    1.808177] xilinx-dpdma fd4c0000.dma: Xilinx DPDMA engine is probed
[    1.813408] xilinx-zynqmp-dma fd500000.dma: ZynqMP DMA driver Probe success
[    1.820022] xilinx-zynqmp-dma fd510000.dma: ZynqMP DMA driver Probe success
[    1.826937] xilinx-zynqmp-dma fd520000.dma: ZynqMP DMA driver Probe success
[    1.833861] xilinx-zynqmp-dma fd530000.dma: ZynqMP DMA driver Probe success
[    1.840780] xilinx-zynqmp-dma fd540000.dma: ZynqMP DMA driver Probe success
[    1.847694] xilinx-zynqmp-dma fd550000.dma: ZynqMP DMA driver Probe success
[    1.854624] xilinx-zynqmp-dma fd560000.dma: ZynqMP DMA driver Probe success
[    1.861542] xilinx-zynqmp-dma fd570000.dma: ZynqMP DMA driver Probe success
[    1.868535] xilinx-zynqmp-dma ffa80000.dma: ZynqMP DMA driver Probe success
[    1.875381] xilinx-zynqmp-dma ffa90000.dma: ZynqMP DMA driver Probe success
[    1.882300] xilinx-zynqmp-dma ffaa0000.dma: ZynqMP DMA driver Probe success
[    1.889223] xilinx-zynqmp-dma ffab0000.dma: ZynqMP DMA driver Probe success
[    1.896142] xilinx-zynqmp-dma ffac0000.dma: ZynqMP DMA driver Probe success
[    1.903059] xilinx-zynqmp-dma ffad0000.dma: ZynqMP DMA driver Probe success
[    1.909980] xilinx-zynqmp-dma ffae0000.dma: ZynqMP DMA driver Probe success
[    1.916906] xilinx-zynqmp-dma ffaf0000.dma: ZynqMP DMA driver Probe success
[    1.955458] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    1.958324] a0000000.serial: ttyS3 at MMIO 0xa0001000 (irq = 50, base_baud = 6250000) is a 16550A
[    1.965740] a0010000.serial: ttyS1 at MMIO 0xa0011000 (irq = 51, base_baud = 6250000) is a 16550A
[    1.976523] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    1.984526] brd: module loaded
[    1.988720] loop: module loaded
[    1.989754] mtdoops: mtd device (mtddev=name/number) must be supplied
[    1.994906] libphy: Fixed MDIO Bus: probed
[    1.997861] tun: Universal TUN/TAP device driver, 1.6
[    2.001939] CAN device driver interface
[    2.006527] usbcore: registered new interface driver asix
[    2.010952] usbcore: registered new interface driver ax88179_178a
[    2.016984] usbcore: registered new interface driver cdc_ether
[    2.022760] usbcore: registered new interface driver net1080
[    2.028382] usbcore: registered new interface driver cdc_subset
[    2.034266] usbcore: registered new interface driver zaurus
[    2.039813] usbcore: registered new interface driver cdc_ncm
[    2.045903] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[    2.052258] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    2.058129] ehci-pci: EHCI PCI platform driver
[    2.062821] usbcore: registered new interface driver uas
[    2.067838] usbcore: registered new interface driver usb-storage
[    2.074367] rtc_zynqmp ffa60000.rtc: rtc core: registered ffa60000.rtc as rtc0
[    2.081025] i2c /dev entries driver
[    2.085376] IR NEC protocol handler initialized
[    2.088903] IR RC5(x/sz) protocol handler initialized
[    2.093927] IR RC6 protocol handler initialized
[    2.098423] IR JVC protocol handler initialized
[    2.102920] IR Sony protocol handler initialized
[    2.107505] IR SANYO protocol handler initialized
[    2.112177] IR Sharp protocol handler initialized
[    2.116847] IR MCE Keyboard/mouse protocol handler initialized
[    2.122642] IR XMP protocol handler initialized
[    2.128626] usbcore: registered new interface driver uvcvideo
[    2.132852] USB Video Class driver (1.1.1)
[    2.137952] cdns-wdt fd4d0000.watchdog: Xilinx Watchdog Timer at ffffff800919d000 with timeout 60s
[    2.146011] cdns-wdt ff150000.watchdog: Xilinx Watchdog Timer at ffffff80091a5000 with timeout 10s
[    2.154931] Bluetooth: HCI UART driver ver 2.3
[    2.159151] Bluetooth: HCI UART protocol H4 registered
[    2.164250] Bluetooth: HCI UART protocol BCSP registered
[    2.169549] Bluetooth: HCI UART protocol LL registered
[    2.174630] Bluetooth: HCI UART protocol ATH3K registered
[    2.179993] Bluetooth: HCI UART protocol Three-wire (H5) registered
[    2.186259] Bluetooth: HCI UART protocol Intel registered
[    2.191585] Bluetooth: HCI UART protocol QCA registered
[    2.196811] usbcore: registered new interface driver bcm203x
[    2.202425] usbcore: registered new interface driver bpa10x
[    2.207961] usbcore: registered new interface driver bfusb
[    2.213412] usbcore: registered new interface driver btusb
[    2.218832] Bluetooth: Generic Bluetooth SDIO driver ver 0.1
[    2.224500] usbcore: registered new interface driver ath3k
[    2.230031] EDAC MC: ECC not enabled
[    2.233680] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[    2.246674] sdhci: Secure Digital Host Controller Interface driver
[    2.251704] sdhci: Copyright(c) Pierre Ossman
[    2.256025] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.305001] mmc0: SDHCI controller on ff160000.mmc [ff160000.mmc] using ADMA 64-bit
[    2.313372] ledtrig-cpu: registered to indicate activity on CPUs
[    2.313900] usbcore: registered new interface driver usbhid
[    2.319272] usbhid: USB HID core driver
[    2.325196] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[    2.330918] usbcore: registered new interface driver snd-usb-audio
[    2.336527] pktgen: Packet Generator for packet performance testing. Version: 2.75
[    2.345354] Netfilter messages via NETLINK v0.30.
[    2.347947] ip_tables: (C) 2000-2006 Netfilter Core Team
[    2.353253] Initializing XFRM netlink socket
[    2.357410] NET: Registered protocol family 10
[    2.362184] Segment Routing with IPv6
[    2.365420] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    2.370873] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    2.377018] NET: Registered protocol family 17
[    2.381038] NET: Registered protocol family 15
[    2.385458] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    2.398331] Ebtables v2.0 registered
[    2.401982] can: controller area network core (rev 20170425 abi 9)
[    2.408052] NET: Registered protocol family 29
[    2.412430] can: raw protocol (rev 20170425)
[    2.416667] can: broadcast manager protocol (rev 20170425 t)
[    2.422292] can: netlink gateway (rev 20170425) max_hops=1
[    2.428042] Bluetooth: RFCOMM TTY layer initialized
[    2.432593] Bluetooth: RFCOMM socket layer initialized
[    2.437401] mmc0: new high speed SDHC card at address 5048
[    2.437621] mmcblk0: mmc0:5048 DDINC 14.9 GiB 
[    2.438509]  mmcblk0: p1 p2
[    2.450336] Bluetooth: RFCOMM ver 1.11
[    2.454039] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    2.459311] Bluetooth: BNEP filters: protocol multicast
[    2.464505] Bluetooth: BNEP socket layer initialized
[    2.469433] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    2.475315] Bluetooth: HIDP socket layer initialized
[    2.480451] 9pnet: Installing 9P2000 support
[    2.484502] Key type dns_resolver registered
[    2.489194] registered taskstats version 1
[    2.493158] Btrfs loaded, crc32c=crc32c-generic
[    2.503038] ff000000.serial: ttyPS2 at MMIO 0xff000000 (irq = 40, base_baud = 6249999) is a xuartps
[    2.506620] serial serial0: tty port ttyPS0 registered
�    2.511757] f�&����S�i��k׋��+W/�*LW�Y�X��edf010000 (irq = 41, base_baud = 6249999) is a xuartps
[    2.526079] console [ttyPS0] enabled
[    2.529670] bootconsole [cdns0] disabled
[    2.529670] bootconsole [cdns0] disabled
[    2.538620] xilinx-psgtr fd400000.zynqmp_phy: Lane:1 type:8 protocol:4 pll_locked:yes
[    2.549258] PLL: shutdown
[    2.551960] PLL: shutdown
[    2.555054] PLL: enable
[    2.557591] PLL: shutdown
[    2.561250] PLL: enable
[    2.563774] xilinx-dp-snd-codec fd4a0000.zynqmp-display:zynqmp_dp_snd_codec0: Xilinx DisplayPort Sound Codec probed
[    2.574460] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm0: Xilinx DisplayPort Sound PCM probed
[    2.582495] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm1: Xilinx DisplayPort Sound PCM probed
[    2.590942] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    2.603387] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    2.616122] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: Xilinx DisplayPort Sound Card probed
[    2.626311] OF: graph: no port node found in /amba/zynqmp-display@fd4a0000
[    2.633331] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    2.639939] [drm] No driver support for vblank timestamp query.
[    2.645929] xlnx-drm xlnx-drm.0: bound fd4a0000.zynqmp-display (ops 0xffffff8008b06f68)
[    2.696877] PLL: enable
[    2.824887] Console: switching to colour frame buffer device 240x67
[    2.850218] zynqmp-display fd4a0000.zynqmp-display: fb0:  frame buffer device
[    2.857584] [drm] Initialized xlnx 1.0.0 20130509 for fd4a0000.zynqmp-display on minor 0
[    2.865695] zynqmp-display fd4a0000.zynqmp-display: ZynqMP DisplayPort Subsystem driver probed
[    2.875557] xilinx-psgtr fd400000.zynqmp_phy: Lane:2 type:0 protocol:3 pll_locked:yes
[    2.887140] xilinx-psgtr fd400000.zynqmp_phy: Lane:3 type:1 protocol:3 pll_locked:yes
[    2.897196] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    2.902695] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
[    2.910615] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x22010010
[    2.919357] xhci-hcd xhci-hcd.0.auto: irq 57, io mem 0xfe300000
[    2.925405] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    2.932193] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    2.939410] usb usb1: Product: xHCI Host Controller
[    2.944278] usb usb1: Manufacturer: Linux 4.14.0 xhci-hcd
[    2.949668] usb usb1: SerialNumber: xhci-hcd.0.auto
[    2.954871] hub 1-0:1.0: USB hub found
[    2.958642] hub 1-0:1.0: 1 port detected
[    2.962759] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    2.968245] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
[    2.975939] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[    2.984099] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003
[    2.990882] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    2.998093] usb usb2: Product: xHCI Host Controller
[    3.002963] usb usb2: Manufacturer: Linux 4.14.0 xhci-hcd
[    3.008352] usb usb2: SerialNumber: xhci-hcd.0.auto
[    3.013476] hub 2-0:1.0: USB hub found
[    3.017236] hub 2-0:1.0: 1 port detected
[    3.022992] i2c i2c-0: Added multiplexed i2c bus 2
[    3.027930] i2c i2c-0: Added multiplexed i2c bus 3
[    3.032859] i2c i2c-0: Added multiplexed i2c bus 4
[    3.037779] i2c i2c-0: Added multiplexed i2c bus 5
[    3.043288] tps65086 6-005e: Failed to read revision register
[    3.049146] i2c i2c-0: Added multiplexed i2c bus 6
[    3.054559] ina2xx 7-0040: error configuring the device: -6
[    3.060172] i2c i2c-0: Added multiplexed i2c bus 7
[    3.065116] i2c i2c-0: Added multiplexed i2c bus 8
[    3.070053] i2c i2c-0: Added multiplexed i2c bus 9
[    3.074839] pca954x 0-0075: registered 8 multiplexed busses for I2C switch pca9548
[    3.082442] i2c i2c-0: Failed to register i2c client pca9548 at 0x75 (-16)
[    3.089313] i2c i2c-0: of_i2c: Failure registering /amba/i2c@ff030000/i2cswitch@75
[    3.096872] i2c i2c-0: Failed to create I2C device for /amba/i2c@ff030000/i2cswitch@75
[    3.104788] cdns-i2c ff030000.i2c: 100 kHz mmio ff030000 irq 31
[    3.112548] sdhci-arasan ff170000.mmc: allocated mmc-pwrseq
[    3.180995] mmc1: SDHCI controller on ff170000.mmc [ff170000.mmc] using ADMA 64-bit
[    3.196172] input: gpio-keys as /devices/platform/gpio-keys/input/input0
[    3.203170] rtc_zynqmp ffa60000.rtc: setting system clock to 2019-05-30 18:36:04 UTC (1559241364)
[    3.212036] of_cfs_init
[    3.214503] of_cfs_init: OK
[    3.217426] clk: Not disabling unused clocks
[    3.221919] ALSA device list:
[    3.224869]   #0: DisplayPort monitor
[    3.232383] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[    3.243669] mmc1: new high speed SDIO card at address 0001
[    3.254491] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    3.262601] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    3.271064] devtmpfs: mounted
[    3.274259] Freeing unused kernel memory: 512K
[    3.357133] usb 2-1: new SuperSpeed USB device number 2 using xhci-hcd
INIT: version 2.88 booting[    3.381658] usb 2-1: New USB device found, idVendor=0424, idProduct=5744
[    3.389694] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=0
[    3.396823] usb 2-1: Product: USB5744
[    3.400477] usb 2-1: Manufacturer: Microchip Tech
[    3.408097] hub 2-1:1.0: USB hub found
[    3.411878] hub 2-1:1.0: 3 ports detected

[    3.509027] usb 1-1: new high-speed USB device number 2 using xhci-hcd
Starting udev
[    3.661514] usb 1-1: New USB device found, idVendor=0424, idProduct=2744
[    3.668219] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    3.675352] usb 1-1: Product: USB2744
[    3.679014] usb 1-1: Manufacturer: Microchip Tech
[    3.712104] hub 1-1:1.0: USB hub found
[    3.715905] hub 1-1:1.0: 4 ports detected
[    3.821058] udevd[1795]: starting version 3.2.2
[    3.891834] udevd[1796]: starting eudev-3.2.2
[    4.021435] mali: loading out-of-tree module taints kernel.
[    4.029076] usb 1-1.4: new high-speed USB device number 3 using xhci-hcd
[    4.039646] zynqmp_r5_remoteproc ff9a0100.zynqmp_r5_rproc: RPU core_conf: split0
[    4.053725] remoteproc remoteproc0: ff9a0100.zynqmp_r5_rproc is available
[    4.141785] usb 1-1.4: New USB device found, idVendor=0424, idProduct=2740
[    4.148673] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    4.156049] usb 1-1.4: Product: Hub Controller
[    4.160556] usb 1-1.4: Manufacturer: Microchip Tech
[    4.669390] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
Starting internet superserver: inetd.
Starting Ultra96 AP setup daemon.
Starting Ultra96 Power Button daemon.
Starting Flask server deamon to serve Ultra96 startup pagelibmraa[2087]: libmraa version v1.7.0 initialised by user 'root' with EUID 0
libmraa[2087]: libmraa initialised for platform 'ULTRA96' of type 9
.
INIT: Entering runlevel: 5
Configuring network interfaces... Successfully initialized wpa_supplicant
rfkill: Cannot get wiphy information
Could not read interface wlan0 flags: No such device
WEXT: Could not set interface 'wlan0' UP
wlan0: Failed to initialize driver interface
Cannot find device "wlan0"
Cannot find device "eth0"
Starting system message bus: dbus.
Starting Xserver
[    5.753042] Bluetooth: hci0 command 0x1001 tx timeout
Starting Dropbear SSH server: dropbear.

Starting rpcbind daemon...done.
Starting watchdog: 

starting statd: 
X.Org X Server 1.19.3
Release Date: 2017-03-15
X Protocol Version 11, Revision 0
Build Operating System: Linux 3.10.0-327.el7.x86_64 x86_64 
Current Operating System: Linux ultra96v2-oob-2018-3 4.14.0 #1 SMP Thu May 30 17:57:52 UTC 2019 aarch64
Kernel command line: earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait
Build Date: 03 December 2018  09:43:45PM
 
Current version of pixman: 0.34.0
    Before reporting problems, check http://wiki.x.org
    to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
    (++) from command line, (!!) notice, (II) informational,
    (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.0.log", Time: Thu May 30 18:36:06 2019
(==) Using config file: "/etc/X11/xorg.conf"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
done
Starting bluetooth: bluetoothd.
Starting Distributed Compiler Daemon: distcc.
exportfs: can't open /etc/exports for reading
NFS daemon support not enabled in kernel
Starting ntpd: done
Starting syslogd/klogd: done
Starting internet superserver: xinetd.
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
Starting Telephony daemon
Starting Linux NFC daemon
Starting tcf-agent: OK

PetaLinux 2018.3 ultra96v2-oob-2018-3 /dev/ttyPS0

ultra96v2-oob-2018-3 login: D-BUS per-session daemon address is: unix:abstract=/tmp/dbus-wP8PRsM4ri,guid=a789e71a1415eb0714d53bf05cf02297
Opening webpage
Error: No calibratable devices found.
GLib-GIO-Message: Using the 'memory' GSettings backend.  Your settings will not be saved or shared with other applications.
matchbox: Cant find a keycode for keysym 269025056
matchbox: ignoring key shortcut XF86Calendar=!$contacts

matchbox: Cant find a keycode for keysym 2809
matchbox: ignoring key shortcut telephone=!$dates

matchbox: Cant find a keycode for keysym 269025050
matchbox: ignoring key shortcut XF86Start=!matchbox-remote -desktop

Activating service name='org.a11y.atspi.Registry'
Successfully activated service 'org.a11y.atspi.Registry'
SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry
[settings daemon] Forking. run with -n to prevent fork

** (matchbox-panel:2308): WARNING **: Failed to load applet "battery" (/usr/lib/matchbox-panel/libbattery.so: cannot open shared object file: No such file or directory).
[   13.881014] Bluetooth: hci0: Reading TI version information failed (-110)
[   13.887809] Bluetooth: hci0: download firmware failed, retrying...
[2502:2502:0530/183616:ERROR:gl_factory.cc(48)] Requested GL implementation is not available.
[2502:2502:0530/183616:ERROR:gpu_child_thread.cc(348)] Exiting GPU process due to errors during initialization
[   16.441071] Bluetooth: hci0 command 0x1001 tx timeout
[2290:2427:0530/183618:ERROR:browser_gpu_channel_host_factory.cc(123)] Failed to launch GPU process.
[2290:2427:0530/183618:ERROR:browser_gpu_channel_host_factory.cc(123)] Failed to launch GPU process.
[   18.236493] random: crng init done
[   24.633008] Bluetooth: hci0: Reading TI version information failed (-110)
[   24.639804] Bluetooth: hci0: download firmware failed, retrying...
[   27.193052] Bluetooth: hci0 command 0x1001 tx timeout
[   35.385009] Bluetooth: hci0: Reading TI version information failed (-110)
[   35.391809] Bluetooth: hci0: download firmware failed, retrying...
[   37.944997] Bluetooth: hci0 command 0x1001 tx timeout
[   46.137013] Bluetooth: hci0: Reading TI version information failed (-110)
[   46.143811] Bluetooth: hci0: download firmware failed, retrying...

PetaLinux 2018.3 ultra96v2-oob-2018-3 /dev/ttyPS0

ultra96v2-oob-2018-3 login: root
Password: 
root@ultra96v2-oob-2018-3:~# ls
ble.sh  bt.sh  wifi.sh  wpa_supplicant.conf
root@ultra96v2-oob-2018-3:~# 

  1. 2019年08月05日 05:23 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Adam Taylerさんの”MicroZed Chronicles: DisplayPort Controller — Part One”をやってみた1

Adam Taylerさんの”MicroZed Chronicles: DisplayPort Controller — Part One”をやってみた。

これは、Ultra96V2 のDisplayPort をベアメタル・アプリケーションで表示するという記事だった。プロジェクトのあるGitHub はAdam Tayler さんから直々にツィッターで教えてもらった。”MicroZed Chronicles: DisplayPort Controller — Part One”のGitHub

GitHub からダウンロードしたVivado 2018.3 プロジェクトを示す。
Adam_Tayler_BM_DP_1_190804.png

Vivado プロジェクトからSDK を起動して、FPGA をコンフィギュレーションして、dispport.elf を起動してみたがDisplayPort に表示されなかった。これは、Vivado でコンパイルして、それを反映したのではなく、ダウンロードしたそのままの状態のSDK で行っている。
Adam_Tayler_BM_DP_2_190804.png

使用しているのはUbuntu 18.04 上のVivado 2018.3 だ。
当初、mini DisplayPort - VGA 変換器が良くないのか?と思い、ツィッターで表示できたと教えてもらったmini DisplayPort - HDMI 変換器を買ってみたが同様に表示できなかった。

これは、ディスプレイかもしくは、Ultra96V2 本体がまずいのか?まずは、Micro SD カードにLinux を書いてみて起動を確かめてみよう。
  1. 2019年08月04日 07:01 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96 MIPI拡張ボードに接続したPcam5C の画像をDisplayPort に表示する12(Vivado Analyzerでデバック)

Ultra96 MIPI拡張ボードに接続したPcam5C の画像をDisplayPort に表示する11(アプリケーションで動作確認)”の続き。

前回は、アプリケーション・ソフトを作成して、回路を動作させてみようということで、DisplayPort に画像を出力することができなかった。今回は、動かないのが悔しいので、Vivado Analyzer を入れてどうなっているのか?を調査してみたい。

まずは、axis2video_out_0 の周りにDebug を設定した。
MIPI_DP_84_190803.png

MIPI_DP_82_190803.png

これで、論理合成、インプリメンテーション、ビットストリームの生成を行って、fpga_dp.bin に変換した。そのfpga_dp.bin をUltra96 のDebian にSFTP で送って、/lib/firmware/ にコピーした。
sudo ./init_camera.sh
で、デバイスツリーをロードして、Vivado Analyzer を立ち上げ、ip_start の立ち上がりでトリガをかけて、
sudo ./pcam5c_disp_dp
を起動した。
これで、ip_start が 0 から 1 になったはず。
Vivado Analyzer を見た。
MIPI_DP_77_190803.png

display_gpio_io_o が 1 になった時に、init_done が 1 となり、axis2video_out_0 の ip_start が 1 になる。これで、disp_dmar_axis_vga の AXI4 Master Read が始まるはずが始まらない?

video_de 、 vsync、hsync は問題なく出ているようだ。
MIPI_DP_78_190803.png

MIPI_DP_79_190803.png

disp_pixel の値はずっと 0 だった。
MIPI_DP_80_190803.png

ip_start はずっと 1 だった。
MIPI_DP_81_190803.png

かなり謎だが、もう一度、Vivado HLS を確認してみようか?
  1. 2019年08月03日 06:58 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96V2 が届いた

昨日、Ultra96V2 が届いた。

Ultra96V2 の箱。
Ultra96V2_1_190801.jpg

Ultra96V2 の基板。
Ultra96V2_2_190801.jpg

Ultra96V1 とUltra96V2 を並べてみた。
Ultra96V2_3_190801.jpg

すぐに気がつく違いは、スイッチが青になって、位置が変わったのと、無線LAN、Bluetooth モジュールが変更になっている。
Ultra96V2 では、電源IC も上に付いているのかな?
  1. 2019年08月01日 05:24 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:3