RPMsg(Remote Processor Messaging)是一种基于virtio
的消息传递总线,允许内核驱动程序与系统上可用的远程处理器进行通信。如果需要,驱动程序可以暴露适当的用户空间接口。每个RPMsg
设备都是与远程处理器的通信通道(因此RPMsg
设备称为通道)。通道由文本名称标识,并具有本地(“source”)RPMsg
地址和远程(“destination”)RPMsg
地址。
如下图所示,消息在端点之间通过双向无连接通信通道传递。iMX6 SoloX
的Core 0是ARM Cortex®-A9
,而Core 1是ARM Cortex®-M4
drivers/rpmsg/virtio_rpmsg_bus.c
drivers/rpmsg/imx_rpmsg.c
drivers/rpmsg/imx_rpmsg_pingpong.c
drivers/rpmsg/imx_rpmsg_tty.c
这里virtio_rpmsg_bus.c
是通用代码,imx_rpmsg.c
是平台相关代码,imx_rpmsg_pingpong.c
是pingpong
测试代码,imx_rpmsg_tty.c
是rpmsg tty
驱动代码。这部分代码一般不需要改动,只需要在内核的defconfig
文件中做相关配置:
For RPMSG pingpong test
Symbol: IMX_RPMSG_PINGPONG [=m]
Type : tristate
Prompt: IMX RPMSG pingpong driver
Location:
-> Device Drivers
-> Rpmsg drivers
-> RPMSG bus driver (RPMSG [=y])
For RPMSG TTY driver
Symbol: IMX_RPMSG_TTY [=m]
Type : tristate
Prompt: IMX RPMSG tty driver
Location:
-> Device Drivers
-> Rpmsg drivers
-> RPMSG bus driver (RPMSG [=y])
reserved-memory {
m4_reserved {
reg= <0x8FF00000 0xF0000>;
no-map;
};
rpmsg_reserved {
reg= <0x8FFF0000 0x10000>;
no-map;
};
};
&rpmsg{
vdev-nums = <1>;
reg = <0x8FFF0000 0x10000>;
status = "okay";
};
这里给M4
预留了0x8FF00000
至0x8FFF0000
的内存空间,这里需要和u-boot
加载M4
的地址保持一致;另外给RPMsg
预留了0x8FFF0000
至0x90000000
的共享内存空间(也就是通信通道),这里需要和M4 FreeRTOS
中给RPMsg
的配置保持一致。
在imx6sx_m4/platform_info.c
文件里面配置RPMsg
的共享内存空间
//256M
#define VRING0_BASE 0x8FFF0000
#define VRING1_BASE 0x8FFF8000
这里共享内存的地址空间也是0x8FFF0000
至0x90000000
,总共64KB大小。
首先使用M4 FreeRTOS源码构建rpmsg_pingpong_freertos_example.bin
测试程序,然后在u-boot
命令行使用tftp
命令在内存0x8FF00000
处运行它
U-Boot> tftpboot 0x8FF00000 rpmsg_pingpong_freertos_example.bin
U-Boot> dcache flush
U-Boot> bootaux 0x8FF00000
接着在内存里运行Linux和ramdisk系统
U-Boot> tftpboot 0x80000000 uImage
U-Boot> tftpboot 0x82000000 imx6sx.dtb
U-Boot> tftpboot 0x83800000 core-image.cpio.gz.u-boot
U-Boot> setenv bootargs 'console=ttymxc0,115200n8 root=/dev/ram0 rw'
U-Boot> bootm 0x80000000 0x83800000 0x82000000
进入系统后,使用insmod imx_rpmsg_tty.ko
运行测试程序
$ insmod imx_rpmsg_tty.ko
$ /unit_tests/mxc_mcc_tty_test.out /dev/ttyRPMSG 115200 R 100 1000 &
Linux系统的log
insmod imx_rpmsg_tty.ko
Install rpmsg tty driver!
echo deadbeaf > /dev/ttyRPMSG
imx_rpmsg_tty rpmsg0: msg(<- src 0x1) deadbeaf len 8
FreeRTOS的log
RPMSG PingPong FreeRTOS RTOS API Demo...
RPMSG Init as Remote
Service handshake is done, M4 has setup a rpmsg channel [0 ---> 1024]
len:4 dst:1024 src:1024
Get Data From Master Side : deadbeaf