STM32MP157-DK2开发板A7端无法读取M4端RPMSG消息求助
STM32MP157-DK2 RPMSG虚拟UART:A7无法读取M4发送的消息
问题根源分析
- 频繁开关设备:每次读写都重新打开
/dev/ttyRPMSG0,破坏了RPMSG会话状态,无法保证M4的回复能被当前文件描述符捕获。 - 非阻塞模式无错误区分:同时使用等效的
O_NONBLOCK和O_NDELAY,发送请求后立即调用read,此时M4回复尚未到达,非阻塞模式下read直接返回-1(错误码EAGAIN),但代码未区分该临时错误与真正的读取失败。 - 缓冲区未初始化:读取失败时直接使用未初始化的
data数组,导致输出垃圾内容。 - M4发送长度可能错误:若
SendMsgVirt0Size为固定值而非实际消息长度,会导致发送不完整或冗余数据。
解决方案代码修改
1. A7端:持久化设备文件描述符
将设备打开操作移到程序初始化阶段,避免频繁开关:
#include <errno.h> static int rpmsg_fd = -1; // 程序启动时调用初始化 void rpmsg_init(void) { // 可选:使用阻塞模式(去掉O_NONBLOCK)简化逻辑;若保留非阻塞需后续处理EAGAIN rpmsg_fd = open("/dev/ttyRPMSG0", O_RDWR | O_NOCTTY); if (rpmsg_fd < 0) { g_print("CA7: Failed to open /dev/ttyRPMSG0, errno: %d\n", errno); } } // 程序退出时调用清理 void rpmsg_cleanup(void) { if (rpmsg_fd != -1) { close(rpmsg_fd); rpmsg_fd = -1; } }
2. A7端:修改读取函数逻辑
static gboolean update_M4_variable(gpointer user_data) { char data[32] = {0}; // 初始化缓冲区,避免垃圾值 char msg[128]; if (rpmsg_fd < 0) { gtk_label_set_text(GTK_LABEL(text_status), "RPMSG device not initialized"); return TRUE; } // 发送请求 ssize_t write_ret = write(rpmsg_fd, "xValue", 6); if (write_ret < 0) { snprintf(msg, sizeof(msg), "Send failed: errno %d", errno); gtk_label_set_text(GTK_LABEL(text_status), msg); return TRUE; } // 读取回复 int read_ret = read(rpmsg_fd, data, sizeof(data) - 1); // 留位置给字符串结束符 data[sizeof(data)-1] = '\0'; // 强制保证字符串终止 if (read_ret < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { snprintf(msg, sizeof(msg), "No data yet, retrying..."); } else { snprintf(msg, sizeof(msg), "Read error: errno %d", errno); } } else if (read_ret == 0) { snprintf(msg, sizeof(msg), "Remote connection closed"); } else { snprintf(msg, sizeof(msg), "Received: %s", data); } gtk_label_set_text(GTK_LABEL(text_status), msg); return TRUE; }
3. M4端:修正发送长度
确保发送的是实际消息长度,而非固定值:
// 替换原VIRT_UART_Transmit调用 uint16_t send_len = strlen((char*)SendMsgVirt0); VIRT_UART_Transmit(&huart0, SendMsgVirt0, send_len);
额外注意事项
- 检查设备节点权限:执行
sudo chmod 666 /dev/ttyRPMSG0测试是否因权限导致读取失败。 - 非阻塞模式优化:若坚持使用非阻塞,建议用
poll()或select()等待数据就绪后再调用read,避免无效重试。 - 验证RPMSG驱动:确认
rpmsg_char驱动已正确加载,可通过lsmod | grep rpmsg查看。
内容的提问来源于stack exchange,提问作者Telmo
相关产品推荐
相关产品推荐

