使用Debian GNU/Linux(v2017.3版)为UltraZed配置FPGA
首先
在下面的文章中,我構建了適用於 UltraZed 的 Debian GNU/Linux (v2017.3 版)。
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(イントロ編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Boot Loader編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Linux Kernel編)」@Qiita
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Debian9 Root File System編)」@Qiita
另外,在下一篇文章中,我們將介紹上一篇文章中建立的系統的概念。
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) ブートイメージの提供」@Qiita
在本文中,我们将使用上一篇文章中构建的系统来展示一个从Linux配置FPGA的实例。本文介绍的FPGA设计和程序已经在以下网址上公开。
- https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed
示例 FPGA 设计
这次 FPG 进行配置的电路将使用在下一篇文章中进行解释的那个。
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Sample FPGA Design編)」@Qiita
设计的框图如下所示。
图1:ZynqMP样例设计
准备梁祝電影的拍攝工作
准备UltraZed
请根据以下文章的参考步骤,将 Debian GNU/Linux (v2017.3 版) 安装到 UltraZed 设备上。
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) ブートイメージの提供」@Qiita
用FPGA登录
当Linux启动后,我们使用用户名为fpga进行登录。密码设置为fpga。
debian-fpga login: fpga
Password:
fpga@debian-fpga:~$
下载存储库
从下面的URL下载样本FPGA设计和程序。
- https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed
在这里,我们将 v2017.3 版本下载为 examples/gpio。
fpga@debian-fpga:~$ mkdir examples
fpga@debian-fpga:~$ cd examples
fpga@debian-fpga:~/examples$ git clone -b v2017.3 https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed gpio
fpga@debian-fpga:~/examples$ cd gpio
fpga@debian-fpga:~/examples/gpio$ git checkout v2017.3
FPGA的配置
将文件转换为二进制文件
本次構建的Debian GNU/Linux中已经集成了FPGA Reagion。不幸的是,根据下一篇文章的内容,FPGA Regsion和FPGA Manager的组合无法直接读取Xilinx的位流。因此,首先需要将位流文件进行转换。
- 「Linux の FPGA Manager で Xilinx のビットストリームファイルを扱う方法」@Qiita
fpga@debian-fpga:~/examples/gpio$ python3 fpga-bit-to-bin.py -f design_1_wrapper.bit design_1_wrapper.bin
Design name: b'design_1_wrapper;UserID=0XFFFFFFFF;Version=2017.2.1\x00'
Full bitstream
Partname b'xczu3eg-sfva625-1-i\x00'
Date b'2017/12/24\x00'
Time b'10:39:58\x00'
Found binary data: 5568668
Flipping data...
Writing data...
将二进制文件复制到/lib/firmware目录下。
在FPGA区域中,需要将配置文件放置在/lib/firmware文件夹中进行配置。
fpga@debian-fpga:~/examples/gpio$ sudo cp design_1_wrapper.bin /lib/firmware
通过设备树覆盖进行 FPGA 配置。
FPGA区域使用设备树来配置FPGA。因此,需要准备以下用于设备树叠加的源文件。
/dts-v1/;
/ {
fragment@0 {
target-path = "/fpga-full";
__overlay__ {
firmware-name = "design_1_wrapper.bin";
};
};
};
请注意目标路径是 “/fpga-full”。这是根据在Linux启动时加载的设备树中指定的fpga-region符号名。
以下是使用Device Tree Overlay进行FPGA配置的步骤:
-
- 使用源文件(在这里是fpga-load.dts),通过设备树编译器(dtc)将其转换为设备树二进制文件(dtb)。
-
- 在/config/device-tree/overlays目录下创建用于设备树叠加的目录(在这里是fpga)。
- 将第1步创建的dtb写入第2步创建的目录中的dtbo文件中。
如果看到以下类似的内核消息,那么 FPGA 的配置就成功了。
fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/fpga
fpga@debian-fpga:~/examples/gpio$ sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo
[ 1462.560122] fpga_manager fpga0: writing design_1_wrapper.bin to Xilinx ZynqMP FPGA Manager
FPGA 的时钟设置
只是配置 FPGAs 并不能使 FPGA 上的电路工作。因为时钟供应至 FPGA 的设置还未完成。
在这里,我们使用 fclkcfg 来设置时钟。fclkcfg 是作者开发的设备驱动程序,并在以下网址中公开。
- https://github.com/ikwzm/fclkcfg
如果已经安装了适用于UltraZed的Debian GNU/Linux引导映像,则fclkcfg已经被集成进去了。
要设置时钟,需要准备以下用于Device Tree Overlay的源文件。
/dts-v1/;/plugin/;
/ {
fragment@0 {
target-path = "/amba";
__overlay__ {
fclk0 {
compatible = "ikwzm,fclkcfg-0.10.a";
clocks = <&clkc 0x47>;
insert-rate = "100000000";
insert-enable = <1>;
remove-rate = "1000000";
remove-enable = <0>;
};
};
};
};
在这里,我们使用 clocks 来指定 ZynqMP的PL CLOCK[0]。&clkc是时钟控制驱动程序的符号名称,0x47是PL CLOCK[0]的索引号。当插入该设备树时,PL CLOCK[0]被设置为输出100MHz频率的时钟。
请按照以下步骤使用设备树叠加来设置时钟。
-
- 使用源文件(这里是fclk0-zynqmp.dts)通过dtc(Device Tree Compiler)将其转换为dtb(这里是fclk0-zynqmp.dtb)的设备树覆盖。
-
- 在/config/device-tree/overlays目录下创建用于设备树覆盖的目录(这里是fclk0)。
- 将第1步生成的dtb写入到第2步创建的目录下的dtbo文件中。
如果看到以下这样的内核消息,则FPGA 时钟设置成功。
fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/fclk0
fpga@debian-fpga:~/examples/gpio$ sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo
[ 1830.238976] fclkcfg amba:fclk0: driver installed.
[ 1830.243617] fclkcfg amba:fclk0: device name : fclk0
[ 1830.248737] fclkcfg amba:fclk0: clock name : pl0
[ 1830.253678] fclkcfg amba:fclk0: clock rate : 99999999
[ 1830.259085] fclkcfg amba:fclk0: clock enabled : 1
[ 1830.263833] fclkcfg amba:fclk0: remove rate : 1000000
[ 1830.269125] fclkcfg amba:fclk0: remove enable : 0
Uio的准备。
要访问通过FPGA配置的电路,需要使用UIO。为了使用UIO,需要准备下面这样的设备树覆盖源文件。
/dts-v1/;
/ {
fragment@0 {
target-path = "/amba_pl@0";
#address-cells = <2>;
#size-cells = <2>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
uio0: uio@80000000 {
compatible = "generic-uio";
reg = <0x0 0x80000000 0x0 0x10000>;
};
uio1: uio@80010000 {
compatible = "generic-uio";
reg = <0x0 0x80010000 0x0 0x10000>;
};
uio2: uio@80020000 {
compatible = "generic-uio";
reg = <0x0 0x80020000 0x0 0x10000>;
};
};
} ;
} ;
与Zynq不同,有一些注意事项。
-
- 将目标路径设置为”/amba_pl@0″。
- 地址单元和大小单元都为2。这是因为ZynqMp地址的位宽为64位。因此,在reg中以<地址的高32位 地址的低32位 大小的高32位 大小的低32位>的形式进行指定。
使用Device Tree Overlay按以下步骤配置Uio。
-
- 将设备树覆盖用的源代码文件(这里是 uio.dts)通过设备树编译器(dtc)转换为设备树二进制文件(这里是uio.dtb)。
-
- 在/config/device-tree/overlays目录下创建一个用于设备树覆盖的目录(这里是uio)。
- 将步骤2中创建的目录下的dtbo文件中写入步骤1中创建的dtb文件。
如果能够得到以下结果:/dev/uio0、/dev/uio1、/dev/uio2,则表示成功。
fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o uio.dtb uio.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/uio
fpga@debian-fpga:~/examples/gpio$ sudo cp uio.dtb /config/device-tree/overlays/uio/dtbo
fpga@debian-fpga:~/examples/gpio$ ls -la /dev/uio*
crw------- 1 root root 245, 0 Dec 31 10:20 /dev/uio0
crw------- 1 root root 245, 1 Dec 31 10:20 /dev/uio1
crw------- 1 root root 245, 2 Dec 31 10:20 /dev/uio2
尝试让LED灯闪烁
我准备了一个如下的Python程序。
from uio import Uio
import numpy as np
import time
import signal
class LED:
def __init__(self):
self.uio = Uio('uio1')
self.regs = self.uio.regs()
self.regs.write_word(4, 0)
self.pattern = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02]
self.index = 0
def run(self):
self.regs.write_word(0, self.pattern[self.index])
if self.index < len(self.pattern)-1:
self.index = self.index + 1
else:
self.index = 0;
if __name__ == '__main__':
led = LED()
for i in range(100):
led.run()
time.sleep(0.1)
在这里导入的uio.py是在下面的文章中介绍过的。
- 「Python と Numpy で UIO を制御」@Qiita
如果运行上面的程序,并且 LED 在几秒钟内左右闪烁,那么就是成功的。
fpga@debian-fpga:~/examples/gpio$ sudo python3 led_on.py
解決問題的過程
遊戲結束後,按照後來添加的順序,使用Device Tree Overlay來刪除添加的設備樹。
fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/uio
fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/fclk0
[ 2149.037235] fclkcfg amba:fclk0: change rate : 992064
[ 2149.042497] fclkcfg amba:fclk0: change enable : 0
[ 2149.047353] fclkcfg amba:fclk0: driver unloaded
fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/fpga
请提供下列资料中的一项翻译,需要纯正的中文版本:
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(イントロ編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Boot Loader編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Sample FPGA Design編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Linux Kernel編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Debian9 Root File System編)」@Qiita
-
- 「UltraZed 向け Debian GNU/Linux (v2017.3版) ブートイメージの提供」@Qiita
-
- 「Linux の FPGA Manager で Xilinx のビットストリームファイルを扱う方法」@Qiita
-
- 「Python と Numpy で UIO を制御」@Qiita
-
- https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed
- https://github.com/ikwzm/fclkcfg