我参加了FPGA+SoC+Linux实践学习班,在Arty-Z7上进行了闪烁的实验

我是前几天参加了这个活动并且进行了L闪烁的,所以这是关于那个工作记录。
本来我想做中断+DMA,但是时间不够,所以我准备把它留到寒假作业。
我使用的FPGA板是Arty-Z7,但我认为其他板子也可以用。
环境是Vivado 2017.3(Windows10)。

制作一个带有Linux环境的microSD卡,可以在FPGA开发板上运行。

我将执行@ikwzmさん的FPGA+SoC+Linux+Device Tree Overlay+FPGA Region(提供引导镜像)的操作,准备一份在FPGA板上运行的Linux。
虽然Arty-Z7不在列表中,但是我尝试使用ZYBO的版本并成功地启动了(?), 所以就先用这个版本吧。

生成bit流(FPGA配置数据)

按照Digilent公司的教程,我们将创建一个Zynq+GPIO(通用输入输出)的设计。
在开始之前,您需要将您现有的FPGA板的板文件放入vivado的文件夹中。
由于我们本次不使用SDK,完成到第6步“生成比特流”后即可。
比特流将生成在项目文件夹的<项目名称>.runs\impl_1<顶层模块名称>.bit文件夹中。
在这里,您可以查看已生成设计的块设计地址编辑器,并确认GPIO模块的基础地址。

image.png
image.png

通过设备树将生成的FPGA二进制文件加载进去。

使用Teraterm等连接到Zynq板,并使用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传输文件。
然而,由Xilinx生成的位流不能直接使用,需要进行转换。
参考:使用Linux的FPGA管理器处理Xilinx位流文件的方法。

使用wget命令从网上获取Python脚本,并进行转换。
以下示例中,将从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文件。

/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>;
                        };
                };
        } ;
} ;

只需更改FPGA_BITSTREAM_FILE,其他的暂时都没问题。

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$

写一个示例程序

我将编写程序时查看Xilinx AXI_GPIO规范书,实际上是从同一团队的成员那里接收到了源代码(笑)。请参考学习会页面附带的PDF文档的第6页。参考链接:http://www.motohashi.org/omi/tmp/Zynq-L-chika.pdf

#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
广告
将在 10 秒后关闭
bannerAds