基於ultra96v2的amp方案驗證
目標計划
- 1.zu3eg下4*apu部署linux+ubuntu16.04操作系統
- 2.zu3eg下2*rpu部署freertos系統
- 3.rpu的程序固件由apu的系統啟動后再進行加載
- 4.apu與rpu完成可靠通信
- 5.rpu控制can外設,硬件定時器,完成在20ms的周期定時下向外發送can信號
- 6.在滿足5的情況下完成rpu控制can接收數據並發送給apu的linux的可靠測試
- 7.測試apu與rpu的通信時延及從rpu接收can數據到apu接收完數據的時間
硬件環境
測試的硬件基於ultra96v2
全部源碼已上傳
https://github.com/tccxy/ultra96v2_openamp_test
軟件環境
vivado2018.2
xilinx sdk2018.2
petalinux2018.2
++在官網上找了好幾個宣稱適用的bsp發現都起不來,逛論壇貌似ultra96v2的bsp還沒有發布++
最后在github上搜到了一個
https://github.com/KeitetsuWorks/SDSoC-Ultra96-V2
這個非官方的vivado工程至少可以讓板子正常啟動了,對於我們完成此次的測試目標夠用了,所以基於這個vivado工程進行后續的開發
amp的開發基於openamp框架完成
重要參考文檔
https://china.xilinx.com/support/documentation/sw_manuals/
xilinx2019_1/ug1186-zynq-openamp-gsg.pdf
https://china.xilinx.com/support/documentation/user_guides/
ug1085-zynq-ultrascale-trm.pdf
openamp的linux端demo在
https://github.com/Xilinx/meta-openamp
因為需要涉及到將ubuntu移植到ultra96v2上,為了方便移植,參考開發板官網的鏡像系統
http://zedboard.org/support/design/28476/181
板載了一個sdio接口的wifi模塊,驅動在
https://github.com/Avnet/u96v2-wilc-driver
還有一些零散的參考在,注意這里面的標號為v2的包是針對ultra96v1的第二個版本的,而不是針對ultra96v2的包
https://github.com/Avnet/Ultra96-PYNQ
開始
vivado階段
這塊只是在原有的基礎上加了一個ps端的can0控制器通過emio的方式引出到板子的40pin上,未做其他的改動
apu部署linux+ubuntu
本節主要敘述如何在ultra96v2上部署一個可以正常使用的Ubuntu系統,這是后續章節的前提
linux內核基於petalinux2018.2進行編譯即可
ubuntu16.02-base的移植之前的文檔也有過專門的敘述
到ultra96v2的板子上實際上主要涉及到一個sdio的wifi驅動的適配
petalinux目錄下添加一個wifi驅動模塊的支持
petalinux-create -t modules --name wilc --enable
在recipes-modules的bb文件中替換為如下文件
SUMMARY = "Recipe for building an external wilc Linux kernel module"
SECTION = "PETALINUX/modules"
LICENSE = "GPLv3"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-3.0;
md5=c79ff39f19dfec6d293b95dea7b07891"
inherit module
SRC_URI = "git://github.com/Avnet/u96v2-wilc-driver;
protocol=http;branch=master"
SRCREV = "master"
DEPENDS += "virtual/kernel"
S = "${WORKDIR}/git/wilc"
EXTRA_OEMAKE = 'CONFIG_WILC=y \
WLAN_VENDOR_MCHP=y \
CONFIG_WILC_SDIO=m \
CONFIG_WILC_SPI=n \
CONFIG_WILC1000_HW_OOB_INTR=n \
KERNEL_SRC="${STAGING_KERNEL_DIR}" \
O=${STAGING_KERNEL_BUILDDIR}'
執行petalinux build
編譯完成后將image/linux下的rootfs/lib/modules下的文件拷貝到ubuntu的/lib/modules下
將官方鏡像包中的/home下的文件拷貝到ubuntu的/home/xxx下
xxx@localhost:~$ ls
ble.sh bt.sh test.sh wifi.sh wpa_supplicant.conf
xxx@localhost:~$
修改wpa_supplicant.conf中的wifi參數
然后sd卡分區fat分區存放petalinux編譯的BOOT.BIN和image.ub
ext4分區存放ubuntu的系統
板子上電,可以正常啟動
以root用戶執行wifi.sh,wifi可以正常使用
xxx@localhost:~$ sudo ./wifi.sh
[sudo] password for xxx:
Successfully initialized wpa_supplicant
xxx@localhost:~$ ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr f8:f0:05:c4:1f:58
inet addr:192.168.0.102 Bcast:192.168.0.255
Mask:255.255.255.0
inet6 addr: fe80::faf0:5ff:fec4:1f58/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:26 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5065 (5.0 KB) TX bytes:2199 (2.1 KB)
xxx@localhost:~$
rpu固件啟動
本節主要敘述如何完成rpu上freertos系統的部署以及如何通過apu的linux啟動rpu的固件,並完成通信demo的測試
1.rpu的固件編譯
點擊vivado中的File > launch SDK
在SDK的界面中點擊File > New > Application Projects
在 Processor中選擇psu_cortexr5_0 或 psu_cortexr5_1 .
os選擇freertos
在Demo中選擇OpenAMP echo-test
在 Board Support Package Settings中的psu_cortexr5_0中的extra_compiler_flags中的Value中添加-DUSE_AMP=1
調試串口選擇uart1,ultra96v2引出來的uart為uart1
執行Project > Build All就可以生成對應的.elf固件了
2.linux+ubuntu上添加openamp的支持
linux內核中添加
petalinuxconfig -c kenel
[*] Enable loadable module support --->
Device Drivers --->
Generic Driver Options --->
<*> Userspace firmware loading support
Device Drivers --->
Remoteproc drivers --->
<M> ZynqMP_r5 remoteproc support
設備樹中system-user.dtsi添加文件系統中添加
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
rproc_0_reserved: rproc@3ed000000 {
no-map;
reg = <0x0 0x3ed00000 0x0 0x1000000>;
};
};
power-domains {
pd_r5_0: pd_r5_0 {
#power-domain-cells = <0x0>;
pd-id = <0x7>;
};
pd_tcm_0_a: pd_tcm_0_a {
#power-domain-cells = <0x0>;
pd-id = <0xf>;
};
pd_tcm_0_b: pd_tcm_0_b {
#power-domain-cells = <0x0>;
pd-id = <0x10>;
};
};
amba {
r5_0_tcm_a: tcm@ffe00000 {
compatible = "mmio-sram";
reg = <0x0 0xFFE00000 0x0 0x10000>;
pd-handle = <&pd_tcm_0_a>;
};
r5_0_tcm_b: tcm@ffe20000 {
compatible = "mmio-sram";
reg = <0x0 0xFFE20000 0x0 0x10000>;
pd-handle = <&pd_tcm_0_b>;
};
elf_ddr_0: ddr@3ed00000 {
compatible = "mmio-sram";
reg = <0x0 0x3ed00000 0x0 0x40000>;
};
test_r50: zynqmp_r5_rproc@0 {
compatible = "xlnx,zynqmp-r5-remoteproc-1.0";
reg = <0x0 0xff9a0100 0x0 0x100>,
<0x0 0xff340000 0x0 0x100>,
<0x0 0xff9a0000 0x0 0x100>;
reg-names = "rpu_base","ipi","rpu_glbl_base";
dma-ranges;
core_conf = "split0";
srams = <&r5_0_tcm_a &r5_0_tcm_b &elf_ddr_0>;
pd-handle = <&pd_r5_0>;
interrupt-parent = <&gic>;
interrupts = <0 29 4>;
} ;
};
petalinuxconfig -c rootfs
Filesystem Packages --->
misc --->
openamp-fw-echo-testd --->
[*] openamp-fw-echo-testd
openamp-fw-mat-muld --->
[*] openamp-fw-mat-muld
openamp-fw-rpc-demo --->
[*] openamp-fw-rpc-demo
Petalinux Package Groups --->
packagegroup-petalinux-openamp --->
[*] packagegroup-petalinux-openamp
執行petalinux build
編譯完成后將image/linux下的rootfs/lib/modules下的文件拷貝到ubuntu的/lib/modules下
將image/linux下的rootfs/lib/firmware下的文件拷貝到ubuntu的/lib/firmware下
3.openamp通信demo測試
這個例子中用到的rpu的固件和linux端的執行程序都是petalinux的rootfs中帶的
在/home/xxx目錄下創建腳本添加以下內容
#!/bin/sh
modprobe zynqmp_r5_remoteproc
echo image_echo_test > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
modprobe rpmsg_user_dev_driver
modprobe virtio_rpmsg_bus
echo_test
exit 0
以root用戶執行該腳本
可以看到控制台打印
Echo test start
Open rpmsg dev /dev/rpmsg0!
**************************************
Echo Test Round 0
**************************************
sending payload number 0 of size 17
echo test: sent : 17
received payload number 0 of size 17
sending payload number 2 of size 18
echo test: sent : 18
received payload number 2 of size 18
sending payload number 3 of size 19
echo test: sent : 19
received payload number 3 of size 19
sending payload number 4 of size 20
echo test: sent : 20
received payload number 4 of size 20
...
對應的源代碼在軟件環境提到的openamp 的linux demo中
4替換自己的源碼編譯的程序進行測試
將第一步生成的.elf固件文件拷貝到ubuntu的/lib/firware中
在petalinux的目錄執行
petalinux-create -t apps --name amptest --enable
在recipes-apps/amptest/files文件夾中添加下面的文件夾內的全部內容,為了便於區分將名字改成amp_test
https://github.com/Xilinx/meta-openamp/tree/master/
recipes-openamp/rpmsg-examples/rpmsg-echo-test
在上層的bb文件中也替換上述git文件的bb文件,注意名字要更改成一致的
執行petalinux build
編譯后將image/linux下的rootfs/usr/bin下的amptest文件拷貝到ubuntu的/usr/local/sbin下
替換第3步中的shell的image_echo_test為rpu的.elf,echo_test為linux的amptest
以root用戶執行腳本,可看到與第3步同樣的控制台輸出
這個amptest的就是后續測試的apu的linux側的源碼基礎
rpu的xsdk的工程是后續測試的rpu側的工程
xsdk的開發界面如下,在裸機這一側,xsdk提供了很多的bsp庫函數
位於_bsp > psu_cortexr5_0 > libsrc 下
同時在system.mss中也給了一定的example參考
ug1085也就是Zynq UltraScale+ Device的trm
后續的測試中因為rpu與apu對同一個外設有同樣的訪問權力,為了可以直觀的看到調試效果,將uart1作為rpu的打印輸出,linux的調試輸出放在網口的telnet中進行
rpu與apu協同測試
本節主要涉及到目標的5、6
涉及到的代碼有點多,無法截圖了,會傳到gitlab上,需要注意的是,如果rpu中用到的外設在apu中應該禁掉,具體的就是dts中應當將相應的節點disable掉
rpmsg的相應API只能在上下文中使用,不能在中斷中使用
整個rpu的freertos的概述流程圖如下
測試效果
左側為rpu的打印共轉發了10000幀,右側為apu的接收打印共接收了10000幀
同時rpu以20ms的周期向外發送can數據
通信時延測試
為了掌握openamp框架的通信時延級別,進行此測試,可以不是十分精確,但是需要測量出為us級還是ms級別
通過在rpu端配置使能一個計數器,當can中斷接收數據完成后讀取一下計數器的值,rpu端發送完數據后讀取一下計數器的值,linux端接收完數據后讀取一下寄存器的值
以此來計算通信時延級別
如上圖可以看到,計數器的時鍾為100M
數據從can中斷接收完成到linux接收到該數據的時間大概為37.69us
$$
(0x50348ccd - 0x50347E14)/100 000 000
$$
而rpmsg的通信時延大概為16.16us
$$
(0x50348ccd - 0x5034867D)/100 000 000
$$