ラベル yocto の投稿を表示しています。 すべての投稿を表示
ラベル yocto の投稿を表示しています。 すべての投稿を表示

2021年1月19日火曜日

ros2 eloquent + orb_slam2_rosをクロスコンパイルして動かした話

ultra96v2とros2 eloquentでorb_slam2を動かした際のメモ。 能力不足なのか、マッピングが動かなかった。

vitisで性能改善させるのにsdkでのクロスコンパイル環境必要かと思ったので整えた。

レシピはここのfeature-v2020.2ブランチから一式取得できる。 もしくはここのfeature-v2020.2ブランチにレシピ類がまとめてある。

レシピの変更

クロスコンパイル用のパッケージにはnativesdkをBBCLASSEXTENDに追加する必要がある。 そのため、/sources/meta-ros/meta-ros-common/classes/ros_superflore_generated.bbclassを変更する。

# BBCLASSEXTEND_append = "${@bb.utils.contains('ROS_SUPERFLORE_GENERATED_BUILDTOOLS', '${BPN}-native', ' native', '', d)}"
BBCLASSEXTEND_append = "${@bb.utils.contains('ROS_SUPERFLORE_GENERATED_BUILDTOOLS', '${BPN}-native', ' native nativesdk', '', d)}"

次のファイルはFILES_${PN} += "*"を追加する。 そのままだとament-cmake向けファイル等がインストールされない模様。
recipes-ros2/ament-index-python/ament-index-python_%.bbappend
recipes-ros2/ament-package/ament-package_%.bbappend
recipes-ros2/domain-coordinator/domain-coordinator_%.bbappend

python3-lark-parserはBsuperfloreのBUILDTOOL登録されていないため、nativesdk化されない。 なのでbbappendでBBCLASSEXTEND_appendにnativesdkを追加する。 recipes-ros2/python3-lark-parser/python3-lark-parser_%.bbappend

rviz-ogre-vendorがmesaに依存しているけど、 zynqではmesa-glを使用するので、mesaを削除してmesa-glを追加する。
recipes-ros2/rviz/rviz-ogre-vendor_%.bbappend

ROS_BUILD_DEPENDS_remove = "mesa"
ROS_BUILD_DEPENDS_append = " mesa-gl"
ROS_EXPORT_DEPENDS_remove = "mesa"
ROS_EXPORT_DEPENDS_append = " mesa-gl"
ROS_EXEC_DEPENDS_remove = "mesa"
ROS_EXEC_DEPENDS_append = " mesa-gl"

あとはpackage.xmlを参考にopencv-camとros2-sharedのレシピを作成する。
recipes-ros2/opencv-cam/opencv-cam_git.bb
recipes-ros2/ros2-shared/ros2-shared_git.bb

あとはSDKのためにTOOLCHAIN_TARGET_TASK_appendとTOOLCHAIN_HOST_TASK_appendを recipes-core/images/petalinux-image-minimal-ultra96v2ros2.bbに追加していく。
yoctoは自動的に依存関係収集してくれないようなので、クロスコンパイルしたい対象の依存関係を手動で解決していく。
*-nativeに依存している場合はnativesdk-*をTOOLCHAIN_HOST_TASK_appendに追加する。
無印の場合にはTOOLCHAIN_TARGET_TASK_appendに該当パッケージを追加する。
クロスコンパイル実行時にライブラリが不足などのメッセージが出た場合には-staticdevや-devなどをTOOLCHAIN_TARGET_TASK_appendに追加する。
(で合ってるはず。自信は無い。)

ビルド

MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal-ultra96v2ros2
MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal-ultra96v2ros2 -c do_populate_sdk

orb-slam2-rosの実行

まずはカメラ画像の確認。 USBのHOSTにwebカメラを接続する。 使用するのはlogicoolのc270n。 ついでにCPU使用率を確認する。

ssh 192.168.2.1 -l root
root@ultra96v2-zynqmp:~# source ros_setup.sh
root@ultra96v2-zynqmp:~# ros2 run opencv_cam opencv_cam_main --ros-args --param index:=0 --param camera_info_path:=camera-info-logicool-c270n.ini &
root@ultra96v2-zynqmp:~# top

topで動作を確認。

top - 23:11:54 up 11:33,  2 users,  load average: 0.86, 1.13, 1.63
Tasks: 103 total,   3 running, 100 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  2.3 sy,  0.0 ni, 97.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1974.4 total,   1682.3 free,    124.8 used,    167.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1780.4 avail Mem 

大したことはなさそう。

orb-slam2-rosを動かす。

root@ultra96v2-zynqmp:~# ros2 run orb_slam2_ros orb_slam2_ros_mono --ros-args --remap /camera/image_raw:=/image_raw --remap /camera/camera_info:=/camera_info --param params_file:=/usr/share/orb_slam2_ros/ros/config/params_d435_mono.yaml --param voc_file:=/usr/share/orb_slam2_ros/orb_slam2/Vocabulary/ORBvoc.txt &

同じくtopで確認。1オプションでCPU毎の負荷も確認しておく。

top - 23:50:13 up 12:11,  2 users,  load average: 3.71, 3.16, 2.74
Tasks: 108 total,   2 running, 106 sleeping,   0 stopped,   0 zombie
%Cpu0  : 85.9 us,  2.0 sy,  0.0 ni, 11.8 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu1  : 21.5 us,  5.0 sy,  0.0 ni, 73.2 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu2  : 48.1 us,  6.5 sy,  0.0 ni, 45.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  3.2 us, 26.4 sy,  0.0 ni, 70.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1974.4 total,   1089.0 free,    665.8 used,    219.6 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1239.2 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                 
 1628 root      20   0 1790424 505660  21916 R 121.2  25.0  26:20.67 orb_slam2_ros_m                                                                         
 1277 root      20   0  516600  47812  23240 S  47.4   2.4  12:44.68 opencv_cam_main                                                                         
 4034 root       0 -20       0      0      0 I  31.8   0.0   3:38.79 kworker/u9:2-uvcvideo                                                                   
 1258 root      20   0  415052  37020  15196 S   1.0   1.8   0:24.32 python3                                                                                 
 6384 root      20   0    3320   2024   1564 R   0.7   0.1   0:02.39 top                                                                                     

CPUごとに見ると1つのCPUの負荷が高く、orb_slam2_rosプロセスの負荷が高い。 load averageも高めで能力足りてないと見ればいいかな。

クロスコンパイル

sdkをインストールしたあと

/sysroots/x86_64-petalinux-linux/usr/share/cmake/OEToolchainConfig.cmake を次のように編集する。 $ENV{OECORE_NATIVE_SYSROOT}が無いとnativeツールが発見できないため

set( CMAKE_FIND_ROOT_PATH "\$ENV{OECORE_TARGET_SYSROOT};\$ENV{OECORE_NATIVE_SYSROOT}" )

sysroots/aarch64-xilinx-linux/usr/share/fastrtps/cmake/fastrtps-targets.cmakeの検索パスが間違っているので修正。 レシピから修正したほうがいいだろうけど、とりあえずなんとかなるから後回し。

#set_target_properties(fastrtps PROPERTIES
#  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
#  INTERFACE_LINK_LIBRARIES "fastcdr;foonathan_memory;-lpthread;dl;/home/akira/work/ultra96v2/petalinux/build/tmp/work/aarch64-xilinx-linux/fastrtps/1.9.3-2-r0/recipe-sysroot/usr/lib/libtinyxml2.so;\$<\$<BOOL:1>:OpenSSL::SSL\$<SEMICOLON>OpenSSL::Crypto>;\$<\$<BOOL:>:iphlpapi\$<SEMICOLON>Shlwapi>"
#)
set_target_properties(fastrtps PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "fastcdr;foonathan_memory;-lpthread;dl;$ENV{OECORE_TARGET_SYSROOT}/usr/lib/libtinyxml2.so;\$<\$<BOOL:1>:OpenSSL::SSL\$<SEMICOLON>OpenSSL::Crypto>;\$<\$<BOOL:>:iphlpapi\$<SEMICOLON>Shlwapi>"
)

buildの実行。インストールパスはsd-cardのrootをマウントした場所を指定する。

source <sdk-installation-path>/environment-setup-aarch64-xilinx-linux
export AMENT_PREFIX_PATH=$OECORE_NATIVE_SYSROOT/usr:$OECORE_TARGET_SYSROOT/usr
export PYTHONPATH=$OECORE_NATIVE_SYSROOT/usr/lib/python3.7/site-packages:$OECORE_TARGET_SYSROOT/usr/lib/python3.7/site-packages
cd <path-to-orb_slam2_ros-repository>
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_SO_NO_EXE=0 -DBUILD_TESTING=OFF -DCMAKE_NO_SYSTEM_FROM_IMPORTED=1 -GNinja -DCMAKE_INSTALL_PREFIX=<sd-card-root>
cmake --build
sudo ninja install

同じようにtopを実行してみると似た結果が得られている。

top - 00:12:13 up 12 min,  2 users,  load average: 3.12, 1.92, 0.98
Tasks: 109 total,   4 running, 105 sleeping,   0 stopped,   0 zombie
%Cpu(s): 45.3 us, 14.8 sy,  0.0 ni, 39.5 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
MiB Mem :   1974.4 total,   1059.6 free,    636.4 used,    278.5 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1249.7 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                 
 1212 root      20   0 1785152 499480  21788 R 125.2  24.7   0:15.17 orb_slam2_ros_m                                                                         
  812 root      20   0  516588  47672  22840 S  67.5   2.4   1:58.91 opencv_cam_main                                                                         
  133 root       0 -20       0      0      0 R  46.4   0.0   0:50.66 kworker/u9:0+uvcvideo                                                                   
 1211 root      20   0    3320   2064   1616 R   0.7   0.1   0:00.10 top                         

また、rviz2でdebug_imageを確認するとorb_slam2_rosから出力されているのでクロスコンパイル版もしっかり動作している模様。

2020年11月20日金曜日

ultra96v2のwifiを2020.1で動かしてみた

ultra96v2のwifiを2020.1で動かした話。 パッチはここにおいておく。

事象

私の環境で、2020.1にアップデートしたデータを起動するとwifiのアクセスポイントが見えなくなる事象が確認された

原因

ultra96-ap-setupによって作成されるアクセスポイントは wpa_supplicantにwpa_ap_actual.confを渡して設定している模様。 私の環境ではwpa_ap_actual.confが空となっていた。

ap.shを順に動かしてみるとどうもsedでwpa_ap_actual.confを作成するところがコケているようなので、パッチを当てる。

対策

自分で使う分にはap.shを直接修正してもいいが、 レシピのファイルに対してパッチを当てるにはquiltというものを使うらしいので使ってみた。 使い方はここにある。 目的のソースの探し方なども書いてあるので読んでおくのがおすすめ。 インストールして使うみたい。

apt install quilt
cd <path-to-src>
quilt new fix-for-my-hw.patch
quilt add ap.sh
#fix ap.sh
quilt refresh

するとpatchesフォルダ配下にfix-for-my-hw.patchが得られるのでこれを自分のレシピへと取り込む。

更に、meta-avnetを見るとconnman使っているようなので、imageに追加した。 connmanのblacklistにp2p0を登録する設定ファイルを追加した。 加えて、shutdown時にAPの設定をoffにできるようにmeta-avnetからultra96-wpaを借りてきた。

また、起動時からネットワークを有効とするためにconnmanの設定を行った。 /var/lib/connman/settingsがあらかじめ存在していればそれに従った動作をするようなので、 ultra96-ap-setup.bbappendでsettingsを追加する。

動作

Ultra96V2-********ctxというAPが見えるのでこれに接続し、192.168.2.1にrootアクセスする。

ssh 192.168.2.1 -l root
#ultra96v2のrootに接続

2020年11月16日月曜日

yocto+petalinux2020.1でカーネルデバッグしてみようとした話

yoctoでカーネルデバッグをしてみようとした話。

エミュレータでは正常起動しているのに、実機だとブートの途中でハングするという問題を調査した際の手順をまとめた。 ビルドし始めてすぐにaxi_intcのdevicetreeが間違っていそうだなと気がついたけど、せっかくなので最後までやってみた。

結果、kgdbwaitはpetalinuxだと期待通りの動きをしないことがわかった。ドライバの修正方法について記載あったりするので、折を見てkgdbが起動時に使えるようにしておきたいところ。

環境

petalinux 2020.1
Ubuntu 18.04
https://github.com/akira-nishiyama/petalinux-ros2-manifests.git

エラー時のメッセージ

...(略)...
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] irq-xilinx: /amba_pl@0/interrupt-controller@a0090000: num_irq=32, sw_irq=0, edge=0x0
実機の場合にここで止まる。

準備

cd ~/work
source setupsdk
MACHINE=ultra96v2 bitbake linux-xlnx -c do_menuconfig

以下の通り設定する。

Kernel hacking -> KGDB: Kernel debugger (Check it and Enter):
Check: KGDB: use kgdb over the serial console
Check: KGDB_KDB: include kdb frontend for kgdb        
Enable: Kernel debugging and Magic SysRq key
Enable: Compile the kernel with debug info

local.confに以下を設定する。 DEBUG_BUILD以降は必要かどうかはよくわからなかった。 RM_WORK_EXCLUDE += "linux-xlnx-dev"だけでも良いかも。

########################
# For debug
########################
EXTRA_IMAGE_FEATURES += "\
      tools-debug \    
      debug-tweaks \   
      "        

# Specifies to build packages with debugging information
DEBUG_BUILD = "1"

# Do not remove debug symbols
INHIBIT_PACKAGE_STRIP = "1"

# OPTIONAL: Do not split debug symbols in a separate file
INHIBIT_PACKAGE_DEBUG_SPLIT= "1"

ビルド

MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal
MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal -c do_populate_sdk

実行

u-bootのautobootを途中で止めてブートオプションを設定する。

setenv bootargs "kgdboc=ttyPS0,115200 kgdbwait"
boot

通常通り起動してしまった。 ここに情報があり、どうもpetalinux(というかxilinx_uartps.c?)の問題のよう。 とりあえずはLinuxが立ち上がった後は使用可能な模様。

root@ultra96v2-zynqmp:~# echo ttyPS0 > /sys/module/kgdboc/parameters/kgdboc
[   48.462920] KGDB: Registered I/O driver kgdboc
[   48.491488] KGDB: Waiting for connection from remote gdb...

Entering kdb (current=0xffffff805b8c1140, pid 390) on processor 2 due to Keyboard Entry
[2]kdb>

devicetreeを修正したら最初に調べようと思っていた問題は解決した。むしろ今まで何故動いていたのかが謎。

参考ページ

https://developer.ridgerun.com/wiki/index.php?title=Preparing_Yocto_Development_Environment_for_Debugging https://sites.google.com/site/kandamotohiro/linux/kgdb https://docs.windriver.com/bundle/Wind_River_Linux_Tutorial_Kernel_Debugging_with_GDB_and_KGDB_LTS_18_1/page/mmo1403548696698.html https://forums.xilinx.com/t5/Embedded-Linux/quot-KGDBWait-quot-parameter-is-not-waiting-while-booting-the/td-p/550816

2020年11月7日土曜日

meta-ultra96v2を作って、yoctoでビルドしてみたをros2対応させてみた

wifi動作させたイメージをベースにros2を動作させてみた話。

イメージの取得

以下のようにmanifestsを実行してビルドに記載の通りpetalinux-image-minimal-ultra96v2ros2をビルドすれば同じものが得られる。ここに至るまで行った設定は後述。

meta-rosを追加

meta-rosをクローンし、bblayerに追加する。petalinuxは2019.1のためthudベースであるからthudブランチを使用する。

cd <petalinux-repository-top>
source setupsdk
git clone https://github.com/ros/meta-ros ../sources/meta-ros -b thud
bitbake-layers add-layer ../sources/meta-ros/meta-ros-backports-warrior ../sources/meta-ros/meta-ros-common ../sources/meta-ros/meta-ros2 ..//sources/meta-ros/meta-ros2-dashing

ros設定の追加。 ROS_DISTRO_BASELINE_PLATFORMとROS_DISTROを指定する。 ROS_DISTRO_BASELINE_PLATFORMは選択したROS_DISTROの対応環境と合わせて選ぶものと思う。今回はros2-dashingなのでbionicを選択。他にはeloquentやfoxyも選択可能な模様。

  • build/conf/bblayer.conf

    ROS_DISTRO_BASELINE_PLATFORM ?= "ubuntu-bionic"
    ROS_DISTRO ?= "dashing"

meta-ros-backports-warriorのpythonレシピがあるとpetalinux環境のpythonとバッティングするため、pythonレシピを除外する。特定のレシピを除外するにはlocal.confにBBMASKを記載して除くことができる。

  • build/conf/local.conf

    BBMASK = "meta-ros/meta-ros-backports-warrior/recipes-devtools/python/python3_3.7.5.bb"

イメージの追加

今回使うのはros-coreだけなので、imageに追加する。

CORE_IMAGE_EXTRA_INSTALL_append = " ros-core"

ビルド

下記の通りビルドを行う。

cd <petalinux-project-path>/build
MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal-ultra96v2ros2

実行結果

wic.qemu-sdをddで/dev/sdXに書き込んで実行する。

dd if=tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.wic.qemu-sd of=/dev/sdX

sshで接続できるので、ros2のpubとechoをテストする。 結果は以下。

akira@akira-Surface-Book:~$ ssh 192.168.2.1 -l root
root@ultra96v2-zynqmp:~# (sleep 5; ros2 topic pub /chatter std_msgs/String "data: Hello world") &
[1] 2219
root@ultra96v2-zynqmp:~# ros2 topic echo /chatter
publisher: beginning loop
publishing #1: std_msgs.msg.String(data='Hello world')

data: Hello world
---
publishing #2: std_msgs.msg.String(data='Hello world')

data: Hello world
---
publishing #3: std_msgs.msg.String(data='Hello world')

data: Hello world
---
publishing #4: std_msgs.msg.String(data='Hello world')

data: Hello world
---
publishing #5: std_msgs.msg.String(data='Hello world')

data: Hello world
---
publishing #6: std_msgs.msg.String(data='Hello world')

data: Hello world
---

2020年11月6日金曜日

meta-ultra96v2を作って、yoctoでビルドしてみたをwifi対応させてみた

前回のmeta-ultra96v2をwifi動作(+bluetooth, i2c, usb対応)させた話。 お手本はultra96v2向けのpetalinux projectで生成されるもの。

改訂版のmeta-ultra96v2はここ。 ビルド用のrepoはここだけど、時間が立つとこの記事に記載以上のものが追加される予定。(主にros2関係) petlainux-image-minimal-ultra96hwのビルドで同じものが生成されるようにはしておく。

今回はimageを新しく作成している。petalinux-image-minimalをコピーし、 必要なイメージをappendしている。 wifiだけ動かすつもりがどうせだからとHW動かすのに必要そうなものを乗せて、 petalinux-image-minimal-ultra96v2hwというimageを新しく作成した。

Wifi設定

CORE_IMAGE_EXTRA_INSTALL_appendで必要なパッケージを追加していく。 ultra96-ap-setupが必要そうなので、追加したが、エラーとなった。

対象の機能はCOMPATIBLE_MACHINEでultra96-zynqmpが指定されているため、 ultra96v2-zynqmpはCOMPATIBLEではないとのことであった。

ポイントはmeta-ultra96v2/conf/machine/ultra96v2-zynqmp.confに、 MACHINEOVERRIDES =. "ultra96-zynqmp:"を指定することだった。 これによってultra96v2-zynqmpのMACHINE設定はultra96-zynqmpとしても扱われるようになるため、 ultra96-zynqmp向けの設定を利用することができるようになる。 派生開発を行う際に非常に有用だなと思った。

他に必要となりそうなwilc,wilc3000-fw,wpa-supplicantとethtoolとbluetooth,i2c,usb関連ファイルを追加した。 Wifiは使えると便利なので確認したけどbluetooth,i2c,usbは使う時が来たときに確認する。

sdイメージへのファイル追加

実機動作させる際にpetalinux-image-minimal-ultra96v2hw-ultra96v2-zynqmp.wic.qemu-sdを使用しても 立ち上がらなかったので中を除いてみるとboot.binが無い様だった。

meta-ultra96v2/conf/machine/ultra96v2-zynqmp.confのIMAGE_BOOT_FILESにboot.binを追加して事なきを得た。 こうしておくと以下のようにsdのデバイスに対してddするだけでよくなるので便利。 この方法だとroot領域拡張するには少し工夫がいるので注意は必要。

dd if=<build_directory>/tmp/deploy/images/petalinux-image-minimal-ultra96v2hw-ultra96v2-zynqmp.wic.qemu-sd of=/dev/sdX

準備

https://github.com/Xilinx/yocto-manifests に記載の通り、repo環境を整える。

curl -k https://storage.googleapis.com/git-repo-downloads/repo > repo
chmod a+x repo
sudo mv repo /usr/local/bin/

manifestを取得し、yocto環境を整える

cd <petalinux-project-path>
repo init -u http://github.com/akira-nishiyama/petalinux-ros2-manifests -b main
repo sync
source setupsdk

この後環境を整える。 build/conf/local.confを開き、末尾のコメントアウトされている部分を編集する。 xsaは指定しないとエラーになるかも。(デフォルト設定があるかどうかよく知らない) QB_TAP_OPTはお好みで。

HDF_EXT_ultra96v2-zynqmp = "xsa"
HDF_BASE_ultra96v2-zynqmp = "file://"
HDF_PATH_ultra96v2-zynqmp = "<xsa-file-path>/<yourdesign.xsa>"
QB_TAP_OPT_forcevariable = "-netdev tap,id=net0,ifname=tap0"

もしも適当なxsaが無い場合はこれを使用してxsa生成すると良いかも。 5a685e1e648a6ba7814c3b99ba6bafd71ceab74bが記事作成時点のデータとなっている。 以下のようにしてxsaが得られる。 windows環境で動くようにはしていないのであしからず。

cd
git clone https://github.com/akira-nishiyama/vivado_cmake_helper.git
gic clone https://github.com/akira-nishiyama/ultra96v2_4z
source <path>/<to>/Vivado/2019.2/settings.sh
source vivado_cmake_helper/setup.sh
cd ultra96v2_4z
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<xsa-file-path>
make
make install

ビルド

設定したら今度は以下のコマンドを発行。

cd <petalinux-project-path>/build
MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal-ultra96v2hw

動作確認

ddでwic.qemu-sdを書き込み動作。 シリアルを確認するとrootでログインしているのが確認できる。 wifiの電波も飛んでいるので、接続の上、以下のコマンドで192.168.2.1にsshでrootアクセス可能なことを確認した。

ssh 192.168.2.1 -l root

2020年11月2日月曜日

meta-ultra96v2を作って、yoctoでビルドしてみた

Xilinxのyocto環境をultra96v2対応させてみた話。
QEMU使ってEmulation可能にしている。
petalinuxのインストールはしなくても良いが、xsctはダウンロードする必要がある。
サイズは1GBくらい。

ビルド方法はこちら

作成したものはここ

全部まとめたrepoはここ

QEMU動作は確認したけど、実機確認はまだやっていない。

準備

Readmeに記載の通りrepoを使用するだけ。

curl -k https://storage.googleapis.com/git-repo-downloads/repo > repo
chmod a+x repo
sudo mv repo /usr/local/bin/
XILINX_SOURCES=/path/to/xilinx/sources
mkdir -p $XILINX_SOURCES
cd $XILINX_SOURCES
repo init -u https://github.com/Xilinx/yocto-manifests -b rel-v2019.2
repo sync

レイヤーの追加

下記コマンドで追加可能

source setupsdk
bitbake-layers create-layer ../sources/meta-ultra96v2
bitbake-layers add-layer ../sources/meta-ultra96v2

meta-ultra96v2をgit cloneした場合はadd-layerだけで良い。

machine設定

meta-ultra96v2/conf/machine/ultra96v2-zynqmp.confを作成する。 内容はmeta-xilinx/meta-xilinx-bsp/conf/machine/zcu102-zynqmp.confを真似て作成する。 -zynqmpってくっつけるとincludeしているファイルがうまいこと設定してくれそうな気がしている。

やったのはMACHINE_FEATURESは"usbgadget wifi bluetooth"を追加、 MACHINE名をultra96v2に変更、qemu向けの設定をultra96v2に合わせる程度の変更を行っている。 QEMU使用したときにLinux上でsd0がなぜか認識されないのはまったく追ってないので間に合せでsd0とsd1に同じイメージを認識させている。 バージョン進めばそのうち期待通りになることを期待。(ちゃんと設定しないといけないのかもしれないけど)

menuconfig

MACHINE=ultra96v2-zynqmp bitbake u-boot-xlnx -c menuconfig
MACHINE=ultra96v2-zynqmp bitbake u-boot-xlnx -c diffconfig

fragmentファイルが出力されるので、recipes-bsp/u-boot/files配下に保存し、 recipes-bsp/u-boot/u-boot-xlnx_%.bbappendでSRC_URI+=しておく。
今回は不要と思われるが、場合によってはdo_configureでinstallを行って反映させる。
kernelも同じように設定変更可能と見られる。

local.conf

devicetreeなどをxsaファイルから生成してもらうために下記の記述を追加。 QEMU実行時に通信させるためにはGEM3を活かしておく必要がある。 (USB-Etherやwifiはエミュレートできないようなので)

# Add system HDF/DSA
HDF_EXT_ultra96v2-zynqmp = "xsa"
HDF_BASE_ultra96v2-zynqmp = "file://"
HDF_PATH_ultra96v2-zynqmp = "path/to/<yourdesign.xsa>"

qemu-devicetree

エミュレータ実行時に使用するdevicetreeはこちら。 この中からマッチするものを使用するか、自身の環境に合うようにパッチを当てるかをする。 SD0が認識しないのはpmuの設定じゃないかとも疑っているけど、とりあえず動くから放置。 recipes-devtool/qemu-devicetrees_%.bbappendでパッチが当てられる。

qemu tap

Host PCとQEMUで通信させるためにbridgeを準備する。 qemuとbridge、tapの使い方あんまりよく分かっていないからもっとスマートな方法あるかも。 忘れないようにhostと通信させることができた設定を置いておく。

bridge作成スクリプト prepare_qemu_com.sh

sudo brctl addbr br0
sudo ip addr add 10.0.2.2/16 dev br0
sudo ip link set br0 up
sudo ip tuntap add user <username> mode tap
sudo dnsmasq --interface=br0 --bind-interfaces --dhcp-range=10.0.2.4,10.0.2.254
sudo route add -net 224.0.0.0/4 dev br0

build/local.confに以下を追加。TAP使用設定。

QB_TAP_OPT_forcevariable = "-netdev tap,id=net0,ifname=tap0"

tap生成スクリプト
/etc/qemu-ifup

echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /sbin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /sbin/brctl addif br0 $1

sleep 3

exit 0

tap削除スクリプト
/etc/qemu-ifdown

echo "Executing /etc/qemu-ifdown"
echo "Removing $1 to br0..."
sudo /sbin/ip link set $1 down
sudo /sbin/brctl delif br0 $1
echo "Shutting down $1..."
sudo /sbin/ip link delete dev $1

exit 0

ビルド

MACHINE=ultra96v2-zynqmp bitbake petalinux-image-minimal

QEMU実行

MACHINE=ultra96v2-zynqmp runqemu

終了はCtrl-a,x

参考ページ

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/59605045/Adding+an+HDF+to+a+Xilinx+Yocto+Layer

https://qiita.com/basaro_k/items/066edec6139bcb9d53e5

https://qiita.com/propella/items/959c040b84a6d978f1cd

QEMU実行ログ

runqemu - INFO - Running MACHINE=ultra96v2-zynqmp bitbake -e...
runqemu - INFO - Continuing with the following parameters:

KERNEL: []
DTB: [/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb]
MACHINE: [ultra96v2-zynqmp]
FSTYPE: [wic.qemu-sd]
ROOTFS: [/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.rootfs.wic.qemu-sd]
CONFFILE: [/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.qemuboot.conf]

runqemu - INFO - Using preconfigured tap device tap0
runqemu - INFO - If this is not intended, touch /tmp/qemu-tap-locks/tap0.skip to make runqemu skip tap0.
runqemu - INFO - Network configuration: 192.168.7.2::192.168.7.1:255.255.255.0
runqemu - INFO - Running /home/akira/work/xilinx-yocto/build/tmp/work/x86_64-linux/qemu-xilinx-helper-native/1.0-r1/recipe-sysroot-native/usr/bin//qemu-xilinx/qemu-system-aarch64-multiarch -net nic -net nic -net nic -net nic,netdev=net0,macaddr=52:54:00:12:34:02 -netdev tap,id=net0,ifname=tap0 -drive if=sd,index=0,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.rootfs.wic.qemu-sd,format=raw  -drive if=sd,index=1,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.rootfs.wic.qemu-sd,format=raw -nographic -serial /dev/null -serial mon:stdio -serial /dev/null -serial /dev/null -dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb -hw-dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/qemu-hw-devicetrees/multiarch/ultra96-arm.dtb -global xlnx,zynqmp-boot.cpu-num=0 -global xlnx,zynqmp-boot.use-pmufw=true -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf,cpu-num=0 -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/u-boot.elf  -boot mode=3 -pmu-args ' -M microblaze-fdt -display none -hw-dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/qemu-hw-devicetrees/multiarch/zynqmp-pmu.dtb -kernel /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-rom.elf -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-firmware-ultra96v2-zynqmp.elf -device loader,addr=0xfd1a0074,data=0x1011003,data-len=4 -device loader,addr=0xfd1a007C,data=0x1010f03,data-len=4 '  -machine arm-generic-fdt  -m 4096


PMU instance cmd: /home/akira/work/xilinx-yocto/build/tmp/work/x86_64-linux/qemu-xilinx-helper-native/1.0-r1/recipe-sysroot-native/usr/bin/qemu-xilinx/qemu-system-microblazeel -M microblaze-fdt -display none -hw-dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/qemu-hw-devicetrees/multiarch/zynqmp-pmu.dtb -kernel /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-rom.elf -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-firmware-ultra96v2-zynqmp.elf -device loader,addr=0xfd1a0074,data=0x1011003,data-len=4 -device loader,addr=0xfd1a007C,data=0x1010f03,data-len=4 -machine-path /tmp/tmpp9r1d34f

APU instance cmd: /home/akira/work/xilinx-yocto/build/tmp/work/x86_64-linux/qemu-xilinx-helper-native/1.0-r1/recipe-sysroot-native/usr/bin/qemu-xilinx/qemu-system-aarch64 -net nic -net nic -net nic -net nic,netdev=net0,macaddr=52:54:00:12:34:02 -netdev tap,id=net0,ifname=tap0 -drive if=sd,index=0,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.rootfs.wic.qemu-sd,format=raw -drive if=sd,index=1,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2-zynqmp-20201102051140.rootfs.wic.qemu-sd,format=raw -nographic -serial /dev/null -serial mon:stdio -serial /dev/null -serial /dev/null -dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb -hw-dtb /home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/qemu-hw-devicetrees/multiarch/ultra96-arm.dtb -global xlnx,zynqmp-boot.cpu-num=0 -global xlnx,zynqmp-boot.use-pmufw=true -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf,cpu-num=0 -device loader,file=/home/akira/work/xilinx-yocto/build/tmp/deploy/images/ultra96v2-zynqmp/u-boot.elf -boot mode=3 -machine arm-generic-fdt -m 4096 -machine-path /tmp/tmpp9r1d34f

Executing /etc/qemu-ifup
Bringing up tap0 for bridged mode...
Adding tap0 to br0...
NOTICE:  ATF running on XCZUUNKN/QEMU v4/RTL0.0 at 0xfffea000
NOTICE:  BL31: Secure code at 0x60000000
NOTICE:  BL31: Non secure code at 0x10080000
NOTICE:  BL31: v2.0(release):xilinx-v2019.2
NOTICE:  BL31: Built : 16:36:49, Oct 30 2020
PMUFW:  v1.1


U-Boot 2019.01 (Nov 01 2020 - 09:46:41 +0000)

Model: Avnet Ultra96 Rev1
Board: Xilinx ZynqMP
DRAM:  2 GiB
EL Level:   EL2
Chip ID:    unknown
MMC:   mmc@ff160000: 0, mmc@ff170000: 1
In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Bootmode: SD_MODE
Reset reason:
Net:   ZYNQ GEM: ff0e0000, phyaddr ffffffff, interface gmii

Warning: ethernet@ff0e0000 (eth0) using random MAC address - 06:12:f1:50:6f:f1
eth0: ethernet@ff0e0000
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
263 bytes read in 6 ms (42 KiB/s)
## Executing script at 20000000
53697 bytes read in 22 ms (2.3 MiB/s)
18293248 bytes read in 2540 ms (6.9 MiB/s)
## Flattened Device Tree blob at 04000000
   Booting using the fdt blob at 0x4000000
   Loading Device Tree to 000000000ffef000, end 000000000ffff1c0 ... OK

Starting kernel ...

INIT: version 2.88 booting
Starting udev
Configuring packages on first boot....
 (This may take several minutes. Please do not power off the machine.)
Running postinst /etc/rpm-postinsts/100-kernel-image-image-4.19.0-xilinx-v2019.2...
Running postinst /etc/rpm-postinsts/101-sysvinit-inittab...
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing)
 Removing any system startup links for run-postinsts ...
  /etc/rcS.d/S99run-postinsts
INIT: Entering runlevel: 5
Configuring network interfaces... udhcpc: started, v1.29.2
udhcpc: sending discover
udhcpc: sending discover
udhcpc: sending discover
udhcpc: sending select for 10.0.2.49
udhcpc: lease of 10.0.2.49 obtained, lease time 3600
/etc/udhcpc.d/50default: Adding DNS 10.0.2.2
done.
Starting haveged: haveged: listening socket at 3
haveged: haveged starting up


Starting Dropbear SSH server: Generating 2048 bit rsa key, this may take a while...
haveged: haveged: ver: 1.9.4; arch: generic; vend: ; build: (gcc 8.2.0 CTV); collect: 128K

haveged: haveged: cpu: (VC); data: 16K (D V); inst: 16K (D V); idx: 11/40; sz: 15528/64688

haveged: haveged: tot tests(BA8): A:1/1 B:1/1 continuous tests(B):  last entropy estimate 7.99866

haveged: haveged: fills: 0, generated: 0

Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMdVJ5VKRXuQp29ljnv2aLA6egiu3WjLaJDBqpznm2tK+HYoWZ9UfAAQtjjxGFNb8eKf6ea68eht010J29f4P3yEbnQmWDAul19GDz34WwAKZW/yOTzn3I4ZhYyFPMi7lcPfb1s6JPbcZauUMjLatK+OYgV99VzGt3T3ZOJ9W80fDFothrO6EerqrMI6tGVkTmfWAkEYdtMT8lvMkqSS/zE+jbPewKK3yCWCBrPpMVIl2M2XHtzRZTaZ95vXP4Y3fvfd+t6QSKQG3jWlVsmazc1YOt8X0EiL2o/kiLmbTmNypxIe1MmdYRtGewog2YLWZdr5+CNBW3CdOUhnz3zG6F root@ultra96v2-zynqmp
Fingerprint: sha1!! 96:a0:e2:1b:bc:48:97:a8:96:1e:72:f2:04:f0:7d:25:3f:f0:e7:9b
dropbear.
Starting internet superserver: inetd.
Starting syslogd/klogd: done
Starting tcf-agent: OK

root@ultra96v2-zynqmp:~# ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=64 time=5.415 ms
64 bytes from 10.0.2.2: seq=1 ttl=64 time=1.795 ms
64 bytes from 10.0.2.2: seq=2 ttl=64 time=5.913 ms
64 bytes from 10.0.2.2: seq=3 ttl=64 time=1.440 ms
64 bytes from 10.0.2.2: seq=4 ttl=64 time=1.672 ms
^C
--- 10.0.2.2 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 1.440/3.247/5.913 ms
root@ultra96v2-zynqmp:~# poweroff

The system is going down for system halt NOW!(ttyPS0) (Mon Nov  2 08:05:33 20
INIT: Switching to runlevel: 0
INIT: Sending processes the TERM signal
Stopping haveged:

Stopping Dropbear SSH server: stopped /usr/sbin/dropbear (pid 2069)
dropbear.
Stopping internet superserver: inetd.
Stopping syslogd/klogd: stopped syslogd (pid 2080)
stopped klogd (pid 2083)
done
Stopping tcf-agent: OK
Deconfiguring network interfaces... ifdown: interface eth0 not configured
done.
Sending all processes the TERM signal...
logout
Sending all processes the KILL signal...
Unmounting remote filesystems...
Deactivating swap...
Unmounting local filesystems...
[  196.685507] reboot: Power down
QEMU: Terminated
Executing /etc/qemu-ifdown
Removing tap0 to br0...
Shutting down tap0...
runqemu - INFO - Cleaning up