马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
RPMsg(Remote Processor Messaging)是一种基于vir tio的消息传递总线,允许内核驱动程序与系统上可用的远程处理器进行 通信。如果需要,驱动程序可以暴露适当的用户空间 接口。每个RPMsg设备都是与远程处理器的通信通道(因此RPMsg设备称为通道)。通道由文本名称标识,并具有本地(“source”)RPMsg地址和远程(“destination”)RPMsg 地址。 如下图所示,消息在端点之间通过双向无连接通信通道传递。对于 STM32MP1系列Core 0是 ARM Cortex®-A7,而Core 1是ARM Cortex®-M4 。Core 1上可以运行 操作系统也可以裸跑。
1. RPMsg_TTY的驱动准备
ST官方提供的linux系统中集成了RPMsg的支持,因此基于自己编译的系统也具备了这个能力。我们可以通过查看系统中的文件来确定是否正确的加载了驱动。通过查询/sys/class目录下的文件夹,看是否出现了remoteproc0 ,如下图所示。
为了让CM4系统可以正确,我们还必须知道CM4系统的启动和停止过程等相关信息:1)固件的 存放CM4系统固件存放于linux文件系统的/lib/firmware/目录下,默认固件文件名为rproc-m4-fw 。如果不想太复杂的话,可以将我们的CM4固件就重命名为rproc-m4-fw,并且存放在/lib/firmware/目录下。 2)启动需要用root用户来完成。 # echo start >/sys/class/remoteproc/remoteproc0/state 3)停止需要用root用户来完成。 # echo stop >/sys/class/remoteproc/remoteproc0/state
2. CM4应用程序基本结构开发2.1. 建立一个DK1上的CM4应用程序第一步:打开STM32CubeIDE,选择新建stm32project
第二步:选择“Board Selector”,在搜索栏输入“STM32MP157A-DK1”后,我们可以看到右侧显示除了DK1板的选项和基本介绍。
第三步:输入工程名后创建一个基本工程,我这里创建工程名为t3。基本工程结构如下图所示。包含调整后的内核设备树例子,存放在CA7目录下,CM4内核程序代码存放在t3_CM4目录下。
此时我们已经创建了基本的没有用户功能的空工程。 第四步:添加用户代码 我希望建立两条RPMsg tty通道,一条为控制通道这里面为VirtUart0,一条为数据通道为VirtUart1。 /* * 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 fai LED.\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 这是观察串口终端的数据,如下所示:[15163.671619]remoteproc remoteproc0: powering up m4 [15163.679561]remoteproc remoteproc0: Booting fw image rproc-m4-fw, size 2152524 [15163.686642]rproc-srm-dev m4@0:m4_system_resources:can@4400f000: pin config potentiallyoverwritten! [15163.695604]rproc-srm-core m4@0:m4_system_resources: boundm4@0:m4_system_resources:can@4400f000 (ops 0xc0758a94) [15163.704929]rproc-srm-core m4@0:m4_system_resources: bound m4@0:m4_system_resources:m4_led(ops 0xc0758a94) [15163.714706] m4@0#vdev0buffer: assigned reserved memorynode vdev0buffer@10044000 [15163.722691]virtio_rpmsg_bus virtio0: creating channel rpmsg-tty-channel addr 0x0 [15163.729837]virtio_rpmsg_bus virtio0: rpmsg host is online [15163.735150]rpmsg_tty virtio0.rpmsg-tty-channel.-1.0: new channel: 0x400 -> 0x0 :ttyRPMSG0 [15163.735173] m4@0#vdev0buffer: registered virtio0 (type 7) [15163.743489]virtio_rpmsg_bus virtio0: creating channel rpmsg-tty-channel addr 0x1 [15163.749311]remoteproc remoteproc0: remote processor m4 is now up [15163.762713]rpmsg_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发送的数据。
到此我们已经建立A7和CM4之间的基本沟通渠道,接下来,主战场将转移到CM4内核,完成一个AD采样的应用实例。 |