NXP iMX8 M4核心FreeRTOS Rpmsg应用示例

时间:2024-04-14 13:40:17

By Toradex秦海

1). 简介

NXP iMX8是NXP去年底发布的基于Cortex-A72/A53和Coretex-M4异构多核架构的ARM处理器,作为NXP i.MX系列最新性能也最为强大的处理器,升级了从iMX6 SoloX开始到iMX7的异构双核架构(如下框图),使得不同架构核心的使用更加方便稳定,本文就演示iMX8 Cortex-A和Coretx-M核心之间通过Rpmsg来进行通讯的示例。

                                              NXP iMX8 M4核心FreeRTOS Rpmsg应用示例

 

本文所演示的ARM平台来自于Toradex 基于NXP iMX8QM ARM处理器的Apalis iMX8QM ARM嵌入式平台。

 

2). 准备

a). Apalis iMX8QM ARM核心版配合Apalis Evaluation Board载板,连接调试串口UART1(载板X29)到开发主机方便调试。

 

b). Apalis iMX8 M40和M41分别使用独立的调试UART,在Apalis Evaluation Board进行跳线将M4对应的调试UART连接到开发主机的方式请参考这里

 

c). Apalis iMX8 Cortex-A核心安装Toradex Ycoto Linux Console image V3.04版本,详细信息请参考这里

 

d). 由于M4s调试UART所用到的管脚和Cortex-A核心Linux系统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). 根据这里的说明从NXP MCUXpresso网站下载对应iMX8QM的SDK,当前的最新版本为2.5.2。下载界面如下图所示,在这个页面同时也可以下载到关于SDK的一些说明文档。下载好的SDK文件为 ”SDK_2.5.2_MIMX8QM6xxxFF.tar.gz”

NXP iMX8 M4核心FreeRTOS Rpmsg应用示例

 

b). 下载Toolchain

./ 根据SDK文档建议使用 gcc-arm 7 2018q2版本,下载地址如下:

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/7-2018-q2-update

./ 解压下载好的Toolchain文件到<Toolchain_dir>

-----------------------------------

# 解压

$ 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.

# 可能需要安装额外的工具供后续编译使用,以Ubuntu为例

$ sudo apt-get install make cmake

-----------------------------------

 

c). 编译Helloworld测试应用

./ 解压步骤a下载的SDK文件到<Work_dir>

-----------------------------------

$ 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中包含的示例代码均在 <Work_dir>/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 区域分配请参考这里

 

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分区的SD卡根目录,然后将SD卡连接到Apalis Evaluation Board X19 4bit SD卡插槽

-----------------------------------

# Apalis iMX8 上电开机,Cortex-A 核心调试串口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: [email protected]

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 调试UART对应的串口终端可以看到 ”hello world” 打印输出,然后应用程序可以接收并打印键盘输入,比如这里输入了” this is input before linux boot up” 字符串。

-----------------------------------

hello world.                                                                              

this is input before linux boot up

-----------------------------------

 

./ 此时切换到UART1 调试串口终端,执行下面命令继续启动Linux

-----------------------------------

Apalis iMX8 # run bootcmd

-----------------------------------

 

./ 再切换到M40调试串口终端,键盘输入测试

-----------------------------------

hello world.

this is input before linux boot up this is input after linux boot up

-----------------------------------

 

./ 对于M41,操作方式类似,只是加载的时候将将命令最后0替换为1

-----------------------------------

Apalis iMX8 # fatload mmc 2 ${loadaddr} m4_1_image.bin && dcache flush && bootaux ${loadaddr} 1

-----------------------------------

 

 

4). M4 FreeRTOS Rpmsg 示例程序测试

a). 根据章节三同样的方法编译 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的测试结果都一致,本文下面就只用M40做演示示例

 

b). str_echo 示例程序测试

./ 使用章节3测试中同样方法从SD卡加载str_echo 示例程序 “m4_image.bin” 执行

-----------------------------------

# UART1 调试串口终端

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 调试串口终端输出

-----------------------------------

RPMSG String Echo FreeRTOS RTOS API Demo...

-----------------------------------

 

./ 启动linux

-----------------------------------

# UART1 调试串口终端

Apalis iMX8 # run bootcmd

-----------------------------------

 

./ M40 调试串口终端输出

-----------------------------------

RPMSG String Echo FreeRTOS RTOS API Demo...

 

Nameservice sent, ready for incoming messages...

-----------------------------------

 

./ 加载Linux下Rpmsg tty驱动建立rpmsg链接

-----------------------------------

# UART1 调试串口终端

[email protected]:~# 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 调试串口终端输出

-----------------------------------

RPMSG String Echo FreeRTOS RTOS API Demo...

 

Nameservice sent, ready for incoming messages...

Get Message From Master Side : "hello world!" [len : 12]

-----------------------------------

 

./ 发送数据测试,如果是M41,则对应虚拟串口为 /dev/ttyRPMSG31

-----------------------------------

[email protected]:~# echo "this is a test from toradex" > /dev/ttyRPMSG30

-----------------------------------

 

./ M40 调试串口终端输出

-----------------------------------

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 调试串口终端

-----------------------------------

# 在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驱动

[email protected]:~# modprobe imx_rpmsg_pingpong

[   34.508241] imx_rpmsg_pingpong virtio1.rpmsg-openamp-demo-channel.-1.30: new channel: 0x400 -> 0x1e!

[email protected]:~# [   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 调试串口终端输出

-----------------------------------

# pingpong 程序启动后输出

RPMSG Ping-Pong FreeRTOS RTOS API Demo...

RPMSG Share Base Addr is 0x90010000

 

# Linux启动后输出

Link is up!

Nameservice announce sent.

 

# Pingpong 驱动加载后输出

Waiting for ping...

Sending pong...

……

Waiting for ping...

Sending pong...

Ping pong done, deinitializing...

Looping forever...

-----------------------------------

 

 

5). M4s Firmware配置开机自动加载执行测试

a). 上面的测试都是通过Uboot命令从SD卡加载M4 Firmware进行加载运行,下面我们通过str_echo示例程序演示将M40和M41的固件存放在Apalis iMX8 eMMC Flash空间内,并开机自动加载运行

 

b). 首先进入Linux系统,分别将之前编译好的存放在SD卡上面的M40和M41的 str_echo程序Firmware复制到Flash vfat分区,也就是存放Linux kernel和device tree等文件的分区

-----------------------------------

# UART1 调试串口终端

[email protected]:~# cd /media/mmcblk0p1/

[email protected]:/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 示例程序固件

[email protected]:/media/mmcblk0p1# cp /media/mmcblk2p1/m4_image.bin .

[email protected]:/media/mmcblk0p1# cp /media/mmcblk2p1/m4_1_image.bin .

[email protected]:/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,配置环境变量

-----------------------------------

# UART1 调试串口终端

# 分别指定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的调试串口都分别打印了相关程序输出

 

-----------------------------------

# UART1 调试串口终端

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 调试串口终端

-----------------------------------

RPMSG String Echo FreeRTOS RTOS API Demo...

 

Nameservice sent, ready for incoming messages...

-----------------------------------

 

./ M41 调试串口终端

-----------------------------------

RPMSG String Echo FreeRTOS RTOS API Demo...

 

Nameservice sent, ready for incoming messages...

app_srtm: AUTO and I2C service registered

-----------------------------------

 

e). Linux端加载Rpmsg tty驱动并进行发送测试

-----------------------------------

# UART1 调试串口终端

# 加载驱动

[email protected]:~# 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!

 

# 发送信息

[email protected]:~# echo "this is a message from apalis imx8 linux to m4 0" > /dev/ttyRPMSG30

[email protected]:~# echo "this is a message from apalis imx8 linux to m4 1" > /dev/ttyRPMSG31

-----------------------------------

 

./ M40 调试串口终端

-----------------------------------

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 调试串口终端

-----------------------------------

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). 总结

本文基于NXP iMX8示例了其多核异构架构下Cortex-A核心Linux通过Rpmsg驱动和Cortex-M4核心通讯的示例