先根据正点原子的操作教程来,一步步十分正常,当加入了一些其他外设的代码后开始出现异常
按照正点原子异核通信教程操作
【正点原子MP157连载】第二十八章 A7和M4联合调试-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南
问题:
- 正点原子裸机例程能正常运行,移植openamp框架后加载程序出现异常输出如下图,没有输出建立虚拟串口连接,如下图:
- 能输出正常建立连接,但是实际上通道并不能正常使用,而且出现时好时坏的现象。虚拟串口回调函数不执行:
上图似乎是已经正常建立通讯了,但是如果按照教程那样采用test.sh脚本文件加载固件,就会无法通讯。
#!/bin/sh
echo RPMsg_TEST_CM4.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
echo "OK" >/dev/ttyRPMSG0
问题解决:
问题1
此时现象输出正常,说明加载的m4固件已经启动(还未建立和间通信),如m4无法正常运行则考虑代码是否有问题,我在测试时出现过直接mcu模式运行正常而使用A7加载固件却m4无法运行。此时一般考虑代码不规范,尤其是初始化外设的代码,最好用cubemx生成。
问题2
此时输出说明已经建立了虚拟串口通讯,但是不保证已经激活了虚拟串口核间通信,因为需要A7先往m4发送消息。
如官方教程,先使用如下命令加载固件,
echo RPMsg_TEST_CM4.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
正常情况下A7端输出结果将会:
使用如下命令向M4发送第一条消息,用于激活A7和M4的异核通信通道
echo "OK" >/dev/ttyRPMSG0
即可激活通道,但是这条语句必须在m4中函数执行完成虚拟串口初始化和回调函数初始化之后才能起作用,提前执行将会导致串口激活失败。因为使用test.sh脚本文件时,命令执行比m4代码一些较慢的初始化代码还快。应保证在m4如下代码全部执行完成后执行。
/* IPCC initialisation */
MX_IPCC_Init();
/* OpenAmp initialisation ---------------------------------*/
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
printf("****** Start Initialize Virtual UART0 ******\r\n");
if (VIRT_UART_Init(&huart0) != VIRT_UART_OK)/* 初始化虚拟串口 */
{
printf("****** VIRT_UART_Init UART0 failed. ******\r\n");
Error_Handler();
}
/* 给虚拟串口 huart0 注册回调函数 VIRT_UART0_RxCpltCallback() */
if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK)
{
Error_Handler();
}
原理分析
在未执行串口加载前我们查看/dev目录下设备情况,可见没有关于虚拟串口的设备。
root@ATK-MP157:/lib/firmware# ls /dev/ttyR*
ls: cannot access '/dev/ttyR*': No such file or directory
如果此时执行echo “OK” >/dev/ttyRPMSG0将会直接创建一个设备文件,而当加载固件的命令执行后将会导致虚拟串口设备无法正常创建,因此即使后面再执行echo “OK” >/dev/ttyRPMSG0也无法创建正常的虚拟设备节点。
具体执行流程涉及到比较底层的openamp框架和Linux端的rpmsg驱动,后面得再详细研究一下。。。