2020年12月31日木曜日

ultra96v2+ros2 eloquentでorb_slam2を動かしてみた話

ultra96v2向けにORB_SLAM2をビルドした話。 ORB_SLAM2のビルドにはPangolinとimage_commonが必要だったので、レシピを作成する。
上記以外の必要なものはmeta-rosに含まれていたものでOKだった。

準備

環境は前に作成したものと同じ。以下に示すレシピもmeta-ultra96v2に追加済なのでそのままビルドすれば実行できる。

Pangolinのビルド

recipetoolを使用してPangolinのレシピを作成してビルドしてみる。

{class="prettyprint lang-sh} recipetool create -o pangolin_git.bb https://github.com/stevenlovegrove/Pangolin.git mv pangolin_git.bb ../sources/meta-ultra96v2/recipes-graphics/pangolin MACHINE=ultra96v2-zynqmp bitbake pangolin

そのままのビルドではエラーが出た。 内容はdo_package_qa: QA Issue: pangolin-dev package contains non-symlink .so ここを参考にして、 パッケージするファイルを選択すると解消する。合ってるかどうかはいまいち自信がない。

あと、ライセンスも修正しておく。

レシピは以下の通り。

LICENSE = "MIT & BSD-3-Clause"
LIC_FILES_CHKSUM = "file://LICENCE;md5=37611e574d0acc5cc68f827d28a9ce8a \
                    file://include/pangolin/utils/xml/license.txt;md5=d63ab70ba21ca0544b03284958324301 \
                    file://external/pybind11/LICENSE;md5=beb87117af69fd10fbf9fb14c22a2e62 \
                    file://external/pybind11/tools/clang/LICENSE.TXT;md5=dfabea443c6c16b6321441a8c8c19705"

SRC_URI = "gitsm://github.com/stevenlovegrove/Pangolin.git;protocol=https"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "86eb4975fc4fc8b5d92148c2e370045ae9bf9f5d"

S = "${WORKDIR}/git"


# NOTE: unable to map the following CMake package dependencies: Pangolin Eigen
inherit cmake
inherit python3native

DEPENDS = "libeigen glew virtual/libgl"

FILES_SOLIBSDEV = ""

FILES_${PN} += " ${libdir}/libpangolin.so"
FILES_${PN} += " ${bindir}/*"
FILES_${PN}-dev += " ${includedir}/*"


# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""

image-commonのビルド

recipetoolを使うとエラーが出てしまったので他のrosレシピを参考に手動で作成。 inherit ros_distro_eloquentと、inherit ros_superflore_generated、 ROS_BUILD_TYPE = “ament_cmake”、inherit ros_${ROS_BUILD_TYPE}を設定すれば良い。 ROS_CNはパッケージ名、ROS_BPNにはイメージ名を記載する。 buld_dependsなどはpackage.xmlに記載された設定と同じにする。 image-commonのパッケージからは4つイメージをビルドする必要があるので、 camera-calibration-parsers,camera-info-manager,image-common,image-transportの4つのレシピを作成する。 次はimage-commonの場合。レシピ名はimage-common_git.bbとしている。

LICENSE = "BSD"
#LIC_FILES_CHKSUM = "file://"

SRC_URI = "git://github.com/ros-perception/image_common.git;protocol=https;branch=ros2"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "4c5053ecf703a58c25a712d1d4a80012f5076a1f"

S = "${WORKDIR}/git"

inherit ros_distro_eloquent
inherit ros_superflore_generated

DESCRIPTION = ""
AUTHOR = "Patrick Mihelich and James Bowman"
ROS_AUTHOR = ""
HOMEPAGE = "https://wiki.ros.org/image_common"
SECTION = "devel"

ROS_CN = "image-common"
ROS_BPN = "image-common"

ROS_BUILD_DEPENDS = ""

ROS_BUILDTOOL_DEPENDS = " \
    ament-cmake-native \
"

ROS_EXPORT_DEPENDS = ""

ROS_BUILDTOOL_EXPORT_DEPENDS = ""

ROS_EXEC_DEPENDS = " \
    camera-calibration-parsers \
    camera-info-manager \
    image-transport \
"

# Currently informational only -- see http://www.ros.org/reps/rep-0149.html#dependency-tags.
ROS_TEST_DEPENDS = " \
    ament-lint-auto \
    ament-lint-common \
"

DEPENDS = "${ROS_BUILD_DEPENDS} ${ROS_BUILDTOOL_DEPENDS}"
# Bitbake doesn't support the "export" concept, so build them as if we needed them to build this package (even though we actually
# don't) so that they're guaranteed to have been staged should this package appear in another's DEPENDS.
DEPENDS += "${ROS_EXPORT_DEPENDS} ${ROS_BUILDTOOL_EXPORT_DEPENDS}"

RDEPENDS_${PN} += "${ROS_EXEC_DEPENDS}"

ROS_BUILD_TYPE = "ament_cmake"

inherit ros_${ROS_BUILD_TYPE}

orb-slam2のビルド

pangolinとcamera-calibration-parsers,camera-info-manager,image-common,image-transportが必要。 これは準備したので、レシピを作成する。

recipetoolを使用してPangolinのレシピを作成してビルドしてみる。 が、meta-ros向けのレシピはうまく作ってくれないので手作業。 package.xmlから以下の通り生成する。 superfloreなんかを使うとこの辺はうまくやってくれるのだと思う。

レシピ名はorb-slam2_git.bbとした。

LICENSE = "GPLv3 & BSD-3-Clause"
LIC_FILES_CHKSUM = "file://License-gpl.txt;md5=d32239bcb673463ab874e80d47fae504 \
                    file://LICENSE.txt;md5=9f7421fb91aef33332dbdfab7e243c01 \
                    file://orb_slam2/Thirdparty/DBoW2/LICENSE.txt;md5=b91b90de616800c44c9ebba46c143a70 \
                    file://orb_slam2/Thirdparty/g2o/license-bsd.txt;md5=9c0c0561478261cb090e64115139d923"

SRC_URI = "git://github.com/appliedAI-Initiative/orb_slam_2_ros.git;protocol=https;branch=ros2"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "0f964c618a2e0b7715c1c6fc49e6b70b2ba2c904"

S = "${WORKDIR}/git"

inherit ros_distro_eloquent
inherit ros_superflore_generated

DESCRIPTION = ""
AUTHOR = "Raul Mur-Artal, Juan D. Tardos, J. M. M. Montiel and Dorian Galvez-Lopez (DBoW2)."
ROS_AUTHOR = ""
HOMEPAGE = ""
SECTION = "devel"

ROS_CN = "orb-slam2"
ROS_BPN = "orb-slam2"

ROS_BUILD_DEPENDS = " \
    rclcpp \
    std-msgs \
    geometry-msgs \
    tf2-geometry-msgs \
    cv-bridge \
    image-common \
    image-transport \
    tf2-ros \
    sensor-msgs \
    rosidl-default-generators \
"

ROS_BUILDTOOL_DEPENDS = " \
    ament-cmake-native \
    rosidl-default-generators-native \
"

ROS_EXPORT_DEPENDS = " \
    boost \
    cairo \
    ceres-solver \
    gflags \
    glog \
    libeigen \
    lua \
    protobuf \
"

ROS_BUILDTOOL_EXPORT_DEPENDS = ""

ROS_EXEC_DEPENDS = " \
    rclcpp \
    std-msgs \
    geometry-msgs \
    cv-bridge \
    image-transport \
    tf2-ros \
    sensor-msgs \
    rosidl-default-runtime \
"

# Currently informational only -- see http://www.ros.org/reps/rep-0149.html#dependency-tags.
ROS_TEST_DEPENDS = " \
    ament-lint-auto \
    ament-lint-common \
"

DEPENDS = "${ROS_BUILD_DEPENDS} ${ROS_BUILDTOOL_DEPENDS}"
# Bitbake doesn't support the "export" concept, so build them as if we needed them to build this package (even though we actually
# don't) so that they're guaranteed to have been staged should this package appear in another's DEPENDS.
DEPENDS += "${ROS_EXPORT_DEPENDS} ${ROS_BUILDTOOL_EXPORT_DEPENDS}"

RDEPENDS_${PN} += "${ROS_EXEC_DEPENDS}"

FILES_${PN} += "*"

ROS_BUILD_TYPE = "ament_cmake"

inherit ros_${ROS_BUILD_TYPE}

動作確認

hostでrviz2を起動し、point_cloudをAddする。 debug_imageは追加してもカクカクなので見ない。

  • window1
source /opt/ros/foxy/setup.sh
rviz2

テスト用にTUM1のbagファイルを再生する。

  • window2
source /opt/ros/noetic/setup.sh
source /opt/ros/foxy/setup.sh
ros2 bag play -s rosbag_v2 rgbd_dataset_freiburg1_xyz.bag --read-ahead-queue-size 1000000

bagファイルの再生には時間がかかるので、 その間にultra96v2にsshでログインしてorb_slam2を起動させる。

  • window3
root@ultra96v2-zynqmp:~# source ros_setup.sh
root@ultra96v2-zynqmp:~# ros2 launch orb_slam2_ros TUM1_mono_launch.py
[INFO] [launch]: All log files can be found below /home/root/.ros/log/2020-12-28-21-11-00-749497-ultra96v2-zynqmp-1140
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [orb_slam2_ros_mono-1]: process started with pid [1149]
[orb_slam2_ros_mono-1] [INFO] [orb_slam2_mono]: Camera info received.
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1] ORB-SLAM2 Copyright (C) 2014-2016 Raul Mur-Artal, University of Zaragoza.
[orb_slam2_ros_mono-1] This program comes with ABSOLUTELY NO WARRANTY;
[orb_slam2_ros_mono-1] This is free software, and you are welcome to redistribute it
[orb_slam2_ros_mono-1] under certain conditions. See LICENSE.txt.
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1] OpenCV version : 3.4.3
[orb_slam2_ros_mono-1] Major version : 3
[orb_slam2_ros_mono-1] Minor version : 4
[orb_slam2_ros_mono-1] Subminor version : 3
[orb_slam2_ros_mono-1] Input sensor was set to: Monocular
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1] Loading ORB Vocabulary.
[orb_slam2_ros_mono-1] Vocabulary loaded!
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1] Camera Parameters:
[orb_slam2_ros_mono-1] - fx: 525
[orb_slam2_ros_mono-1] - fy: 525
[orb_slam2_ros_mono-1] - cx: 319.5
[orb_slam2_ros_mono-1] - cy: 239.5
[orb_slam2_ros_mono-1] - k1: 0
[orb_slam2_ros_mono-1] - k2: 0
[orb_slam2_ros_mono-1] - p1: 0
[orb_slam2_ros_mono-1] - p2: 0
[orb_slam2_ros_mono-1] - fps: 30
[orb_slam2_ros_mono-1] - bf: 0
[orb_slam2_ros_mono-1] - color order: RGB (ignored if grayscale)
[orb_slam2_ros_mono-1]
[orb_slam2_ros_mono-1] ORB Extractor Parameters:
[orb_slam2_ros_mono-1] - Number of Features: 2000
[orb_slam2_ros_mono-1] - Scale Levels: 8
[orb_slam2_ros_mono-1] - Scale Factor: 1.2
[orb_slam2_ros_mono-1] - Initial Fast Threshold: 20
[orb_slam2_ros_mono-1] - Minimum Fast Threshold: 7
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] [WARN] [orb_slam2_mono]: Map point vector is empty!
[orb_slam2_ros_mono-1] New Map created with 237 points
[ 1284.850620] NOHZ: local_softirq_pending 08

2020年12月26日土曜日

Ubuntu 20.04 + ros2 foxyでORB_SLAM2を使ってみた

Ubuntu 20.04 + ros2 foxyでORB_SLAM2を使ってみた話。

環境

Ubuntu 20.04
ros2 foxy ros noetic(rosbag2によるデータセット再生用)

ros2はソースビルドをした場合にrosbag2_bag_v2をビルドするのがうまくできなかったので、 パッケージ版を使用する。 今回はros1で保存されているbagファイルを再生させるためにrosbag2_bag_v2プラグインを使用したいので、 noeticの環境をセットアップした後にfoxyとrosbag2の環境を準備した。

まずはnoeticのセットアップを行う。 公式ページにしたがって環境セットアップだけする。 必要なパッケージは後でインストールされるのでここでは不要。

sudo apt update && sudo apt install curl gnupg2 lsb-release
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

次はros2側のセットアップを行う。foxyを使用し、rosbag2とbag_v2プラグインをセットアップする。 インストールするのはros-foxy-ros2bagとros-foxy-rosbag2*なので注意。 公式ページにしたがって以下のように準備。

curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2-latest.list'
sudo apt update
sudo apt install ros-foxy-base
sudo apt update && apt-get install -y ros-foxy-ros2bag ros-foxy-rosbag2*

ORB_SLAM2のビルド

必要なソースを取得してきてビルドを行う。

cd <work-dir>
mkdir src
cd src
git clone https://github.com/ros-perception/vision_opencv.git -b ros2
git clone https://github.com/ros-perception/image_common.git -b ros2
git clone https://github.com/appliedAI-Initiative/orb_slam_2_ros.git -b ros2

今回試した際のHash値は次の通りだった。 image_common:4c5053ecf703a58c25a712d1d4a80012f5076a1f
vision_opencv:2026f6d66833e0830f9ce69004d43c9abd1e5fa4 orb_slam_2_ros:0f964c618a2e0b7715c1c6fc49e6b70b2ba2c904

orb_slam_2_rosのLaunchファイルを作成する。 なぜかは分からないけど、コマンドラインからのRemapオプションが受け付けられないので。

今回は動かすだけなので、params_fileはデフォルトのparams_d435_mono.yamlを使用する。 オリジナルのTUM1.yamlを使用しても良い。

import os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory


def generate_launch_description():

    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    voc_file = LaunchConfiguration('voc_file')

    remappings = [
        ('/camera/image_raw', '/camera/rgb/image_color'),
        ('/camera/camera_info', '/camera/rgb/camera_info'),
    ]

    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='false',
            description='Use simulation (Gazebo) clock if true'),

        DeclareLaunchArgument(
            'params_file',
            default_value=os.path.join(
                get_package_share_directory("orb_slam2_ros"),
                'ros', 'config', 'params_d435_mono.yaml'),
            description='Full path to the ROS2 parameters file to use for all launched nodes'),

        DeclareLaunchArgument(
            'voc_file',
            default_value=os.path.join(
                get_package_share_directory("orb_slam2_ros"),
                'orb_slam2', 'Vocabulary', 'ORBvoc.txt'),
            description='Full path to vocabulary file to use'),

        Node(
            parameters=[
              params_file,
              {"voc_file": voc_file,
               "use_sim_time": use_sim_time},
            ],
            package='orb_slam2_ros',
            node_executable='orb_slam2_ros_mono',
            node_name='orb_slam2_mono',
            output='screen',
            remappings=remappings
        )
    ])

あとは依存関係正しく無いと思われるので、orb_slam_2_rosのpackage.xmlを修正する。
image_commonを足しておく。

cd <work-dir>
source /opt/ros/foxy/setup.sh
colcon build --symlink-install

ORB_SLAM2の動作確認

  • window1
source install/setup.sh
ros2 launch orb_slam2_ros TUM1_mono_launch.py
  • window2
source /opt/ros/foxy/setup.sh
rviz2

debug_imageと、point_cloudをAddする。


bagファイルをここから取得する。 テストにはrgbd_dataset_freiburg1_xyzを使用した。

  • window3
source /opt/ros/noetic/setup.sh
source /opt/ros/foxy/setup.sh
ros2 bag play -s rosbag_v2 rgbd_dataset_freiburg1_xyz.bag --read-ahead-queue-size 1000000

以下の通りの結果が得られた。


 

2020年12月9日水曜日

ultra96v2でVitis_AIを試してみた(2020.2)

ultra96v2でVitis_AIを試してみた話。

参考ページ

sdイメージの作成はここ

MNISTの実行はここ

日本語ならここ

環境

Ubuntu 20.04
Vitis 2020.2
Vivado 2020.2
Petalinux 2020.2

準備

ここに書いてあるplatformを準備する。 petalinuxのイメージは記事から変更している。(Vitis-AI関連とparted関連) vitis-ai-devパッケージは念の為入れといたけど動かす分には不要そう。(試して無いのでリポジトリはそのまま)

Platformの作成

VItis-AIにあるDPU-TRDをultra96v2向けに設定する。

cd <path-to-work-dir>
git clone https://github.com/Xilinx/Vitis-AI.git -b v1.2.1
cd DPU-TRD/prj/Vitis

そのままだと合成できなかったので以下3つのファイルを変更した。

  • DPU-TRD/prj/Vitis/Makefile そのままの設定だとultra96v2に乗らないので、Configを変更する。 また、pre-builtの環境を使用しないので指定できるように変更する。

hwhファイルのパスが変更となっているのか、取得できなかったので合わせて修正している。

-XOCC_OPTS = -t ${TARGET} --platform ${SDX_PLATFORM} --save-temps --config ${DIR_PRJ}/config_file/prj_config_102_3dpu_LPD --xp param:compiler.userPostSysLinkOverlayTcl=${DIR_PRJ}/syslink/strip_interconnects.tcl 
+XOCC_OPTS = -t ${TARGET} --platform ${SDX_PLATFORM} --save-temps --config ${DIR_PRJ}/config_file/prj_config --xp param:compiler.userPostSysLinkOverlayTcl=${DIR_PRJ}/syslink/strip_interconnects.tcl

-   v++ -t ${TARGET} --platform ${SDX_PLATFORM} -p binary_container_1/dpu.xclbin --package.out_dir binary_container_1 --package.rootfs $(EDGE_COMMON_SW)/rootfs.ext4 --package.sd_file $(EDGE_COMMON_SW)/Image 
-   cp ./binary_*/link/vivado/vpl/prj/prj.srcs/sources_1/bd/*/hw_handoff/*.hwh ./binary_*/sd_card
+   v++ -t ${TARGET} --platform ${SDX_PLATFORM} -p binary_container_1/dpu.xclbin --package.out_dir binary_container_1 --package.rootfs $(ROOTFS) --package.sd_file $(IMAGE)
+   cp ./binary_*/link/vivado/vpl/prj/*/sources_1/bd/*/hw_handoff/*.hwh ./binary_*/sd_card
  • DPU-TRD/prj/Vitis/config_file/prj_config DPUを1個に設定する。
-freqHz=300000000:DPUCZDX8G_2.aclk
-freqHz=600000000:DPUCZDX8G_2.ap_clk_2
+#freqHz=300000000:DPUCZDX8G_2.aclk
+#freqHz=600000000:DPUCZDX8G_2.ap_clk_2

-sp=DPUCZDX8G_2.M_AXI_GP0:HPC0
-sp=DPUCZDX8G_2.M_AXI_HP0:HP2
-sp=DPUCZDX8G_2.M_AXI_HP2:HP3
+#sp=DPUCZDX8G_2.M_AXI_GP0:HPC0
+#sp=DPUCZDX8G_2.M_AXI_HP0:HP2
+#sp=DPUCZDX8G_2.M_AXI_HP2:HP3

-nk=DPUCZDX8G:2
+nk=DPUCZDX8G:1
  • DPU-TRD/prj/Vitis/dpu_conf.vh b/DPU-TRD/prj/Vitis/dpu_conf.vh DPUの型式を変更する。
-`define B4096 
+`define B512

修正したらmakeする。

source <vitis_install_path>/2020.2/settings.sh
make KERNEL=DPU_SM DEVICE=ultra96v2 SDX_PLATFORM=<path-to-platform>/ultra96v2-platform.xpfm ROOTFS=<path-to-rootfs>/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.ext4 IMAGE=<path-to-image>/Image

ビルドが終了したらsdカードを作成する。

dd if=binary_container_1/sd_card.img of=/dev/sdX

MNIST実行ファイルの作成

Vitis-AI-Tutorialを利用する。 dockerのsetupは必要。 理由は不明だが、vitis-ai-cpu:latestはdletがうまく動作しなかったので、 xilinx/vitis-ai:latestを使用。2020.2を使用しているからか?

cd <path-to-work-dir>
git clone https://github.com/Xilinx/Vitis-AI-Tutorials.git -b MNIST=Classification-TensorFlow
    cd Vitis-AI-Tutorials/files
cp <path-to-work-dir>/Vitis-AI/DPU-TRD/prj/Vitis/binary_container_1/sd_card/ultra96v2_4z.hwh .
wget https://www.fpga.co.jp/u96v2_vitisai_2020.1/u96v2.json
./docker_run xilinx/vitis-ai:latest

vitis-aiが起動したらTutorialに従い以下の通り実行する。 6_compileと7_make_targetはultra96v2向けに変更が必要。

source 0_setenv.sh
dlet -f ultra96v2_4z.hwh
export COMPILE_u96v2=${BUILD}/compile_u96v2
export TARGET_u96v2=${BUILD}/target_u96v2
source 1_train.sh
source 2_freeze.sh
source 3_eval_frozen_graph.sh
source 4_quant.sh
source 5_eval_quant_graph.sh

#source 6_compile_u96v2.sh
rm -rf ${COMPILE_u96v2}
mkdir -p ${COMPILE_u96v2}
vai_c_tensorflow --frozen_pb  ${QUANT}/deploy_model.pb --arch ./u96v2.json --output_dir ${COMPILE_u96v2} --net_name ${NET_NAME}

#source 7_make_target_u96v2.sh
# remove previous results
rm -rf ${TARGET_u96v2}
mkdir -p ${TARGET_u96v2}/model_dir

# copy application to target folder
cp ${APP}/*.py ${TARGET_u96v2}
echo "  Copied application to target folder"

# copy elf to target folder
cp ${COMPILE_u96v2}/*.elf ${TARGET_u96v2}/model_dir/.
echo "  Copied elf file(s) to target folder"

# create image files and copy to target folder
mkdir -p ${TARGET_u96v2}/images

python generate_images.py  \
    --dataset=mnist \
    --image_dir=${TARGET_u96v2}/images \
    --image_format=jpg \
    --max_images=10000

ultra96v2の電源を投入し、ログインしてSDのパーティションを広げる。 wifiを有効にしているので、wifi経由でアクセスする場合にはネットワーク接続したあと以下の通り実行する。

ssh 192.168.2.1 -l root
parted
resizepart
2
Yes
100%
quit
resize2fs /dev/mmcblk0p2

このあと、ホストから必要なファイルを転送してチュートリアルを実行する。

cd <path-to-work-dir>/Vitis-AI-Tutorials/files
tar cvfz target_u96v2.tar.gz build/target_u96v2
scp target_u96v2.tar.gz root@192.168.2.1:~/

ターゲット側で以下の通り実行して動作確認する。 2スレッド実行時は-t 2を指定する。

tar xzvf target_u96v2.tar.gz
cd build/target_u96v2
python3 app_mt.py -m model_dir/dpu_customcnn.elf

実行結果

root@ultra96v2-zynqmp:~/build/target_u96v2# python3 app_mt.py -m model_dir/dpu_customcnn.elf 
Command line options:
 --image_dir :  images
 --threads   :  1
 --model     :  model_dir/dpu_customcnn.elf
Pre-processing 10000 images...
Starting 1 threads...
FPS=2679.56, total frames = 10000 , time=3.7320 seconds
Correct: 980 Wrong: 9020 Accuracy: 0.098

root@ultra96v2-zynqmp:~/build/target_u96v2# python3 app_mt.py -m model_dir/dpu_customcnn.elf -t 2
Command line options:
 --image_dir :  images
 --threads   :  2
 --model     :  model_dir/dpu_customcnn.elf
Pre-processing 10000 images...
Starting 2 threads...
FPS=3346.35, total frames = 10000 , time=2.9883 seconds
Correct: 980 Wrong: 9020 Accuracy: 0.098

2020年12月4日金曜日

ultra96v2のembedded acceleration platformをvitis2020.2で作成してみた話その2

ultra96v2のembedded platformをvitis 2020.2で作成した話。 VitisのVecaddを動かすまで。 前回の続き。

準備

vitisで使用するlinux_bifとqemu_args.txtとpmu_args.txtを準備する。

cd <work-dir-path>
mkdir vitis_args

vitis_argsにlinux.bifとqemu_args.txtとpmu_args.txtを保存する。内容は以下の通り。

  • linux.bif
/* linux */
the_ROM_image:
{
    [fsbl_config] a53_x64
    [bootloader] <fsbl-ultra96v2-zynqmp.elf>
    [destination_device=pl] <bitstream>
    [pmufw_image] <pmu-firmware-ultra96v2-zynqmp.elf>
    [destination_cpu=a53-0, exception_level=el-3, trustzone] <arm-trusted-firmware.elf>
    [load=0x100000] <system.dtb>
    [destination_cpu=a53-0, exception_level=el-2] <u-boot.elf>
}
  • qemu_args.txt
    system.dtbは2020.1からBOOT.binで書き込むようにしている模様。
    ##work-dir-path##は環境に合わせて置き換えてください。
-M arm-generic-fdt
-net nic -net nic -net nic
-serial /dev/null -serial mon:stdio
-display none
-device loader,file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf,cpu-num=0
-device loader,file=<u-boot.elf>
-device loader,file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb,addr=0x100000
-drive file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.wic.qemu-sd,if=sd,id=sd0,format=raw,index=0
-boot mode=3
-global xlnx,zynqmp-boot.cpu-num=0
-global xlnx,zynqmp-boot.use-pmufw=true
-m 4G
  • pmu_args.txt
    ##work-dir-path##は環境に合わせて置き換えてください。
-M microblaze-fdt
-serial /dev/null -serial /dev/null
-display none
-device loader,file=##work-dir-path##/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-ultra96v2-zynqmp.elf
-device loader,addr=0xfd1a0074,data=0x1011003,data-len=4
-device loader,addr=0xfd1a007C,data=0x1010f03,data-len=4

Platformの作成

ここを参考にplatformを作成していく。 日本語ならこちら

export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
source <path-to-vitis-installation>/2020.2/settings64.sh
cd <work-dir-path>
mkdir vitis_pfm
cd vitis_pfm
mkdir wksp1
vitis -workspace wksp1

create platformを行い、platform名はultra96v2-platform、xsaは/xsa_dir/ultra96v2_4z/ultra96v2_4z.xsaを指定する。

linux domainの設定を以下のように行う。

Bif File: <work-dir-path>/vitis_args/linux.bif
Boot Components Directory:<work-dir-path>/boot
Linux Image Directory:<work-dir-path>/boot
Linux Rootfs:<work-dir-path>/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.ext4
Bootmode:SD
Sysroot Directory:<work-dir-path>/sdk/sysroots/aarch64-xilinx-linux
QEMU Data:<work-dir-path>/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp
QEMU Arguments:<work-dir-path>/vitis_args/qemu_args.txt
PMU QEMU Arguments:<work-dir-path>vitis_args/pmu_args.txt

platformをbuildする。Application projectを作成するところまでは同じだが、その後のUIが少し変わっている。


 

vecadd_systemを開いてActive Build Configurationを変更してAssistant上でBuildする。

また、最初にリソースファイルを作成するようになったためか、buildボタンを押してしばらく反応が無かったりする。ビルドが始まるまで気長に待つ必要があった。 ビルドの際にkernelとhw_linkとhostプログラムを分けてビルドしてくれるようになったり、変更後のビルドで影響ある部分だけビルドしてくれたりと少し賢くなったけど、初動は遅くなったイメージを持った。

Platformのテスト

ここを参考にplatformのテストを行う。 日本語ならこちら

application project nameはvecaddとした。 途中、Kernel Imageが空欄となっているので、/boot/Imageを指定しておく。

Emulation-SW

まずはvecadd_systemを開いてActive Build ConfigurationをEmulation-SWに変更してBuildする。 Launch on Emulatorを試す。 RunかDebugのボタンを押し、Launch SW Emulatorを選択する。 Application Timelineはデフォルトで有効になっていないので、有効にする場合はRun ConfigurationsからXilinx Runtime ProfilingのConfigurationをEditして、OpenCL detailed profile summary and timeline traceを選択する。


 
 

結果は以前と変化ないので省略。

また、2020.2ではEmulation-SWのLaunch on Hardwareに相当する操作はできなくなっていた。 アクセラレーション前の実行時間を計測するのに便利そうと思っていたのに。 直接動かしたり、コマンドラインからのデバッグ実行ならばいけるかもしれないので、後で試す。 (または、Emulatorが起動したとしてもTCFの接続先を実機にしておけば目的は達成されるかも)

Emulation-HW

vecadd_systemを開いてActive Build ConfigurationをEmulation-HWに変更してBuildする。 Launch Emulator in GUI modeを選択するとvivado simulatorが立ち上がるのが見える。


 

GUI modeの場合は手動で実行されるまでQEMUは実行を待機している模様。必要な信号線をaddした後にrun allすることを想定しているのかな。


 

今回Emulation-HWの動作が期待通りとなることを確認したけど、v2020.1でEmulation-HW(Launch on Hardware)は何をやっていたことになるのか謎。 Timelineあったけど、普通にHardwareの動作していただけ?

Hardware

vecadd_systemを開いてActive Build ConfigurationをHardwareに変更してBuildする。 SDの準備はv2020.1と同じ。sd_card.imgをddすれば良い。

また、これもv2020.1の時と同じであるが、Lunch Target Connectionで実機に接続できるように設定を行う。Emulation-SWのLaunch Target Connectionを参照。

実行結果はTEST PASSEDが出るだけで特別言うことも無いので省略。

Vitis Analyzer 

それぞれの実行結果を記載する。
Emulation-HWの結果がエラい長いけどこんな感じでいいのか?

Emulation-SW



 

Emulation-HW

 


Hardware



 

 

2020年12月3日木曜日

ultra96v2のembedded acceleration platformをvitis2020.2で作成してみた話その1

ultra96v2のembedded platformを作成した話。 今回はHW-ComponentとSW-Componentを作成するところまで。 やり方はは2020.1のときと同じ

準備

使用するのは以下のもの。 

  • cmake
  • make
  • repo
  • Vivado 2020.2
  • Vitis 2020.2

cmake と repoが無い場合は以下の通り入手可能。

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

HW-Componentの作成

ここを参考にしてブロックデザインを作成している。 日本語ならこちら

なお、Emulation-HWを実行するためにひと手間加えている。 参考にしたのは公式ドキュメントの、 “Enabling Hardware Emulation for Extensible XSA”。
明確にEmbedded環境に関する話は書いていないが、Versal向けの設定をEmbedded環境向けに適用してみたところ、 期待通りにEmulation動作したので採用した。 (公式の記載通りではないので使用する際は自己責任です) 行った内容はブロックデザインを開き以下の通りplatform_stateの設定と、 PS部のSELECTED_SIM_MODELをrtl=>tlmに変更した。 この変更をしないとEmulation-HW実行時にQEMUが動作開始できないのだと思う。

set_property platform.platform_state "pre_synth" [current_project]
set_property SELECTED_SIM_MODEL tlm [get_bd_cells /zynq_ultra_ps_e_0]

 


公式ドキュメントに記載されているwrite_hw_platformのオプション-hw_emuは2020.1以降は多分不要。(どこかで非推奨と書いてあったような気もする。つけて無くても必要なファイルは出力されるっぽい) 

ただ、2019.2だと必要と思われる。(オプションのあるなしでファイルサイズがだいぶ違ったので) 

GUIだと、Vivado File > Export > Export Platform からHardware and hardware emulationを選択すれば問題はなさそう。このときpre_synthの設定もされる。(はず。tclで設定してしまったのでよくわからない。)

以下の手順はすでに実施済のものを生成し、xsa_dirにxsaファイルをコピーする。

cd <work-dir-path>
source <path-to-vivado-installation>/2020.1/settings64.sh
git clone https://github.com/akira-nishiyama/vivado_cmake_helper.git
git clone https://github.com/akira-nishiyama/ultra96v2_4z.git -b v2020.2
source vivado_cmake_helper/setup.sh
mkdir xsa_dir
cd ultra96v2_4z
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=../../xsa_dir
make
make install
cd ../../

buildディレクトリ以下にvivadoのプロジェクトが作られるので、これを操作してカスタマイズも可能。カスタマイズ後はscriptsフォルダにExport Blockdesignをアップデートする必要がある。また、ソース等を編集、追加した場合はsrcフォルダにRTLファイルをコピーしてバージョン管理しないと再生成できない。(ソースファイルなどはプロジェクトにインポートしておかないとxsaファイルが作成できないことが理由)

SW-Componentの作成

mkdir petalinux
mkdir sdk
mkdir boot
cd PetaLinux
repo init -u http://github.com/akira-nishiyama/petalinux-ros2-manifests -b feature-v2020.2
repo sync
source setupsdk
#edit conf/local.conf

conf/local.confを開き、下記の通りHDF設定を修正する。

HDF_EXT_ultra96v2-zynqmp = "xsa"
HDF_BASE_ultra96v2-zynqmp = "file://"
HDF_PATH_ultra96v2-zynqmp = "<work-dir-path>/xsa_dir/ultra96v2_4z/ultra96v2_4z.xsa"

bitbakeする。

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

動作のためにQEMUを起動する。

cp <path-to-vitis-installation>/2020.1/data/emulation/dtbs/zynqmp/pmu_rom_qemu_sha3.elf tmp/deploy/image/tmp/deploy/images/ultra96v2-zynqmp/pmu-rom.elf
MACHINE=ultra96v2-zynqmp runqemu

起動したら以下の通り実行して動作を確認する。

root@ultra96v2-zynqmp:~# source ros_setup.sh
root@ultra96v2-zynqmp:~# (sleep 5; ros2 topic pub /chatter std_msgs/String "data: Hello world") &
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')

終了するにはpoweroffを入力し、Ctrl-a, Ctrl-x。

sdkを展開する

tmp/deploy/sdk/petalinux-glibc-x86_64-petalinux-image-minimal-ultra96v2ros2-aarch64-ultra96v2-zynqmp-toolchain-2020.1.sh -d ../../sdk/

必要なデータをbootフォルダにコピーしておく。 2020.2ではVitisで絶対パス指定がうまく行かなくなっていたので、 ブートデータ作成に必要なファイルはすべてbootフォルダに保存する。

cp tmp/deploy/images/ultra96v2-zynqmp/fsbl-ultra96v2-zynqmp.elf ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/pmu-firmware-ultra96v2-zynqmp.elf ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/system.dtb ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/u-boot.elf ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/boot.scr ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/uEnv.txt ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/Image ../../boot/

2020年11月29日日曜日

ultra96v2のembedded acceleration platformをvitis2020.1で作成してみた話その2

ultra96v2のembedded platformを作成した話。 VitisのVecaddを動かすまで。 前回の続き。

準備

vitisで使用するlinux_bifとqemu_args.txtとpmu_args.txt

cd <work-dir-path>
mkdir vitis_args

vitis_argsにlinux.bifとqemu_args.txtとpmu_args.txtを保存する。内容は以下の通り。 <>で囲んだファイルはvitisが補完してくれるようだけど、よく問題が出たのでbitstream以外は直接指定することにしている。

  • linux.bif
    ##work-dir-path##は環境に合わせて置き換えてください。

    /* linux */
    the_ROM_image:
    {
      [fsbl_config] a53_x64
      [bootloader] ##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/fsbl-ultra96v2-zynqmp.elf
      [destination_device=pl] <bitstream>
      [pmufw_image] ##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-firmware-ultra96v2-zynqmp.elf
      [destination_cpu=a53-0, exception_level=el-3, trustzone] ##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf
      [load=0x100000] ##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb
      [destination_cpu=a53-0, exception_level=el-2] ##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/u-boot.elf
    }
  • qemu_args.txt
    system.dtbは2020.1からBOOT.binで書き込むようにしている模様。
    ##work-dir-path##は環境に合わせて置き換えてください。

    -M arm-generic-fdt
    -net nic -net nic -net nic
    -serial /dev/null -serial mon:stdio
    -display none
    -device loader,file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/arm-trusted-firmware.elf,cpu-num=0
    -device loader,file=<u-boot.elf>
    -device loader,file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/system.dtb,addr=0x100000
    -drive file=##work-dir-path##/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.wic.qemu-sd,if=sd,id=sd0,format=raw,index=0
    -boot mode=3
    -global xlnx,zynqmp-boot.cpu-num=0
    -global xlnx,zynqmp-boot.use-pmufw=true
    -m 4G
  • pmu_args.txt
    ##work-dir-path##は環境に合わせて置き換えてください。

    -M microblaze-fdt
    -serial /dev/null -serial /dev/null
    -display none
    -device loader,file=##work-dir-path##/build/tmp/deploy/images/ultra96v2-zynqmp/pmu-ultra96v2-zynqmp.elf
    -device loader,addr=0xfd1a0074,data=0x1011003,data-len=4
    -device loader,addr=0xfd1a007C,data=0x1010f03,data-len=4

Platformの作成

ここを参考にplatformを作成していく。 日本語ならこちら。 2020.1ではこのARを実行しないとEmulation-HWのビルドができない。

export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
source <path-to-vitis-installation>/2020.1/settings64.sh
cd <work-dir-path>
mkdir vitis_pfm
cd vitis_pfm
mkdir wksp1
vitis -workspace wksp1

create platformを行い、platform名はultra96v2-platform、xsaは/xsa_dir/ultra96v2_4z/ultra96v2_4z.xsaを指定する。

linux domainの設定を以下のように行う。

Bif File: <work-dir-path>/vitis_args/linux.bif
Boot Components Directory:<work-dir-path>/boot
Linux Image Directory:<work-dir-path>/boot
Linux Rootfs:<work-dir-path>/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp/petalinux-image-minimal-ultra96v2ros2-ultra96v2-zynqmp.ext4
Bootmode:SD
Sysroot Directory:<work-dir-path>/sdk/sysroots/aarch64-xilinx-linux
QEMU Data:<work-dir-path>/petalinux/build/tmp/deploy/images/ultra96v2-zynqmp
QEMU Arguments:<work-dir-path>/vitis_args/qemu_args.txt
PMU QEMU Arguments:<work-dir-path>vitis_args/pmu_args.txt

platformをbuildする。方法は上記ページを参照のこと。

Platformのテスト

ここを参考にplatformのテストを行う。 日本語ならこちら

application project nameはvecaddとした。 途中、Kernel Imageが空欄となっているので、/boot/Imageを指定しておく。

Emulation-SW

まずはEmulation-SWをLaunch on EmulatorとLaunch on Hardwareで試す。 Emulation-SWを右クリックで選択し、Buildを実行する。

その後Emulation-SWを右クリックで選択し、Run->Launch On Emulatorを実行する。

Launch on Emulator 実行結果


Launch on HardwareではSDを作成する必要がある。 SDは以下の通り作成する。

cd <work-dir-path>/vitis_pfm/wksp1/vecadd/Emulation-SW/package
dd if=sd_card.img of=/dev/sdX

上記のsd_card.imgにはBOOT.binが含まれていないので、 /petalinux/build/tmp/image/ultra96v2-zynqmp/boot.binをパーティション1に追加する。

SDをultra96v2に挿入し、電源をONする。 しばらく待っているとWifiのアクセスポイントが見えて来るので、これに接続する。

Lunch Target Connectionで実機に接続できるように設定を行う。 ultra96v2のwifi APはデフォルトで192.168.2.1のIPを持っているので、以下のように設定する。 ultra96v2が起動していればTest Connectionで接続を確認できる。

Launch Target Connection


 
Target Connectionsの+ボタンから設定を追加する。


その後Emulation-HWを右クリックで選択し、Run->Launch On Hardwareを実行する。

Launch on Hardware 実行結果
省略

Emulation-HW

Launch on Emulatorでは理由は不明だが、Launch on Emulatorを実行するとQEMUのプロセスが停止したままとなる。 恐らくはVivado Simulatorからの接続待ちなのではないかと思っているけど、 どうしても使用したいわけでもないのでツールのバージョンアップに期待する。 ここでは実機との組み合わせで動かしてみる。

SDの準備はEmulation-HWのものを使用する他はEmulation-SWと同じ。 すでにEmulation-SWをLaunch on Hardwareで実行している場合にはbinary_container_1.xclbinとvecaddを差し替えるだけで良い(はず。あまり自信が無い)。 scpで/media/sd-mmcblk0p1に送り込むのが便利。Vitisが勝手にやってくれるかもしれないけど。

あと、Vivado simが動いていないように見えるのも気になる。これのやり方合ってるのだろうか?

Launch on Hardware 実行結果


Hardware

Hardwareを右クリックしてBuildする。 SDの準備はHardwareのものを使用する他はEmulation-SWと同じ。 その後Hardwareを右クリックで選択し、Run->Launch On Hardwareを実行する。

Launch on Hardware実行結果


Vitis Analyzer 

それぞれの実行結果を記載する。
Kernel RuntimeをSW実行時とHW実行時で比較するのと、 Application Timelineでボトルネックを特定して改良していく感じなのかな?
Emulation-HW(Launch on Hardware)はHardware実行に比べてApplication Timelineが得られるということだろうか。
このあたりはもう少しドキュメントの読み込みが必要そう。

Emulation-SW(Launch on Emulator)


Emulation-SW(Launch on Hardware)





Emulation-HW(Launch on Hardware)



Hardware(Launch on Hardware)







2020年11月28日土曜日

ultra96v2のembedded acceleration platformをvitis2020.1で作成してみた話その1

ultra96v2のembedded platformを作成した話。 今回はHW-ComponentとSW-Componentを作成するところまで。

準備

使用するのは以下のもの。 

  • cmake
  • make
  • repo
  • Vivado 2020.1
  • Vitis 2020.1

cmake と repoが無い場合は以下の通り入手可能。

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

HW-Componentの作成

ここを参考にしてブロックデザインを作成している。 日本語ならこちら。 以下の手順はすでに実施済のものを生成し、xsa_dirにxsaファイルをコピーする。

cd <work-dir-path>
source <path-to-vivado-installation>/2020.1/settings64.sh
git clone https://github.com/akira-nishiyama/vivado_cmake_helper.git
git clone https://github.com/akira-nishiyama/ultra96v2_4z.git -b v2020.1
source vivado_cmake_helper/setup.sh
mkdir xsa_dir
cd ultra96v2_4z
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=../../xsa_dir
make
make install
cd ../../

buildディレクトリ以下にvivadoのプロジェクトが作られるので、これを操作してカスタマイズも可能。

SW-Componentの作成

mkdir petalinux
mkdir sdk
mkdir boot
cd PetaLinux
repo init -u http://github.com/akira-nishiyama/petalinux-ros2-manifests -b feature-rel-v2020.1
repo sync
source setupsdk
#edit conf/local.conf

conf/local.confを開き、下記の通りHDF設定を修正する。

HDF_EXT_ultra96v2-zynqmp = "xsa"
HDF_BASE_ultra96v2-zynqmp = "file://"
HDF_PATH_ultra96v2-zynqmp = "<work-dir-path>/xsa_dir/ultra96v2_4z/ultra96v2_4z.xsa"

bitbakeする。

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

動作のためにQEMUを起動する。

cp <path-to-vitis-installation>/2020.1/data/emulation/dtbs/zynqmp/pmu_rom_qemu_sha3.elf tmp/deploy/image/tmp/deploy/images/ultra96v2-zynqmp/pmu-rom.elf
MACHINE=ultra96v2-zynqmp runqemu

起動したら以下の通り実行して動作を確認する。

root@ultra96v2-zynqmp:~# source ros_setup.sh
root@ultra96v2-zynqmp:~# (sleep 5; ros2 topic pub /chatter std_msgs/String "data: Hello world") &
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')

終了するにはpoweroffを入力し、Ctrl-a, Ctrl-x。

sdkを展開する

tmp/deploy/sdk/petalinux-glibc-x86_64-petalinux-image-minimal-ultra96v2ros2-aarch64-ultra96v2-zynqmp-toolchain-2020.1.sh -d ../../sdk/

必要なデータをbootフォルダにコピーしておく。

cp tmp/deploy/images/ultra96v2-zynqmp/boot.scr ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/uEnv.txt ../../boot/
cp tmp/deploy/images/ultra96v2-zynqmp/Image ../../boot/

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月10日火曜日

ros2 eloquent+Ubuntu18.04でorb_slam_2_rosを動作させてみた

dashingだとros2対応版のORB_SLAMがうまくビルドできなかったので、eloquentに変更して動作させてみた。とりあえず動かしてみた結果のメモ。

ros2 eloquentのソースフェッチ

ここに書いてあるとおりにすればOK。 だけどgeometoryを変更したほうが良いのでInstall dependencies using rosdepまでで止めておく。 ros1_bridgeのビルド方法は後で確認する。前回の環境使用すれば動作するので。

ros2 eloquentのgeometoryを変更

0.12.0でorb_slam_2_rosのビルドに成功したので、変更する。

cd ~/ros2_eloquent/src/ros2/geometory
git checkout 0.12.0

ros2 eloquent+のビルド

cd ~/ros2_eloquent
colcon build --symlink-install --packages-skip ros1_bridge

image_commonとcv_bridgeのビルド

image_commonはちょうど良いタグが見つからなかったのでログかビルド成功しそうなものを選択した。 vision_opencvはとりあえずros2ブランチを選択したところうまく行った。 hashは2026f6d66833e0830f9ce69004d43c9abd1e5fa4。

source ~/ros2_eloquent/local_setup.sh
mkdir -p ~/ros2_ws
cd ~/ros2_ws
git clone https://github.com/ros-perception/image_common.git
cd image_common
git checkout e7f682e68016ea855bf8ef7d0d752c94a4053a61
cd ..
git clone https://github.com/ros-perception/vision_opencv.git -b ros2
colcon build --symlink-install

orb_slam_2_rosのビルド

image_commonとcv_bridgeと同じワークスペースに突っ込んで同時にビルドしてみたけど、 find_packageがどうも失敗する模様。記述上はいいように見えるんだけどなぁ。 colconの動作をよく分かっていないので何故失敗するかは不明だけど、 順番にビルドすればとりあえずは動くようになる。 hashは0f964c618a2e0b7715c1c6fc49e6b70b2ba2c904を使用。

git clone https://github.com/appliedAI-Initiative/orb_slam_2_ros.git -b ros2

動かすだけなので以下のorb_slam_2_ros/ros/launchにTUM1_mono_launch.pyを置く。 ちゃんとやるならTUM1.yamlとかも持ってきて設定する。

import os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory


def generate_launch_description():

    use_sim_time = LaunchConfiguration('use_sim_time')
    params_file = LaunchConfiguration('params_file')
    voc_file = LaunchConfiguration('voc_file')

    remappings = [
        ('/camera/image_raw', '/camera/rgb/image_color'),
        ('/camera/camera_info', '/camera/rgb/camera_info'),
    ]

    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='false',
            description='Use simulation (Gazebo) clock if true'),

        DeclareLaunchArgument(
            'params_file',
            default_value=os.path.join(
                get_package_share_directory("orb_slam2_ros"),
                'ros', 'config', 'params_d435_mono.yaml'),
            description='Full path to the ROS2 parameters file to use for all launched nodes'),

        DeclareLaunchArgument(
            'voc_file',
            default_value=os.path.join(
                get_package_share_directory("orb_slam2_ros"),
                'orb_slam2', 'Vocabulary', 'ORBvoc.txt'),
            description='Full path to vocabulary file to use'),

        Node(
            parameters=[
              params_file,
              {"voc_file": voc_file,
               "use_sim_time": use_sim_time},
            ],
            package='orb_slam2_ros',
            node_executable='orb_slam2_ros_mono',
            node_name='orb_slam2_mono',
            output='screen',
            remappings=remappings
        )
    ])

ビルドする。

source install/setup.sh
colcon build --symlink-install

orb_slam_2_rosのテスト

TUM1を流して試してみる。

ターミナル1で以下を実行

cd ~/ros2_ws
source install/setup.sh
ros2 launch orb_slam2_ros TUM1_mono_launch.py

ターミナル2で以下を実行

cd ~/ros2_ws
source install/setup.sh
rviz2

左下のAddボタンからorb_slam2_monoのpointcloud2とimageトピックを追加しておく。
TFも追加しておくとmapとcamera_linkの動く様子が見られる。


ターミナル3で以下を実行。前回と同じ。

source /opt/ros/melodic/setup.sh
source /opt/ros/dashing/setup.sh
ros2 bag play -s rosbag_v2 rgbd_dataset_freiburg1_xyz.bag -r 1000000

実行結果

カメラのパラメータが間違ってからか微妙な感じだがキーボードや机の上の障害物等の形は出ている。

 




 

2020年11月9日月曜日

ROS2 dashing + Ubuntu18.04でORB_SLAM2を動かしてみた

ORB_SLAM2をros2+ubuntu18.04で動かしてみた話。

ORB_SLAM2をubuntu18.04で動かした記事が一番参考になる。 ros2でORB_SLAM2を動かしてみたので動かし方を残す。

環境

ROS2 dashing Ubuntu 18.04 Intel® Core™ i7-6600U CPU @ 2.60GHz × 4 メモリ 16G

ros2のインストール

ここを参考にする。

Pangolinのインストール

昔インストールしていたので、特に何もしていない。 ここに記載の方法と同じで良い。

ORB_SLAM2のインストール

ここに記載の通り。

cd ~/ros_dev
git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2
cd ORB_SLAM2
chmod +x build.sh
./build.sh

usleepのエラーが出るので対処する。 個人的にはこの対処法が好きなので、 自分のリポジトリに取り込む。 もう一度build.shを実行し、待つ。 libORB_SLAM2.soと各種exampleが出来上がる。

ORB_SLAM2を試す

特に何も考えずにTUM1を使用する。 ダウンロードはここから。 fr1がTUM1に相当している模様。 .tgzがSEQUENCEファイルのようなので、解凍したパスを覚えておく。 サンプルの実行は以下の通り。

./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml PATH_TO_SEQUENCE_FOLDER

実行結果は以下の通りであった。トラッキングにかかる時間が33msec程度ってことのように見える。 論文だと他の処理時間も計測しているみたいだけど、どうやっているんだ?

median tracking time: 0.0328202
mean tracking time: 0.0341189

ros2_ORB_SLAM2のビルド

ここを使用する。 書いてあるとおりにビルドする。特に問題は出なかった。

ros2_ORB_SLAM2のテスト1

書いてある通りに実行すると画面が立ち上がる。 カメラのキャリブレーション方法は別途確認する。 image_toolsはid=0のvideoデバイスのみをpublishするので、 所望の結果を得るにはデバイスの認識順をどうにかするか、 image_toolsのソースを変更するかが必要。

  • ターミナル1

    source <path-to-ros>/dashing/setup.sh
    ros2 run image_tools cam2image -t camera
  • ターミナル2

    cd <path-to-ros2_ORB_SLAM2>
    source install/setup.sh
    export LD_LIBRARY_PATH=~/Pangolin/build/src/:~/ORB_SLAM2/Thirdparty/DBoW2/lib:~/ORB_SLAM2/Thirdparty/g2o/lib:~/ORB_SLAM2/lib:$LD_LIBRARY_PATH
    ros2 run ros2_orbslam mono ~/ORB_SLAM2/Vocabulary/ORBvoc.txt ~/ORB_SLAM2/Examples/Monocular/TUM1.yaml

ros2_ORB_SLAMのテスト2

テスト1同様にros2_orbslamを起動しておくが、購読するtopicは/cameraではなく、/camera/rgb/image_colorなので、ソースを修正して再ビルド。 (ros2にtopic_toolがあればそれを使っても良いが。それか知らないだけで実行時に変更できたりするのかも) 変更はsrc/monocular/monocular-slam-node.cpp内のcamera => camera/rgb/image_colorとすれば良い。 再ビルドして同じように実行する。
2020/11/10追記
実行時にremapオプション付加するのが正解みたい。
(ros2 run ros2_orbslam mono ~/ORB_SLAM2/Vocabulary/ORBvoc.txt ~/ORB_SLAM2/Examples/Monocular/TUM1.yaml --ros-args -r camera:=camera/rgb/image_color)

次はrosbagを使用してTUM1を流す。 リンク先でbagファイルを入手すること。

rosbag2のインストールは以下の通り。 ros1のbagイメージを再生するにはros1_bridgeが必要で、これのインストールにはmelodicのapt設定が必要(dashingの場合)

sudo su -
sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key  421C365BD9FF1F717815A3895523BAEEB01FA116
apt update
apt upgrade
apt install ros-dashing-ros2bag ros-dashing-rosbag2*

TUM1のデータは以下の通り再生可能。そのままだと再生できないのでここを参考にした。

source /opt/ros/melodic/setup.sh
source /opt/ros/dashing/setup.sh
ros2 bag play -s rosbag_v2 rgbd_dataset_freiburg1_xyz.bag -r 1000000

テスト1と同じように動作が確認できる。

その他

ros2_ORB_SLAM2から各種topicが出ていないようなので調べてみると、 どうも/cameraでイメージをsubscribeだけして動作させるだけの模様。 元のORB_SLAM2のros1向けのノード実装も同じ動作だったようなので、これの移植かと思う。 本格的には多分これのros2ブランチを使用する必要があるかも。 これは後で試してみる。

カメラの動作確認メモ

対象:logicool c270
cheeseで動作しない。
fswebcamでは動作確認できた。
qv4l2では動作確認できた。

http://joe.ash.jp/program/ros/tutorial/tutorial_camera.htm https://qiita.com/naoppy/items/74bdfa8216c7223f584b

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

2020年10月28日水曜日

petalinuxの設定内容を読む,devicetreeカスタム方法

devicetreeのカスタム方法について調査。

基本的にはXSAファイルをmeta-xilinx-toolに渡すと基本的な設定ファイルは抽出されそう。 なのでsystem-user.dtsiでuio設定などを追加で記載すれば良さそう。

新しいマシンを定義して、既存のultra96設定を呼び出すようにしてみる。

意外といけそうなので、とりあえずvanilla-pealinuxをultra96向けにするものを書いてみるか。

参考ページ https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/61669922/Customizing+Device+Trees+in+Xilinx+Yocto

2020年10月27日火曜日

petalinuxの設定内容を読むその4,zcu102-zynqmp.conf

meta-xilinx/meta-xilinx-bsp/conf/machine/zcu102-zynqmp.confを確認していく。

まずはコード。QEMU関連の設定前までを確認する。

#@TYPE: Machine
#@NAME: zcu102-zynqmp
#@DESCRIPTION: Machine support for ZCU102 Evaluation Board.

SOC_VARIANT ?= "eg"

require conf/machine/include/tune-zynqmp.inc
require conf/machine/include/machine-xilinx-overrides.inc
require conf/machine/include/machine-xilinx-default.inc
require conf/machine/include/machine-xilinx-qemu.inc

MACHINE_FEATURES = "rtc ext2 ext3 vfat usbhost"

UBOOT_MACHINE = "xilinx_zynqmp_zcu102_rev1_0_defconfig"
SPL_BINARY ?= "spl/boot.bin"

# Default SD image build onfiguration, use qemu-sd to pad
IMAGE_CLASSES += "image-types-xilinx-qemu"
IMAGE_FSTYPES += "wic.qemu-sd"
WKS_FILES ?= "sdimage-bootpart.wks"

SERIAL_CONSOLE = "115200 ttyPS0"
SERIAL_CONSOLES_CHECK = "${SERIAL_CONSOLES}"

KERNEL_DEVICETREE = "xilinx/zynqmp-zcu102-rev1.0.dtb"

PREFERRED_PROVIDER_virtual/kernel ?= "linux-xlnx"
PREFERRED_PROVIDER_virtual/bootloader ?= "u-boot-xlnx"

EXTRA_IMAGEDEPENDS += " \
        u-boot-zynq-uenv \
        arm-trusted-firmware \
        qemu-devicetrees \
        virtual/boot-bin \
        virtual/bootloader \
        u-boot-zynq-scr \
        "

IMAGE_BOOT_FILES += " \
        uEnv.txt \
        atf-uboot.ub \
        ${@bb.utils.contains('PREFERRED_PROVIDER_virtual/dtb', 'device-tree', 'system.dtb', '', d)} \
        boot.scr \
        "

これまで見た感じの記述がなrんでいる。IMAGE_CLASSESと、IMAGE_FSTYPESと、WKS_FILESはよくわからないな。QEMUもしくはSDカード生成に関係しているのか?とりあえずそのまま採用してみよう。 SPL_BINARYも設定されているので、これもやはり使用してみよう。 DEVICETREEの設定の仕方がいまいち分かっていないので、これは後で追う。
IMAGE_BOOT_FILESはなんとなくブートパーティションに保存しているファイルっぽいけど、ビルドして調べてみるか。

続いてQEMUの設定っぽい部分。 ほとんどqemu呼び出しのための引数設定って感じなので省略。 xilinxのリファレンスマニュアル(UG1169)見れば正しく設定できそう。 実際使うときに細かく確認していくこととする。

あとはデバイスツリー周りとHDF関連の変数の使われ方調べて一区切りさせて、petalinuxをインストールしないでビルドしてみる。

# This machine has a QEMU model, runqemu setup:
IMAGE_CLASSES += "qemuboot-xilinx"
QB_MACHINE = "-machine xlnx-zcu102"
QB_MEM = "-m 4096"
QB_OPT_APPEND ?= "-nographic -serial mon:stdio -serial null"
QB_NETWORK_DEVICE = "-net nic -net nic -net nic -net nic,netdev=net0,macaddr=@MAC@"

# Use qemu-xilinx instead of mainline
PREFERRED_PROVIDER_qemu-helper-native = "qemu-xilinx-helper-native"

# Use the multiarch script instead of launching QEMU directly
QB_SYSTEM_NAME_append = "-multiarch"

# Replicate BootROM like behaviour, having loaded SPL and PMU(ROM+FW)
QB_OPT_APPEND_append_qemuboot-xilinx = " \
        -hw-dtb ${DEPLOY_DIR_IMAGE}/qemu-hw-devicetrees/multiarch/zcu102-arm.dtb \
        ${@qemu_zynqmp_unhalt(d, True)} \
        -device loader,file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware.elf,cpu-num=0 \
        -device loader,file=${DEPLOY_DIR_IMAGE}/u-boot.elf \
        "

# Attach the rootfs disk image to the second SD interface of QEMU (which is SD0)
QB_DEFAULT_FSTYPE_qemuboot-xilinx = "wic.qemu-sd"
QB_OPT_APPEND_append_qemuboot-xilinx = " -boot mode=5"
QB_ROOTFS_OPT_qemuboot-xilinx = " -drive if=sd,index=1,file=@ROOTFS@,format=raw"

# PMU instance args
PMU_ROM ?= "${DEPLOY_DIR_IMAGE}/pmu-rom.elf"
PMU_FIRMWARE_DEPLOY_DIR ?= "${TOPDIR}/pmutmp/deploy/images/zynqmp-pmu"
PMU_FIRMWARE_IMAGE_NAME ?= "pmu-firmware-zynqmp-pmu"

QB_PMU_OPT = " \
        -M microblaze-fdt \
        -display none \
        -hw-dtb ${DEPLOY_DIR_IMAGE}/qemu-hw-devicetrees/multiarch/zynqmp-pmu.dtb \
        -kernel ${PMU_ROM} \
        -device loader,file=${PMU_FIRMWARE_DEPLOY_DIR}/${PMU_FIRMWARE_IMAGE_NAME}.elf \
        -device loader,addr=0xfd1a0074,data=0x1011003,data-len=4 \
        -device loader,addr=0xfd1a007C,data=0x1010f03,data-len=4 \
        "
QB_OPT_APPEND_append_qemuboot-xilinx = " -pmu-args '${QB_PMU_OPT}'"

do_write_qemuboot_conf[depends] += "u-boot-zynq-uenv:do_deploy"