By Toradex秦海
1).?簡介
NXP iMX8是NXP去年底發(fā)布的基于Cortex-A72/A53和Coretex-M4異構(gòu)多核架構(gòu)的ARM處理器劫恒,作為NXP i.MX系列最新性能也最為強大的處理器贩幻,升級了從iMX6 SoloX開始到iMX7的異構(gòu)雙核架構(gòu)(如下框圖),使得不同架構(gòu)核心的使用更加方便穩(wěn)定两嘴,本文就演示iMX8 Cortex-A和Coretx-M核心之間通過Rpmsg來進行通訊的示例。
本文所演示的ARM平臺來自于Toradex?基于NXP iMX8QM ARM處理器的Apalis iMX8QM ARM嵌入式平臺族壳。
2).?準備
a).?Apalis iMX8QM?ARM核心版配合Apalis Evaluation Board載板憔辫,連接調(diào)試串口UART1(載板X29)到開發(fā)主機方便調(diào)試。
b). Apalis iMX8 M40和M41分別使用獨立的調(diào)試UART仿荆,在Apalis Evaluation Board進行跳線將M4對應的調(diào)試UART連接到開發(fā)主機的方式請參考這里贰您。
c). Apalis iMX8 Cortex-A核心安裝Toradex Ycoto Linux Console image V3.04版本,詳細信息請參考這里拢操。
d).?由于M4s調(diào)試UART所用到的管腳和Cortex-A核心Linux系統(tǒng)device tree中管腳配置有沖突锦亦,需要修改device tree并重新編譯部署
./ device tree?修改patch文件請參考如下,下載Linux kernel源代碼以及編譯部署方法請參考這里令境。
https://github.com/simonqin09/Apalis_iMX8_M4_Rpmsg/blob/master/apalis_imx8_m4s_uart.patch
3). M4 FreeRTOS SDK部署
a).?根據(jù)這里的說明從NXP MCUXpresso網(wǎng)站下載對應iMX8QM的SDK杠园,當前的最新版本為2.5.2。下載界面如下圖所示舔庶,在這個頁面同時也可以下載到關于SDK的一些說明文檔抛蚁。下載好的SDK文件為?”SDK_2.5.2_MIMX8QM6xxxFF.tar.gz”
b).?下載Toolchain
./?根據(jù)SDK文檔建議使用?gcc-arm 7 2018q2版本,下載地址如下:
./?解壓下載好的Toolchain文件到
-----------------------------------
#?解壓
$ cd <Toolchain_dir>
$ tar xvf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
#?測試
$ gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.? There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#?可能需要安裝額外的工具供后續(xù)編譯使用惕橙,以Ubuntu為例
$ sudo apt-get install make cmake
-----------------------------------
c).?編譯Helloworld測試應用
./?解壓步驟a下載的SDK文件到
-----------------------------------
$ cd <Work_dir>
$ tar xvf SDK_2.5.2_MIMX8QM6xxxFF.tar.gz
-----------------------------------
./?導出toolchain路徑
-----------------------------------
$ export ARMGCC_DIR=<Toolchain_dir>/gcc-arm-none-eabi-7-2018-q2-update/
-----------------------------------
./?編譯M40 Helloworld應用
-----------------------------------
# SDK中包含的示例代碼均在?/boards/mekmimx8qm/?目錄
# M40 Helloworld demo?編譯
$ cd <Work_dir>/boards/mekmimx8qm/demo_apps/hello_world/cm4_core0
$ armgcc/build_all.sh
-----------------------------------
./?編譯好的二進制文件位于?armgcc?目錄下的?debug/release瞧甩、ddr_debug/ddr_release、flash_debug/flash_release?目錄弥鹦。默認M4應用從TCM加載肚逸,ddr和flash分別對應ddr和flash加載模式,本文不做討論。另外朦促,Apalis iMX8的memory?區(qū)域分配請參考這里膝晾。
d).?部署測試M40 Helloworld示例應用
./?由于目前Apalis iMX8 uboot版本(U-Boot 2018.03-toradex_imx_v2018.03_4.14.78_1.0.0_ga-bringup+g92d0497781)暫時還不支持ELF格式鏡像,因此我們將生成的二進制文件m4_image.bin?復制到FAT32分區(qū)的SD卡根目錄思灰,然后將SD卡連接到Apalis Evaluation Board X19 4bit SD卡插槽
-----------------------------------
# Apalis iMX8?上電開機玷犹,Cortex-A?核心調(diào)試串口UART1?串口終端按住空格鍵進入uboot
U-Boot 2018.03-toradex_imx_v2018.03_4.14.98_2.3.0_bringup+gd626574ba1 (Apr 17 2020 - 19:28:04 +0000)
CPU:?? Freescale i.MX8QM revB A53 at 1200 MHz at 25C
DRAM:? 4 GiB
MMC:?? FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... OK
In:??? serial
Out:?? serial
Err:?? serial
Model: Toradex Apalis iMX8 QuadMax 4GB Wi-Fi / BT IT V1.0B, Serial# 06548514
?BuildInfo:
? - SCFW b929edfe, SECO-FW 27167ff2, IMX-MKIMAGE d7f9440d, ATF bb209a0
? - U-Boot 2018.03-toradex_imx_v2018.03_4.14.98_2.3.0_bringup+gd626574ba1
switch to partitions #0, OK
mmc0(part 0) is current device
flash target is MMC:0
Net:?? eth0: ethernet@5b040000
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot:? 0
Apalis iMX8 #
#?查看SD卡image
Apalis iMX8 # ls mmc 2
…
#?加載Helloworld程序并運行
Apalis iMX8 # fatload mmc 2 ${loadaddr} m4_image.bin && dcache flush && bootaux ${loadaddr} 0
9032 bytes read in 20 ms (440.4 KiB/s)
## Starting auxiliary core at 0x80280000 ...
Power on M4 and MU
Copy M4 image from 0x80280000 to TCML 0x34fe0000
Start M4 0
bootaux complete
-----------------------------------
./?運行后,在M40?調(diào)試UART對應的串口終端可以看到?”hello world”?打印輸出洒疚,然后應用程序可以接收并打印鍵盤輸入歹颓,比如這里輸入了” this is input before linux boot up”?字符串。
-----------------------------------
hello world.??????????????????????????????????????????????????????????????????????????????
this is input before linux boot up
-----------------------------------
./?此時切換到UART1?調(diào)試串口終端油湖,執(zhí)行下面命令繼續(xù)啟動Linux
-----------------------------------
Apalis iMX8 # run bootcmd
-----------------------------------
./?再切換到M40調(diào)試串口終端巍扛,鍵盤輸入測試
-----------------------------------
hello world.
this is input before linux boot up this is input after linux boot up
-----------------------------------
./?對于M41,操作方式類似乏德,只是加載的時候?qū)⒚钭詈?替換為1
-----------------------------------
Apalis iMX8 # fatload mmc 2 ${loadaddr} m4_1_image.bin && dcache flush && bootaux ${loadaddr} 1
-----------------------------------
4). M4 FreeRTOS Rpmsg?示例程序測試
a).?根據(jù)章節(jié)三同樣的方法編譯?M40/M41 Rpmsg?示例程序撤奸,分為兩個:
./ rpmsg_lite_str_echo_rtos
<Work_dir>/boards/mekmimx8qm/multicore_examples/rpmsg_lite_str_echo_rtos
./ rpmsg_lite_pingpong_rtos
<Work_dir>/boards/mekmimx8qm/multicore_examples/rpmsg_lite_pingpong_rtos/linux_remote
./?相關demo的說明請參考對應項目下的readme.txt文件,因為M40和M41的測試結(jié)果都一致喊括,本文下面就只用M40做演示示例
b). str_echo?示例程序測試
./?使用章節(jié)3測試中同樣方法從SD卡加載str_echo?示例程序?“m4_image.bin”?執(zhí)行
-----------------------------------
# UART1?調(diào)試串口終端
Apalis iMX8 # fatload mmc 2 ${loadaddr} m4_image.bin && dcache flush && bootaux ${loadaddr} 0
20112 bytes read in 21 ms (934.6 KiB/s)
## Starting auxiliary core at 0x80280000 ...
Power on M4 and MU
Copy M4 image from 0x80280000 to TCML 0x34fe0000
Start M4 0
bootaux complete
-----------------------------------
./ M40?調(diào)試串口終端輸出
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
-----------------------------------
./?啟動linux
-----------------------------------
# UART1?調(diào)試串口終端
Apalis iMX8 # run bootcmd
-----------------------------------
./ M40?調(diào)試串口終端輸出
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
-----------------------------------
./?加載Linux下Rpmsg tty驅(qū)動建立rpmsg鏈接
-----------------------------------
# UART1?調(diào)試串口終端
root@apalis-imx8:~# modprobe imx_rpmsg_tty
[? 539.316502] imx_rpmsg_tty virtio1.rpmsg-virtual-tty-channel.-1.30: new channel: 0x400 -> 0x1e!
[? 539.325355] Install rpmsg tty driver!
-----------------------------------
./ M40?調(diào)試串口終端輸出
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]
-----------------------------------
./?發(fā)送數(shù)據(jù)測試胧瓜,如果是M41,則對應虛擬串口為?/dev/ttyRPMSG31
-----------------------------------
root@apalis-imx8:~# echo "this is a test from toradex" > /dev/ttyRPMSG30
-----------------------------------
./ M40?調(diào)試串口終端輸出
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]
Get Message From Master Side : "this is a test from toradex" [len : 27]
Get New Line From Master Side
-----------------------------------
c). pingpong?示例程序測試,測試流程和str_echo基本一致,這里簡單羅列對應串口打印輸出
./ UART1?調(diào)試串口終端
-----------------------------------
#?在M41上運行Rpmsg pingpong?示例程序
Apalis iMX8 # fatload mmc 2 ${loadaddr} m4_image_pingpong.bin && dcache flush && bootaux ${loadaddr} 0
20696 bytes read in 21 ms (961.9 KiB/s)
## Starting auxiliary core at 0x80280000 ...
Power on M4 and MU
Copy M4 image from 0x80280000 to TCML 0x34fe0000
Start M4 0
bootaux complete
#?啟動Linux
Apalis iMX8 # run bootcmd
#?加載Pinpong驅(qū)動
root@apalis-imx8:~# modprobe imx_rpmsg_pingpong
[?? 34.508241] imx_rpmsg_pingpong virtio1.rpmsg-openamp-demo-channel.-1.30: new channel: 0x400 -> 0x1e!
root@apalis-imx8:~# [?? 34.520657] get 1 (src: 0x1e)
[?? 34.525069] get 3 (src: 0x1e)
[?? 34.529515] get 5 (src: 0x1e)
……
[?? 34.738211] get 99 (src: 0x1e)
[?? 34.742665] get 101 (src: 0x1e)
[?? 34.745865] imx_rpmsg_pingpong virtio1.rpmsg-openamp-demo-channel.-1.30: goodbye!
-----------------------------------
./ M40?調(diào)試串口終端輸出
-----------------------------------
# pingpong?程序啟動后輸出
RPMSG Ping-Pong FreeRTOS RTOS API Demo...
RPMSG Share Base Addr is 0x90010000
# Linux啟動后輸出
Link is up!
Nameservice announce sent.
# Pingpong?驅(qū)動加載后輸出
Waiting for ping...
Sending pong...
……
Waiting for ping...
Sending pong...
Ping pong done, deinitializing...
Looping forever...
-----------------------------------
5). M4s Firmware配置開機自動加載執(zhí)行測試
a).?上面的測試都是通過Uboot命令從SD卡加載M4 Firmware進行加載運行窗声,下面我們通過str_echo示例程序演示將M40和M41的固件存放在Apalis iMX8 eMMC Flash空間內(nèi),并開機自動加載運行
b).?首先進入Linux系統(tǒng)钝满,分別將之前編譯好的存放在SD卡上面的M40和M41的?str_echo程序Firmware復制到Flash vfat分區(qū),也就是存放Linux kernel和device tree等文件的分區(qū)
-----------------------------------
# UART1?調(diào)試串口終端
root@apalis-imx8:~# cd /media/mmcblk0p1/
root@apalis-imx8:/media/mmcblk0p1# ls
Image??? dpfw.bin???? fsl-imx8qm-apalis-eval.dtb.bak??? fsl-imx8qm-apalis-v1.1-eval.dtb
boot.scr??? fsl-imx8qm-apalis-eval.dtb???? fsl-imx8qm-apalis-ixora-v1.1.dtb? hdmitxfw.bin
#?從SD卡掛載路徑復制M4s Str_echo?示例程序固件
root@apalis-imx8:/media/mmcblk0p1# cp /media/mmcblk2p1/m4_image.bin .
root@apalis-imx8:/media/mmcblk0p1# cp /media/mmcblk2p1/m4_1_image.bin .
root@apalis-imx8:/media/mmcblk0p1# ls
Image??? fsl-imx8qm-apalis-eval.dtb?? fsl-imx8qm-apalis-v1.1-eval.dtb??? m4_image.bin ???boot.scr??? fsl-imx8qm-apalis-eval.dtb.bak??? hdmitxfw.bin dpfw.bin??? fsl-imx8qm-apalis-ixora-v1.1.dtb? m4_1_image.bin
-----------------------------------
c).?重啟進入uboot申窘,配置環(huán)境變量
-----------------------------------
# UART1?調(diào)試串口終端
#?分別指定M4s固件名稱
Apalis iMX8 # setenv m4_0_image 'm4_image.bin'
Apalis iMX8 # setenv m4_1_image 'm4_1_image.bin'
#?設置啟動順序弯蚜,分別啟動M40,M41以及Linux
Apalis iMX8 # setenv bootcmd 'run m4boot_0 && run m4boot_1 && run distro_bootcmd'
Apalis iMX8 # saveenv && reset
-----------------------------------
d).?配置好重啟后可以看到在Linux啟動過程中?M40和M41的調(diào)試串口都分別打印了相關程序輸出
-----------------------------------
# UART1?調(diào)試串口終端
U-Boot 2018.03-toradex_imx_v2018.03_4.14.98_2.3.0_bringup+gd626574ba1 (Apr 17 2020 - 19:28:04 +0000)
……
Normal Boot
Hit any key to stop autoboot:? 0
20112 bytes read in 13 ms (1.5 MiB/s)
## Starting auxiliary core at 0x80280000 ...
Power on M4 and MU
Copy M4 image from 0x80280000 to TCML 0x34fe0000
Start M4 0
bootaux complete
61488 bytes read in 13 ms (4.5 MiB/s)
## Starting auxiliary core at 0x80280000 ...
Power on M4 and MU
Copy M4 image from 0x80280000 to TCML 0x38fe0000
Start M4 1
bootaux complete
……
Scanning mmc 0:1...
Found U-Boot script /boot.scr
……
Starting kernel ...
……
-----------------------------------
./ M40?調(diào)試串口終端
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
-----------------------------------
./ M41?調(diào)試串口終端
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
app_srtm: AUTO and I2C service registered
-----------------------------------
e). Linux端加載Rpmsg tty驅(qū)動并進行發(fā)送測試
-----------------------------------
# UART1?調(diào)試串口終端
#?加載驅(qū)動
root@apalis-imx8:~# modprobe imx_rpmsg_tty
[?? 34.795096] imx_rpmsg_tty virtio1.rpmsg-virtual-tty-channel.-1.30: new channel: 0x400 -> 0x1e!
[?? 34.803985] Install rpmsg tty driver!
[?? 34.807934] imx_rpmsg_tty virtio3.rpmsg-virtual-tty-channel-1.-1.31: new channel: 0x400 -> 0x1f!
[?? 34.817031] Install rpmsg tty driver!
#?發(fā)送信息
root@apalis-imx8:~# echo "this is a message from apalis imx8 linux to m4 0" > /dev/ttyRPMSG30
root@apalis-imx8:~# echo "this is a message from apalis imx8 linux to m4 1" > /dev/ttyRPMSG31
-----------------------------------
./ M40?調(diào)試串口終端
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Nameservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]
Get Message From Master Side : "this is a message from apalis imx8 linux to m4 0" [len : 48]
Get New Line From Master Side
-----------------------------------
./ M41?調(diào)試串口終端
-----------------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
Namapp_srtm: AUTO and I2C service registered
eservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]
Get Message From Master Side : "this is a message from apalis imx8 linux to m4 1" [len : 48]
Get New Line From Master Side
-----------------------------------
6).?總結(jié)
本文基于NXP iMX8示例了其多核異構(gòu)架構(gòu)下Cortex-A核心Linux通過Rpmsg驅(qū)動和Cortex-M4核心通訊的示例