STM32MP157A异构信息交互通道
RPMsg(Remote Processor Messaging)是一种基于virtio的消息传递总线,允许内核驱动程序与系统上可用的远程处理器进行通信。如果需要,驱动程序可以暴露适当的用户空间接口。每个RPMsg设备都是与远程处理器的通信通道(因此RPMsg设备称为通道)。通道由文本名称标识,并具有本地(“source”)RPMsg地址和远程(“destination”)RPMsg 地址。如下图所示,消息在端点之间通过双向无连接通信通道传递。对于STM32MP1系列Core 0是ARM Cortex®-A7,而Core 1是ARM Cortex®-M4 。Core 1上可以运行操作系统也可以裸跑。http://bbs.elecfans.com/data/attachment/forum/202004/13/075131kv9ygtt0t2ad9but.png.thumb.jpg
1.RPMsg_TTY的驱动准备
ST官方提供的linux系统中集成了RPMsg的支持,因此基于自己编译的系统也具备了这个能力。我们可以通过查看系统中的文件来确定是否正确的加载了驱动。通过查询/sys/class目录下的文件夹,看是否出现了remoteproc0 ,如下图所示。
http://bbs.elecfans.com/data/attachment/forum/202004/13/075344l5oayaz2g4m5egpg.jpg.thumb.jpg
为了让CM4系统可以正确,我们还必须知道CM4系统的启动和停止过程等相关信息:1)固件的存放CM4系统固件存放于linux文件系统的/lib/firmware/目录下,默认固件文件名为rproc-m4-fw 。如果不想太复杂的话,可以将我们的CM4固件就重命名为rproc-m4-fw,并且存放在/lib/firmware/目录下。2)启动需要用root用户来完成。# echo start >/sys/class/remoteproc/remoteproc0/state3)停止需要用root用户来完成。# echo stop >/sys/class/remoteproc/remoteproc0/state
2.CM4应用程序基本结构开发2.1. 建立一个DK1上的CM4应用程序第一步:打开STM32CubeIDE,选择新建stm32projecthttp://bbs.elecfans.com/data/attachment/forum/202004/13/075428smqzpbkbb2gdwl7l.jpg.thumb.jpg
第二步:选择“Board Selector”,在搜索栏输入“STM32MP157A-DK1”后,我们可以看到右侧显示除了DK1板的选项和基本介绍。http://bbs.elecfans.com/data/attachment/forum/202004/13/075505e8pu55r3zb6tu4d2.png.thumb.jpg
第三步:输入工程名后创建一个基本工程,我这里创建工程名为t3。基本工程结构如下图所示。包含调整后的内核设备树例子,存放在CA7目录下,CM4内核程序代码存放在t3_CM4目录下。
http://bbs.elecfans.com/data/attachment/forum/202004/13/075530o9gx9jiagod8apgd.png.thumb.jpg
此时我们已经创建了基本的没有用户功能的空工程。 第四步:添加用户代码我希望建立两条RPMsg tty通道,一条为控制通道这里面为VirtUart0,一条为数据通道为VirtUart1。1)初始化两个虚拟串口/** Create Virtual UART device* defined by a rpmsg channel attached to the remote device*/IF (VIRT_UART_Init(&huart0) != VIRT_UART_OK) { log_err("VIRT_UART_InitUART0 faiLED.\r\n"); Error_Handler();}
if (VIRT_UART_Init(&huart1) != VIRT_UART_OK) { log_err("VIRT_UART_InitUART1 failed.\r\n"); Error_Handler();}
2)挂载回调函数其中VIRT_UART0_RxCpltCallback和VIRT_UART1_RxCpltCallback为我们的回调函数,主要目的为当RPMsg完成数据接收后,将接收数据复制到用户内存,并通知用户完成数据接收,可以进行数据处理了。/*Need to registercallback for message reception by channels*/if(VIRT_UART_RegisterCallback(&huart0,VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK){Error_Handler();}if(VIRT_UART_RegisterCallback(&huart1,VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}3) 回调函数
void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart){
log_info("Msgreceived on VIRTUAL UART0 channel:%s\n\r", (char *) huart->pRxBuffPtr);
/* copyreceived msg in a variable to sent it back to master processor in maininfinite loop*/ VirtUart0ChannelRxSize = huart->RxXferSize < MAX_BUFFER_SIZE?huart->RxXferSize : MAX_BUFFER_SIZE-1; memcpy(VirtUart0ChannelBuffRx, huart->pRxBuffPtr, VirtUart0ChannelRxSize); VirtUart0RxMsg = SET;}
void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart){
log_info("Msgreceived on VIRTUAL UART1 channel:%s\n\r", (char *) huart->pRxBuffPtr);
/* copyreceived msg in a variable to sent it back to master processor in maininfinite loop*/ VirtUart1ChannelRxSize = huart->RxXferSize < MAX_BUFFER_SIZE?huart->RxXferSize : MAX_BUFFER_SIZE-1; memcpy(VirtUart1ChannelBuffRx, huart->pRxBuffPtr, VirtUart1ChannelRxSize); VirtUart1RxMsg = SET;}
4)轮询RPMsg消息在主循环中,必须轮询如下函数: OPENAMP_check_for_message();这个函数的目的是查询MailBox状态,进行数据传递。也就是说,他是驱动RPMsg的关键接口函数。
一切准备就绪后,编译工程,生成我们所需要的t3_CM4.elf,这个是CM4内核的可执行固件。
3.CM4应用程序运行前面的帖子我们建立SSH的通道,我们可以通过SFTP将编译好的CM4固件t3_CM4.elf下载到DK1中。执行: # cpt3_CM4.elf /lib/firmware/rproc-m4-fw # echo start >/sys/class/remoteproc/remoteproc0/state 这是观察串口终端的数据,如下所示:remoteproc remoteproc0: powering up m4remoteproc remoteproc0: Booting fw image rproc-m4-fw, size 2152524rproc-srm-dev m4@0:m4_system_resources:can@4400f000: pin config potentiallyoverwritten!rproc-srm-core m4@0:m4_system_resources: boundm4@0:m4_system_resources:can@4400f000 (ops 0xc0758a94)rproc-srm-core m4@0:m4_system_resources: bound m4@0:m4_system_resources:m4_led(ops 0xc0758a94)m4@0#vdev0buffer: assigned reserved memorynode vdev0buffer@10044000virtio_rpmsg_bus virtio0: creating channel rpmsg-tty-channel addr 0x0virtio_rpmsg_bus virtio0: rpmsg host is onlinerpmsg_tty virtio0.rpmsg-tty-channel.-1.0: new channel: 0x400 -> 0x0 :ttyRPMSG0m4@0#vdev0buffer: registered virtio0 (type 7)virtio_rpmsg_bus virtio0: creating channel rpmsg-tty-channel addr 0x1remoteproc remoteproc0: remote processor m4 is now uprpmsg_tty virtio0.rpmsg-tty-channel.-1.1: new channel: 0x401 -> 0x1 :ttyRPMSG1这里我们可以得到几个重要的信息:1)CM4启动了,启动的固件为rproc-m4-fw2)加载了资源分配表,并且显示了分配到CM4内核的外设资源3)创建了两条rpmsg-tty-channel,分别叫做ttyRPMSG0和ttyRPMSG14.数据交互效果需要开发一个linux端应用程序,接收CM4发送的数据。http://bbs.elecfans.com/data/attachment/forum/202004/13/075753ymbk5m44645b66vb.png.thumb.jpg
到此我们已经建立A7和CM4之间的基本沟通渠道,接下来,主战场将转移到CM4内核,完成一个AD采样的应用实例。 谢谢分享STM32MP157A异构信息交互通道
页:
[1]
