FC2カウンター FPGAの部屋 FPGA+SoC+Linux実践勉強会での課題をやってみた7(dma_pow2 IP のドライバを使用したアプリケーション)
FC2ブログ

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

FPGAの部屋

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

FPGA+SoC+Linux実践勉強会での課題をやってみた7(dma_pow2 IP のドライバを使用したアプリケーション)

前回は、Vivado HLS 2017.3 で作成した 2 乗倍するDMAIP をVivado 2017.3 のブロック・デザインでインスタンスして構成した回路で Device Tree Overlay でデバイスツリー・オーバーレイで、 FPGA Region を使用して、ビット・ファイルをコンフィギュレーションした。今回は、それに加えて udmabuf を実装し、udmabuf を使用し、更にアプリケーションソフト test_dma.c を書いて、dma_pow2 IP を動作させた。今回はその続きで、前回の test_dma.c を dma_pow2 IP のドライバを使用するコードに書きなおす。それを test_dma_wd.c とする。そして、Makefile も書いて make し、動作させてみる。

dma_pow2 IP のドライバを使用したアプリケーションソフト test_dma_wd.c を作成してテストする。
まずは、dma_pow2 IP のドライバをZYBO Z7 上のDebian に dma_pow2_drivers というディレクトリを作成してアップロードした。
FPGA-SoC-Linux4ZYBO_Z7_76_171214.png

test_dma_wd.c を作成した。test_dma_wd.c を示す。

// test_dma_wd.c
// test_dma with drivers
// 2017/12/14 by marsee
//

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

#include "xdma_pow2.h"

int main(){
    int fd1, fd2;
    
    XDma_pow2 xdma_ap;
    int Xdma_status;
    volatile unsigned int *cma_buffer;
    
    char  attr[1024];
    unsigned long  phys_addr;
    int i;
    
    // Initialize the Device
    Xdma_status = XDma_pow2_Initialize(&xdma_ap, "dma_pow2");
    if (Xdma_status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDma_pow2\n");
        return(-1);
    }
    
    // udmabuf0
    fd1 = open("/dev/udmabuf0", O_RDWR); // frame_buffer, The chache is enabled. 
    if (fd1 == -1){
        fprintf(stderr, "/dev/udmabuf0 open error\n");
        exit(-1);
    }
    cma_buffer = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!cma_buffer){
        fprintf(stderr, "cma_buffer mmap error\n");
        exit(-1);
    }
    
    // phys_addr of udmabuf0
    fd2 = open("/sys/class/udmabuf/udmabuf0/phys_addr", O_RDONLY);
    if (fd2 == -1){
        fprintf(stderr, "/sys/class/udmabuf/udmabuf0/phys_addr open error\n");
        exit(-1);
    }
    read(fd2, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd2);
    printf("phys_addr = %x\n", (int)phys_addr);

    XDma_pow2_Set_in_r(&xdma_ap, phys_addr);
    XDma_pow2_Set_out_r(&xdma_ap, phys_addr+sizeof(int)*10);
    
    for(i=0; i<10; i++)
        cma_buffer[i] = i;

    XDma_pow2_Start(&xdma_ap);
    
    while(!XDma_pow2_IsDone(&xdma_ap)) ;
    
    printf("in[] =  ");
    for(i=0; i<10; i++)
        printf("%2d ", cma_buffer[i]);
    printf("\n");
    
    printf("out[] = ");
    for(i=10; i<20; i++)
        printf("%2d ", cma_buffer[i]);
    printf("\n");
    
    munmap((void *)cma_buffer, 0x10000);
    close(fd1);
    
    return(0);
}


Makefile も作成した。貼っておく。

# Makefile(test_dma_wd.c)
# Referred to http://www.ie.u-ryukyu.ac.jp/~e085739/c.makefile.tuts.html

PROGRAM = test_dma_wd
OBJS = test_dma_wd.o xdma_pow2.o xdma_pow2_linux.o

CC = gcc
CFLAGS = -Wall -O2

.SUFFIXES: .c .o

.PHONY: all

all: test_dma_wd

test_dma_wd: $(OBJS)
    $(CC) -Wall -o $@ $(OBJS)
    
.c.o:
    $(CC) $(CFLAGS) -c $<

    
.PHONY: clean
clean:
    $(RM) $(PROGRAM) $(OBJS)


ここまでできたので、make し、./dma_pow2_wd で実行した。
FPGA-SoC-Linux4ZYBO_Z7_77_171214.png

前回同様に、in[] を 2乗した値が out[] に出力されているのが分かる。こちらも成功だ。
  1. 2017年12月14日 05:02 |
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/4003-9a442a3a
この記事にトラックバックする(FC2ブログユーザー)