在 Xilinx SoC 上放上自己的 IP(三)
上一篇系列文中,我們把自己寫的 Verilog AHB IP 包裝成 Xilinx FPGA 的 SoC,並且編譯了一個 bitstream 出來,接下必須要將 bitstream 燒錄到 FPGA 上,在 FPGA 執行 PetaLinux 系統,寫一個 C++ 程式去控制這個 Verilog AHB IP。
預先設定
這篇文章希望說明在 PetaLinux 上面編譯我們自己的 C++ 程式來操作自己寫的 Verilog IP,所以仍然必須編譯出 PetaLinux 在 FPGA 上執行起來。前面的系列 的前兩篇中,提及了怎麼編譯出可用的 PetaLinux。
使用 UIO 讓 PetaLinux 開機之後可以看到我們的 IP
如果依照上面的文章步驟完成,理論上我們應該完成了這三件事(如果沒有的話,那請再回去確認一次):
petalinux-build
完成了。- 在開機磁區放入了
BOOT.BIN
、image.ub
、boos.scr
三個檔案。 - 在另外一個磁區用
cpio
解開了 rootfs。
接下來的步驟就是……前兩個步驟要修正一下重新跑一次。這是因為我們要透過 UIO 這個通用 driver 來把 Verilog IP 界面 expose 出來。UIO 這個 IP 相當好用,他可以:
- 建立一個檔案,把給定 IP 的 AXI 的 register space 建立一個檔案,讓使用者可以透過
mmap
來 access。(這個功能雖然用/dev/mem
也能作到,但是 UIO 的方法封裝程度相對高很多。) - 承上,這個檔案還允許我們很容易的去 wait IP 發出來的 interrupt。(
/dev/mem
不行)
修改 PetaLinux 開機參數
首先,我們要設定 PetaLinux 開機參數,讓其開機時可以 load UIO module,我們要去看 PetaLinux project 資料夾下面的 components/plnx_workspace/device-tree/device-tree
這個檔案,在我的設定中,我看到的參數是這樣。
1/ {
2 chosen {
3 bootargs = " earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait";
4 };
5};
project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
這個檔案,把剛剛的內容複製過去,並且後面加上一小段:
1/ {
2 chosen {
3 bootargs = " earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio";
4 };
5};
petalinux-build
的時候覆蓋掉的,改他沒有用。)
告訴 PetaLinux 我們的 Verilog IP 可以用 UIO 讀寫
在上一篇文章中,我們的 IP 在 SoC 裡面長這個樣子,可以看到他的名字是 my_test_0
:
所以我們同樣在 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
加入這段:
1&my_test_0 {
2 compatible = "generic-uio";
3};
components/plnx_workspace/device-tree/device-tree/pl.dtsi
裡面有沒有 my_test_0
這個字串。)
都完成了之後,最終的 system-user.dtsi
的前面幾行應該是長這個樣子:
1/include/ "system-conf.dtsi"
2/ {
3 xlnk {
4 compatible = "xlnx,xlnk-1.0";
5 };
6 chosen {
7 bootargs = " earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio";
8 };
9};
10&my_test_0 {
11 compatible = "generic-uio";
12};
接著,我們重複這兩個步驟就可以開機我們的 FPGA 了:
petalinux-build
。- 在開機磁區放入
BOOT.BIN
、image.ub
、boos.scr
三個檔案。
撰寫操控 Verilog IP 的 C++ Code
接著,我們把 FPGA 開機,用 cat
可以找出我們的 UIO 在 OS 下對應到了哪個檔案:
1cat /sys/class/uio/uio?/name
2axi-pmon
3my_test
4axi-pmon
5axi-pmon
6...
/dev/uio0
、/dev/uio1
、/dev/uio2
…,像是這個例子就是 /dev/uio1
。要讀寫 register,就直接用跟 這篇 一樣的方法,去 mmap
就好了。這個 example 中,我們設計是不管怎麼讀取,都會得到 32 bit 的 0x55665566
。
如果要等 interrupt 的話,則是連 mmap
都不需要,直接對 開出來的 file descriptor write
跟 read
各一次就好了。
1int ret;
2write(fd, &ret, 4);
3read(fd, &ret, 4);
結論
這篇文章說明了怎麼把我們寫的 IP 透過 UIO 拉出來,UIO 提供了一個免寫 driver 的方式來操控 IP,對於僅需要簡單 register, interrupt 控制的 IP 來說相當便利。
系列文連結
-
在 Xilinx SoC 上放上自己的 IP(一)
-
在 Xilinx SoC 上放上自己的 IP(二)
-
在 Xilinx SoC 上放上自己的 IP(三)
- 在 Xilinx SoC 上放上自己的 IP(一)
- 在 Xilinx SoC 上放上自己的 IP(二)
- 在 Xilinx SoC 上放上自己的 IP(三)