LoginSignup
1
0
お題は不問!Qiita Engineer Festa 2023で記事投稿!

Ultra96-V2でAPUからRPUへプログラムをロードして実行する

Posted at

はじめに

Ultra96-V2には、APUにCortex-A53が4個、RPUにCortex-R5が2個搭載されています。
これまで自分は、RPUは使わず、APUにPetalinux + Ubuntu20.04のシステムをロードして使っていました。
そこで今回、APUからRPUにプログラム(Lチカ)をロードして実行するということをやってみます。

環境・ツール

  • Petalinux 2020.2
  • APU ユーザランド: Ubuntu20.04
  • Xilinx Vitis IDE v2022.2.0 (RPUコア用ベアメタルプログラム開発用)

前提条件

Vivadoで生成したUltra96-V2のハードウェアファイル(.xsa)が用意されている。

RPU用Lチカプログラムの作成

Vitisを起動し、[File -> New -> Application Project...]を選択しプロジェクトを作成。

用意した.xsaファイルを読み込む。
qiita1.png

led_blinkという名前でプロジェクトを作る。
qiita2.png

qiita3.png

Hello Worldのテンプレートを選択。
qiita4.png

プロジェクトが生成されたら、helloworld.cを編集。

helloworld.c
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "sleep.h"
#include "xgpiops.h"

int main()
{
	init_platform();

	XGpioPs instXGpioPs;
	XGpioPs_Config *configxGpioPs;

	configxGpioPs = XGpioPs_LookupConfig(XPAR_PSU_GPIO_0_DEVICE_ID);
	XGpioPs_CfgInitialize(&instXGpioPs, configxGpioPs, configxGpioPs->BaseAddr);

	XGpioPs_SetDirectionPin(&instXGpioPs, 20, 1);
	XGpioPs_SetDirectionPin(&instXGpioPs, 19, 1);
	XGpioPs_SetDirectionPin(&instXGpioPs, 18, 1);
	XGpioPs_SetDirectionPin(&instXGpioPs, 17, 1);

	XGpioPs_SetOutputEnablePin(&instXGpioPs, 20, 1);
	XGpioPs_SetOutputEnablePin(&instXGpioPs, 19, 1);
	XGpioPs_SetOutputEnablePin(&instXGpioPs, 18, 1);
	XGpioPs_SetOutputEnablePin(&instXGpioPs, 17, 1);

	while(1)
	{
		XGpioPs_WritePin(&instXGpioPs, 20, 1);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 19, 1);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 18, 1);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 17, 1);
		sleep(1);

		XGpioPs_WritePin(&instXGpioPs, 17, 0);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 18, 0);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 19, 0);
		sleep(1);
		XGpioPs_WritePin(&instXGpioPs, 20, 0);
		sleep(1);
	}
}

次に、アプリケーション用にDDRメモリを予約するために、lscript.ldファイルのメモリレジスタを更新する。
psu_r5_ddr_0_MEM_0の値を以下のように編集。

qiita5.png

[Project -> Buuild Project]を実行。
ビルドが成功すると、led_blink.elfが生成される。

Petalinux側の対応

PetalinuxにLチカファームウェアを追加するレシピを作成

Petlinux アプリケーション レシピを作成する

$ cd {Petalinux Project Path}
$ petalinux-create -t apps --template install -n led-blink --enable

Vitisで作成したled_blink.elfをproject-spec/meta-user/recipes-apps/led-blink/files/ 以下にコピーする。

また、led-blink.bbを以下のように編集。

led-blink.bb
#
# This file is the led-blink recipe.
#

SUMMARY = "Simple led-blink application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://led_blink.elf \
	"

S = "${WORKDIR}"
INSANE_SKIP_${PN} = "arch"

FILES_${PN} += "/lib/firmware/"

do_install() {
	install -d ${D}/lib/firmware
	install -m 0644 ${S}/led_blink.elf ${D}/lib/firmware/led_blink.elf
}

Device Treeの修正

続いて、project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsiに以下を記述。

system-user.dtsi
/ {
    reserved-memory {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        rpu0vdev0vring0: rpu0vdev0vring0@3ed40000 {
            no-map;
            reg = <0x0 0x3ed40000 0x0 0x4000>;
        };
        rpu0vdev0vring1: rpu0vdev0vring1@3ed44000 {
            no-map;
            reg = <0x0 0x3ed44000 0x0 0x4000>;
        };
        rpu0vdev0buffer: rpu0vdev0buffer@3ed48000 {
            no-map;
            reg = <0x0 0x3ed48000 0x0 0x100000>;
        };
        rproc_0_reserved: rproc@3ed00000 {
            no-map;
            reg = <0x0 0x3ed00000 0x0 0x40000>; // Vitisで指定したのと同じ領域
        };
    };

    zynqmp-rpu {
        compatible = "xlnx,zynqmp-r5-remoteproc-1.0";
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        core_conf = "split";
        reg = <0x0 0xFF9A0000 0x0 0x10000>;
        r5_0: r5@0 {
            #address-cells = <2>;
            #size-cells = <2>;
            ranges;
            memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
            pnode-id = <0x7>;
            mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
            mbox-names = "tx", "rx";
            tcm_0_a: tcm_0@0 {
                reg = <0x0 0xFFE00000 0x0 0x10000>;
                pnode-id = <0xf>;
            };
            tcm_0_b: tcm_0@1 {
                reg = <0x0 0xFFE20000 0x0 0x10000>;
                pnode-id = <0x10>;
            };
        };
    };

    zynqmp_ipi1 {
        compatible = "xlnx,zynqmp-ipi-mailbox";
        interrupt-parent = <&gic>;
        interrupts = <0 29 4>;
        xlnx,ipi-id = <7>;
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
        /* APU<->RPU0 IPI mailbox controller */
        ipi_mailbox_rpu0: mailbox@ff90000 {
            reg = <0xff990600 0x20>,
                  <0xff990620 0x20>,
                  <0xff9900c0 0x20>,
                  <0xff9900e0 0x20>;
            reg-names = "local_request_region",
                        "local_response_region",
                        "remote_request_region",
                        "remote_response_region";
            #mbox-cells = <1>;
            xlnx,ipi-id = <1>;
        };
    };
};

Kernel configurationの確認

$ petalinux-config -c kernel

・Device Drivers --->
Remoteproc drivers --->
<*> Support for Remote Processor subsystem
<M> ZynqMP_r5 remoteproc support

rootfsの設定

$ petalinux-config -c rootfs
  • apps ---> led-blink [*]
  • Filesystem Packages ---> misc ---> sysfsutils ---> libsysfs [*]
  • Filesystem Packages ---> libs ---> libmetal ---> libmetal [*]
  • Petalinux Package Groups ---> packagegroup-petalinux-openamp ---> packagegroup-petalinux-openamp [*]

テスト用アプリも有効化しておく。

  • Filesystem Packages ---> misc ---> openamp-fw-echo-testd ---> openamp-fw-echo-testd [*]
  • Filesystem Packages ---> misc ---> openamp-fw-mat-muld ---> openamp-fw-mat-muld [*]
  • Filesystem Packages ---> misc ---> openamp-fw-rpc-demo ---> openamp-fw-rpc-demo [*]

Petalinuxのビルドとimageの作成

$ petalinux-build

$  petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --pmufw images/linux/pmufw.elf --fpga images/linux/system.bit --u-boot --force

Ultra96-V2上での実行

$ lsmod
zynqmp_r5_remoteproc    20480  0

$ cd /lib/firmware

$ echo led_blink.elf > /sys/class/remoteproc/remoteproc0/firmware
$ echo start > /sys/class/remoteproc/remoteproc0/state

これで、自作したLチカプログラムをRPUコアにロードし、実行することができた。
プログラムの停止は以下のようにする。

$ echo stop > /sys/class/remoteproc/remoteproc0/state

テスト用アプリの実行

ついでにテスト用アプリも動かしてみる。

$ echo image_echo_test > /sys/class/remoteproc/remoteproc0/firmware
$ echo start > /sys/class/remoteproc/remoteproc0/state
$ echo_test
$ echo stop > /sys/class/remoteproc/remoteproc0/state

$ echo image_matrix_multiply > /sys/class/remoteproc/remoteproc0/firmware
$ echo start > /sys/class/remoteproc/remoteproc0/state
$ mat_mul_demo
$ echo stop > /sys/class/remoteproc/remoteproc0/state

参考URL

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0