FPGA+SoC+Linux 실습 공부회에 참가하여 Arty-Z7에서 L치카를 한 이야기

요 전날 여기의 이벤트에 참가해, L치카를 했으므로 그쪽의 작업 기록입니다.
사실은 인터럽트+DMA까지 하고 싶었습니다만, 시간이 부족했기 때문에 그쪽은 겨울방학의 숙제로 하고 싶습니다.
FPGA 보드는 Arty-Z7에서 했지만 다른 것도 괜찮다고 생각합니다.
환경은 Vivado 2017.3(Windows10)입니다.

FPGA 보드에서 실행되는 Linux 환경이 들어있는 microSD 만들기



@ikwzmFPGA + SoC + Linux + Device Tree Overlay + FPGA Region (부팅 이미지 제공)
Arty-Z7은 리스트에 없습니다만, ZYBO의 것을 사용해 보았더니 문제 없게(?) 일어났으므로, 우선 이대로 사용합니다.

비트 스트림 (FPGA 구성 데이터) 생성



Digilent 님의 자습서 기사 에 따라 Zynq+GPIO(범용 입출력) 디자인을 작성합니다.
미리 자신이 가지고있는 FPGA 보드의 보드 파일을 vivado 폴더에 보관 필요합니다.
이번에는 SDK를 사용하지 않으므로 6.Generate the Bitstream까지 가면 OK입니다.
프로젝트 폴더의 <프로젝트 이름>.runs\impl_1.bit이라는 폴더에 비트 스트림이 생성되었습니다.
이제 생성 된 디자인의 블록 디자인의 주소 편집기를보고 GPIO 모듈의 기본 주소를 확인합니다.



이 예에서 GPIO_0은 0x4120_0000이고 GPIO_1은 0x4121_0000입니다.


생성 된 FPGA 바이너리를 디바이스 트리를 통해 읽습니다.



Zynq 보드를 Teraterm 등으로 연결하고 fpga 사용자로 로그인. 비밀번호는 fpga.
debian-fpga login: fpga
Password:
Last login: Fri Nov  4 02:17:08 JST 2016 on ttyPS0
Linux debian-fpga 4.12.14-armv7-fpga #3 SMP PREEMPT Mon Nov 13 15:14:45 JST 2017 armv7l

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:~$

샘플을 가져옵니다. 가져오는 것은 examples/uio_irq_sample.
fpga@debian-fpga:~$ cp examples/uio_irq_sample/ ~/my_uio_sample -r
fpga@debian-fpga:~$ cd my_uio_sample
fpga@debian-fpga:~/my_uio_sample$ ls -l
total 1648
-rw-r--r-- 1 fpga fpga    2958 Dec  3 09:31 Rakefile
-rw-r--r-- 1 fpga fpga     647 Dec  3 09:31 devicetree.dts
-rw-r--r-- 1 fpga fpga 4045564 Dec  3 09:31 pump_axi4.bin
-rw-r--r-- 1 fpga fpga    2541 Dec  3 09:31 sample1.c
-rw-r--r-- 1 fpga fpga    2746 Dec  3 09:31 sample2.c
-rw-r--r-- 1 fpga fpga    5844 Dec  3 09:31 sample_common.h
drwxr-xr-x 2 fpga fpga    4096 Dec  3 09:31 uio_irq_sample

여기에 방금 생성한 비트 스트림을 복사합니다.
자신은 Zynq 보드에 이더넷으로 연결하여 SCP를 통해 파일을 전송했습니다.
그러나 자일링스에서 생성 된 비트 스트림은 그대로 사용할 수 없으므로 변환해야합니다.
참고 : Linux FPGA Manager에서 자일링스 비트 스트림 파일을 처리하는 방법

wget으로 파이썬 스크립트를 가져와서 변환합니다.
다음 예제에서는 system_wrapper.bit라는 파일에서 arty_gpio.bin으로 변환합니다.
--flip이라는 옵션이 키모입니다.
fpga@debian-fpga:~/my_uio_sample$ wget https://raw.githubusercontent.com/topic-embedded-products/meta-topic/master/recipes-bsp/fpga/fpga-bit-to-bin/fpga-bit-to-bin.py
--2017-12-03 09:41:38--  https://raw.githubusercontent.com/topic-embedded-products/meta-topic/master/recipes-bsp/fpga/fpga-bit-to-bin/fpga-bit-to-bin.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.72.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.72.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2964 (2.9K) [text/plain]
Saving to: 'fpga-bit-to-bin.py'

fpga-bit-to-bin.py  100%[===================>]   2.89K  --.-KB/s    in 0.001s  

2017-12-03 09:41:38 (4.42 MB/s) - 'fpga-bit-to-bin.py' saved [2964/2964]

fpga@debian-fpga:~/my_uio_sample$ python fpga-bit-to-bin.py --flip system_wrapper.bit arty_gpio.bin
Design name: system_wrapper;UserID=0XFFFFFFFF;Version=2017.3
Full bitstream
('Partname', '7z020clg400\x00')
('Date', '2017/11/11\x00')
('Time', '17:46:53\x00')
Found binary data: 4045564
Flipping data...
Writing data...
fpga@debian-fpga:~/my_uio_sample$ 

devicetree.dts를 수정합니다.

devicetree.dts
/dts-v1/;
/ {
        fragment@0 {
                target-path = "/amba/fpga-region0";
                #address-cells = <0x1>;
                #size-cells = <0x1>;

                __overlay__ {
                        #address-cells = <0x1>;
                        #size-cells = <0x1>;

                        firmware-name = "arty_gpio.bin";      #Vivadoで生成して変換したbinファイルにする

                        pump-uio@41210000 {                   #VivadoのOffsetにする
                                compatible = "generic-uio";
                                reg = <0x41210000 0x10000>;   #VivadoのOffsetとRangeにする。LEDはGPIO1に接続されている。
                                #interrupts = <0x0 0x1d 0x4>; #割り込みは使用しない
                        };

                        pump-udmabuf4 {
                                compatible  = "ikwzm,udmabuf-0.10.a";
                                device-name = "udmabuf4";
                                size = <0x00400000>;
                        };

                        pump-udmabuf5 {
                                compatible = "ikwzm,udmabuf-0.10.a";
                                device-name = "udmabuf5";
                                size = <0x00400000>;
                        };
                };
        } ;
} ;

Rakefile을 수정합니다.
FPGA_BITSTREAM_FILE 만 변경하면 우선 괜찮습니다.

Rakefile
CC                     = "gcc"
CFLAGS                 = ""
FPGA_BITSTREAM_FILE    = "arty_gpio.bin" #ここを先ほど生成したbinにする
DEVICE_TREE_DIRECTORY  = "uio_irq_sample"
DEVICE_TREE_FILE       = "devicetree.dts"
UIO_DEVICE_NAME        = "uio0"
UDMABUF4_DEVICE_NAME   = "udmabuf4"
UDMABUF5_DEVICE_NAME   = "udmabuf5"

그리고 sudo rake install을 하면 생성한 FPGA 컨피그가 로드되는 것 같습니다.
fpga@debian-fpga:~/my_uio_sample$ sudo rake install
sudo: unable to resolve host debian-fpga
[sudo] password for fpga:
cp arty_gpio.bin /lib/firmware/arty_gpio.bin
dtbocfg.rb --install uio_irq_sample --dts devicetree.dts
/config/device-tree/overlays/uio_irq_sample/dtbo: Warning (unit_a[   29.758004] fpga_manager fpga0: writing arty_gpio.bin to Xilinx Zynq FPGA Manager
ddress_vs_reg): Node /fragment@0 has a unit name, but no reg property
[   29.837519] udmabuf amba:fpga-region0:pump-udmabuf4: driver probe start.
[   29.861480] udmabuf udmabuf4: driver installed
[   29.865845] udmabuf udmabuf4: major number   = 245
[   29.872518] udmabuf udmabuf4: minor number   = 0
[   29.877058] udmabuf udmabuf4: phys address   = 0x1f100000
[   29.884086] udmabuf udmabuf4: buffer size    = 4194304
[   29.890086] udmabuf amba:fpga-region0:pump-udmabuf4: driver installed.
[   29.897096] udmabuf amba:fpga-region0:pump-udmabuf5: driver probe start.
[   29.920640] udmabuf udmabuf5: driver installed
[   29.925008] udmabuf udmabuf5: major number   = 245
[   29.931676] udmabuf udmabuf5: minor number   = 1
[   29.936213] udmabuf udmabuf5: phys address   = 0x1f500000
[   29.943232] udmabuf udmabuf5: buffer size    = 4194304
[   29.949204] udmabuf amba:fpga-region0:pump-udmabuf5: driver installed.
fpga@debian-fpga:~/my_uio_sample$


샘플 프로그램 작성



자일링스 AXI_GPIO 사양 을 보면서 프로그램을 작성합니다.
라고, 좋은 동안 실제로는 같은 팀으로부터 소스를 받았습니다(웃음)
공부회 페이지 자료에 첨부된 pdf 6p 참조
참고 : h tp // w w. 원래. rg/오미/tmp/Zynq-L-치치. pdf

led.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <assert.h>
#include <sys/mman.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int  fd;
    char *p;
    fd = open("/dev/uio0", O_RDWR);
    p = mmap(NULL, 4096, (PROT_READ|PROT_WRITE), MAP_SHARED, fd, 0);
    *(p + 4) = 0; // Set tristate register to output mode.
    while (1) {
        *p = 0; // LED OFF
        sleep(1);
        *p = 0xff; // LED ON
        sleep(1);
    }
}

컴파일하고 실행



Zynq 보드에서 컴파일하고 실행합니다.
안전 L 치카했습니다.
fpga@debian-fpga:~/my_uio_sample$ gcc -o led led.c
fpga@debian-fpga:~/my_uio_sample$ ./led

좋은 웹페이지 즐겨찾기