Blog:
Verdin iMX8M Plus M7開発
Toradex の Verdin iMX8M PlusコンピューターオンモジュールはNXPのiMX8M Plusプロセッサーを使用しています。AIハードウェアアクセラレーションユニットに対応するNPUに加え、CPUにもM7マイクロコントローラーが搭載されています。M7の動作周波数は800MHzです。これに比較して、iMX8 QuadMaxプロセッサーのM4マイクロコントローラーの動作周波数は266MHzです。さらに、倍精度浮動小数点演算にも対応しており、コンピューティング性能が大幅に向上されています。本記事では、Verdin iMX8M PlusコンピューターオンモジュールでM7マイクロコントローラーを開発し、ヘテロジニアスなコア間でrpmsg通信を利用する方法を紹介します。
利用するハードウェアは、Verdin iMX8M PlusコンピューターオンモジュールとVerdin開発ボードです。BSPはLinux BSP v5.7.0 multimedia reference imageです。ハードウェア接続は次のとおりで、電源、ネットワークとUSBデバッグシリアルポートを接続します。Verdin開発ボードのUSBデバッグシリアルポートには、ttyUSB0、ttyUSB1、ttyUSB2、ttyUSB3があります。このうち、ttyUSB3はVerdin iMX8M PlusのA53デバッグシリアルポートで、ttyUSB2はM7のデバッグシリアルポートです。デフォルトのボーレートは115200です。
デバイスツリー構成
こちらの手順に沿ってLinuxカーネルのソースコードをダウンロードしてください。rpmsgノードとM7リザーブドアドレススペースの構成は、デフォルトのデバイスツリー構成に含まれていません。ソースコードのarch/arm64/boot/dts/freescale/にimx8mp-verdin-rpmsg.dtsiファイルを作成し、次の内容を入力します。
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Copyright 2022 Toradex
*/
#include <dt-bindings/clock/imx8mp-clock.h>
// Enable RPMSG support
/ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
/* use linux config instead */
/delete-node/ linux,cma;
/* Allocate 16MB DDR RAM memory for cortex M -> check the ram drr linker file for details */
m7_reserved: m7@0x80000000 {
no-map;
reg = <0 0x80000000 0 0x1000000>;
};
/* Allocate resource table from Cortex-M7 -> check copyResourceTable inside rsc_table.c for details */
rsc_table: rsc_table@550ff000 {
reg = <0 0x550ff000 0 0x1000>;
no-map;
};
/* VDEV0_VRING_BASE 0 comes from FreeRTOS rsc_table.c */
vdev0vring0: vdev0vring0@55000000 {
reg = <0 0x55000000 0 0x8000>;
no-map;
};
/* VDEV0_VRING_BASE 1 comes from FreeRTOS rsc_table.c */
vdev0vring1: vdev0vring1@55008000 {
reg = <0 0x55008000 0 0x8000>;
no-map;
};
/* Buffers to use with RPMSG */
vdevbuffer: vdevbuffer@55400000 {
compatible = "shared-dma-pool";
reg = <0 0x55400000 0 0x100000>;
no-map;
};
};
imx8mp-cm7 {
compatible = "fsl,imx8mp-cm7";
rsc-da = <0x55000000>;
clocks = <&clk IMX8MP_CLK_M7_DIV>;
mbox-names = "tx", "rx", "rxdb";
mboxes = <&mu 0 1
&mu 1 1
&mu 3 1>;
memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdevbuffer>, <&rsc_table>, <&m7_reserved>;
status = "okay";
};
};
&rpmsg{
/*
* 64K for one rpmsg instance:
* --0x55000000~0x5500ffff: pingpong
*/
vdev-nums = <1>;
reg = <0x0 0x55000000 0x0 0x10000>;
memory-region = <&vdevbuffer>, <&rsc_table>, <&m7_reserved>;
status = "disabled";
};
そして、次をimx8mp-verdin-wifi-dev.dtsに追加します。
#include "imx8mp-verdin-rpmsg.dtsi"
imx8mp-verdin-wifi.dtsi内の&iomuxcから<&pinctrl_gpio_hog4>を削除します。
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
<&pinctrl_gpio3>, <&pinctrl_gpio4>,
<&pinctrl_gpio7>, <&pinctrl_gpio8>,
<&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
<&pinctrl_hdmi_hog>;
};
SODIMM 151とSODIMM 153が、M7のデフォルトのデバッグシリアルポートです。Verdin iMX8M Plus Quad 4GB WB IT V1.1A以降のモジュールでは、モジュールのBluetoothへの接続にUART4が使用されます。デフォルトの構成では、SODIMM 151とSODIMM 153は、&pinctrl_gpio_hog4でGPIOモードに設定されています。Linuxを起動した後にM7のデバッグシリアルポート機能を利用し続ける場合は、このノードを削除する必要があります。
/* Wifi usage only */
pinctrl_gpio_hog4: gpiohog4grp {
fsl,pins = <
MX8MP_IOMUXC_UART4_RXD__GPIO5_IO28 0x1c4 /* SODIMM 151 */
MX8MP_IOMUXC_UART4_TXD__GPIO5_IO29 0x1c4 /* SODIMM 153 */
>;
};
デバイスツリーへの変更が完了したら再コンパイルを行います。これを開発ボードの/bootディレクトリーにコピーして、元のファイルに上書きします。
make freescale/imx8mp-verdin-wifi-dev.dtb
MCUxpresso SDK
まず、MCUXpresso SDK Builderのページを開き、「Select Development Board」をクリックします。この際、アカウント番号を入力する必要があります。アカウントをお持ちでない場合は、まず登録を行ってください。
「Search for Hardware」のフィールドに「MIMX8ML8xxxKZ」と入力します。
「Processors」の下に表示される「MIMX8ML8xxxKZ」をクリックします。
右側の「Build MCUXpresso SDK」をクリックします。
必要に応じて「Host OS」、「Toolchain/IDE」、「SDK」のコンポーネントを選択します。一般に、開発コンピューターとしてLinuxを使用することが推奨されています。少なくとも「multicore」と「FreeRTOS」のコンポーネントにチェックを入れます。最後に「DOWNLOAD SDK」をクリックします。
SDKの圧縮パッケージを解凍します。SDK圧縮パッケージの解凍先ディレクトリ—のドキュメンテーション(SDK_2_12_1_MIMX8ML8xxxKZ/docs/MCUXpresso SDK Release Notes for EVK-MIMX8MP.pdfで説明されているGCCバージョン)に従い、対応するソフトウェアをこちらからダウンロードします。SDK 2.12.1はGCC Arm Embedded 10.3-2021.10を使用します。
RPMSGデモのコンパイル
SDKインストールディレクトリーの
SDK_2_12_1_MIMX8ML8xxxKZ/boards/evkmimx8mp/multicore_examples/rpmsg_lite_str_echo_rtos/のパスを入力します。
$ cd SDK_2_12_1_MIMX8ML8xxxKZ/boards/evkmimx8mp/multicore_examples/rpmsg_lite_str_echo_rtos/
GCCコンパイルツールの実際のインストールパスに基づいて、ARMGCC_DIR変数を設定します。
$ export ARMGCC_DIR=gcc-arm-none-eabi-10.3-2021.10
armgccフォルダー内でコンパイルスクリプトを実行します。
$ cd armgcc
$ ./build_all.sh
コンパイルが終了すると、debug/release、ddr_debug/ddr_release、flash_debug/flash_releaseフォルダー内にbinファイルが表示されます。上記の3つのフォルダーは、それぞれTCM、DDR、QSPIフラッシュのbin読み込み場所に相当します。TCMとDDRは、Verdinモジュールで利用できます。
RPMSGデモの実行
M7のファームウェアがTCMでの実行には大きすぎる場合、モジュールのDDRを利用する必要があります。ddr_releaseディレクトリー内のコンパイルされたM7ファームウェアをm7.binという名前に変更し、モジュールの/home/root/ディレクトリーにコピーします。U-Bootで以下のパラメーターを設定します。
setenv m4boot 'ext4load mmc 2:2 0x80000000 /home/root/m7.bin; dcache flush; bootaux 0x80000000'
setenv fdt_high=0xffffffffffffffff
saveenv
M7のファームウェアが大きくない場合は、TCMで実行可能です。TCMはM7固有のストレージであるため、DDRコントローラーにアクセスする必要はありません。これにより、M7のランタイムIOオーバーヘッドが軽減されます。releaseディレクトリー内のコンパイルされたM7ファームウェアをm7.binという名前に変更し、モジュールの/home/root/ディレクトリーにコピーします。U-Bootで以下のパラメーターを設定します。
setenv m4boot 'ext4load mmc 2:2 ${loadaddr} /home/root/m7.bin; cp.b ${loadaddr} 0x7e0000 ${filesize}; dcache flush; bootaux 0x7e0000'
setenv fdt_high=0xffffffffffffffff
saveenv
M7のデバッグシリアルポートを開くと、モジュール起動後に次の情報を見ることができます。
Nameservice sent, ready for incoming messages..
Linuxデバッグシリアルポートに次のコマンドを入力してrpmsgドライバーを読み込みます。
~# modprobe imx_rpmsg_tty
M7のデバッグシリアルポートは次のコンテンツを出力します。これは、A53でrmpsgドライバーが送信したデフォルトのメッセージをM7が受信したことを示します。
Get Message From Master Side : "hello world!" [len : 12]
Linuxデバッグシリアルポートに次のコマンドを入力して、指定したコンテンツをM7に送信します。
~# echo 'Toradex' > /dev/ttyRPMSG30
M7のデバッグシリアルポートが受信したメッセージを出力します。
Get Message From Master Side : "Toradex" [len : 7]
Get New Line From Master Side
デバッグの際には、M7ファームウェアをTFTPを介して転送する方が便利です。以下は、TFTPを介してDDRとTCMそれぞれにファームウェアをダウンロードするのに必要なU-Bootの設定です。これらは、ddr_releaseとreleaseという2つの異なるフォルダーのものであることに留意してください。
- DDR
setenv m4boot 'tftp 0x80000000 m7.bin; dcache flush; bootaux 0x80000000'
setenv fdt_high=0xffffffffffffffff
saveenv
- TCM
setenv m4boot 'tftp ${loadaddr} m7.bin; cp.b ${loadaddr} 0x7e0000 ${filesize}; dcache flush; bootaux 0x7e0000'
setenv fdt_high=0xffffffffffffffff
saveenv
まとめ
Verdin iMX8M PlusのM7マイクロプロセッサーは、リアルタイムまたは低消費電力のタスクに最適です。上記で紹介したA53とM7のコア通信ルーチンのほかにも、MCUxpresso SDKには、CAN、GPIO、SPIといった多数のオペレーティングペリフェラルがあり、迅速なユーザー開発を可能にします。
Shanfeng Hu, FAE, Toradex